surfaceflinger对INVALIDATE和REFRESH消息的处理
Surfaceflinger初始化 VSync 调度器(Scheduler),控制 VSync事件的触发,以确保屏幕刷新和渲染管线的同步。surfaceflinger后续收到MessageQueue::INVALIDATE和MessageQueue::REFRESH消息。关于VSync的更多信息参考:DispSync,这里主要关注surfaceflinger对INVALIDATE和REFRESH消息的处理。
void SurfaceFlinger::initScheduler(DisplayId primaryDisplayId) {
mScheduler =
getFactory().createScheduler([this](bool enabled) { setPrimaryVsyncEnabled(enabled); },
*mRefreshRateConfigs, *this);
mAppConnectionHandle =
mScheduler->createConnection("app", mPhaseConfiguration->getCurrentOffsets().late.app,
impl::EventThread::InterceptVSyncsCallback());
mSfConnectionHandle =
mScheduler->createConnection("sf", mPhaseConfiguration->getCurrentOffsets().late.sf,
[this](nsecs_t timestamp) {
mInterceptor->saveVSyncEvent(timestamp);
});
mEventQueue->setEventConnection(mScheduler->getEventConnection(mSfConnectionHandle));
mVSyncModulator.emplace(*mScheduler, mAppConnectionHandle, mSfConnectionHandle,
mPhaseConfiguration->getCurrentOffsets());
}
MessageQueue
void MessageQueue::setEventConnection(const sp<EventThreadConnection>& connection) {
if (mEventTube.getFd() >= 0) {
mLooper->removeFd(mEventTube.getFd());
}
mEvents = connection;
mEvents->stealReceiveChannel(&mEventTube);
mLooper->addFd(mEventTube.getFd(), 0, Looper::EVENT_INPUT, MessageQueue::cb_eventReceiver,
this);
}
int MessageQueue::cb_eventReceiver(int fd, int events, void* data) {
MessageQueue* queue = reinterpret_cast<MessageQueue*>(data);
return queue->eventReceiver(fd, events);
}
int MessageQueue::eventReceiver(int /*fd*/, int /*events*/) {
ssize_t n;
DisplayEventReceiver::Event buffer[8];
while ((n = DisplayEventReceiver::getEvents(&mEventTube, buffer, 8)) > 0) {
for (int i = 0; i < n; i++) {
if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
mHandler->dispatchInvalidate(buffer[i].vsync.expectedVSyncTimestamp);
break;
}
}
}
return 1;
}
void MessageQueue::Handler::dispatchInvalidate(nsecs_t expectedVSyncTimestamp) {
if ((android_atomic_or(eventMaskInvalidate, &mEventMask) & eventMaskInvalidate) == 0) {
mExpectedVSyncTime = expectedVSyncTimestamp;
mQueue.mLooper->sendMessage(this, Message(MessageQueue::INVALIDATE));
}
}
void MessageQueue::Handler::handleMessage(const Message& message) {
switch (message.what) {
case INVALIDATE:
android_atomic_and(~eventMaskInvalidate, &mEventMask);
mQueue.mFlinger->onMessageReceived(message.what, mExpectedVSyncTime);
break;
case REFRESH:
android_atomic_and(~eventMaskRefresh, &mEventMask);
mQueue.mFlinger->onMessageReceived(message.what, mExpectedVSyncTime);
break;
}
}
SurfaceFlinger::onMessageReceived,surfaceflinger接收到消息。
void SurfaceFlinger::onMessageReceived(int32_t what, nsecs_t expectedVSyncTime) {
ATRACE_CALL();
switch (what) {
case MessageQueue::INVALIDATE: {
onMessageInvalidate(expectedVSyncTime);
break;
}
case MessageQueue::REFRESH: {
onMessageRefresh();
break;
}
}
}
- MessageQueue::INVALIDATE,调用onMessageInvalidate:latching new buffers and applying incoming transactions。
- 从应用获取最新的缓冲数据并将其锁定,以便进行合成和显示。
- 处理到来的transactions。
- MessageQueue::REFRESH,调用onMessageRefresh:sending the current frame down to RenderEngine and the Composer HAL for presentation.
把当前帧送给RenderEngine 和 HWC显示。
1. INVALIDATE
前面说过onMessageInvalidate的作用是从应用获取最新的缓冲数据并将其锁定,以便进行合成和显示,还有处理到来的transactions。
void SurfaceFlinger::onMessageInvalidate(nsecs_t expectedVSyncTime) {
bool refreshNeeded;
{
ConditionalLockGuard<std::mutex> lock(mTracingLock, mTracingEnabled);
refreshNeeded = handleMessageTransaction(); // 处理到来的transactions。
refreshNeeded |= handleMessageInvalidate(); // 从应用获取最新的缓冲数据并将其锁定,以便进行合成和显示。
}
updateCursorAsync(); //更新指针位置。
updateInputFlinger(); //sf更新InputWindowInfo:displayId, visible,touchableRegion等信息给if
refreshNeeded |= mRepaintEverything;
if (refreshNeeded && CC_LIKELY(mBootStage != BootStage::BOOTLOADER)) {
signalRefresh(); //请求Vsync信号
}
}
handleMessageTransaction,SurfaceFlinger类定义了两个SurfaceFlinger::State对象:
State mCurrentState{LayerVector::StateSet::Current};
,被binder线程更新。State mDrawingState{LayerVector::StateSet::Drawing};
,只能被surfaceflinger主线程访问。
State是SurfaceFlinger的内部类,stateSet变量是SortedVector<sp<Layer>>
类型,保存了所有的Layer指针,traverse
,traverseInZOrder
,traverseInReverseZOrder
分别实现了对stateSet进行遍历的方式。
class State {
public:
explicit State(LayerVector::StateSet set) : stateSet(set), layersSortedByZ(set) {}
State& operator=(const State& other) {
// We explicitly don't copy stateSet so that, e.g., mDrawingState
// always uses the Drawing StateSet.
layersSortedByZ = other.layersSortedByZ;
displays = other.displays;
colorMatrixChanged = other.colorMatrixChanged;
if (colorMatrixChanged) {
colorMatrix = other.colorMatrix;
}
globalShadowSettings = other.globalShadowSettings;
return *this;
}
const LayerVector::StateSet stateSet = LayerVector::StateSet::Invalid;
LayerVector layersSortedByZ;
DefaultKeyedVector< wp<IBinder>, DisplayDeviceState> displays;
bool colorMatrixChanged = true;
mat4 colorMatrix;
renderengine::ShadowSettings globalShadowSettings;
void traverse(const LayerVector::Visitor& visitor) const;
void traverseInZOrder(const LayerVector::Visitor& visitor) const;
void traverseInReverseZOrder(const LayerVector::Visitor& visitor) const;
};
handleMessageTransaction主要处理mTransactions部分。
bool SurfaceFlinger::handleMessageTransaction() {
ATRACE_CALL();
uint32_t transactionFlags = peekTransactionFlags();
bool flushedATransaction = flushTransactionQueues();
bool runHandleTransaction =
(transactionFlags && (transactionFlags != eTransactionFlushNeeded)) ||
flushedATransaction ||
mForceTraversal;
if (runHandleTransaction) {
handleTransaction(eTransactionMask);
} else {
getTransactionFlags(eTransactionFlushNeeded);
}
if (transactionFlushNeeded()) {
setTransactionFlags(eTransactionFlushNeeded);
}
return runHandleTransaction;
}
handleTransaction处理被binder线程更新后的mTransactionQueues,处理完成后将mCurrentState赋值给mDrawingState。
handleMessageInvalidate主要处理layer显示数据相关部分。
bool SurfaceFlinger::handleMessageInvalidate() {
ATRACE_CALL();
//1. 遍历mDrawingState所有layer,判断是否需要latch buffer.
bool refreshNeeded = handlePageFlip();
//2. 计算layer显示区域。
if (mVisibleRegionsDirty) {
computeLayerBounds();
}
//3. 更新display的dirtyRegion。
for (auto& layer : mLayersPendingRefresh) {
Region visibleReg;
visibleReg.set(layer->getScreenBounds());
invalidateLayerStack(layer, visibleReg);
}
mLayersPendingRefresh.clear();
return refreshNeeded;
}
- handlePageFlip: 如果layer->hasReadyFrame()且
layer->shouldPresentNow(expectedPresentTime)
,则添加到mLayersWithQueuedFrames,后续对mLayersWithQueuedFrames所有的layer进行latchBuffer
,锁定缓冲数据,并添加到SurfaceFlinger的mLayersPendingRefresh变量中。 - 计算layer显示区域,
layer->computeBounds
。参考Layer显示区域计算 - 根据
layer->getScreenBounds()
,更新对应display的dirtyRegion。
2. REFRESH
前面说过onMessageRefresh方法的作用是把当前帧送给RenderEngine 和 HWC显示。
void SurfaceFlinger::onMessageRefresh() {
ATRACE_CALL();
mRefreshPending = false;
// 1.初始化CompositionRefreshArgs
// 1.1. 创建CompositionRefreshArgs对象。
compositionengine::CompositionRefreshArgs refreshArgs;
// 1.2. outputs, 所有需要被刷新的Outputs
const auto& displays = ON_MAIN_THREAD(mDisplays);
refreshArgs.outputs.reserve(displays.size());
for (const auto& [_, display] : displays) {
refreshArgs.outputs.push_back(display->getCompositionDisplay());
}
// 1.3. layers,所有可能在outputs可见的layer,顺序很重要,应该从后往前遍历。
mDrawingState.traverseInZOrder([&refreshArgs](Layer* layer) {
if (auto layerFE = layer->getCompositionEngineLayerFE())
refreshArgs.layers.push_back(layerFE);
});
// 1.4. layersWithQueuedFrames,所有锁定缓存的layer,INVALIDATE阶段handlePageFlip时更新mLayersWithQueuedFrames。
refreshArgs.layersWithQueuedFrames.reserve(mLayersWithQueuedFrames.size());
for (sp<Layer> layer : mLayersWithQueuedFrames) {
if (auto layerFE = layer->getCompositionEngineLayerFE())
refreshArgs.layersWithQueuedFrames.push_back(layerFE);
}
// 1.5. repaintEverything,如果为true,强制认为整个display都为dirty并且重。赋值后将mRepaintEverything赋为false。
refreshArgs.repaintEverything = mRepaintEverything.exchange(false);
// 1.6. outputColorSetting,色彩设置。
refreshArgs.outputColorSetting = useColorManagement
? mDisplayColorSetting
: compositionengine::OutputColorSetting::kUnmanaged;
// 1.7. colorSpaceAgnosticDataspace,色彩空间。
refreshArgs.colorSpaceAgnosticDataspace = mColorSpaceAgnosticDataspace;
// 1.8. forceOutputColorMode,强制色彩模式。
refreshArgs.forceOutputColorMode = mForceColorMode;
// 1.9. updatingOutputGeometryThisFrame,如果true,这个frame的geometry将会被重新计算。
refreshArgs.updatingOutputGeometryThisFrame = mVisibleRegionsDirty;
// 1.10. updatingGeometryThisFrame,如果true,这个framw的geometry被更新过。
refreshArgs.updatingGeometryThisFrame = mGeometryInvalid || mVisibleRegionsDirty;
// 1.11. blursAreExpensive,如果true,GPU渲染blur区域会增加时钟频率。
refreshArgs.blursAreExpensive = mBlursAreExpensive;
// 1.12. internalDisplayRotationFlags,处理屏幕旋转的情况。
refreshArgs.internalDisplayRotationFlags = DisplayDevice::getPrimaryDisplayRotationFlags();
// 1.13. colorTransformMatrix,色彩矩阵color matrix。
if (CC_UNLIKELY(mDrawingState.colorMatrixChanged)) {
refreshArgs.colorTransformMatrix = mDrawingState.colorMatrix;
mDrawingState.colorMatrixChanged = false;
}
// 1.14. devOptForceClientComposition,强制client合成。
refreshArgs.devOptForceClientComposition = mDebugDisableHWC || mDebugRegion;
// 1.15. devOptFlashDirtyRegionsDelay,如果设置了此项,dirty区域在一定时间后闪烁。
if (mDebugRegion != 0) {
refreshArgs.devOptFlashDirtyRegionsDelay =
std::chrono::milliseconds(mDebugRegion > 1 ? mDebugRegion : 0);
}
mGeometryInvalid = false;
// Store the present time just before calling to the composition engine so we could notify
// the scheduler.
const auto presentTime = systemTime();
// 2. 将refreshArgs发送给compositionEngine。
mCompositionEngine->present(refreshArgs);
mTimeStats->recordFrameDuration(mFrameStartTime, systemTime());
// Reset the frame start time now that we've recorded this frame.
mFrameStartTime = 0;
// 3. 通知调度器刷新时间,判断是否要再次发送REFRESH信号。
mScheduler->onDisplayRefreshed(presentTime);
// 4. 合成工作完成,善后。
postFrame();
postComposition();
const bool prevFrameHadDeviceComposition = mHadDeviceComposition;
mHadClientComposition = std::any_of(displays.cbegin(), displays.cend(), [](const auto& pair) {
const auto& state = pair.second->getCompositionDisplay()->getState();
return state.usesClientComposition && !state.reusedClientComposition;
});
mHadDeviceComposition = std::any_of(displays.cbegin(), displays.cend(), [](const auto& pair) {
const auto& state = pair.second->getCompositionDisplay()->getState();
return state.usesDeviceComposition;
});
mReusedClientComposition =
std::any_of(displays.cbegin(), displays.cend(), [](const auto& pair) {
const auto& state = pair.second->getCompositionDisplay()->getState();
return state.reusedClientComposition;
});
// Only report a strategy change if we move in and out of composition with hw overlays
if (prevFrameHadDeviceComposition != mHadDeviceComposition) {
mTimeStats->incrementCompositionStrategyChanges();
}
// TODO: b/160583065 Enable skip validation when SF caches all client composition layers
mVSyncModulator->onRefreshed(mHadClientComposition || mReusedClientComposition);
mLayersWithQueuedFrames.clear();
if (mVisibleRegionsDirty) {
mVisibleRegionsDirty = false;
if (mTracingEnabled && mAddCompositionStateToTrace) {
mTracing.notify("visibleRegionsDirty");
}
}
if (mCompositionEngine->needsAnotherUpdate()) {
signalLayerUpdate();
}
}
onMessageRefresh主要做了4部分工作:
- 根据sf当前状态,初始化CompositionRefreshArgs。
- 将CompositionRefreshArgs发送给compositionEngine,通知其开始合成工作。
- 通知调度器刷新时间,判断是否要再次发送REFRESH信号。
- 合成工作完成,
postFrame()
和postComposition()
处理善后工作。
对于第一点就不细化了,代码中的注释都写明了,最重要的操作在第二点mCompositionEngine->present(refreshArgs);
。
2.1 CompositionEngine::present
// CompositionEngine.cpp
void CompositionEngine::present(CompositionRefreshArgs& args) {
ATRACE_CALL();
ALOGV(__FUNCTION__);
// 1.遍历args.layers,layer->onPreComposition判断是否hasReadyFrame,如果true则给mNeedsAnotherUpdate赋值true。
preComposition(args);
{
// latchedLayers is used to track the set of front-end layer state that
// has been latched across all outputs for the prepare step, and is not
// needed for anything else.
LayerFESet latchedLayers;
// 2.output->prepare, 输出设备的准备工作,更新OutputLayers。
for (const auto& output : args.outputs) {
output->prepare(args, latchedLayers);
}
}
// 3.每个layer更新各自状态:LayerFECompositionState。
updateLayerStateFromFE(args);
// 4.显示
for (const auto& output : args.outputs) {
output->present(args);
}
}
- 遍历args.layers,
layer->onPreComposition
判断是否hasReadyFrame,如果true则给mNeedsAnotherUpdate赋值true。不是很重要的开始工作。 output->prepare
, 输出设备的准备工作,更新OutputLayers。- 每个layer更新各自状态:
LayerFECompositionState
。 - 显示,合成的最后一个工作。
下面分别关注一下2、3、4点。
2.1.1 Output::prepare
//Output.cpp
void Output::prepare(const compositionengine::CompositionRefreshArgs& refreshArgs,
LayerFESet& geomSnapshots) {
rebuildLayerStacks(refreshArgs, geomSnapshots);
}
//Output.cpp
void Output::rebuildLayerStacks(const compositionengine::CompositionRefreshArgs& refreshArgs,
LayerFESet& layerFESet) {
ATRACE_CALL();
ALOGV(__FUNCTION__);
// 1.获取OutputCompositionState mState对象开始编辑。
auto& outputState = editState();
// Do nothing if this output is not enabled or there is no need to perform this update
if (!outputState.isEnabled || CC_LIKELY(!refreshArgs.updatingOutputGeometryThisFrame)) {
return;
}
// 2.收集所有可见的OutputLayer到mCurrentOutputLayersOrderedByZ保存。
// Process the layers to determine visibility and coverage
compositionengine::Output::CoverageState coverage{layerFESet};
collectVisibleLayers(refreshArgs, coverage);
// Compute the resulting coverage for this output, and store it for later
const ui::Transform& tr = outputState.transform;
Region undefinedRegion{outputState.displaySpace.getBoundsAsRect()};
undefinedRegion.subtractSelf(tr.transform(coverage.aboveOpaqueLayers));
// 3.更新undefinedRegion:display的undefined region的逻辑坐标;
// 更新dirtyRegion:display的dirty region的逻辑坐标;
outputState.undefinedRegion = undefinedRegion;
outputState.dirtyRegion.orSelf(coverage.dirtyRegion);
}
android::compositionengine::impl::Output类OutputCompositionState mState
;变量保存了output对象的合成状态,比如使用client合成或者device合成,layerStackId,viewport等,还有两个很重要的和layer相关的变量:std::vector<std::unique_ptr<OutputLayer>> mCurrentOutputLayersOrderedByZ;
, std::vector<std::unique_ptr<OutputLayer>> mPendingOutputLayersOrderedByZ;
,OutputLayer表示layer映射到display的状态,mPendingOutputLayersOrderedByZ在collectVisibleLayers
操作完成后赋值给mCurrentOutputLayersOrderedByZ,表示所有可见的layer需要显示到display上。
回到rebuildLayerStacks,主要有3个步骤:
- 获取OutputCompositionState mState对象开始编辑,步骤3中会更新undefinedRegion、dirtyRegion。
- 收集所有可见的OutputLayer到mCurrentOutputLayersOrderedByZ保存。
- 更新步骤1中的OutputCompositionState属性,undefinedRegion:display的undefined region的逻辑坐标;更新dirtyRegion:display的dirty region的逻辑坐标;
collectVisibleLayers方法很关键,步骤也很多,主要作用是从前往后遍历surfaceflinger传递过来的CompositionRefreshArgs.layers
,判断是否可见,如果可见添加到mCurrentOutputLayersOrderedByZ。
2.1.2 CompositionEngine::updateLayerStateFromFE
//CompositionEngine.cpp
void CompositionEngine::updateLayerStateFromFE(CompositionRefreshArgs& args) {
// Update the composition state from each front-end layer
for (const auto& output : args.outputs) {
output->updateLayerStateFromFE(args);
}
}
遍历所有output,通知updateLayerStateFromFE。
//Output.cpp
void Output::updateLayerStateFromFE(const CompositionRefreshArgs& args) const {
for (auto* layer : getOutputLayersOrderedByZ()) {
layer->getLayerFE().prepareCompositionState(
args.updatingGeometryThisFrame ? LayerFE::StateSubset::GeometryAndContent
: LayerFE::StateSubset::Content);
}
}
遍历每个output中的所有layer(getOutputLayersOrderedByZ()
返回的就是上文提到的mCurrentOutputLayersOrderedByZ
),通知prepareCompositionState。
layer根据传递过来的状态参数选择更新范围:
- LayerFE::StateSubset::BasicGeometry:获取layer的基本几何信息(bounds、ransparent region、visibility、transforms、alpha),用于计算可见性和覆盖范围。调用
prepareBasicGeometryCompositionState()
。 - LayerFE::StateSubset::GeometryAndContent:获取layer的完整几何信息(crops、buffer transforms、metadata)及内容状态(buffer or color)。调用
prepareBasicGeometryCompositionState()
、prepareGeometryCompositionState()
、preparePerFrameCompositionState()
。 - LayerFE::StateSubset::Content:获取layer的内容状态(buffer or color)。调用
preparePerFrameCompositionState()
。 - LayerFE::StateSubset::Cursor:获取layer的指针状态。调用
prepareCursorCompositionState()
。
上述的layer的这些状态,都是用LayerFECompositionState
对象表示。
2.1.3 CompositionEngine::present
void Output::present(const compositionengine::CompositionRefreshArgs& refreshArgs) {
ATRACE_CALL();
ALOGV(__FUNCTION__);
// 1.更新ColorProfile.
updateColorProfile(refreshArgs);
// 2.编译OutputLayer,更新OutputCompositionState
updateCompositionState(refreshArgs);
// 3.调用mPlaner->plan,在确定合成策略之前,使用当前的图层集合更新 Planner。
planComposition();
// 4.更新Ouput.mState:earliestPresentTime,previousPresentFence,expectedPresentTime,outputLayerHash
writeCompositionState(refreshArgs);
// 5.更新Ouput.mState:colorTransformMatrix,dirtyRegion
setColorTransform(refreshArgs);
// 6.调用mRenderSurface->beginFrame。
beginFrame();
// 7.判断合成模式是否可预测,如果可预测prepareFrameAsync直接开始合成工作,否则prepareFrame计算合成模式更新状态。
GpuCompositionResult result;
const bool predictCompositionStrategy = canPredictCompositionStrategy(refreshArgs);
if (predictCompositionStrategy) {
result = prepareFrameAsync(refreshArgs);
} else {
// prepareFrame:选择渲染模式,更新OutputLayer:如果有对应的hwcLayer,更新OutputLayerCompositionState.hwc.hwcCompositionType,OutputLayerCompositionState.clearClientTarget;
// 更新OUtput.mState:flipClientTarget,clearClientTarget,dataspace,clientTargetBrightness,clientTargetDimmingStage,usesClientComposition,usesDeviceComposition;
// 更新state.usesClientComposition、state.usesDeviceComposition
prepareFrame();
}
// 8.如果脏区域不为空,开始合成工作。
devOptRepaintFlash(refreshArgs);
// 9.mRenderSurface提交合成的buffer。
finishFrame(refreshArgs, std::move(result));
// 10.清空脏区域,等Fence信号触发后,释放mRenderSurface的mPreviousBuffer,让BufferQueue可以复用该缓冲区;释放各BufferQueueLayer的Buffer,让BufferQueue可以复用该缓冲区。
postFramebuffer();
// 11.渲染第3步缓存的layer集合,复用多个图层(Layers)合成后的结果。
renderCachedSets(refreshArgs);
}
- 更新ColorProfile。
- 编译OutputLayer,更新OutputCompositionState。
- 调用mPlaner->plan,在确定合成策略之前,使用当前的图层集合更新 Planner。plan方法更新 Layer 变化:比对 mPreviousLayers 和 layers,标记哪些 Layer 新增、移除或更新。根据当前layer:mCurrentLayers计算Hash值,Flattener将mCurrentLayers和Hash值对应,合并冗余图层,后续第11步统一渲染这些图层。
- 更新Ouput.mState:earliestPresentTime,previousPresentFence,expectedPresentTime,outputLayerHash。
- 更新Ouput.mState:colorTransformMatrix,dirtyRegion。
- 调用mRenderSurface->beginFrame。RenderSurface继续调用其类变量
mDisplaySurface->beginFrame(mustRecompose)
;,mDisplaySurface是一个FrameBuffreSurface
对象,其beginFrame()
实现为空。每个Output(或者说是DisplayDevice)都有一个mRenderSurface对象,在DisplayDevice初始化时被创建,DisplayDevice初始化时还有同时创建一个生产者消费者队列IGraphicBufferProducer
、IGraphicBufferConsumer
,producer被关联到DisplayDevice对象的RenderSurface的ANativeWindow
对象,RenderSurface就是这个DisplayDevice生产者消费者模型中的生产者,后续dequeueBuffer和dequeueBuffer实际操作对象都是const sp<ANativeWindow> mNativeWindow;
,也就是每个Display都会将其要显示的所有layer合成都这个ANativeWindow中显示。关于ANativeWindow参考安卓硬件加速hwui。那么RenderSurface的constsp<DisplaySurface> mDisplaySurface;
变量又是做什么的,FrameBufferSurface
实现了DisplaySurface接口,它也在DisplayDevice初始化时被同时创建,关联了consumer,FrameBufferSurface就是这个DisplayDevice生产者消费者模型中的消费者。 - 判断合成模式是否可预测,如果可预测prepareFrameAsync直接开始合成工作,否则prepareFrame计算合成模式更新状态。surfaceflinger有两种合成模式:HWC、Client,HWC直接让显示控制器(Display HAL)合成多个 Layer,节省 GPU 计算,适用于 静态内容(例如 UI 按钮、视频播放),Client合成使用 GPU 合成多个 Layer 到单个缓冲区,再交给显示设备,适用于复杂变换(例如透明度、滤镜、旋转等),预测(Prediction)就是提前判断应该使用哪种合成方式,避免 GPU 过度计算,提高帧率。如果
refreshArgs.devOptFlashDirtyRegionsDelay
(脏区域在一定延迟后刷新)或者lastOutputLayerHash != outputLayerHash
(outputLayerHash在第3步骤更新,通过hash值判断当前帧与上一帧layer不一致)那么就是不可预测的。- prepareFrameAsync
因为合成模式可预测,应用上一帧的合成策略state.previousDeviceRequestedChanges;
,开始合成工作;生产者mRenderSurface通过mNativeWindow申请缓存dequeueBuffer
,调用Output::composeSurfaces
,初始化renderengine::DisplaySettings,调用renderEngine.drawLayers
将GraphicBuffer合成到ExternalTexture。后续再判断一下合成模式是否预测成功,如果失败重新应用新计算的模式。 - prepareFrame
计算合成模式,记录到outputState.previousDeviceRequestedChanges
,应用合成模式:如果有对应的hwcLayer,更新OutputLayerCompositionState.hwc.hwcCompositionType,OutputLayerCompositionState.clearClientTarget,更新OUtput.mState:flipClientTarget,clearClientTarget,dataspace,clientTargetBrightness,clientTargetDimmingStage,usesClientComposition,usesDeviceComposition,更新state.usesClientComposition、state.usesDeviceComposition。更新mRenderSurface的合成模式:state.usesClientComposition选择CompositionType::Gpu
,state.usesDeviceComposition选择CompositionType::Hwc
,如果都为true选择CompositionType::Mixed
。
- prepareFrameAsync
- 如果脏区域不为空,开始合成工作,同步骤7.1;调用postFramebuffer(),同步骤10。调用prepareFrame(),同步骤7.2。
- 生产者mRenderSurface提交缓存
queueBuffer
,通知消费者mDisplaySurface
开始消费acquireBufferLocked
,此时显示画面。 - 清空脏区域,等Fence信号触发后,消费者
mDisplaySurface
释放缓存releaseBufferLocked
,让BufferQueue可以复用该缓冲区(在这里surfaceflinger作为生产者,负责合成最终的屏幕图像,并将其提交给显示设备(Display HAL));释放各BufferQueueLayer的Buffer,让BufferQueue可以复用该缓冲区(在这里surfaceflinger作为消费者,从 应用进程或 GPU 获取图像数据,处理并准备进行合成)。 - 渲染第3步缓存的layer集合,复用多个图层(Layers)合成后的结果。
上文中所提到的各种类UML关系图: