Android UI架构(八)--探秘刷新动力Vsync(4)之Layer&Surface准备.md

参考资料

  1. Android Synchronization Fences – An Introduction
  2. Android中的GraphicBuffer同步机制-Fence
  3. 深入浅出Android BufferQueue
  4. 从systrace看app冷启动过程(三)-首帧的合成与送显
  5. Android显示Surface
  6. surfaceflinger中各个layer的排序
  7. Android 4.0.3 显示系统深入理解
  8. 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
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7zO1Yc6s-1591794142113)(picture/4_1.png)]

Surface FLAG一览

名称作用
HIDDEN0x00000004Surface是隐藏的
SECURE0x00000080包含安全内容,禁止内容被其他进程复制。而且屏幕截图和VNC服务器将被禁用,但可能不会采用硬件加速。Window带有FLAG_SECURE标签,或者该应用禁止截图就会带有这个FLAG
NON_PREMULTIPLIED0x00000100预乘透明度,创建一个Surface,其中颜色分量被Alpha通道解释为“非预乘”。对于没有alpha通道的Surface,这个标志是没有意义的。 默认情况下,Surface是预乘的,这意味着每个颜色分量已经乘以其alpha值。
OPAQUE0x00000400表示Surface必须为不透明,即使其像素格式包含Alpha通道。
PROTECTED_APP0x00000800应用程序需要通过外部显示接收器的硬件保护路径。 如果硬件保护路径不可用,则此表面将不会显示在外部接收器上。
CURSOR_WINDOW0x00002000窗口表示光标字形。
FX_SURFACE_NORMAL0x00000000创建一个默认Surface
FX_SURFACE_DIM0x00020000创建一个暗淡的Surface。 此Surface后面的所有内容都会被{@link #setAlpha}中指定的数量调暗。 锁定Dim Surface是错误的,因为它没有后备存储。
FX_SURFACE_CONTAINER创建容器Surface。 此Surface将没有缓冲区,仅用作其他Surface或其InputInfo的容器。
SURFACE_HIDDEN0x01隐藏该Surface, 等同于调用Surface.hide()
SURFACE_OPAQUE0x02尽可能不混合的复合材料。 更新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();
}

重点关注的是:

名称作用
zz-order,表示x,y,z轴的z轴上的顺序。数字越大,表示越在上面,数字越小,表示越在下面。
layerStacklayerStack是存储layer的容器,我们知道每个display只会有一个layerstack来存储他要显示的layer,但是不同的display可以使用同一个layerStack,也可以使用不同的layerStack。可以理解为组的含义。也就是说属于不同组的layer之间互不干扰。SurfaceFlinger中有一个DisplayDevice类,他表示用来显示的设备,譬如LCD或者是HDMI。DisplayDevice里也有一个成员变量mLayerStack,在进行composition的时候,只有和这个device的layerstack相同的layer才可能被显示在这个设备上。
sequencesSequence是一个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轴的位置

如图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-by6rW4tY-1591794142115)(picture/4_2.png)]

到目前为止还只是创建了一个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

大致流程如下图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lWp49VOt-1591794142116)(picture/4_3.png)]

现在我们已经获取了渲染引擎中的Surface,向其中填充数据的过程就是performDraw的流程;
这个部分在RenderThread中有分析,不在赘述。

那当我们的Surface中已经被填充了数据后,是如何传递给SurfaceFlinger做合成的呢?
这个部分我们稍后详细分析,目前仅从trace上也可以看出来:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tcHFT1Lp-1591794142117)(picture/4_4_app.png)]

上图中eglSwapBuffer最终就是通过binder通知到surfaceflinger中处理的:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-orhCRUZH-1591794142119)(picture/4_4_sf.png)]

五. 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={}

示意图如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RjuCOrwC-1591794142121)(picture/screenshot_phone_layer.png)]

总的来说就是,树形结构+Z order排序。

六. 类图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nBJwUkmF-1591794142122)(picture/4_5_classmap.png)]

现在我们Surface有了,也有渲染的内容了,那SurfaceFlinger是如何将这些Surface对应的Layer合成为一帧并显示出来的呢?

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值