Android GUI系统之SurfaceFlinger(09)服务端分析4-handleMessageRefresh处理

该系列文章总纲链接:Android GUI系统之SurfaceFlinger 系列文章目录


本章关键点总结 & 说明:

本章节思维导图如上。主要讲述了SurfaceFlinger 处理Vsync机制的流程。主要分析handleMessageRefresh 处理方法。


1 从signalRefresh到handleMessageRefresh

signalRefresh的代码实现如下:

void SurfaceFlinger::signalRefresh() {
    mEventQueue.refresh();
}

这里继续分析mEventQueue的refresh方法,代码实现如下:

void MessageQueue::refresh() {
#if INVALIDATE_ON_VSYNC
    mHandler->dispatchRefresh();//调用这里
#else
    mEvents->requestNextVsync();
#endif
}

继续分析mHandler的dispatchRefresh()方法,代码实现如下:

void MessageQueue::Handler::dispatchRefresh() {
    if ((android_atomic_or(eventMaskRefresh, &mEventMask) & eventMaskRefresh) == 0) {
        mQueue.mLooper->sendMessage(this, Message(MessageQueue::REFRESH));
    }
}

这里使用了handler Message 机制,因此看如何处理的,代码如下:

void MessageQueue::Handler::handleMessage(const Message& message) {
    switch (message.what) {
        case INVALIDATE:
            android_atomic_and(~eventMaskInvalidate, &mEventMask);
            mQueue.mFlinger->onMessageReceived(message.what);
            break;
        case REFRESH:
            android_atomic_and(~eventMaskRefresh, &mEventMask);
            mQueue.mFlinger->onMessageReceived(message.what);
            break;
        case TRANSACTION:
            android_atomic_and(~eventMaskTransaction, &mEventMask);
            mQueue.mFlinger->onMessageReceived(message.what);
            break;
    }
}

这里会调用SurfaceFlinger的onMessageReceived方法,最后调用的是onMessageReceived,代码如下:

void SurfaceFlinger::onMessageReceived(int32_t what) {
    switch (what) {
        //...
        case MessageQueue::REFRESH: {
            handleMessageRefresh();
            break;
        }
    }
}

到这里可以看到,signalRefresh的调用最后还会回到SurfaceFlinger的onMessageReceived调用,只不过参数变成了MessageQueue::REFRESH,这里继续分析handleMessageRefresh(),

2 handleMessageRefresh 分析

handleMessageRefresh()的代码实现如下:

void SurfaceFlinger::handleMessageRefresh() {
    //关键点1 合成前预处理
    preComposition();
    //关键点2 计算可见区域,主要依据:z-order大的覆盖有重叠区域z-order小的
    rebuildLayerStacks();

    //关键点3 下面几个方法都是页面合成相关
    setUpHWComposer();
    doDebugFlashRegions();
    //关键点4 合成所有层的图像, 经过这一步后,就显示新的内容了
    doComposition();
    //合成之后的工作
    postComposition();
}

这里重点分析rebuildLayerStacks,最后整体简要分析下preComposition函数 和 合成界面相关的函数。

2.1 preComposition简要分析

先看Vsync Rate相关的代码:

virtual void setVsyncRate(uint32_t count)

当count为1时,表示每个信号都要报告,当count =2 时,表示信号 间隔一个后才报告,当count=0时表示不自动报告,除非主动触发requestNextVsync,接下来分析preComposition,代码实现如下:

void SurfaceFlinger::preComposition()
{
    bool needExtraInvalidate = false;
    const LayerVector& layers(mDrawingState.layersSortedByZ);
    const size_t count = layers.size();
    //获取全部的layer
    for (size_t i=0 ; i<count ; i++) {
        //执行 每个layer onPrecomposition
        if (layers[i]->onPreComposition()) {
            needExtraInvalidate = true;
        }
    }
    if (needExtraInvalidate) {
        signalLayerUpdate();//请求VSYNC
    }
}

这里会调用 每个Layer 的onPreComposition,代码实现如下:

bool Layer::onPreComposition() {
    mRefreshPending = false;
    return mQueuedFrames > 0 || mSidebandStreamChanged;
}

也就是说,当layer里存放被queue的frame以后,就会出发layer update,signalLayerUpdate这这里分析过,具体位置在这个链接:(Android GUI系统之SurfaceFlinger(06)服务端分析1-处理VSYNC)因此这里就不展开了。

2.2 rebuildLayerStacks 分析

在分析之前需要明确个基本概念:

  1. dirtyRegion:表示该区域是需要被刷新的。
  2. opaqueRegion:表示不透明区域。
  3. transparentRegion:表示完全透明区域。
  4. translucentRegion:表示半透明区域。

说明:对于opaqueRegion,应为layer是按Z-order排序的,左右排在前面的opaqueRegion 会挡住后面的layer。

接下来开始分析代码,rebuildLayerStacks 代码 实现如下:

void SurfaceFlinger::rebuildLayerStacks() {
    // rebuild the visible layer list per screen
    if (CC_UNLIKELY(mVisibleRegionsDirty)) {
        mVisibleRegionsDirty = false;
        invalidateHwcGeometry();
        //计算每个设备上的可见Layer
        const LayerVector& layers(mDrawingState.layersSortedByZ);
        //系统的display可能不止一个,存在于mDisplays中
        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
            Region opaqueRegion;
            Region dirtyRegion;
            Vector< sp<Layer> > layersSortedByZ;
            const sp<DisplayDevice>& hw(mDisplays[dpy]);
            const Transform& tr(hw->getTransform());
            const Rect bounds(hw->getBounds());
            if (hw->isDisplayOn()) {
                //计算可视区域,最关键方法
                SurfaceFlinger::computeVisibleRegions(layers,
                        hw->getLayerStack(), dirtyRegion, opaqueRegion);

                const size_t count = layers.size();
                for (size_t i=0 ; i<count ; i++) {
                    const sp<Layer>& layer(layers[i]);
                    const Layer::State& s(layer->getDrawingState());
                    //这里只要 和显示设备的layerStack相同的 layer
                    if (s.layerStack == hw->getLayerStack()) {
                        //程序需要进一步得出每个layer 绘制的区域
                        Region drawRegion(tr.transform(
                                layer->visibleNonTransparentRegion));
                        drawRegion.andSelf(bounds);
                        //如果Layer的显示区域和显示设备的窗口有交集
                        if (!drawRegion.isEmpty()) {
                            layersSortedByZ.add(layer);
                        }
                    }
                }
            }
            //设置显示设备的可见列表,将这些结果保存在hw中
            hw->setVisibleLayersSortedByZ(layersSortedByZ);//Z序layer
            hw->undefinedRegion.set(bounds);
            hw->undefinedRegion.subtractSelf(tr.transform(opaqueRegion));//
            hw->dirtyRegion.orSelf(dirtyRegion);//刷新区
        }
    }
}

rebuildLayerStacks主要是做两件事:

  1. 重建每个显示设备的可见layer对象的列表。layer按照Z序排列,但每个Layer都有 透明区、不透明区、半透明区即下面的Layer某些区域也是有机会显示的
  2. 对每个显示设备,先计算和显示设备相同的layerStack值的layer对象在显示设备上的可见区域,然后将可见区域和显示设备的窗口有交集的layer组成一个新的列表,最后把这个列表设置到显示设备对象中。

这里 主要关注computeVisibleRegions的实现,代码如下:

void SurfaceFlinger::computeVisibleRegions(
        const LayerVector& currentLayers, uint32_t layerStack,
        Region& outDirtyRegion, Region& outOpaqueRegion)
{
    Region aboveOpaqueLayers;//当前层之上累计的不透明区域
    Region aboveCoveredLayers;//当前层之上累计的被覆盖区域,不透明+半透明
    Region dirty;
    outDirtyRegion.clear();总值

    size_t i = currentLayers.size();//最上层layer的索引
    while (i--) {//从Z轴 最上面的layer开始处理,由上到下
        const sp<Layer>& layer = currentLayers[i];
        const Layer::State& s(layer->getDrawingState());
        // 只计算和layerstack相同的layer,其他忽略
        if (s.layerStack != layerStack)
            continue;

        Region opaqueRegion;        //不透明区域
        Region visibleRegion;       //可见区域,不透明区域+半透明区域
        Region coveredRegion;       //覆盖区域,可见区域覆盖的地方
        Region transparentRegion;   //完全透明区域
        //stage1-start 得到当前Layer的原始可视区域 和 opaque区域
        // handle hidden surfaces by setting the visible region to empty
        if (CC_LIKELY(layer->isVisible())) {
            const bool translucent = !layer->isOpaque(s);
            Rect bounds(s.transform.transform(layer->computeBounds()));
            visibleRegion.set(bounds);
            if (!visibleRegion.isEmpty()) {
                // Remove the transparent area from the visible region
                if (translucent) {//计算透明区域
                    const Transform tr(s.transform);
                    if (tr.transformed()) {
                        if (tr.preserveRects()) {
                            // transform the transparent region
                            transparentRegion = tr.transform(s.activeTransparentRegion);
                        } else {
                            // transformation too complex, can't do the
                            // transparent region optimization.
                            transparentRegion.clear();
                        }
                    } else {
                        transparentRegion = s.activeTransparentRegion;
                    }
                }

                // 计算不透明区域
                const int32_t layerOrientation = s.transform.getOrientation();
                if (s.alpha==255 && !translucent &&
                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
                    opaqueRegion = visibleRegion;
                }
            }
        }
        //stage1-end

        //当前Layer被遮盖区域:上层的覆盖区 和 layer所在区域的 交集
        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);

        // 扩大覆盖区域,为下次循环、即下层计算做准备
        aboveCoveredLayers.orSelf(visibleRegion);

        //可见区域 = 抠掉上层的不透明区域
        visibleRegion.subtractSelf(aboveOpaqueLayers);

        // 计算需要重绘的区域
        if (layer->contentDirty) {
            //内容变了,重绘整个可见区域
            dirty = visibleRegion;
            //以前的看见区域也要加进来,因为以前的内容需要抹掉
            dirty.orSelf(layer->visibleRegion);
            layer->contentDirty = false;
        } else {
            //暴露区域 = 可见区域-被覆盖区域
            const Region newExposed = visibleRegion - coveredRegion;
            const Region oldVisibleRegion = layer->visibleRegion;
            const Region oldCoveredRegion = layer->coveredRegion;
            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
        }
        
        //layer的重绘区域 = 抠掉上层的不透明区域
        dirty.subtractSelf(aboveOpaqueLayers);

        //累计每层需要重绘的区域
        outDirtyRegion.orSelf(dirty);

        //更新aboveOpaqueLayers,为下层layer绘制做准备
        aboveOpaqueLayers.orSelf(opaqueRegion);

        //设置layer对象的区域
        layer->setVisibleRegion(visibleRegion);
        layer->setCoveredRegion(coveredRegion);
        //设置可见的非透明区域
        layer->setVisibleNonTransparentRegion(
                visibleRegion.subtract(transparentRegion));
    }

    outOpaqueRegion = aboveOpaqueLayers;
}

总结下computeVisibleRegions的逻辑如下:

先计算每个layer在设备上的可见区域visibleRegion(不透明区域 + 半透明区域)。计算方法:整个Layer的区域-上层所有不透明区域aboveOpaqueLayers。而上层所有不透明区域的值 是一个逐层累积的过程,每层都把自己的不透明区域累加到aboveOpaqueLayers中。

每层的不透明区域的计算方法:如果layer的alpha值=255,并且layer的isOpaque = true,则本层的不透明区域 == layer所在区域。否则为0。这样一层层计算下来,就很容易得到每层的可见区域大小了。

这里以下图为例,解读下computeVisibleRegions这段逻辑:

假设有三个Layer,按照Z值从大到小,依次是Layer1->Layer2->Layer3,最后按照computeVisibleRegions的规则来合成Layer。有了这个图,看这段逻辑 便会更加直观。同时理解这段逻辑 最好的方法是将3个Layer带入到computeVisibleRegions方法中。

2.3 setUpHWComposer

setUpHWComposer的代码实现如下:

void SurfaceFlinger::setUpHWComposer() {
    //mDisplays变量中维护者每个显示变量的信息
    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
        bool dirty = !mDisplays[dpy]->getDirtyRegion(false).isEmpty();
        bool empty = mDisplays[dpy]->getVisibleLayersSortedByZ().size() == 0;
        bool wasEmpty = !mDisplays[dpy]->lastCompositionHadVisibleLayers;
        bool mustRecompose = dirty && !(empty && wasEmpty);
        mDisplays[dpy]->beginFrame(mustRecompose);

        if (mustRecompose) {
            mDisplays[dpy]->lastCompositionHadVisibleLayers = !empty;
        }
    }

    HWComposer& hwc(getHwComposer());//得到系统的HWC对象
    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++) {
                sp<const DisplayDevice> hw(mDisplays[dpy]);
                const int32_t id = hw->getHwcDisplayId();
                if (id >= 0) {
                    //遍历DisplayDevice所有可见layer 
                    const Vector< sp<Layer> >& currentLayers(
                        hw->getVisibleLayersSortedByZ());
                    const size_t count = currentLayers.size();
                    //根据layer数量调用createWorkList创建hwc_layer_list_t列表  
                    if (hwc.createWorkList(id, count) == NO_ERROR) {
                        //...
                    }
                }
            }
        }

        // set the per-frame data
        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
            sp<const DisplayDevice> hw(mDisplays[dpy]);
            const int32_t id = hw->getHwcDisplayId();
            if (id >= 0) {
                const Vector< sp<Layer> >& currentLayers(
                    hw->getVisibleLayersSortedByZ());
                const size_t count = currentLayers.size();
                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的ActiveBuffer设置到HWComposer中的hwc_layer_1_t中
                    layer->setPerFrameData(hw, *cur);
                }
            }
        }

        // If possible, attempt to use the cursor overlay on each display.
        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
            //...
        }

        status_t err = hwc.prepare();
        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
            sp<const DisplayDevice> hw(mDisplays[dpy]);
            hw->prepareFrame(hwc);
        }
    }
}

该函数的作用是更新HWComposer对象中图层对象列表以及涂层属性。详细点就是 构造Worklist,并且给DisplayData的list 申请空间,并填充各个layer的数据,最后调用HWComposer的prepare函数(往下延伸,这部分就是由厂家来实现了)。

2.4 doCompostion

setUpHWComposer 只是交给HWC来负责显示,真正显示的地方在这,doCompostion的代码实现如下:

void SurfaceFlinger::doComposition() {
    const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
        const sp<DisplayDevice>& hw(mDisplays[dpy]);
        if (hw->isDisplayOn()) {
            // transform the dirty region into this screen's coordinate space
            const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));

            //关键点1:进行图像合成
            doDisplayComposition(hw, dirtyRegion);

            hw->dirtyRegion.clear();
            hw->flip(hw->swapRegion);
            hw->swapRegion.clear();
        }
        // 通知HWC合成结束了
        hw->compositionComplete();
    }
    //关键点2:完成后调用该方法
    postFramebuffer();
}

这里我们关键分析几个方法:getDirtyRegiondoDisplayComposition和postFramebuffer。

2.4.1 getDirtyRegion分析

在前面重构Layer时,Display的脏区域dirtyRegion已经计算出来。如果是重画,mRepaintEverything为true,那么脏区域就是整个屏幕的大小。getDirtyRegion的代码实现如下:

Region DisplayDevice::getDirtyRegion(bool repaintEverything) const {
    Region dirty;
    if (repaintEverything) {
        dirty.set(getBounds());
    } else {
        const Transform& planeTransform(mGlobalTransform);
        dirty = planeTransform.transform(this->dirtyRegion);
        dirty.andSelf(getBounds());
    }
    return dirty;
}

2.4.2 doDisplayComposition分析

doDisplayComposition代码实现如下:

void SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw,
        const Region& inDirtyRegion)
{
    bool isHwcDisplay = hw->getHwcDisplayId() >= 0;
    if (!isHwcDisplay && inDirtyRegion.isEmpty()) {
        return;
    }

    Region dirtyRegion(inDirtyRegion);
    //swapRegion设置为 需要更新的区域
    hw->swapRegion.orSelf(dirtyRegion);

    uint32_t flags = hw->getFlags();
    if (flags & DisplayDevice::SWAP_RECTANGLE) {//支持矩形更更新
        dirtyRegion.set(hw->swapRegion.bounds());
    } else {//支持部分更新
        if (flags & DisplayDevice::PARTIAL_UPDATES) {
            dirtyRegion.set(hw->swapRegion.bounds());
        } else {
            // we need to redraw everything (the whole screen)
            dirtyRegion.set(hw->bounds());//将更新区域调整为整个窗口的大小
            hw->swapRegion = dirtyRegion;
        }
    }
    //关键点1:都会执行 doComposeSurfaces方法
    if (CC_LIKELY(!mDaltonize && !mHasColorMatrix)) {
        if (!doComposeSurfaces(hw, dirtyRegion)) return;
    } else {
        RenderEngine& engine(getRenderEngine());
        mat4 colorMatrix = mColorMatrix;
        if (mDaltonize) {
            colorMatrix = colorMatrix * mDaltonizer();
        }
        engine.beginGroup(colorMatrix);
        doComposeSurfaces(hw, dirtyRegion);
        engine.endGroup();
    }

    // update the swap region and clear the dirty region
    hw->swapRegion.orSelf(dirtyRegion);

    //关键点2:在系统不支持HWC的情况下调用eglSwapBuffers来输出图像到显示设备。
    hw->swapBuffers(getHwComposer());
}

传入的参数inDirtyRegion,是要刷新的“脏”区域,但我们的刷新机制决定了必须是矩形的区域。因此需要一个最小的矩形,能够包裹inDirtyRegion的区域。这里有两种模式:

  1. SWAP_RECTANGLE:系统支持软件层面的部分刷新,就需要计算这个最小矩形。
  2. PARTIAL_UPDATES:硬件层面的部分刷新,同理需要这个最小矩形。

总之 最后就是重绘这个区域。 该部分专注两个关键方法 doComposeSurfaces 和 hw->swapBuffers(getHwComposer());

@1 doComposeSurfaces分析

doComposeSurfaces的代码实现如下:

bool SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty)
{
    RenderEngine& engine(getRenderEngine());
    const int32_t id = hw->getHwcDisplayId();
    HWComposer& hwc(getHwComposer());
    HWComposer::LayerListIterator cur = hwc.begin(id);
    const HWComposer::LayerListIterator end = hwc.end(id);

    bool hasGlesComposition = hwc.hasGlesComposition(id);
    if (hasGlesComposition) {
        if (!hw->makeCurrent(mEGLDisplay, mEGLContext)) {
            eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
            if(!getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext)) {
              ALOGE("DisplayDevice::makeCurrent on default display failed. Aborting.");
            }
            return false;
        }

        // Never touch the framebuffer if we don't have any framebuffer layers
        const bool hasHwcComposition = hwc.hasHwcComposition(id);
        if (hasHwcComposition) {
            engine.clearWithColor(0, 0, 0, 0);
        } else {
            const Region bounds(hw->getBounds());
            const Region letterbox(bounds.subtract(hw->getScissor()));
            Region region(hw->undefinedRegion.merge(letterbox));
            region.andSelf(dirty);

            // screen is already cleared here
            if (!region.isEmpty()) {
                // can happen with SurfaceView
                drawWormhole(hw, region);
            }
        }

        if (hw->getDisplayType() != DisplayDevice::DISPLAY_PRIMARY) {
            const Rect& bounds(hw->getBounds());
            const Rect& scissor(hw->getScissor());
            if (scissor != bounds) {
                const uint32_t height = hw->getHeight();
                engine.setScissor(scissor.left, height - scissor.bottom,
                        scissor.getWidth(), scissor.getHeight());
            }
        }
    }

    const Vector< sp<Layer> >& layers(hw->getVisibleLayersSortedByZ());
    const size_t count = layers.size();
    const Transform& tr = hw->getTransform();
    if (cur != end) {
        // 使用 h/w composer
        for (size_t i=0 ; i<count && cur!=end ; ++i, ++cur) {
            const sp<Layer>& layer(layers[i]);
            const Region clip(dirty.intersect(tr.transform(layer->visibleRegion)));
            if (!clip.isEmpty()) {
                switch (cur->getCompositionType()) {
                    case HWC_CURSOR_OVERLAY:
                    case HWC_OVERLAY: {
                        const Layer::State& state(layer->getDrawingState());
                        if ((cur->getHints() & HWC_HINT_CLEAR_FB)
                                && i
                                && layer->isOpaque(state) && (state.alpha == 0xFF)
                                && hasGlesComposition) {
                            layer->clearWithOpenGL(hw, clip);
                        }
                        break;
                    }
                    case HWC_FRAMEBUFFER: {
                        layer->draw(hw, clip);
                        break;
                    }
                    case HWC_FRAMEBUFFER_TARGET: {
                        // this should not happen as the iterator shouldn't
                        // let us get there.
                        ALOGW("HWC_FRAMEBUFFER_TARGET found in hwc list (index=%zu)", i);
                        break;
                    }
                }
            }
            layer->setAcquireFence(hw, *cur);
        }
    } else {
        // 不使用 h/w composer,只用openGL ES
        for (size_t i=0 ; i<count ; ++i) {
            const sp<Layer>& layer(layers[i]);
            const Region clip(dirty.intersect(
                    tr.transform(layer->visibleRegion)));
            if (!clip.isEmpty()) {
                layer->draw(hw, clip);
            }
        }
    }

    // disable scissor at the end of the frame
    engine.disableScissor();
    return true;
}

这里无论是使用openGL ES  还是HWC 来处理,都会调用layer->draw方法。只不过HWC的相对复杂一些而已。

@2 hw->swapBuffers(getHwComposer())分析

这里hw就是DisplayDevice,该部分 在章节(Android GUI系统之SurfaceFlinger(14)理解DisplayDevice)中 分析过,所以这里不再重复。

2.4.3 postFramebuffer分析

postFramebuffer代码实现如下:

void SurfaceFlinger::postFramebuffer()
{
    const nsecs_t now = systemTime();
    mDebugInSwapBuffers = now;

    HWComposer& hwc(getHwComposer());
	//检查是否支持HWC,如果不支持在前面就输出了,直接返回
    if (hwc.initCheck() == NO_ERROR) {
        if (!hwc.supportsFramebufferTarget()) {
            getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
        }
		//关键点:支持HWC则 调用该方法
        hwc.commit();
    }
	//...
}

这里继续分析hwc的commit()方法,代码实现如下:

status_t HWComposer::commit() {
    int err = NO_ERROR;
    if (mHwc) {
        if (!hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
            mLists[0]->dpy = eglGetCurrentDisplay();
            mLists[0]->sur = eglGetCurrentSurface(EGL_DRAW);
        }

        for (size_t i=VIRTUAL_DISPLAY_ID_BASE; i<mNumDisplays; i++) {
            DisplayData& disp(mDisplayData[i]);
            if (disp.outbufHandle) {
                mLists[i]->outbuf = disp.outbufHandle;
                mLists[i]->outbufAcquireFenceFd =
                        disp.outbufAcquireFence->dup();
            }
        }
        //关键点
        err = mHwc->set(mHwc, mNumDisplays, mLists);
        //...
    }
    return (status_t)err;
}

这里主要调用了HWC的 set函数处理之后的工作(set的代码实现往下延伸,就是由厂家来实现了)。同时图像最后输出到显示屏上。

2.5 postComposition分析

postComposition的代码实现如下:

void SurfaceFlinger::postComposition()
{
    const LayerVector& layers(mDrawingState.layersSortedByZ);
    const size_t count = layers.size();
    for (size_t i=0 ; i<count ; i++) {
        layers[i]->onPostComposition();
    }
	
    const HWComposer& hwc = getHwComposer();
    sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);

	//VSync同步
    if (presentFence->isValid()) {
        if (mPrimaryDispSync.addPresentFence(presentFence)) {
            enableHardwareVsync();
        } else {
            disableHardwareVsync(false);
        }
    }

    if (kIgnorePresentFences) {
        const sp<const DisplayDevice> hw(getDefaultDisplayDevice());
        if (hw->isDisplayOn()) {
            enableHardwareVsync();
        }
    }
	
	//动画合成处理
    if (mAnimCompositionPending) {
        mAnimCompositionPending = false;

        if (presentFence->isValid()) {
            mAnimFrameTracker.setActualPresentFence(presentFence);
        } else {
            nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
            mAnimFrameTracker.setActualPresentTime(presentTime);
        }
        mAnimFrameTracker.advanceFrame();
    }
}

至此,整个handleMessageRefresh的处理流程就分析结束了。

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

图王大胜

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

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

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

打赏作者

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

抵扣说明:

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

余额充值