surfaceflinger刷新动作和client合成

在这里插入图片描述
首先来看看,createlayer这个是后面刷新的基本。createsurface生成surface的时候会调用createlayer

status_t SurfaceFlinger::createLayer(
        const String8& name,
        const sp<Client>& client,
        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
        uint32_t windowType, uint32_t ownerUid, sp<IBinder>* handle,
        sp<IGraphicBufferProducer>* gbp, sp<Layer>* parent)
{
    if (int32_t(w|h) < 0) {
        ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
                int(w), int(h));
        return BAD_VALUE;
    }

    status_t result = NO_ERROR;

    sp<Layer> layer;

    String8 uniqueName = getUniqueLayerName(name);

	//创建layer
    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
        case ISurfaceComposerClient::eFXSurfaceNormal:
            result = createNormalLayer(client,
                    uniqueName, w, h, flags, format,
                    handle, gbp, &layer);
            break;
        case ISurfaceComposerClient::eFXSurfaceDim:
            result = createDimLayer(client,
                    uniqueName, w, h, flags,
                    handle, gbp, &layer);
            break;
        default:
            result = BAD_VALUE;
            break;
    }

    if (result != NO_ERROR) {
        return result;
    }

    // window type is WINDOW_TYPE_DONT_SCREENSHOT from SurfaceControl.java
    // TODO b/64227542
    if (windowType == 441731) {
        windowType = 2024; // TYPE_NAVIGATION_BAR_PANEL
        layer->setPrimaryDisplayOnly();
    }

    layer->setInfo(windowType, ownerUid);

	//将layer增加到mCurrentState的layer向量里面
    result = addClientLayer(client, *handle, *gbp, layer, *parent);
    if (result != NO_ERROR) {
        return result;
    }
    mInterceptor.saveSurfaceCreation(layer);

    setTransactionFlags(eTransactionNeeded);
    return result;
}
status_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
        const sp<IBinder>& handle,
        const sp<IGraphicBufferProducer>& gbc,
        const sp<Layer>& lbc,
        const sp<Layer>& parent)
{
    // add this layer to the current state list
    {
        Mutex::Autolock _l(mStateLock);
        if (mNumLayers >= MAX_LAYERS) {
            ALOGE("AddClientLayer failed, mNumLayers (%zu) >= MAX_LAYERS (%zu)", mNumLayers,
                  MAX_LAYERS);
            return NO_MEMORY;
        }
        if (parent == nullptr) {
        	//增加到向量里面,后面能得到的layer都是从这里来的
            mCurrentState.layersSortedByZ.add(lbc);
        } else {
            if (mCurrentState.layersSortedByZ.indexOf(parent) < 0) {
                ALOGE("addClientLayer called with a removed parent");
                return NAME_NOT_FOUND;
            }
            parent->addChild(lbc);
        }

        mGraphicBufferProducerList.add(IInterface::asBinder(gbc));
        mLayersAdded = true;
        mNumLayers++;
    }

    // attach this layer to the client
    client->attachLayer(handle, lbc);

    return NO_ERROR;

在创建surface时候会创建layer同时会保存到mCurrentState里面

2.handleMessageRefresh

void SurfaceFlinger::handleMessageRefresh() {
    ATRACE_CALL();

    mRefreshPending = false;

    nsecs_t refreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC);

    preComposition(refreshStartTime);
    rebuildLayerStacks();
    setUpHWComposer();
    doDebugFlashRegions();
    doComposition();
    postComposition(refreshStartTime);

    mPreviousPresentFence = mHwc->getPresentFence(HWC_DISPLAY_PRIMARY);

    mHadClientComposition = false;
    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
        const sp<DisplayDevice>& displayDevice = mDisplays[displayId];
        mHadClientComposition = mHadClientComposition ||
                mHwc->hasClientComposition(displayDevice->getHwcDisplayId());
    }

    mLayersWithQueuedFrames.clear();
}

handleMessageRefresh是处理vsync信号的,也就是刷新用的。preComposition这个预处理合成函数不太清楚具体的作用,从第二个函数调用看起

3.rebuildLayerStacks

void SurfaceFlinger::rebuildLayerStacks() {
    ATRACE_CALL();
    ALOGV("rebuildLayerStacks");

    // rebuild the visible layer list per screen
    if (CC_UNLIKELY(mVisibleRegionsDirty)) {
        ATRACE_CALL();
        mVisibleRegionsDirty = false;
        invalidateHwcGeometry();

        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
            Region opaqueRegion;
            Region dirtyRegion;
            Vector<sp<Layer>> layersSortedByZ;
            const sp<DisplayDevice>& displayDevice(mDisplays[dpy]);
            const Transform& tr(displayDevice->getTransform());
            const Rect bounds(displayDevice->getBounds());
            if (displayDevice->isDisplayOn()) {
                computeVisibleRegions(displayDevice, dirtyRegion, opaqueRegion);

				mDrawingState里面的traverseInZOrder成员,前面说过会保存我们创建的layer,这里mDrawingState.traverseInZOrder这个函数调用,看代码实现就是回调传过去的函数地址,这种lamda表达方式不管别人说的有多好,在我看来就是装逼用的,代码是真难理解。
                mDrawingState.traverseInZOrder([&](Layer* layer) {
                    if (layer->belongsToDisplay(displayDevice->getLayerStack(),
                                displayDevice->isPrimary())) {
                        Region drawRegion(tr.transform(
                                layer->visibleNonTransparentRegion));
                        drawRegion.andSelf(bounds);
                        if (!drawRegion.isEmpty()) {
                        	//如果这个layer的drawRegion不为空,那边就将这个layer增加到临时变量layersSortedByZ里面,这里注意了有个类成员变量和这个临时变量名一模一样
                            layersSortedByZ.add(layer);
                        } else {
                            // Clear out the HWC layer if this layer was
                            // previously visible, but no longer is
                            layer->setHwcLayer(displayDevice->getHwcDisplayId(),
                                    nullptr);
                        }
                    } else {
                        // WM changes displayDevice->layerStack upon sleep/awake.
                        // Here we make sure we delete the HWC layers even if
                        // WM changed their layer stack.
                        layer->setHwcLayer(displayDevice->getHwcDisplayId(),
                                nullptr);
                    }
                });
            }
            //将需要绘制的layer赋值为displayDevice
            displayDevice->setVisibleLayersSortedByZ(layersSortedByZ);
            displayDevice->undefinedRegion.set(bounds);
            displayDevice->undefinedRegion.subtractSelf(
                    tr.transform(opaqueRegion));
            displayDevice->dirtyRegion.orSelf(dirtyRegion);
        }
    }
}

这个函数主要作用就是将保存在surfaceflinger里面的layer赋给各个displaydevice,设置需在绘图区域大小。

4.setUpHWComposer

void SurfaceFlinger::setUpHWComposer() {
    ATRACE_CALL();
    ALOGV("setUpHWComposer");

    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;

        // If nothing has changed (!dirty), don't recompose.
        // If something changed, but we don't currently have any visible layers,
        //   and didn't when we last did a composition, then skip it this time.
        // The second rule does two things:
        // - When all layers are removed from a display, we'll emit one black
        //   frame, then nothing more until we get new layers.
        // - When a display is created with a private layer stack, we won't
        //   emit any black frames until a layer is added to the layer stack.
        bool mustRecompose = dirty && !(empty && wasEmpty);

        ALOGV_IF(mDisplays[dpy]->getDisplayType() == DisplayDevice::DISPLAY_VIRTUAL,
                "dpy[%zu]: %s composition (%sdirty %sempty %swasEmpty)", dpy,
                mustRecompose ? "doing" : "skipping",
                dirty ? "+" : "-",
                empty ? "+" : "-",
                wasEmpty ? "+" : "-");

		//这个beginFrame函数是个空函数,不关注
        mDisplays[dpy]->beginFrame(mustRecompose);

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

    // build the h/w work list
    if (CC_UNLIKELY(mGeometryInvalid)) {
        mGeometryInvalid = false;
        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
            sp<const DisplayDevice> displayDevice(mDisplays[dpy]);
            const auto hwcId = displayDevice->getHwcDisplayId();
            一般来说hwcid是>=0的,其id和type是同一个值
                    DISPLAY_ID_INVALID = -1,
        DISPLAY_PRIMARY     = HWC_DISPLAY_PRIMARY,
        DISPLAY_EXTERNAL    = HWC_DISPLAY_EXTERNAL,
        DISPLAY_VIRTUAL     = HWC_DISPLAY_VIRTUAL,

            if (hwcId >= 0) {
            //这里就是拿到上面给每个displaydevice设置的layer
                const Vector<sp<Layer>>& currentLayers(
                        displayDevice->getVisibleLayersSortedByZ());
                for (size_t i = 0; i < currentLayers.size(); i++) {
                    const auto& layer = currentLayers[i];
                    //对每个layer进行判断有没有hwclayer
                    if (!layer->hasHwcLayer(hwcId)) {
                        auto hwcLayer = mHwc->createLayer(hwcId);
                        //创建成功则使用hwc合成
                        if (hwcLayer) {
                            layer->setHwcLayer(hwcId, std::move(hwcLayer));
                        } else {
                        	//创建失败则使用client合成
                            layer->forceClientComposition(hwcId);
                            continue;
                        }
                    }

                    layer->setGeometry(displayDevice, i);
                    if (mDebugDisableHWC || mDebugRegion) {
                        layer->forceClientComposition(hwcId);
                    }
                }
            }
        }
    }


    mat4 colorMatrix = mColorMatrix * computeSaturationMatrix() * mDaltonizer();

    // Set the per-frame data
    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
        auto& displayDevice = mDisplays[displayId];
        const auto hwcId = displayDevice->getHwcDisplayId();

        if (hwcId < 0) {
            continue;
        }
        if (colorMatrix != mPreviousColorMatrix) {
        	//设置颜色转换
            status_t result = mHwc->setColorTransform(hwcId, colorMatrix);
            ALOGE_IF(result != NO_ERROR, "Failed to set color transform on "
                    "display %zd: %d", displayId, result);
        }
        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
            layer->setPerFrameData(displayDevice);
        }

        if (hasWideColorDisplay) {
            android_color_mode newColorMode;
            android_dataspace newDataSpace = HAL_DATASPACE_V0_SRGB;

            for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
                newDataSpace = bestTargetDataSpace(layer->getDataSpace(), newDataSpace);
                ALOGV("layer: %s, dataspace: %s (%#x), newDataSpace: %s (%#x)",
                      layer->getName().string(), dataspaceDetails(layer->getDataSpace()).c_str(),
                      layer->getDataSpace(), dataspaceDetails(newDataSpace).c_str(), newDataSpace);
            }
            newColorMode = pickColorMode(newDataSpace);

            setActiveColorModeInternal(displayDevice, newColorMode);
        }
    }

    mPreviousColorMatrix = colorMatrix;

    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
        auto& displayDevice = mDisplays[displayId];
        if (!displayDevice->isDisplayOn()) {
            continue;
        }

        status_t result = displayDevice->prepareFrame(*mHwc);
        ALOGE_IF(result != NO_ERROR, "prepareFrame for display %zd failed:"
                " %d (%s)", displayId, result, strerror(-result));
    }
}

这个函数主要几点:
1.对所有创建的layer进行HwcLayer的创建,创建成功那么就会使用硬件混合的方式。如果失败则会使用client方式混合主要就是GPU
2.作一些显示前的处理工作,具体做的些什么事还没看明白。目前主要看流程,很多细节的东西没有过于追求

5.doComposition

void SurfaceFlinger::doComposition() {
    ATRACE_CALL();
    ALOGV("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));

            // repaint the framebuffer (if needed)
            doDisplayComposition(hw, dirtyRegion);

            hw->dirtyRegion.clear();
            hw->flip(hw->swapRegion);
            hw->swapRegion.clear();
        }
    }
    postFramebuffer();
}

上面主要是获取需要绘制的区域然后调用doDisplayComposition继续进行绘制流程

6.doDisplayComposition

void SurfaceFlinger::doDisplayComposition(
        const sp<const DisplayDevice>& displayDevice,
        const Region& inDirtyRegion)
{
    // We only need to actually compose the display if:
    // 1) It is being handled by hardware composer, which may need this to
    //    keep its virtual display state machine in sync, or
    // 2) There is work to be done (the dirty region isn't empty)
    bool isHwcDisplay = displayDevice->getHwcDisplayId() >= 0;
    if (!isHwcDisplay && inDirtyRegion.isEmpty()) {
        ALOGV("Skipping display composition");
        return;
    }

    ALOGV("doDisplayComposition");

    Region dirtyRegion(inDirtyRegion);

    // compute the invalid region
    displayDevice->swapRegion.orSelf(dirtyRegion);

    uint32_t flags = displayDevice->getFlags();
    if (flags & DisplayDevice::SWAP_RECTANGLE) {
        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
        // takes a rectangle, we must make sure to update that whole
        // rectangle in that case
        dirtyRegion.set(displayDevice->swapRegion.bounds());
    } else {
        if (flags & DisplayDevice::PARTIAL_UPDATES) {
            // We need to redraw the rectangle that will be updated
            // (pushed to the framebuffer).
            // This is needed because PARTIAL_UPDATES only takes one
            // rectangle instead of a region (see DisplayDevice::flip())
            dirtyRegion.set(displayDevice->swapRegion.bounds());
        } else {
            // we need to redraw everything (the whole screen)
            dirtyRegion.set(displayDevice->bounds());
            displayDevice->swapRegion = dirtyRegion;
        }
    }

    if (!doComposeSurfaces(displayDevice, dirtyRegion)) return;

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

    // swap buffers (presentation)
    displayDevice->swapBuffers(getHwComposer());
}

1如果绘制区域是空的则退出此次操作
2调用绘制的区域
3调用doComposeSurfaces进行绘制

7.doComposeSurfaces

bool SurfaceFlinger::doComposeSurfaces(
        const sp<const DisplayDevice>& displayDevice, const Region& dirty)
{
  ....
    ALOGV("Rendering client layers");
    const Transform& displayTransform = displayDevice->getTransform();
    //hwcId >= 0只会对实际存在的硬件屏作操作
    if (hwcId >= 0) {
        // we're using h/w composer
        bool firstLayer = true;
        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
            const Region clip(dirty.intersect(
                    displayTransform.transform(layer->visibleRegion)));
            ALOGV("Layer: %s", layer->getName().string());
            ALOGV("  Composition type: %s",
                    to_string(layer->getCompositionType(hwcId)).c_str());
            if (!clip.isEmpty()) {
                switch (layer->getCompositionType(hwcId)) {
                	//硬件hwc合成
                    case HWC2::Composition::Cursor:
                    case HWC2::Composition::Device:
                    case HWC2::Composition::Sideband:
                    case HWC2::Composition::SolidColor: {
                        const Layer::State& state(layer->getDrawingState());
                        if (layer->getClearClientTarget(hwcId) && !firstLayer &&
                                layer->isOpaque(state) && (state.alpha == 1.0f)
                                && hasClientComposition) {
                            // never clear the very first layer since we're
                            // guaranteed the FB is already cleared
                            layer->clearWithOpenGL(displayDevice);
                        }
                        break;
                    }
                    case HWC2::Composition::Client: {
                    	//client方式合成
                        layer->draw(displayDevice, clip);
                        break;
                    }
                    default:
                        break;
                }
            } else {
                ALOGV("  Skipping for empty clip");
            }
            firstLayer = false;
        }
    } else {
        // we're not using h/w composer
        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
            const Region clip(dirty.intersect(
                    displayTransform.transform(layer->visibleRegion)));
            if (!clip.isEmpty()) {
                layer->draw(displayDevice, clip);
            }
        }
    }

    if (applyColorMatrix) {
        getRenderEngine().setupColorTransform(oldColorMatrix);
    }

    // disable scissor at the end of the frame
    mRenderEngine->disableScissor();
    return true;
}

8.Layer::draw

void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
    onDraw(hw, clip, false);
}

void Layer::draw(const sp<const DisplayDevice>& hw,
        bool useIdentityTransform) const {
    onDraw(hw, Region(hw->bounds()), useIdentityTransform);
}

void Layer::draw(const sp<const DisplayDevice>& hw) const {
    onDraw(hw, Region(hw->bounds()), false);
}


client合成最终是调用layer的onDraw函数进行完成的,具体的代码可以继续研究。这里暂时只跟踪调用流程,也不太清楚代码具体的操作细节。希望能与大家一起学习

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

bruk_spp

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

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

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

打赏作者

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

抵扣说明:

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

余额充值