surfaceflinger 合成过程解析

[TOC]来生成目录:

整体流程

我们知道,当VSync信号到来时,SurfaceFlinger最主要是通过处理INVALIDATE和REFRESH消息来做合并渲染和输出的工作的。这里的核心思想是能少处理一点是一点,所以在渲染前有很多脏区域的计算工作,这样后面只要处理那些区域的更新就可以了。
这样是有现实意义的,一方面由于图层间的遮盖,有些不可见图层不需要渲染。另一方面,因为我们的应用程序中前后帧一般只有一小部分变化,要是每帧都全变估计人都要看吐了。这里主要是调用了这几个函数:
handleMessageTransaction()主要处理之前对屏幕和应用程序窗口的改动。因这些改动很有可能会改变图层的可见区域,进而影响脏区域的计算。
handleMessageInvalidate()主要调用handlePageFlip()函数。这里Page Flip是指从BufferQueue中取下一个图形缓冲区内容,就好像是“翻页”一样。该函数主要是从各Layer对应的BufferQueue中拿图形缓冲区数据,并根据内容更新脏区域。
handleMessageRefresh()就是合并和渲染输出了。

handleMessageInvalidate

如上所说,这个主要是把所有可见的layer的buffer拿出来。
handleMessageInvalidate只调用了handlePageFlip

bool SurfaceFlinger::handlePageFlip()
{
    Region dirtyRegion;

    bool visibleRegions = false;
    const LayerVector& layers(mDrawingState.layersSortedByZ);//拿出所有的layer
    bool frameQueued = false;

    Vector<Layer*> layersWithQueuedFrames;
    for (size_t i = 0, count = layers.size(); i<count ; i++) {
        const sp<Layer>& layer(layers[i]);
        if (layer->hasQueuedFrame()) {//看Layer的mQueuedFrames > 0?
            frameQueued = true;
            if (layer->shouldPresentNow(mPrimaryDispSync)) {
                layersWithQueuedFrames.push_back(layer.get());
            }
        }
    }
    //如果layersWithQueuedFrames.size()>0,说明有更新
    for (size_t i = 0, count = layersWithQueuedFrames.size() ; i<count ; i++) {
        Layer* layer = layersWithQueuedFrames[i];
        const Region dirty(layer->latchBuffer(visibleRegions));//调用latchBuffer,该函数会拿出BufferQueue的新buffer
        const Layer::State& s(layer->getDrawingState());
        invalidateLayerStack(s.layerStack, dirty);
    }

    mVisibleRegionsDirty |= visibleRegions;

    if (frameQueued && layersWithQueuedFrames.empty()) {
        signalLayerUpdate();//如果没有任何layer更新,那就调用signalLayerUpdate->requestNextVsync,等待下一个vsync
    }
    return !layersWithQueuedFrames.empty();//有新帧,就返回true
}

handleMessageRefresh

前一步,已经把各个layer的buffer更新了,接着就是要合成并输出了,这个函数就干这个事情。
且看其定义。

void SurfaceFlinger::handleMessageRefresh() {
    ATRACE_CALL();
    preComposition();
    rebuildLayerStacks();
    setUpHWComposer();
    doDebugFlashRegions();
    doComposition();
    postComposition();
}

1. preComposition

void SurfaceFlinger::preComposition()
{
    bool needExtraInvalidate = false;
    const LayerVector& layers(mDrawingState.layersSortedByZ);
    const size_t count = layers.size();
    for (size_t i=0 ; i<count ; i++) {
        if (layers[i]->onPreComposition()) {//判断mQueuedFrames > 0
            needExtraInvalidate = true;
        }
    }
    if (needExtraInvalidate) {
        signalLayerUpdate();//一旦有某一个layer有更新,就调用signalLayerUpdate->requestNextVsync
    }
}

signalLayerUpdate主要调用
mEvents->requestNextVsync();

2. rebuildLayerStacks

根据函数名字就可以知道,他主要是对所有的layer过滤一遍,拿出可见的layer,等待下一步处理。
函数比较简单,这里不详说。

3. setUpHWComposer

void SurfaceFlinger::setUpHWComposer() {
    //省略。。。
    HWComposer& hwc(getHwComposer());
    if (hwc.initCheck() == NO_ERROR) {
        // build the h/w work list
        if (CC_UNLIKELY(mHwWorkListDirty)) {
            mHwWorkListDirty = false;
            for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {//其实大部分情况,只有一个DisplayDevice
                sp<const DisplayDevice> hw(mDisplays[dpy]);
                const int32_t id = hw->getHwcDisplayId();//DisplayDevice的id
                if (id >= 0) {
                    const Vector< sp<Layer> >& currentLayers(
                        hw->getVisibleLayersSortedByZ());//rebuildLayerStacks时,把可见的layer存在DisplayDevice了
                    const size_t count = currentLayers.size();//可见的layer
                    if (hwc.createWorkList(id, count) == NO_ERROR) {//HWC的createWorkList很重要。
                        HWComposer::LayerListIterator cur = hwc.begin(id);
                        const HWComposer::LayerListIterator end = hwc.end(id);
                        for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
                            const sp<Layer>& layer(currentLayers[i]);
                            layer->setGeometry(hw, *cur);
                            if (mDebugDisableHWC || mDebugRegion || mDaltonize || mHasColorMatrix) {
                                cur->setSkip(true);
                            }
                        }
                    }
                }
            }
        }
}

4. doDebugFlashRegions

5. doComposition

6. postComposition

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

newchenxf

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值