文章目录
参考资料
- Android Synchronization Fences – An Introduction
- Android中的GraphicBuffer同步机制-Fence
- 深入浅出Android BufferQueue
- 从systrace看app冷启动过程(三)-首帧的合成与送显
- Android显示Surface
- surfaceflinger中各个layer的排序
- Android 4.0.3 显示系统深入理解
- Android窗口管理分析(3):窗口分组及Z-order的确定
Android Q
前面分析了Vsync信号的始末,其实还有很多可以细究的部分。比如硬件vsync是什么时候开始,什么时候结束?校准算法的原理等等。
接下来我们先看看SurfaceFlinger合成帧的部分。
一. SF EventThread接收vsync的准备
在SFEventThread一文中已经探明,当产生Vsync信号后,会通过BitTube发送事件(EventThreadConnection.postEvent):
status_t EventThreadConnection::postEvent(const DisplayEventReceiver::Event& event) {
ssize_t size = DisplayEventReceiver::sendEvents(&mChannel, &event, 1);
return size < 0 ? status_t(size) : status_t(NO_ERROR);
}
这里我们就需要知道 mChannel 是被谁监听了。
1.1 SurfaceFlinger.init
void SurfaceFlinger::init() {
...
// 1.1.1 创建SfEventThread以及EventThreadConnection
mSfConnectionHandle = mScheduler->createConnection("sf", mPhaseOffsets->getCurrentSfOffset(),
resyncCallback, [this](nsecs_t timestamp) {
mInterceptor->saveVSyncEvent(timestamp);
});
// 1.2 赋值 BitTube, 用来通信
mEventQueue->setEventConnection(mScheduler->getEventConnection(mSfConnectionHandle));
...
}
这里的mEventQueue是在SurfaceFlinger.onFirstRef中初始化的。
void SurfaceFlinger::onFirstRef()
{
mEventQueue->init(this);
...
}
void MessageQueue::init(const sp<SurfaceFlinger>& flinger) {
mFlinger = flinger;
mLooper = new Looper(true);
mHandler = new Handler(*this);
}
这个Looper就是SurfaceFlinger主线程的Looper.
1.1.1 Scheduler.createConnection
sp<Scheduler::ConnectionHandle> Scheduler::createConnection(
const char* connectionName, int64_t phaseOffsetNs, ResyncCallback resyncCallback,
impl::EventThread::InterceptVSyncsCallback interceptCallback) {
const int64_t id = sNextId++;
ALOGV("Creating a connection handle with ID: %" PRId64 "\n", id);
// 创建 sfEventThread
std::unique_ptr<EventThread> eventThread =
makeEventThread(connectionName, mPrimaryDispSync.get(), phaseOffsetNs,
std::move(interceptCallback));
// 创建EventThreadConnection
auto eventThreadConnection =
createConnectionInternal(eventThread.get(), std::move(resyncCallback));
// 保存创建的connection
mConnections.emplace(id,
std::make_unique<Connection>(new ConnectionHandle(id),
eventThreadConnection,
std::move(eventThread)));
return mConnections[id]->handle;
}
sp<EventThreadConnection> Scheduler::createConnectionInternal(EventThread* eventThread,
ResyncCallback&& resyncCallback) {
return eventThread->createEventConnection(std::move(resyncCallback));
}
1.1.2 EventThread.createEventConnection
sp<EventThreadConnection> EventThread::createEventConnection(ResyncCallback resyncCallback) const {
return new EventThreadConnection(const_cast<EventThread*>(this), std::move(resyncCallback));
}
EventThreadConnection::EventThreadConnection(EventThread* eventThread,
ResyncCallback resyncCallback)
: resyncCallback(std::move(resyncCallback)),
mEventThread(eventThread),
// 注意这里创建了 BitTube, 此时是在SurfaceFlinger主线程
mChannel(gui::BitTube::DefaultSize) {}
1.2 MessageQueue.setEventConnection
void MessageQueue::setEventConnection(const sp<EventThreadConnection>& connection) {
if (mEventTube.getFd() >= 0) {
mLooper->removeFd(mEventTube.getFd());
}
mEvents = connection;
// 1.2.1 通过BitTube建立与SFEventThread的通信通道
mEvents->stealReceiveChannel(&mEventTube);
// 有vsync事件会回调cb_eventReceiver事件
mLooper->addFd(mEventTube.getFd(), 0, Looper::EVENT_INPUT, MessageQueue::cb_eventReceiver,
this);
}
这里的mLooper就是SurfaceFlinger主线程的Looper.
1.2.1 EventThreadConnection.stealReceiveChannel
status_t EventThreadConnection::stealReceiveChannel(gui::BitTube* outChannel) {
// 这里的mChannel就是[1.1.2]中新建的BitTube
outChannel->setReceiveFd(mChannel.moveReceiveFd());
return NO_ERROR;
}
二. SF EventThread接收vsync
上面我们知道了,当SFEventThread发出Vsync信号时,会通过BitTube发送该消息至SurfaceFlinger主线程,并调用MessageQueue.cb_eventReceiver方法处理。
2.1 MessageQueue.cb_eventReceiver
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++) {
// 只关心VSYNC消息
if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
// 2.2 触发composition
mHandler->dispatchInvalidate();
break;
}
}
}
return 1;
}
2.2 MessageQueue.Handler.dispatchInvalidate
void MessageQueue::Handler::dispatchInvalidate() {
if ((android_atomic_or(eventMaskInvalidate, &mEventMask) & eventMaskInvalidate) == 0) {
// 这里通过Looper发送INVALIDATE消息
mQueue.mLooper->sendMessage(this, Message(MessageQueue::INVALIDATE));
}
}
void MessageQueue::Handler::handleMessage(const Message& message) {
switch (message.what) {
case INVALIDATE:
android_atomic_and(~eventMaskInvalidate, &mEventMask);
// 处理INVALIDATE消息
mQueue.mFlinger->onMessageReceived(message.what);
break;
case REFRESH:
android_atomic_and(~eventMaskRefresh, &mEventMask);
mQueue.mFlinger->onMessageReceived(message.what);
break;
}
}
2.3 SurfaceFlinger.onMessageReceived
void SurfaceFlinger::onMessageReceived(int32_t what) NO_THREAD_SAFETY_ANALYSIS {
ATRACE_CALL();
switch (what) {
case MessageQueue::INVALIDATE: {
// 通过fence机制来判断是否掉帧
bool frameMissed = previousFrameMissed();
bool hwcFrameMissed = mHadDeviceComposition && frameMissed;
bool gpuFrameMissed = mHadClientComposition && frameMissed;
ATRACE_INT("FrameMissed", static_cast<int>(frameMissed));
ATRACE_INT("HwcFrameMissed", static_cast<int>(hwcFrameMissed));
ATRACE_INT("GpuFrameMissed", static_cast<int>(gpuFrameMissed));
if (frameMissed) {
mFrameMissedCount++;
mTimeStats->incrementMissedFrames();
}
if (hwcFrameMissed) {
mHwcFrameMissedCount++;
}
if (gpuFrameMissed) {
mGpuFrameMissedCount++;
}
if (performSetActiveConfig()) {
break;
}
// 如果丢帧,则不处理此次VSYNC
if (frameMissed && mPropagateBackpressure) {
if ((hwcFrameMissed && !gpuFrameMissed) ||
mPropagateBackpressureClientComposition) {
signalLayerUpdate();
break;
}
}
......
// transaction主要针对Layer和Display的变化更新脏区域
// 通过Layer的变化来计算脏区域,目的是需要更新我才刷新
bool refreshNeeded = handleMessageTransaction();
// 2.4 主要是调用handlePageFlip()函数,该函数在systrace图上对应latchBuffer及其所包含的方法。
// 作用是从各Layer对应的BufferQueue中拿图形缓冲区数据,并根据内容更新脏区域
// 并且把GraphicBuffer映射为OpenGL的texture
refreshNeeded |= handleMessageInvalidate();
updateCursorAsync();
updateInputFlinger();
refreshNeeded |= mRepaintEverything;
if (refreshNeeded && CC_LIKELY(mBootStage != BootStage::BOOTLOADER)) {
// 发送刷新合成请求
signalRefresh();
}
break;
}
case MessageQueue::REFRESH: {
if (mDolphinFuncsEnabled) {
mDolphinRefresh();
}
// 2.6 SF 处理合成
handleMessageRefresh();
break;
}
}
}
这里我们先忽略Fence机制,先看看大致流程。
2.4 SurfaceFlinger.handleMessageInvalidate
bool SurfaceFlinger::handleMessageInvalidate() {
ATRACE_CALL();
bool refreshNeeded = handlePageFlip();
if (mVisibleRegionsDirty) {
computeLayerBounds();
if (mTracingEnabled) {
mTracing.notify("visibleRegionsDirty");
}
}
for (auto& layer : mLayersPendingRefresh) {
Region visibleReg;
visibleReg.set(layer->getScreenBounds());
invalidateLayerStack(layer, visibleReg);
}
mLayersPendingRefresh.clear();
return refreshNeeded;
}
2.5 SurfaceFlinger.handlePageFlip
bool SurfaceFlinger::handlePageFlip()
{
ATRACE_CALL();
ALOGV("handlePageFlip");
nsecs_t latchTime = systemTime();
bool visibleRegions = false;
bool frameQueued = false;
bool newDataLatched = false;
// 存储需要更新的图层集。 当缓冲区被锁存时,不得更改,因为可能导致死锁。
mDrawingState.traverseInZOrder([&](Layer* layer) {
if (layer->hasReadyFrame()) {
frameQueued = true;
nsecs_t expectedPresentTime;
expectedPresentTime = mScheduler->expectedPresentTime();
if (layer->shouldPresentNow(expectedPresentTime)) {
// mLayersWithQueuedFrames用于标记那些已经有Frame的Layer
mLayersWithQueuedFrames.push_back(layer);
} else {
ATRACE_NAME("!layer->shouldPresentNow()");
layer->useEmptyDamage();
}
} else {
layer->useEmptyDamage();
}
});
if (!mLayersWithQueuedFrames.empty()) {
// mStateLock is needed for latchBuffer as LayerRejecter::reject()
// writes to Layer current state. See also b/119481871
Mutex::Autolock lock(mStateLock);
for (auto& layer : mLayersWithQueuedFrames) {
if (layer->latchBuffer(visibleRegions, latchTime)) {
mLayersPendingRefresh.push_back(layer);
}
layer->useSurfaceDamage();
if (layer->isBufferLatched()) {
newDataLatched = true;
}
}
}
mVisibleRegionsDirty |= visibleRegions;
// If we will need to wake up at some time in the future to deal with a
// queued frame that shouldn't be displayed during this vsync period, wake
// up during the next vsync period to check again.
if (frameQueued && (mLayersWithQueuedFrames.empty() || !newDataLatched)) {
signalLayerUpdate();
}
// enter boot animation on first buffer latch
if (CC_UNLIKELY(mBootStage == BootStage::BOOTLOADER && newDataLatched)) {
ALOGI("Enter boot animation");
mBootStage = BootStage::BOOTANIMATION;
}
// Only continue with the refresh if there is actually new work to do
return !mLayersWithQueuedFrames.empty() && newDataLatched;
}
2.6 SurfaceFlinger.handleMessageRefresh
void SurfaceFlinger::handleMessageRefresh() {
ATRACE_CALL();
mRefreshPending = false;
const bool repaintEverything = mRepaintEverything.exchange(false);
// 合成前再过一遍Layer是否被更新了
// 如果有则触发signalLayerUpdate(),通过EventThread安排一次invalidate sf vsync。
preComposition();
// 重建layer堆栈, 提取可见的Laye并计算可见区域,为合成准备好数据材料。
rebuildLayerStacks();
// hwcomposer的设定
calculateWorkingSet();
for (const auto& [token, display] : mDisplays) {
beginFrame(display);
prepareFrame(display);
doDebugFlashRegions(display, repaintEverything);
doComposition(display, repaintEverything); //正式的合成处理
}
logLayerStats();
postFrame();
// 将图像传递到物理屏幕。但是在下一个vsync信号才被消费。
// 回调每个layer的onPostComposition
postComposition();
mHadClientComposition = false;
mHadDeviceComposition = false;
for (const auto& [token, displayDevice] : mDisplays) {
auto display = displayDevice->getCompositionDisplay();
const auto displayId = display->getId();
mHadClientComposition =
mHadClientComposition || getHwComposer().hasClientComposition(displayId);
mHadDeviceComposition =
mHadDeviceComposition || getHwComposer().hasDeviceComposition(displayId);
}
mVsyncModulator.onRefreshed(mHadClientComposition);
mLayersWithQueuedFrames.clear();
}
再继续分析之前,我们需要先了解Layer的结构,以及他是如何被添加至SurfaceFlinger中的。
三. Layer的产生
Layer, 即图层。Layer是图像合成中最重要的单元。图层是Surface和SurfaceControl的组合。
说到底也就是每个Window都有对应Surface,也就对应一个Layer;SurfaceFlinger的合成就是将所有图层按照顺序和特定属性合成一帧画面。
每个图层都有一组属性,用于定义它与其他图层的交互方式。
属性 | 描述 |
---|---|
Positional | 定义图层在其显示屏上显示的位置。 包括诸如图层边缘的位置及其相对于其他图层的Z顺序的信息 |
Content | 定义图层上显示的内容应如何在位置属性定义的边界内显示。 包括裁剪和变换等信息 |
Composition | 定义图层应如何与其他图层合成。 包括混合模式和alpha合成的图层范围Alpha值等信息 |
Optimization | 提供正确合成图层非必要的信息,但硬件编写器(HWC)设备可以使用该信息来优化其执行合成的方式。 包括诸如图层的可见区域以及自上一帧以来图层的哪个部分已更新的信息。 |
在创建Window或者Window产生变化时就会更新对应的Surface所属的Layer.
ViewRootImpl.performTraversals() --[App进程] 绘制三部曲
Session.relayout(...) --[App进程] 通过binder与WMS通信:窗口属性有更新
WindowManagerService.relayoutWindow(...) --[SystemServer进程]
WindowManagerService.createSurfaceControl(...) --[SystemServer进程]
WindowStateAnimator.createSurfaceLocked(...) --[SystemServer进程] 这里传入Surface的FLAG
WindowSurfaceController.new() --[SystemServer进程]
WindowContainer.makeSurface() --[SystemServer进程]
WindowContainer.makeSurface(WindowContainer) --[SystemServer进程]
SurfaceControl.Builder.build() --[SystemServer进程]
SurfaceControl.new() --[SystemServer进程]
android_view_SurfaceControl:nativeCreate() --[JNI][SystemServer进程]
SurfaceComposerClient:getDefault() --[SystemServer进程]
DefaultComposerClient:getComposerClient() --[SystemServer进程]
SurfaceComposerClient:new() --[SystemServer进程]
SurfaceComposerClient:onFirstRef() --[SystemServer进程]通过Binder从SF获取SurfaceComposerClient
SurfaceFlinger:createConnection() --[SurfaceFlinger进程] 创建SurfaceComposerClient
SurfaceComposerClient:createSurfaceChecked(...) --[SystemServer进程]Binder调用
Client:createSurface(...) --[SurfaceFlinger进程]
SurfaceFlinger:createLayer(...) --[SurfaceFlinger进程] 这里假设创建一个默认Surface
SurfaceFlinger:createBufferQueueLayer(...) --[SurfaceFlinger进程]
SurfaceFlingerFactory:createBufferQueueLayer(...) --[SurfaceFlinger进程]
BufferQueueLayer:new(LayerCreationArgs) --[SurfaceFlinger进程]
BufferLayer:new(LayerCreationArgs) --[SurfaceFlinger进程]
SurfaceControl:new(...) --[SystemServer进程]
图片来源:https://www.jianshu.com/p/fc3c3d6f9bf7
Surface FLAG一览
名称 | 值 | 作用 |
---|---|---|
HIDDEN | 0x00000004 | Surface是隐藏的 |
SECURE | 0x00000080 | 包含安全内容,禁止内容被其他进程复制。而且屏幕截图和VNC服务器将被禁用,但可能不会采用硬件加速。Window带有FLAG_SECURE标签,或者该应用禁止截图就会带有这个FLAG |
NON_PREMULTIPLIED | 0x00000100 | 预乘透明度,创建一个Surface,其中颜色分量被Alpha通道解释为“非预乘”。对于没有alpha通道的Surface,这个标志是没有意义的。 默认情况下,Surface是预乘的,这意味着每个颜色分量已经乘以其alpha值。 |
OPAQUE | 0x00000400 | 表示Surface必须为不透明,即使其像素格式包含Alpha通道。 |
PROTECTED_APP | 0x00000800 | 应用程序需要通过外部显示接收器的硬件保护路径。 如果硬件保护路径不可用,则此表面将不会显示在外部接收器上。 |
CURSOR_WINDOW | 0x00002000 | 窗口表示光标字形。 |
FX_SURFACE_NORMAL | 0x00000000 | 创建一个默认Surface |
FX_SURFACE_DIM | 0x00020000 | 创建一个暗淡的Surface。 此Surface后面的所有内容都会被{@link #setAlpha}中指定的数量调暗。 锁定Dim Surface是错误的,因为它没有后备存储。 |
FX_SURFACE_CONTAINER | 创建容器Surface。 此Surface将没有缓冲区,仅用作其他Surface或其InputInfo的容器。 | |
SURFACE_HIDDEN | 0x01 | 隐藏该Surface, 等同于调用Surface.hide() |
SURFACE_OPAQUE | 0x02 | 尽可能不混合的复合材料。 更新Surface创建期间设置的值(请参阅{@link #OPAQUE})。 |
3.1 SurfaceFlinger:createLayer
当上次Window变化时,或者会创建Layer,并保存在SurfaceFlinger中.
status_t SurfaceFlinger::createLayer(const String8& name, const sp<Client>& client, uint32_t w,
uint32_t h, PixelFormat format, uint32_t flags,
LayerMetadata metadata, sp<IBinder>* handle,
sp<IGraphicBufferProducer>* gbp,
const sp<IBinder>& parentHandle,
const sp<Layer>& parentLayer) {
......
// 假设创建默认的Surface
switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
case ISurfaceComposerClient::eFXSurfaceBufferQueue:
result = createBufferQueueLayer(client, uniqueName, w, h, flags, std::move(metadata),
format, handle, gbp, &layer);
break;
......
}
......
// 检查是否有访问SurfaceFlinger的权限
bool addToCurrentState = callingThreadHasUnscopedSurfaceFlingerAccess();
// 3.2 保存新建的Layer
result = addClientLayer(client, *handle, *gbp, layer, parentHandle, parentLayer,
addToCurrentState);
if (result != NO_ERROR) {
return result;
}
mInterceptor->saveSurfaceCreation(layer);
setTransactionFlags(eTransactionNeeded);
return result;
}
3.1.1 SurfaceFlinger.createBufferQueueLayer
中间细琐流程略过,最终是创建了一个Layer对象
Layer::Layer(const LayerCreationArgs& args)
: mFlinger(args.flinger),
mName(args.name),
mClientRef(args.client),
mWindowType(args.metadata.getInt32(METADATA_WINDOW_TYPE, 0)) {
mCurrentCrop.makeInvalid();
uint32_t layerFlags = 0;
if (args.flags & ISurfaceComposerClient::eHidden) layerFlags |= layer_state_t::eLayerHidden;
if (args.flags & ISurfaceComposerClient::eOpaque) layerFlags |= layer_state_t::eLayerOpaque;
if (args.flags & ISurfaceComposerClient::eSecure) layerFlags |= layer_state_t::eLayerSecure;
mTransactionName = String8("TX - ") + mName;
mCurrentState.active_legacy.w = args.w;
mCurrentState.active_legacy.h = args.h;
mCurrentState.flags = layerFlags;
mCurrentState.active_legacy.transform.set(0, 0);
mCurrentState.crop_legacy.makeInvalid();
mCurrentState.requestedCrop_legacy = mCurrentState.crop_legacy;
mCurrentState.z = 0; // 这里就是layer在Z轴的位置
mCurrentState.color.a = 1.0f;
mCurrentState.layerStack = 0; // layer所在layerStack
mCurrentState.sequence = 0; // layer序号
mCurrentState.requested_legacy = mCurrentState.active_legacy;
mCurrentState.active.w = UINT32_MAX;
mCurrentState.active.h = UINT32_MAX;
mCurrentState.active.transform.set(0, 0);
mCurrentState.transform = 0;
mCurrentState.transformToDisplayInverse = false;
mCurrentState.crop.makeInvalid();
mCurrentState.acquireFence = new Fence(-1);
mCurrentState.dataspace = ui::Dataspace::UNKNOWN;
mCurrentState.hdrMetadata.validTypes = 0;
mCurrentState.surfaceDamageRegion.clear();
mCurrentState.cornerRadius = 0.0f;
mCurrentState.api = -1;
mCurrentState.hasColorTransform = false;
mCurrentState.colorSpaceAgnostic = false;
mCurrentState.metadata = args.metadata;
// drawing state & current state are identical
mDrawingState = mCurrentState;
CompositorTiming compositorTiming;
args.flinger->getCompositorTiming(&compositorTiming);
mFrameEventHistory.initializeCompositorTiming(compositorTiming);
mFrameTracker.setDisplayRefreshPeriod(compositorTiming.interval);
mSchedulerLayerHandle = mFlinger->mScheduler->registerLayer(mName.c_str(), mWindowType);
mFlinger->onLayerCreated();
}
重点关注的是:
名称 | 作用 |
---|---|
z | z-order,表示x,y,z轴的z轴上的顺序。数字越大,表示越在上面,数字越小,表示越在下面。 |
layerStack | layerStack是存储layer的容器,我们知道每个display只会有一个layerstack来存储他要显示的layer,但是不同的display可以使用同一个layerStack,也可以使用不同的layerStack。可以理解为组的含义。也就是说属于不同组的layer之间互不干扰。SurfaceFlinger中有一个DisplayDevice类,他表示用来显示的设备,譬如LCD或者是HDMI。DisplayDevice里也有一个成员变量mLayerStack,在进行composition的时候,只有和这个device的layerstack相同的layer才可能被显示在这个设备上。 |
sequence | sSequence是一个static的变量,所以递加的效果就是为每一个layer设置一个唯一且递增的序列号。 |
3.2 SurfaceFlinger.addClientLayer
status_t SurfaceFlinger::addClientLayer(const sp<Client>& client, const sp<IBinder>& handle,
const sp<IGraphicBufferProducer>& gbc, const sp<Layer>& lbc,
const sp<IBinder>& parentHandle,
const sp<Layer>& parentLayer, bool addToCurrentState) {
// add this layer to the current state list
{
Mutex::Autolock _l(mStateLock);
......
if (parent == nullptr && addToCurrentState) {
// 3.2.1 将新创建的Layer按照Z轴顺序存储至队列中
mCurrentState.layersSortedByZ.add(lbc);
} else if (parent == nullptr) {
lbc->onRemovedFromCurrentState();
} else if (parent->isRemovedFromCurrentState()) {
parent->addChild(lbc);
lbc->onRemovedFromCurrentState();
} else {
parent->addChild(lbc);
}
if (gbc != nullptr) {
mGraphicBufferProducerList.insert(IInterface::asBinder(gbc).get());
LOG_ALWAYS_FATAL_IF(mGraphicBufferProducerList.size() >
mMaxGraphicBufferProducerListSize,
"Suspected IGBP leak: %zu IGBPs (%zu max), %zu Layers",
mGraphicBufferProducerList.size(),
mMaxGraphicBufferProducerListSize, mNumLayers);
}
mLayersAdded = true;
}
// 3.2.2 将该Layer保存至mClient的mLayers中,键为IBinder,供后续使用
client->attachLayer(handle, lbc);
return NO_ERROR;
}
搞清楚Layer的Z轴顺序,对与我们理解Layer合成过程有很大帮助。
Layer排序建议参考:https://www.cnblogs.com/riskyer/p/3297226.html
3.2.1 LayerVector.add
将新创建的Layer按照Z轴顺序存储至队列中.
LayerVector继承了SortedVector,并且重载了函数 do_compare.
int LayerVector::do_compare(const void* lhs, const void* rhs) const
{
// 先对LayerStack排序,然后是Z轴排序,最后是序号
const auto& l = *reinterpret_cast<const sp<Layer>*>(lhs);
const auto& r = *reinterpret_cast<const sp<Layer>*>(rhs);
const auto& lState =
(mStateSet == StateSet::Current) ? l->getCurrentState() : l->getDrawingState();
const auto& rState =
(mStateSet == StateSet::Current) ? r->getCurrentState() : r->getDrawingState();
uint32_t ls = lState.layerStack;
uint32_t rs = rState.layerStack;
if (ls != rs)
return (ls > rs) ? 1 : -1;
int32_t lz = lState.z;
int32_t rz = rState.z;
if (lz != rz)
return (lz > rz) ? 1 : -1;
if (l->sequence == r->sequence)
return 0;
return (l->sequence > r->sequence) ? 1 : -1;
}
先比较layerstack,不同的layerstack分开。然后再比较z,假设都相同,就比较唯一的layer序列号。
但是至今为止,layerStack和z都还只是初始化时的0,所以在创建layer的时候,只是把他根据序列号放进layersSortedByZ而已,其实他的顺序还是没有设置的。
3.2.2 SurfaceFlinger:addClientLayer
void Client::attachLayer(const sp<IBinder>& handle, const sp<Layer>& layer)
{
Mutex::Autolock _l(mLock);
mLayers.add(handle, layer);
}
3.4 Layer更新流程
当java层调用setLayer时就会确定对应Layer的Z-Order顺序。
ViewRootImpl.performTraversals() --[App进程] 绘制三部曲
ViewRootImpl.relayoutWindow(...) --[App进程]
Session.relayout(...) --[App进程] 通过binder与WMS通信:窗口属性有更新
WindowManagerService.relayoutWindow(...) --[SystemServer进程]
WindowSurfacePlacer.performSurfacePlacement(...) --[SystemServer进程]
WindowSurfacePlacer.performSurfacePlacementLoop() --[SystemServer进程]
RootWindowContainer.performSurfacePlacement(boolean) --[SystemServer进程]
RootWindowContainer.performSurfacePlacementNoTrace(boolean) --[SystemServer进程]
WindowManagerService.openSurfaceTransaction() --[SystemServer进程]
SurfaceControl.openTransaction() --[SystemServer进程] 创建Transaction, 或者计数+1
android_view_SurfaceControl:nativeCreateTransaction(...) --[SystemServer进程]
SurfaceComposerClient:Transaction:new() --[SystemServer进程]
WindowManagerService.applySurfaceChangesTransaction(boolean) --[SystemServer进程]
SurfaceControl.mergeToGlobalTransaction(Transaction) --[SystemServer进程]
SurfaceControl.Transaction.merge(Transaction) --[SystemServer进程]合并更新后的属性
android_view_SurfaceControl:nativeMergeTransaction(...) --[SystemServer进程]
SurfaceComposerClient:Transaction:merge(Transaction) --[SystemServer进程]也就是保存新的属性
WindowManagerService.closeSurfaceTransaction(String) --[SystemServer进程]
SurfaceControl.closeTransaction() --[SystemServer进程]
SurfaceControl.Transaction.apply() --[SystemServer进程]
android_view_SurfaceControl:nativeApplyTransaction(...) --[SystemServer进程]
SurfaceComposerClient:Transaction:apply(bool) --[SystemServer进程]
SurfaceFlinger:setTransactionState(...) --[SurfaceFlinger进程]传递更新后的属性到sf
SurfaceFlinger:applyTransactionState(...) --[SurfaceFlinger进程]
TransactionCompletedThread:run() --[SurfaceFlinger进程]
TransactionCompletedThread:threadMain() --[SurfaceFlinger子线程]
mConditionVariable.wait(mMutex);// 等待执行
TransactionCompletedListener:onTransactionCompleted(...)--[SurfaceFlinger子线程]
TransactionCompletedThread:addCallback() --[SurfaceFlinger进程]
TransactionCompletedThread:sendCallbacks() --notify TransactionCompletedThread执行
SurfaceFlinger:setClientStateLocked(...) --[SurfaceFlinger进程]
Layer:setLayer(int32_t) --[SurfaceFlinger进程] 更新Layer所处Z轴的位置
如图:
到目前为止还只是创建了一个SurfaceControl,对应SurfaceFlinger中的BufferQueueLayer。
真正的Surface还没有被创建,那是什么时候创建的呢?
四. Surface的生成
一个ViewRootImpl对应一个Suface, 也就是一个Layer.
当我们创建了Layer之后,总要向其中填充数据内容,SurfaceFlinger才好做合成。
在RendererThread中,我们知道了Surface数据是通过渲染引擎OpenGL(android Q上是Vulkan)生成的。
4.1 Suface的生成
参阅:RenderThread深入分析(三)–绑定窗口对应的Surface到RenderThread的过程
ViewRootImpl.performTraversals(...) --[App UI进程] 绘制三部曲
ViewRootImpl.relayoutWindow(...) --[App UI进程]
mSurface.copyFrom(mSurfaceControl) 注意这里会将赋值mSurface
android_view_Surface:nativeCreateFromSurfaceControl(...) --[App UI进程]
SurfaceControl:createSurface() --[App UI进程]
SurfaceControl:generateSurfaceLocked()
Surface:new() 这里创建了native Surface
ThreadedRenderer.initializeIfNeeded(...) --[App UI进程]
ThreadedRenderer.initialize(Surface) --[App UI进程]
ThreadedRenderer.setSurface(Surface) --[App UI进程]
HardwareRenderer.setSurface(Surface) --[App UI进程]
android_view_ThreadedRenderer:setSurface(...) --[App UI进程]
android_view_Surface:getSurface(...) --[App UI进程] 这里返回上面创建的native Surface
RenderProxy:setSurface(Surface) --[App UI进程] 接下来转进RenderThread线程处理
CanvasContext:setSurface(...) --[RenderThread线程]
SkiaVulkanPipeline:setSurface(...) --[RenderThread线程]
VulkanManager:createSurface(...) --[RenderThread线程]
VulkanSurface:Create(...) --[RenderThread线程]
VulkanManager.mGetPhysicalDeviceSurfaceCapabilitiesKHR(...)
获取Vulkan引擎中的Surface
大致流程如下图:
现在我们已经获取了渲染引擎中的Surface,向其中填充数据的过程就是performDraw的流程;
这个部分在RenderThread中有分析,不在赘述。
那当我们的Surface中已经被填充了数据后,是如何传递给SurfaceFlinger做合成的呢?
这个部分我们稍后详细分析,目前仅从trace上也可以看出来:
上图中eglSwapBuffer最终就是通过binder通知到surfaceflinger中处理的:
五. Layer实例
以如下图为例,看看对应Layer:
Display 19260235133379457 HWC layers:
-------------------------------------------------------------------------------------------
Layer name
Z | Window Type | Comp Type | Transform | Disp Frame (LTRB) | Source Crop (LTRB)
-------------------------------------------------------------------------------------------
com.android.dialer/com.oneplus.contacts.activities.OPDialtactsActivity#0
rel 0 | 1 | DEVICE | 0 | 0 0 1080 2340 | 0.0 0.0 1080.0 2340.0
- - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - -- - - - - - - - - - - - - - -
PopupWindow:b04e24#0
rel 0 | 1002 | DEVICE | 0 | 646 56 1080 656 | 0.0 0.0 434.0 600.0
- - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - -- - - - - - - - - - - - - - -
StatusBar#0
rel 0 | 2000 | DEVICE | 0 | 0 0 1080 80 | 0.0 0.0 1080.0 80.0
- - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - -- - - - - - - - - - - - - - -
NavigationBar0#0
rel 0 | 2019 | DEVICE | 0 | 0 2214 1080 2340 | 0.0 0.0 1080.0 126.0
- - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - -- - - - - - - - - - - - - - -
ScreenDecorOverlay#0
rel 0 | 2024 | DEVICE | 0 | 0 0 1080 240 | 0.0 0.0 1080.0 240.0
- - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - -- - - - - - - - - - - - - - -
ScreenDecorOverlayBottom#0
rel 0 | 2024 | DEVICE | 0 | 0 2100 1080 2340 | 0.0 0.0 1080.0 240.0
- - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - -- - - - - - - - - - - - - - -
+ ContainerLayer (5fd44db PopupWindow:b04e24#0)
Region TransparentRegion (this=0 count=0)
Region VisibleRegion (this=0 count=0)
Region SurfaceDamageRegion (this=0 count=0)
layerStack= 0, z= 2, pos=(646,56), size=( 0, 0), crop=[ 0, 0, -1, -1], cornerRadius=0.000000, isProtected=0, isOpaque=0, invalidate=1, dataspace=Default, defaultPixelFormat=Unknown/None, color=(0.000,0.000,0.000,1.000), flags=0x00000000, tr=[0.00, 0.00][0.00, 0.00]
parent=9628544 com.android.dialer/com.oneplus.contacts.activities.OPDialtactsActivity#0
zOrderRelativeOf=none
activeBuffer=[ 0x 0: 0,Unknown/None], tr=[0.00, 0.00][0.00, 0.00] queued-frames=0, mRefreshPending=0, metadata={}
+ ContainerLayer (9628544 com.android.dialer/com.oneplus.contacts.activities.OPDialtactsActivity#0)
Region TransparentRegion (this=0 count=0)
Region VisibleRegion (this=0 count=0)
Region SurfaceDamageRegion (this=0 count=0)
layerStack= 0, z= 0, pos=(0,0), size=( 0, 0), crop=[ 0, 0, -1, -1], cornerRadius=0.000000, isProtected=0, isOpaque=0, invalidate=1, dataspace=Default, defaultPixelFormat=Unknown/None, color=(0.000,0.000,0.000,1.000), flags=0x00000000, tr=[0.00, 0.00][0.00, 0.00]
parent=AppWindowToken{8380fd9 token=Token{2f31a20 ActivityRecord{7c5523 u0 com.android.dialer/com.oneplus.contacts.activities.OPDialtactsActivity t5}}}#0
zOrderRelativeOf=none
activeBuffer=[ 0x 0: 0,Unknown/None], tr=[0.00, 0.00][0.00, 0.00] queued-frames=0, mRefreshPending=0, metadata={}
+ ContainerLayer (AppWindowToken{8380fd9 token=Token{2f31a20 ActivityRecord{7c5523 u0 com.android.dialer/com.oneplus.contacts.activities.OPDialtactsActivity t5}}}#0)
Region TransparentRegion (this=0 count=0)
Region VisibleRegion (this=0 count=0)
Region SurfaceDamageRegion (this=0 count=0)
layerStack= 0, z= 0, pos=(0,0), size=( 0, 0), crop=[ 0, 0, -1, -1], cornerRadius=0.000000, isProtected=0, isOpaque=0, invalidate=1, dataspace=Default, defaultPixelFormat=Unknown/None, color=(0.000,0.000,0.000,1.000), flags=0x00000000, tr=[0.00, 0.00][0.00, 0.00]
parent=Task=5#0
zOrderRelativeOf=none
activeBuffer=[ 0x 0: 0,Unknown/None], tr=[0.00, 0.00][0.00, 0.00] queued-frames=0, mRefreshPending=0, metadata={}
+ ContainerLayer (Task=5#0)
Region TransparentRegion (this=0 count=0)
Region VisibleRegion (this=0 count=0)
Region SurfaceDamageRegion (this=0 count=0)
layerStack= 0, z= 0, pos=(0,0), size=( 0, 0), crop=[ 0, 0, -1, -1], cornerRadius=0.000000, isProtected=0, isOpaque=0, invalidate=1, dataspace=Default, defaultPixelFormat=Unknown/None, color=(0.000,0.000,0.000,1.000), flags=0x00000000, tr=[0.00, 0.00][0.00, 0.00]
parent=Stack=2#0
zOrderRelativeOf=none
activeBuffer=[ 0x 0: 0,Unknown/None], tr=[0.00, 0.00][0.00, 0.00] queued-frames=0, mRefreshPending=0, metadata={taskId:5}
+ ContainerLayer (Stack=2#0)
Region TransparentRegion (this=0 count=0)
Region VisibleRegion (this=0 count=0)
Region SurfaceDamageRegion (this=0 count=0)
layerStack= 0, z= 5, pos=(0,0), size=( 0, 0), crop=[ 0, 0, 1080, 2340], cornerRadius=0.000000, isProtected=0, isOpaque=0, invalidate=1, dataspace=Default, defaultPixelFormat=Unknown/None, color=(0.000,0.000,0.000,1.000), flags=0x00000000, tr=[0.00, 0.00][0.00, 0.00]
parent=com.android.server.wm.DisplayContent$TaskStackContainers@c19f2e#0
zOrderRelativeOf=none
activeBuffer=[ 0x 0: 0,Unknown/None], tr=[0.00, 0.00][0.00, 0.00] queued-frames=0, mRefreshPending=0, metadata={}
+ ContainerLayer (com.android.server.wm.DisplayContent$TaskStackContainers@c19f2e#0)
Region TransparentRegion (this=0 count=0)
Region VisibleRegion (this=0 count=0)
Region SurfaceDamageRegion (this=0 count=0)
layerStack= 0, z= 1, pos=(0,0), size=( 0, 0), crop=[ 0, 0, -1, -1], cornerRadius=0.000000, isProtected=0, isOpaque=0, invalidate=1, dataspace=Default, defaultPixelFormat=Unknown/None, color=(0.000,0.000,0.000,1.000), flags=0x00000000, tr=[0.00, 0.00][0.00, 0.00]
parent=Display Root#0
zOrderRelativeOf=none
activeBuffer=[ 0x 0: 0,Unknown/None], tr=[0.00, 0.00][0.00, 0.00] queued-frames=0, mRefreshPending=0, metadata={}
+ ContainerLayer (Display Root#0)
Region TransparentRegion (this=0 count=0)
Region VisibleRegion (this=0 count=0)
Region SurfaceDamageRegion (this=0 count=0)
layerStack= 0, z= 0, pos=(0,0), size=( 0, 0), crop=[ 0, 0, -1, -1], cornerRadius=0.000000, isProtected=0, isOpaque=0, invalidate=1, dataspace=Default, defaultPixelFormat=Unknown/None, color=(0.000,0.000,0.000,1.000), flags=0x00000002, tr=[0.00, 0.00][0.00, 0.00]
parent=none
zOrderRelativeOf=none
activeBuffer=[ 0x 0: 0,Unknown/None], tr=[0.00, 0.00][0.00, 0.00] queued-frames=0, mRefreshPending=0, metadata={}
示意图如下:
总的来说就是,树形结构+Z order排序。
六. 类图
现在我们Surface有了,也有渲染的内容了,那SurfaceFlinger是如何将这些Surface对应的Layer合成为一帧并显示出来的呢?