onMessageRefresh
compositionengine::CompositionRefreshArgs:Layer合成的数据结构
Layers和Outputs分别是相关layer和Display的基类,大部分的接口,在这两个基类中体现,可以由子类覆写相关方法
using Layers = std::vector<sp<compositionengine::LayerFE>>;
using Outputs = std::vector<std::shared_ptr<compositionengine::Output>>;
/**
* A parameter object for refreshing a set of outputs
*/
struct CompositionRefreshArgs {
// All the outputs being refreshed
Outputs outputs;
// All the layers that are potentially visible in the outputs. The order of
// the layers is important, and should be in traversal order from back to
// front.
Layers layers;
// All the layers that have queued updates.
Layers layersWithQueuedFrames;
// If true, forces the entire display to be considered dirty and repainted
bool repaintEverything{false};
DisplayDevice : mDisplays,一般就一个。DisplayDevice ----> compositionengine::Display ---> Output
所以大部分方法是在Output实现的
// this may only be written from the main thread with mStateLock held
// it may be read from other threads with mStateLock held
std::map<wp<IBinder>, sp<DisplayDevice>> mDisplays GUARDED_BY(mStateLock);
class DisplayDevice : public LightRefBase<DisplayDevice> {//强引用
private:
const sp<SurfaceFlinger> mFlinger; //surfaceFlinger
const wp<IBinder> mDisplayToken; // 支持多屏幕,每一块屏幕,一个Ibinder
const int32_t mSequenceId;
const std::optional<DisplayConnectionType> mConnectionType;
const std::shared_ptr<compositionengine::Display> mCompositionDisplay; //合成设备主体,接口
/**
* A display is a composition target which may be backed by a hardware composer
* display device
*/
class Display : public virtual Output {
refreshArgs.outputs.push_back:将合成设备push到参数中
void SurfaceFlinger::onMessageRefresh() {
ATRACE_CALL();
mRefreshPending = false;
compositionengine::CompositionRefreshArgs refreshArgs;
const auto& displays = ON_MAIN_THREAD(mDisplays);
refreshArgs.outputs.reserve(displays.size());
for (const auto& [_, display] : displays) {
refreshArgs.outputs.push_back(display->getCompositionDisplay());
}
将需要合成的图层push_back到合成参数中
SurfaceFlinger类有两个类型为State的成员变量mCurrentState和mDrawingState。其中,成员变量mCurrentState用来描述系统下一次要渲染的UI的状态;而mDrawingState用来描述当前正在渲染的UI的状态。
mDrawingState.traverseInZOrder([&refreshArgs](Layer* layer) {
if (auto layerFE = layer->getCompositionEngineLayerFE())//asLayerFE()
refreshArgs.layers.push_back(layerFE);
});
layersWithQueuedFrames
refreshArgs.layersWithQueuedFrames.reserve(mLayersWithQueuedFrames.size());
for (sp<Layer> layer : mLayersWithQueuedFrames) {
if (auto layerFE = layer->getCompositionEngineLayerFE())
refreshArgs.layersWithQueuedFrames.push_back(layerFE);
}
refreshArgs中的一些重要参数
refreshArgs.repaintEverything = mRepaintEverything.exchange(false);
refreshArgs.updatingOutputGeometryThisFrame = mVisibleRegionsDirty;//在handleTransaction会更新
refreshArgs.updatingGeometryThisFrame = mGeometryInvalid || mVisibleRegionsDirty;
refreshArgs.blursAreExpensive = mBlursAreExpensive;
refreshArgs.internalDisplayRotationFlags = DisplayDevice::getPrimaryDisplayRotationFlags();
(49条消息) Android系统Surface机制的SurfaceFlinger服务渲染应用程序UI的过程分析_老罗的Android之旅-CSDN博客_android surfaceflinger
CompositionEngine->present
R和Q上的区别
mCompositionEngine->present(refreshArgs);
/*
preComposition();
rebuildLayerStacks();
calculateWorkingSet();
for (const auto& [token, display] : mDisplays) {
beginFrame(display);
prepareFrame(display);
doDebugFlashRegions(display, repaintEverything);
doComposition(display, repaintEverything);
}
logLayerStats();
*/
postFrame(); // 通知composer,即HWC
postComposition();// 回调每个layer的onPostComposition
// 清空mLayersWithQueuedFrames,下一次vsync来到时,会在handlePageFlip中重新添加
mLayersWithQueuedFrames.clear();
if (mCompositionEngine->needsAnotherUpdate()) {
signalLayerUpdate();
}
// 合成前再过一遍Layer是否被更新了
// 如果有则触发signalLayerUpdate(),通过EventThread安排一次invalidate sf vsync。
void CompositionEngine::present(CompositionRefreshArgs& args) {
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;
for (const auto& output : args.outputs) {
output->prepare(args, latchedLayers);
}
}
updateLayerStateFromFE(args);
for (const auto& output : args.outputs) {
output->present(args);
}
}
1 CompositionEngine::preComposition
合成前的准备工作
layersSortedByZ中存储的layer都是SurfaceFlinger.addClientLayer过程中添加的。
bool needsAnotherUpdate = false;
for (auto& layer : args.layers) {
// 调用每个Layer的预合成接口
if (layer->onPreComposition(mRefreshStartTime)) {
needsAnotherUpdate = true;
}
}
mNeedsAnotherUpdate = needsAnotherUpdate;
BufferLayer::onPreComposition
基类没有实现该方法,后续子类也没有覆写该方法
bool BufferLayer::onPreComposition(nsecs_t refreshStartTime) {
if (mBufferInfo.mBuffer != nullptr) {
Mutex::Autolock lock(mFrameEventHistoryMutex);
mFrameEventHistory.addPreComposition(mCurrentFrameNumber, refreshStartTime);
}
mRefreshPending = false;
return hasReadyFrame();
}
/*
bool BufferLayer::hasReadyFrame() const {
return hasFrameUpdate() || getSidebandStreamChanged() || getAutoRefresh();
}
*/
hasReadyFrame
BufferQueueLayer实现了该方法
只在onFrameAvailable中递增,说明在这一帧合成的时候,app已绘制好下一帧
bool BufferQueueLayer::hasFrameUpdate() const {
return mQueuedFrames > 0;
}
mQueueItems.push_back(item);
mQueuedFrames++;
3 updateLayerStateFromFE
getOutputLayersOrderedByZ这里是最新的outputLayer
再去更新对应layer
void CompositionEngine::updateLayerStateFromFE(CompositionRefreshArgs& args) {
// Update the composition state from each front-end layer
for (const auto& output : args.outputs) {
output->updateLayerStateFromFE(args);
}
}
void Output::updateLayerStateFromFE(const CompositionRefreshArgs& args) const {
for (auto* layer : getOutputLayersOrderedByZ()) {
layer->getLayerFE().prepareCompositionState(
args.updatingGeometryThisFrame ? LayerFE::StateSubset::GeometryAndContent
: LayerFE::StateSubset::Content);
}
}
确认合成方式,复制layer属性
这里可以定制合成方式,如果layer是受保护的,
策略:只在主设备显示,只用client合成。这样子投屏就不会有该layer
也可以在截屏时定制
compositionState->forceClientComposition
void Layer::prepareCompositionState(compositionengine::LayerFE::StateSubset subset) {
using StateSubset = compositionengine::LayerFE::StateSubset;
switch (subset) {
case StateSubset::BasicGeometry:
prepareBasicGeometryCompositionState();
/*auto* compositionState = editCompositionState();
compositionState->internalOnly = getPrimaryDisplayOnly();*/
break;
case StateSubset::GeometryAndContent:
prepareBasicGeometryCompositionState();
prepareGeometryCompositionState();
preparePerFrameCompositionState();
/*compositionState->forceClientComposition = true;*/
break;
case StateSubset::Content:
preparePerFrameCompositionState();
break;
case StateSubset::Cursor:
prepareCursorCompositionState();
break;
}
}
2 output->prepare
{
// 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;
for (const auto& output : args.outputs) {
output->prepare(args, latchedLayers);
}
}
// 1.3 重建layer堆栈, 提取可见的Laye并计算可见区域 // 并将数据更新给对应的Display
移出之前的outputLayer,依据可见性,生成新的outputLayer
// Prepare the output, updating the OutputLayers used in the output
void Output::prepare(const compositionengine::CompositionRefreshArgs& refreshArgs,
LayerFESet& geomSnapshots) {
ATRACE_CALL();
ALOGV(__FUNCTION__);
rebuildLayerStacks(refreshArgs, geomSnapshots);
}
rebuildLayerStacks
mVisibleRegionsDirty;//在遍历layer时为true,说明有layer内容发生了变化
auto& outputState = editState();
// Process the layers to determine visibility and coverage
compositionengine::Output::CoverageState coverage{layerFESet};//包含不透明区域,脏区域
// 收集可见区域发生变化的Layer
collectVisibleLayers(refreshArgs, coverage);
// Compute the resulting coverage for this output, and store it for later
const ui::Transform& tr = outputState.transform;
Region undefinedRegion{outputState.bounds};
undefinedRegion.subtractSelf(tr.transform(coverage.aboveOpaqueLayers));
outputState.undefinedRegion = undefinedRegion;
outputState.dirtyRegion.orSelf(coverage.dirtyRegion);
}
collectVisibleLayers
finalizePendingOutputLayers会更新mCurrentOutputLayersOrderedByZ
void Output::collectVisibleLayers(const compositionengine::CompositionRefreshArgs& refreshArgs,
compositionengine::Output::CoverageState& coverage) {
// Evaluate the layers from front to back to determine what is visible. This
// also incrementally calculates the coverage information for each layer as
// well as the entire output.
for (auto layer : reversed(refreshArgs.layers)) {
// Incrementally process the coverage for each layer
ensureOutputLayerIfVisible(layer, coverage);
// TODO(b/121291683): Stop early if the output is completely covered and
// no more layers could even be visible underneath the ones on top.
}
setReleasedLayers(refreshArgs);
finalizePendingOutputLayers();
// Generate a simple Z-order values to each visible output layer
uint32_t zOrder = 0;
for (auto* outputLayer : getOutputLayersOrderedByZ()) {
outputLayer->editState().z = zOrder++;
}
}
ensureOutputLayerIfVisible
如果可见,需要生成一个outputLayer,放在mPendingOutputLayersOrderedByZ
// Get coverage information for the layer as previously displayed,
// also taking over ownership from mOutputLayersorderedByZ.
auto prevOutputLayerIndex = findCurrentOutputLayerForLayer(layerFE);
auto prevOutputLayer =
prevOutputLayerIndex ? getOutputLayerOrderedByZByIndex(*prevOutputLayerIndex) : nullptr;
// The layer is visible. Either reuse the existing outputLayer if we have
// one, or create a new one if we do not.
auto result = ensureOutputLayer(prevOutputLayerIndex, layerFE);
ensureOutputLayer
181 OutputLayer* ensureOutputLayer(std::optional<size_t> prevIndex,
182 const sp<LayerFE>& layerFE) {
183 auto outputLayer = (prevIndex && *prevIndex <= mCurrentOutputLayersOrderedByZ.size())
184 ? std::move(mCurrentOutputLayersOrderedByZ[*prevIndex])
185 : BaseOutput::createOutputLayer(layerFE);
186 auto result = outputLayer.get();
187 mPendingOutputLayersOrderedByZ.emplace_back(std::move(outputLayer));
188 return result;
189 }
// A helper function for enumerating all the output layers in Z order using
// a C++11 range-based for loop.
auto getOutputLayersOrderedByZ() const { return OutputLayersEnumerator(*this); }
setReleasedLayers
Display
// For layers that are being removed from a HWC display, and that have
// queued frames, add them to a a list of released layers so we can properly
// set a fence.
compositionengine::Output::ReleasedLayers releasedLayers;
// Any non-null entries in the current list of layers are layers that are no
// longer going to be visible
for (auto* outputLayer : getOutputLayersOrderedByZ()) {
if (!outputLayer) {
continue;
}
compositionengine::LayerFE* layerFE = &outputLayer->getLayerFE();
const bool hasQueuedFrames =
std::any_of(refreshArgs.layersWithQueuedFrames.cbegin(),
refreshArgs.layersWithQueuedFrames.cend(),
[layerFE](sp<compositionengine::LayerFE> layerWithQueuedFrames) {
return layerFE == layerWithQueuedFrames.get();
});
if (hasQueuedFrames) {
releasedLayers.emplace_back(layerFE);
}
}
setReleasedLayers(std::move(releasedLayers));
void finalizePendingOutputLayers() override {
// The pending layers are added in reverse order. Reverse them to
// get the back-to-front ordered list of layers.
std::reverse(mPendingOutputLayersOrderedByZ.begin(),
mPendingOutputLayersOrderedByZ.end());
mCurrentOutputLayersOrderedByZ = std::move(mPendingOutputLayersOrderedByZ);
}
4 output->present
前期准备工作就绪,这里开始合成正式工作
for (const auto& output : args.outputs) {
output->present(args);
}
void Output::present(const compositionengine::CompositionRefreshArgs& refreshArgs) {
ATRACE_CALL();
ALOGV(__FUNCTION__);
updateColorProfile(refreshArgs);
updateAndWriteCompositionState(refreshArgs);
setColorTransform(refreshArgs);
beginFrame();
prepareFrame();
devOptRepaintFlash(refreshArgs);
// 1.6 正式的合成处理,简单来说就是申请GraphicBuffer,向其中填充帧数据
// 最终给到硬件帧缓冲区
finishFrame(refreshArgs);
postFramebuffer();
}
(49条消息) Android UI架构(九)--探秘刷新动力Vsync(5)之Layer合成composer.md_SwallowJoe的博客-CSDN博客
updateAndWriteCompositionState
对每一个outputlayer更新状态,并告知HWC
for (auto* layer : getOutputLayersOrderedByZ()) {
layer->updateCompositionState(refreshArgs.updatingGeometryThisFrame,
refreshArgs.devOptForceClientComposition ||
forceClientComposition,
refreshArgs.internalDisplayRotationFlags);
if (mLayerRequestingBackgroundBlur == layer) {
forceClientComposition = false;
}
// Send the updated state to the HWC, if appropriate.
layer->writeStateToHWC(refreshArgs.updatingGeometryThisFrame);
}
updateCompositionState
更新属性后,writeStateToHWC
const auto* layerFEState = getLayerFE().getCompositionState();
// These are evaluated every frame as they can potentially change at any
// time.
if (layerFEState->forceClientComposition || !profile.isDataspaceSupported(state.dataspace) ||
forceClientComposition) {
state.forceClientComposition = true;
}
beginFrame
mRenderSurface->beginFrame(mustRecompose);
prepareFrame
chooseCompositionStrategy
之前告知了HWC,现在需要HWC如何合成,有变化,进行更新
Display
// Get any composition changes requested by the HWC device, and apply them.
std::optional<android::HWComposer::DeviceRequestedChanges> changes;
auto& hwc = getCompositionEngine().getHwComposer();
if (status_t result = hwc.getDeviceCompositionChanges(*mId, anyLayersRequireClientComposition(),
&changes);
if (changes) {
applyChangedTypesToLayers(changes->changedTypes);
applyDisplayRequests(changes->displayRequests);
applyLayerRequestsToLayers(changes->layerRequests);
applyClientTargetRequests(changes->clientTargetProperty);
}
compositionengine
virtual bool needsAnotherUpdate() const = 0;
void updateLayerStateFromFE(CompositionRefreshArgs& args);
std::unique_ptr<HWComposer> mHwComposer;
std::unique_ptr<renderengine::RenderEngine> mRenderEngine;
「Android」SurfaceFlinger分析 - sunwengang - 博客园 (cnblogs.com)
Output
/**
* Encapsulates all the state involved with composing layers for an output
*/
class Output {
// Gets the current render surface for the output
virtual RenderSurface* getRenderSurface() const = 0;
// Prepare the output, updating the OutputLayers used in the output
virtual void prepare(const CompositionRefreshArgs&, LayerFESet&) = 0;
// Presents the output, finalizing all composition details
virtual void present(const CompositionRefreshArgs&) = 0;
/**
* A display is a composition target which may be backed by a hardware composer
* display device
*/
class Display : public virtual Output {
LayerFE
namespace impl {
struct OutputLayerCompositionState;
} // namespace impl
using CompositionState = compositionengine::impl::OutputLayerCompositionState;
// Gets the raw composition state data for the layer
// TODO(lpique): Make this protected once it is only internally called.
virtual const CompositionState& getState() const = 0;
// Allows mutable access to the raw composition state data for the layer.
// This is meant to be used by the various functions that are part of the
// composition process.
// TODO(lpique): Make this protected once it is only internally called.
virtual CompositionState& editState() = 0;
namespace android {
class Fence;
namespace compositionengine {
struct LayerFECompositionState;
// Defines the interface used by the CompositionEngine to make requests
// of the front-end layer
class LayerFE : public virtual RefBase {
public:
// Gets the raw front-end composition state data for the layer
virtual const LayerFECompositionState* getCompositionState() const = 0;
// Called before composition starts. Should return true if this layer has
// pending updates which would require an extra display refresh cycle to
// process.
virtual bool onPreComposition(nsecs_t refreshStartTime) = 0;
RenderSurface
纯虚函数
// Called to signal that rendering has started. 'mustRecompose' should be
// true if the entire frame must be recomposed.
virtual status_t beginFrame(bool mustRecompose) = 0;
// Prepares the frame for rendering
virtual void prepareFrame(bool usesClientComposition, bool usesDeviceComposition) = 0;
// Allocates a buffer as scratch space for GPU composition
virtual sp<GraphicBuffer> dequeueBuffer(base::unique_fd* bufferFence) = 0;
// Queues the drawn buffer for consumption by HWC. readyFence is the fence
// which will fire when the buffer is ready for consumption.
virtual void queueBuffer(base::unique_fd readyFence) = 0;
RenderSurface由CompositionEngine、Display和RenderSurfaceCreationArgs组成
std::unique_ptr<compositionengine::RenderSurface> createRenderSurface(
const compositionengine::CompositionEngine& compositionEngine,
compositionengine::Display& display,
const compositionengine::RenderSurfaceCreationArgs& args) {
return std::make_unique<RenderSurface>(compositionEngine, display, args);
}
RenderSurface的合成有三种方式,混合,GPU,HWC
具体的实现,是由DisplaySurface实现
void RenderSurface::prepareFrame(bool usesClientComposition, bool usesDeviceComposition) {
DisplaySurface::CompositionType compositionType;
if (usesClientComposition && usesDeviceComposition) {
compositionType = DisplaySurface::COMPOSITION_MIXED;
} else if (usesClientComposition) {
compositionType = DisplaySurface::COMPOSITION_GPU;
} else if (usesDeviceComposition) {
compositionType = DisplaySurface::COMPOSITION_HWC;
} else {
// Nothing to do -- when turning the screen off we get a frame like
// this. Call it a HWC frame since we won't be doing any GPU work but
// will do a prepare/set cycle.
compositionType = DisplaySurface::COMPOSITION_HWC;
}
if (status_t result = mDisplaySurface->prepareFrame(compositionType); result != NO_ERROR) {
OutputLayer
纯虚函数
class OutputLayer {
public:
virtual ~OutputLayer();
// Sets the HWC2::Layer associated with this layer
virtual void setHwcLayer(std::shared_ptr<HWC2::Layer>) = 0;
// Gets the output which owns this output layer
virtual const Output& getOutput() const = 0;
// Gets the front-end layer interface this output layer represents
virtual LayerFE& getLayerFE() const = 0;
SurfaceFlinger
void SurfaceFlinger::run() {
while (true) {
mEventQueue->waitMessage();
}
}
template <typename F, typename T>
inline std::future<T> SurfaceFlinger::schedule(F&& f) {
auto [task, future] = makeTask(std::move(f));
mEventQueue->postMessage(std::move(task));
return std::move(future);
}
mCompositionEngine->setRenderEngine(renderengine::RenderEngine::create(
renderengine::RenderEngineCreationArgs::Builder()
mCompositionEngine->setHwComposer(getFactory().createHWComposer(getBE().mHwcServiceName));
status_t SurfaceFlinger::setDisplayBrightness(const sp<IBinder>& displayToken, float brightness) {
if (!displayToken) {
return BAD_VALUE;
}
return promise::chain(schedule([=]() MAIN_THREAD {
if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
return getHwComposer().setDisplayBrightness(*displayId, brightness);
} else {
ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
return promise::yield<status_t>(NAME_NOT_FOUND);
}
}))
.then([](std::future<status_t> task) { return task; })
.get();
}
BufferQueueProducer
dequeueBuffer
//已分配slot标记,并分配了对应的buffer,这里只是赋值指针,但指针所指向的内存或许并没有
const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer);
//将其移到ActiveBuffer
mCore->mActiveBuffers.insert(found);
//将buffer状态更改为dequeue
mSlots[found].mBufferState.dequeue();
sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(
width, height, format, BQ_LAYER_COUNT, usage,
{mConsumerName.string(), mConsumerName.size()});
if (error == NO_ERROR && !mCore->mIsAbandoned) {
graphicBuffer->setGenerationNumber(mCore->mGenerationNumber);
//分配buffer
mSlots[*outSlot].mGraphicBuffer = graphicBuffer;
if (mCore->mConsumerListener != nullptr) {
//通知consumer,buffer出队
mCore->mConsumerListener->onFrameDequeued(
mSlots[*outSlot].mGraphicBuffer->getId());
}
}
attachBuffer
status_t BufferQueueProducer::attachBuffer(int* outSlot,
const sp<android::GraphicBuffer>& buffer) {
mSlots[*outSlot].mGraphicBuffer = buffer;
mSlots[*outSlot].mBufferState.attachProducer();
mCore->mActiveBuffers.insert(found);
BufferQueue is inside SurfaceFlinger's process
queueBuffer
sp<IConsumerListener> frameAvailableListener;
sp<IConsumerListener> frameReplacedListener;
BufferItem item;
const sp<GraphicBuffer>& graphicBuffer(mSlots[slot].mGraphicBuffer);
mSlots[slot].mBufferState.queue();
item.mAcquireCalled = mSlots[slot].mAcquireCalled;
item.mGraphicBuffer = mSlots[slot].mGraphicBuffer;
item.mSlot = slot;
item.mQueuedBuffer = true;
//将其打包push队列
mCore->mQueue.push_back(item);
frameAvailableListener = mCore->mConsumerListener;
if (frameAvailableListener != nullptr) {
frameAvailableListener->onFrameAvailable(item);
BufferQueueConsumer
与producer分配的是同一个对象
BufferQueueConsumer::BufferQueueConsumer(const sp<BufferQueueCore>& core) :
DequeueBuffer
int slot;
sp<Fence> outFence;
status_t ret = mProducer->dequeueBuffer(&slot, &outFence, kWidth, kHeight, 0, 0,
nullptr, nullptr);
if (ret & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) {
ret = mProducer->requestBuffer(slot, &mBuffers[slot]);
}
*outSlot = slot;
void QueueBuffer(int slot) {
IGraphicBufferProducer::QueueBufferInput bufferInput(
0ULL, true, HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
IGraphicBufferProducer::QueueBufferOutput bufferOutput;
status_t ret = mProducer->queueBuffer(slot, bufferInput, &bufferOutput);
}
void AcquireBuffer(int* outSlot) {
BufferItem buffer;
status_t ret = mBIC->acquireBuffer(&buffer, 0, false);
*outSlot = buffer.mSlot;
}
sp<IGraphicBufferProducer> producer;
sp<IGraphicBufferConsumer> consumer;
BufferQueue::createBufferQueue(&producer, &consumer);
sp<DummyConsumer> dummyConsumer(new DummyConsumer);
consumer->consumerConnect(dummyConsumer, false);
consumer->setConsumerName(String8("TestConsumer"));
sp<Surface> surface = new Surface(producer);
sp<ANativeWindow> window(surface);
Loop
// Locked list of file descriptor monitoring requests.
KeyedVector<int, Request> mRequests; // guarded by mLock
// This state is only used privately by pollOnce and does not require a lock since
// it runs on a single thread.
Vector<Response> mResponses;
int pollInner(int timeoutMillis);
int removeFd(int fd, int seq);
void awoken();
void pushResponse(int events, const Request& request);
void rebuildEpollLocked();
typedef int (*Looper_callbackFunc)(int fd, int events, void* data);
/**
* A message that can be posted to a Looper.
*/
struct Message {
Message() : what(0) { }
Message(int w) : what(w) { }
/* The message type. (interpretation is left up to the handler) */
int what;
};
EventThread
对于vsyncSource,分配一个线程,创建一个连接。返回一个标记该连接的句柄值mAppConnectionHandle
核心:不断循环,监听事件消息,派发
Scheduler::ConnectionHandle Scheduler::createConnection(
const char* connectionName, nsecs_t phaseOffsetNs,
impl::EventThread::InterceptVSyncsCallback interceptCallback) {
auto vsyncSource = makePrimaryDispSyncSource(connectionName, phaseOffsetNs);
auto eventThread = std::make_unique<impl::EventThread>(std::move(vsyncSource),
std::move(interceptCallback));
return createConnection(std::move(eventThread));
}
mThread = std::thread([this]() NO_THREAD_SAFETY_ANALYSIS {
std::unique_lock<std::mutex> lock(mMutex);
threadMain(lock);
});
有一个channel,与TcpConnection类似
EventThreadConnection::EventThreadConnection(EventThread* eventThread,
ResyncCallback resyncCallback,
ISurfaceComposer::ConfigChanged configChanged)
: resyncCallback(std::move(resyncCallback)),
mConfigChanged(configChanged),
mEventThread(eventThread),
mChannel(gui::BitTube::DefaultSize) {}
void EventThreadConnection::onFirstRef() {
// NOTE: mEventThread doesn't hold a strong reference on us
mEventThread->registerDisplayEventConnection(this);
}
用lambda表达式封装了一个函数
using ResyncCallback = std::function<void()>;
[&] { resync(); }//Scheduler
using InterceptVSyncsCallback = std::function<void(nsecs_t)>;
[this](nsecs_t timestamp) {
mInterceptor->saveVSyncEvent(timestamp);
}
//using InterceptVSyncsCallback = std::function<void(nsecs_t)>;
// start the EventThread
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));
创建eventThread,
Scheduler::ConnectionHandle Scheduler::createConnection(
const char* connectionName, nsecs_t phaseOffsetNs,
impl::EventThread::InterceptVSyncsCallback interceptCallback) {
auto vsyncSource = makePrimaryDispSyncSource(connectionName, phaseOffsetNs);
auto eventThread = std::make_unique<impl::EventThread>(std::move(vsyncSource),
std::move(interceptCallback));
return createConnection(std::move(eventThread));
}
Scheduler
std::unique_ptr<DispSync> mPrimaryDispSync;
std::unique_ptr<EventControlThread> mEventControlThread;
ISchedulerCallback& mSchedulerCallback;
mPrimaryDispSync(createDispSync(mSupportKernelTimer)),
mEventControlThread(new impl::EventControlThread(std::move(function))),
mSchedulerCallback(schedulerCallback),
Scheduler(impl::EventControlThread::SetVSyncEnabledFunction,
const scheduler::RefreshRateConfigs&, ISchedulerCallback& schedulerCallback,
bool useContentDetectionV2, bool useContentDetection);
事件通知
using ConnectionHandle = scheduler::ConnectionHandle;
ConnectionHandle createConnection(const char* connectionName, nsecs_t phaseOffsetNs,
impl::EventThread::InterceptVSyncsCallback);
sp<IDisplayEventConnection> createDisplayEventConnection(ConnectionHandle,
ISurfaceComposer::ConfigChanged);
sp<EventThreadConnection> getEventConnection(ConnectionHandle);
Connection 的封装
// Stores EventThread associated with a given VSyncSource, and an initial EventThreadConnection.
struct Connection {
sp<EventThreadConnection> connection;
std::unique_ptr<EventThread> thread;
};
ConnectionHandle::Id mNextConnectionHandleId = 0;
std::unordered_map<ConnectionHandle, Connection> mConnections;
std::unique_ptr<DispSync> mPrimaryDispSync;
std::unique_ptr<EventControlThread> mEventControlThread;
ISchedulerCallback& mSchedulerCallback;
//初始化
mThread = new DispSyncThread(name, mTraceDetailedInfo);
mThread->run("DispSync", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
Scheduler::ConnectionHandle Scheduler::createConnection(
const char* connectionName, nsecs_t phaseOffsetNs,
impl::EventThread::InterceptVSyncsCallback interceptCallback) {
auto vsyncSource = makePrimaryDispSyncSource(connectionName, phaseOffsetNs);
auto eventThread = std::make_unique<impl::EventThread>(std::move(vsyncSource),
std::move(interceptCallback));
return createConnection(std::move(eventThread));
}
threadLoop
callbackInvocations =
gatherCallbackInvocationsLocked(now, computeNextRefreshLocked(0, now));
}
if (callbackInvocations.size() > 0) {
fireCallbackInvocations(callbackInvocations);
}
DispSyncSource
class EventControlThread {
public:
virtual ~EventControlThread();
virtual void setVsyncEnabled(bool enabled) = 0;
};
class DispSyncSource final : public VSyncSource, private DispSync::Callback {
setVSyncEnabled是将自己封装为callback,注册到设备同步线程中
void DispSyncSource::setVSyncEnabled(bool enable) {
std::lock_guard lock(mVsyncMutex);
if (enable) {
status_t err = mDispSync->addEventListener(mName, mPhaseOffset,
c++ static_cast<DispSync::Callback*>(this),
mLastCallbackTime);
EventControlThread
class EventControlThread final : public android::EventControlThread {
const SetVSyncEnabledFunction mSetVSyncEnabled;
//using SetVSyncEnabledFunction = std::function<void(bool)>;
bool mVsyncEnabled GUARDED_BY(mMutex) = false;
bool mKeepRunning GUARDED_BY(mMutex) = true;
// Must be last so that everything is initialized before the thread starts.
std::thread mThread{&EventControlThread::threadMain, this};
EventThread
可以收到VSyncSource的回调
class EventThread : public android::EventThread, private VSyncSource::Callback {
std::vector<wp<EventThreadConnection>> mDisplayEventConnections GUARDED_BY(mMutex);
std::deque<DisplayEventReceiver::Event> mPendingEvents GUARDED_BY(mMutex);
using DisplayEventConsumers = std::vector<sp<EventThreadConnection>>;
const std::unique_ptr<VSyncSource> mVSyncSource GUARDED_BY(mMutex);
//在初始化时,注册
void EventThreadConnection::onFirstRef() {
// NOTE: mEventThread doesn't hold a strong reference on us
mEventThread->registerDisplayEventConnection(this);
}
void EventThread::dispatchEvent(const DisplayEventReceiver::Event& event,
const DisplayEventConsumers& consumers) {
for (const auto& consumer : consumers) {
switch (consumer->postEvent(event)) {
void SurfaceFlinger::onFirstRef() {
mEventQueue->init(this);
}
VsyncModulator
VSyncReactor
// if (property_get_bool("debug.sf.vsync_reactor", true)) {
// return std::make_unique<scheduler::VSyncReactor>
class VSyncReactor : public android::DispSync {
std::unordered_map<DispSync::Callback*, std::unique_ptr<CallbackRepeater>> mCallbacks
GUARDED_BY(mMutex);
addEventListener
auto repeater = std::make_unique<CallbackRepeater>(*mDispatch, callback, name, period,
phase, mClock->now());
it = mCallbacks.emplace(std::pair(callback, std::move(repeater))).first;
it->second->start(phase);
. // Called when the display is presenting a new frame. usedRenderEngine
// should be set to true if RenderEngine was involved with composing the new
// frame.
void onRefreshed(bool usedRenderEngine);
IPhaseOffsetControl& mPhaseOffsetControl;
const ConnectionHandle mAppConnectionHandle;
const ConnectionHandle mSfConnectionHandle;
processDisplayHotplugEventsLocked
if (event.connection == hal::Connection::CONNECTED) {
if (it == mPhysicalDisplayTokens.end()) {
if (event.hwcDisplayId == getHwComposer().getInternalHwcDisplayId()) {
initScheduler(displayId);
}
state.isSecure = true; // All physical displays are currently considered secure.
state.displayName = info->name;
sp<IBinder> token = new BBinder();
mCurrentState.displays.add(token, state);
mPhysicalDisplayTokens.emplace(displayId, std::move(token));
mInterceptor->saveDisplayCreation(state);
processDisplayChangesLocked
processDisplayAdded
sp<compositionengine::DisplaySurface> displaySurface;
sp<IGraphicBufferProducer> producer;
sp<IGraphicBufferProducer> bqProducer;
sp<IGraphicBufferConsumer> bqConsumer;
getFactory().createBufferQueue(&bqProducer, &bqConsumer, /*consumerIsSurfaceFlinger =*/false);
displaySurface = new FramebufferSurface(getHwComposer(), *displayId, bqConsumer,
maxGraphicsWidth, maxGraphicsHeight);
producer = bqProducer;
const auto display = setupNewDisplayDeviceInternal(displayToken, compositionDisplay, state,
displaySurface, producer);
dispatchDisplayHotplugEvent
void SurfaceFlinger::dispatchDisplayHotplugEvent(PhysicalDisplayId displayId, bool connected) {
mScheduler->onHotplugReceived(mAppConnectionHandle, displayId, connected);
mScheduler->onHotplugReceived(mSfConnectionHandle, displayId, connected);
}
initScheduler
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));
Schedulerc初始化
createDispSync DispSync
mEventQueue->setEventConnection(mScheduler->getEventConnection(mSfConnectionHandle));
mEventControlThread(new impl::EventControlThread(std::move(function)))
Scheduler::Scheduler(impl::EventControlThread::SetVSyncEnabledFunction function,
const scheduler::RefreshRateConfigs& refreshRateConfig,
ISchedulerCallback& schedulerCallback, bool useContentDetectionV2,
bool useContentDetection)
: mSupportKernelTimer(sysprop::support_kernel_idle_timer(false)),
mPrimaryDispSync(createDispSync(mSupportKernelTimer)),
mEventControlThread(new impl::EventControlThread(std::move(function))),
mSchedulerCallback(schedulerCallback),
Scheduler::ConnectionHandle Scheduler::createConnection(
const char* connectionName, nsecs_t phaseOffsetNs,
impl::EventThread::InterceptVSyncsCallback interceptCallback) {
auto vsyncSource = makePrimaryDispSyncSource(connectionName, phaseOffsetNs);
auto eventThread = std::make_unique<impl::EventThread>(std::move(vsyncSource),
std::move(interceptCallback));
return createConnection(std::move(eventThread));
}
dequeueBuffer
Surface.h
struct BufferSlot {
sp<GraphicBuffer> buffer;
Region dirtyRegion;
};
// mSurfaceTexture is the interface to the surface texture server. All
// operations on the surface texture client ultimately translate into
// interactions with the server using this interface.
// TODO: rename to mBufferProducer
sp<IGraphicBufferProducer> mGraphicBufferProducer;
// must be used from the lock/unlock thread
sp<GraphicBuffer> mLockedBuffer;
sp<GraphicBuffer> mPostedBuffer;
sp<IProducerListener> mListenerProxy;
status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, reqWidth, reqHeight
sp<GraphicBuffer>& gbuf(mSlots[buf].buffer);
result = mGraphicBufferProducer->requestBuffer(buf, &gbuf);
BufferQueueProducer
dequeueBuffer
const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer);
if (mCore->mConsumerListener != nullptr) {
mCore->mConsumerListener->onFrameDequeued(mSlots[*outSlot].mGraphicBuffer->getId());
}
if (returnFlags & BUFFER_NEEDS_REALLOCATION) {
sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(
width, height, format, BQ_LAYER_COUNT, usage,
{mConsumerName.string(), mConsumerName.size()});
queueBuffer
int i = getSlotFromBufferLocked(buffer);
status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output);
sp<IConsumerListener> frameAvailableListener;
const sp<GraphicBuffer>& graphicBuffer(mSlots[slot].mGraphicBuffer);
mCore->mQueue.push_back(item);
frameAvailableListener = mCore->mConsumerListener;
if (frameAvailableListener != nullptr) {
frameAvailableListener->onFrameAvailable(item);
BufferQueueLayer
mFlinger->mInterceptor->saveBufferUpdate(layerId, item.mGraphicBuffer->getWidth(),
item.mGraphicBuffer->getHeight(), item.mFrameNumber);
mFlinger->signalLayerUpdate();
mConsumer->onBufferAvailable(item);
/*
mImages[item.mSlot] = std::make_shared<Image>(item.mGraphicBuffer, mRE);*/
Vsync到来的时候通过mSendFd写入消息,然后app监听mReceiveFd接受消息,就完成了app对Vsync的接收,需要注意一点,此时的mReceiveFd依然还在SurfaceFlinger进程,app端要使用肯定是需要回传回去的,
void fireCallbackInvocations(const std::vector<CallbackInvocation>& callbacks) {
if (mTraceDetailedInfo) ATRACE_CALL();
for (size_t i = 0; i < callbacks.size(); i++) {
callbacks[i].mCallback->onDispSyncEvent(callbacks[i].mEventTime,
callbacks[i].mExpectedVSyncTime);
}C++
}
(76条消息) DJLZPP的博客_CSDN博客-笔记,Android源码分析,Android图形系统领域博主
Android VSYNC (Choreographer)与UI刷新原理分析 - 简书 (jianshu.com)
《Android进阶之光》勘误 | BATcoder - 刘望舒 (liuwangshu.cn)
Android SurfaceFlinger SW Vsync模型 - 简书 (jianshu.com)
Layer
struct State {
uint32_t layerStack;
wp<Layer> zOrderRelativeOf; // 指定的相对参考系
SortedVector<wp<Layer>> zOrderRelatives; // 以我为相对参考系的layer节点
int backgroundBlurRadius;
sp<GraphicBuffer> buffer;
sp<Fence> acquireFence;
}
// These are only accessed by the main thread or the tracing thread.
State mDrawingState;
// these are protected by an external lock (mStateLock)
State mCurrentState;
// Layer::commitChildList()
// Child list about to be committed/used for editing.
LayerVector mCurrentChildren{LayerVector::StateSet::Current};
// Child list used for rendering.
LayerVector mDrawingChildren{LayerVector::StateSet::Drawing};
wp<Layer> mCurrentParent;
wp<Layer> mDrawingParent;
doTransaction
在doTransaction之前,使用mCurrentState,处理事务时,更新到mDrawingState
if (c.sequence != s.sequence) {
// invalidate and recompute the visible regions if needed
flags |= eVisibleRegion;
this->contentDirty = true;
void Layer::commitTransaction(const State& stateToCommit) {
mDrawingState = stateToCommit;
}
sp<Layer> mClonedChild;// 由this所clone的layer
virtual sp<Layer> createClone() = 0;
sp<Layer> getClonedFrom() { return mClonedFrom != nullptr ? mClonedFrom.promote() : nullptr; }
bool isClone() { return mClonedFrom != nullptr; }
wp<Layer> mClonedFrom;
void addChild(const sp<Layer>& layer);
// Returns index if removed, or negative value otherwise
// for symmetry with Vector::remove
ssize_t removeChild(const sp<Layer>& layer);
sp<Layer> getParent() const { return mCurrentParent.promote(); }
void setParent(const sp<Layer>& layer);
void Layer::setParent(const sp<Layer>& layer) {
mCurrentParent = layer;
}
Layer::makeTraversalList
- outSkipRelativeZUsers 跳过相对列表,则仅返回subtree
- 若为false,则包含相对节点。如果子节点是相对其他节点的,不包括这样子的子节点
const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren;
const State& state = useDrawing ? mDrawingState : mCurrentState;
if (state.zOrderRelatives.size() == 0) {
*outSkipRelativeZUsers = true;
return children;
}
LayerVector traverse(stateSet);
for (const wp<Layer>& weakRelative : state.zOrderRelatives) {
sp<Layer> strongRelative = weakRelative.promote();
if (strongRelative != nullptr) {
traverse.add(strongRelative);
}
}
for (const sp<Layer>& child : children) {
if (child->usingRelativeZ(stateSet)) {
continue;
}
traverse.add(child);
}
return traverse;
traverseInZOrder
- skipRelativeZUsers 表示是否跳过相对序
- -1 0 +1
void Layer::traverseInZOrder(LayerVector::StateSet stateSet, const LayerVector::Visitor& visitor) {
// In the case we have other layers who are using a relative Z to us, makeTraversalList will
// produce a new list for traversing, including our relatives, and not including our children
// who are relatives of another surface. In the case that there are no relative Z,
// makeTraversalList returns our children directly to avoid significant overhead.
// However in this case we need to take the responsibility for filtering children which
// are relatives of another surface here.
bool skipRelativeZUsers = false;
const LayerVector list = makeTraversalList(stateSet, &skipRelativeZUsers);
size_t i = 0;
for (; i < list.size(); i++) {
const auto& relative = list[i];
// 如果跳过相对序,这relative是该树的孩子节点,但该孩子节点的z是相对别layer,不访问这样子的节点
// 如果不跳过相对序,则先访问相对序的节点,再访问该树的孩子节点
if (skipRelativeZUsers && relative->usingRelativeZ(stateSet)) {
continue;
}
if (relative->getZ(stateSet) >= 0) {
break;
}
relative->traverseInZOrder(stateSet, visitor);
}
visitor(this); // 访问当前节点
for (; i < list.size(); i++) {
const auto& relative = list[i];
if (skipRelativeZUsers && relative->usingRelativeZ(stateSet)) {
continue;
}
relative->traverseInZOrder(stateSet, visitor);
}
}
traverse
traverse该方法是顺序访问该树的节点,没有按照z序访问traverseInZOrder
void Layer::traverse(LayerVector::StateSet state, const LayerVector::Visitor& visitor) {
visitor(this);
const LayerVector& children =
state == LayerVector::StateSet::Drawing ? mDrawingChildren : mCurrentChildren;
for (const sp<Layer>& child : children) {
child->traverse(state, visitor);
}
}
Layer::prepareClientComposition
std::optional<compositionengine::LayerFE::LayerSettings> Layer::prepareClientComposition(
compositionengine::LayerFE::ClientCompositionTargetSettings& targetSettings) {
if (!getCompositionState()) {
return {};
}
FloatRect bounds = getBounds();
half alpha = getAlpha();
compositionengine::LayerFE::LayerSettings layerSettings;
layerSettings.geometry.boundaries = bounds;
if (targetSettings.useIdentityTransform) {
layerSettings.geometry.positionTransform = mat4();
} else {
layerSettings.geometry.positionTransform = getTransform().asMatrix4();
}
if (hasColorTransform()) {
layerSettings.colorTransform = getColorTransform();
}
const auto roundedCornerState = getRoundedCornerState();
layerSettings.geometry.roundedCornersRadius = roundedCornerState.radius;
layerSettings.geometry.roundedCornersCrop = roundedCornerState.cropRect;
layerSettings.alpha = alpha;
layerSettings.sourceDataspace = getDataSpace();
layerSettings.backgroundBlurRadius = getBackgroundBlurRadius();
return layerSettings;
}
BufferLayer
- hasFrameUpdate
- bindTextureImage
struct BufferInfo {
nsecs_t mDesiredPresentTime;
std::shared_ptr<FenceTime> mFenceTime;
sp<Fence> mFence;
uint32_t mTransform{0};
ui::Dataspace mDataspace{ui::Dataspace::UNKNOWN};
Rect mCrop;
uint32_t mScaleMode{NATIVE_WINDOW_SCALING_MODE_FREEZE};
Region mSurfaceDamage;
HdrMetadata mHdrMetadata;
int mApi;
PixelFormat mPixelFormat{PIXEL_FORMAT_NONE};
bool mTransformToDisplayInverse{false};
sp<GraphicBuffer> mBuffer;
int mBufferSlot{BufferQueue::INVALID_BUFFER_SLOT};
bool mFrameLatencyNeeded{false};
};
prepareClientComposition
会对LayerSettings赋值
layer.source.buffer.buffer = mBufferInfo.mBuffer;
layer.source.buffer.fence = mBufferInfo.mFence;