Android P 显示流程分析(五)---界面刷新

上篇分析完了setUpHWComposer(), 这篇就来分析实际图层合成部分了。

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));
			//重画所有的脏区域
            // repaint the framebuffer (if needed)
            doDisplayComposition(hw, dirtyRegion);

            hw->dirtyRegion.clear();
            hw->flip();
        }
    }
    //发送Framebuffer
    postFramebuffer();
}

dirtyRegion(hw->getDirtyRegion(repaintEverything))

找到发生变化的区域

Region DisplayDevice::getDirtyRegion(bool repaintEverything) const {
    Region dirty;
    //这里的repainEverything = 0
    if (repaintEverything) {
        dirty.set(getBounds());
    } else {
        const Transform& planeTransform(mGlobalTransform);
        dirty = planeTransform.transform(this->dirtyRegion);
        dirty.andSelf(getBounds());
    }
    return dirty;
}
//确实显示区域的上下左右
FloatRect Transform::transform(const FloatRect& bounds) const
{
    vec2 lt(bounds.left, bounds.top);
    vec2 rt(bounds.right, bounds.top);
    vec2 lb(bounds.left, bounds.bottom);
    vec2 rb(bounds.right, bounds.bottom);

    lt = transform(lt);
    rt = transform(rt);
    lb = transform(lb);
    rb = transform(rb);

    FloatRect r;
    r.left = min(lt[0], rt[0], lb[0], rb[0]);
    r.top = min(lt[1], rt[1], lb[1], rb[1]);
    r.right = max(lt[0], rt[0], lb[0], rb[0]);
    r.bottom = max(lt[1], rt[1], lb[1], rb[1]);

    return r;
}

doDisplayComposition(hw, dirtyRegion)

上面获取到了显示区域,现在需要做显示合成了

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");
    //设置渲染的区域,对区域做渲染的初始化,如颜色,区域大小等
    if (!doComposeSurfaces(displayDevice)) return;

	//交互分区
    // swap buffers (presentation)
    displayDevice->swapBuffers(getHwComposer());
}

这个里面做了两件事,一个是区域的初始化,主要是针对Render的。第二个是交互分区,这个需要重点分析下,分区是如何切换的

void DisplayDevice::swapBuffers(HWComposer& hwc) const {
    if (hwc.hasClientComposition(mHwcDisplayId) || hwc.hasFlipClientTargetRequest(mHwcDisplayId)) {
    	//surface 切换buffer
        mSurface->swapBuffers();
    }
	//为下一个buffer做准备
    status_t result = mDisplaySurface->advanceFrame();
    if (result != NO_ERROR) {
        ALOGE("[%s] failed pushing new frame to HWC: %d",
                mDisplayName.string(), result);
    }
}

mSurface->swapBuffers() 也就是调用opengl里的最终送显函数eglSwapBuffers(mEGLDisplay, mEGLSurface)。
重点来看看如何为下一个buffer做准备的

status_t FramebufferSurface::advanceFrame() {
    uint32_t slot = 0;
    sp<GraphicBuffer> buf;
    sp<Fence> acquireFence(Fence::NO_FENCE);
    Dataspace dataspace = Dataspace::UNKNOWN;
    //获取下一个槽位,buffer,fence,以及数据空间
    status_t result = nextBuffer(slot, buf, acquireFence, dataspace);
    mDataSpace = dataspace;
    if (result != NO_ERROR) {
        ALOGE("error latching next FramebufferSurface buffer: %s (%d)",
                strerror(-result), result);
    }
    return result;
}

继续分析nextBuffer

status_t FramebufferSurface::nextBuffer(uint32_t& outSlot,
        sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence,
        Dataspace& outDataspace) {
    Mutex::Autolock lock(mMutex);

    BufferItem item;
    //获取下一个Buffer
    status_t err = acquireBufferLocked(&item, 0);
    if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
    	//如果没有可用buff,从缓存中获取
        mHwcBufferCache.getHwcBuffer(mCurrentBufferSlot, mCurrentBuffer,
                &outSlot, &outBuffer);
        return NO_ERROR;
    } else if (err != NO_ERROR) {
        ALOGE("error acquiring buffer: %s (%d)", strerror(-err), err);
        return err;
    }

    // If the BufferQueue has freed and reallocated a buffer in mCurrentSlot
    // then we may have acquired the slot we already own.  If we had released
    // our current buffer before we call acquireBuffer then that release call
    // would have returned STALE_BUFFER_SLOT, and we would have called
    // freeBufferLocked on that slot.  Because the buffer slot has already
    // been overwritten with the new buffer all we have to do is skip the
    // releaseBuffer call and we should be in the same state we'd be in if we
    // had released the old buffer first.
    if (mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT &&
        item.mSlot != mCurrentBufferSlot) {
        mHasPendingRelease = true;
        mPreviousBufferSlot = mCurrentBufferSlot;
        mPreviousBuffer = mCurrentBuffer;
    }
    mCurrentBufferSlot = item.mSlot;
    mCurrentBuffer = mSlots[mCurrentBufferSlot].mGraphicBuffer;
    mCurrentFence = item.mFence;

    outFence = item.mFence;
    mHwcBufferCache.getHwcBuffer(mCurrentBufferSlot, mCurrentBuffer,
            &outSlot, &outBuffer);
    outDataspace = static_cast<Dataspace>(item.mDataSpace);
    //设置目标的显示buffer
    status_t result =
            mHwc.setClientTarget(mDisplayType, outSlot, outFence, outBuffer, outDataspace);
    if (result != NO_ERROR) {
        ALOGE("error posting framebuffer: %d", result);
        return result;
    }

    return NO_ERROR;
}

这里主要做了三件事,获取下一次显示的buffer, 将此buffer 做一个缓存处理,将buffer相关信息送到hwc中,设置为下一次目标。
往下看看获取buffer的过程:

status_t ConsumerBase::acquireBufferLocked(BufferItem *item,
        nsecs_t presentWhen, uint64_t maxFrameNumber) {
    if (mAbandoned) {
        CB_LOGE("acquireBufferLocked: ConsumerBase is abandoned!");
        return NO_INIT;
    }
	//从消费者获取可以用buffer
    status_t err = mConsumer->acquireBuffer(item, presentWhen, maxFrameNumber);
    if (err != NO_ERROR) {
        return err;
    }

    if (item->mGraphicBuffer != NULL) {
        if (mSlots[item->mSlot].mGraphicBuffer != NULL) {
            freeBufferLocked(item->mSlot);
        }
        mSlots[item->mSlot].mGraphicBuffer = item->mGraphicBuffer;
    }

    mSlots[item->mSlot].mFrameNumber = item->mFrameNumber;
    mSlots[item->mSlot].mFence = item->mFence;

    CB_LOGV("acquireBufferLocked: -> slot=%d/%" PRIu64,
            item->mSlot, item->mFrameNumber);

    return OK;
}

这里是从消费者的buffer队列中获取 到buffer, 这里要引出一个生产者–消费者模式的buffer队列。下一篇来重点讲生产者–消费者模式的Buffer对列。

postFramebuffer()

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

    const nsecs_t now = systemTime();
    mDebugInSwapBuffers = now;
	//遍历所有显示屏
    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
        auto& displayDevice = mDisplays[displayId];
        if (!displayDevice->isDisplayOn()) {
            continue;
        }
        const auto hwcId = displayDevice->getHwcDisplayId();
        if (hwcId >= 0) {
            getBE().mHwc->presentAndGetReleaseFences(hwcId);
        }
        //回调onSwapBuffersCompleted()
        displayDevice->onSwapBuffersCompleted();
        //重新设置当前的Surface
        displayDevice->makeCurrent();
        //按照Z轴显示顺序来遍历图层
        for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
            // The layer buffer from the previous frame (if any) is released
            // by HWC only when the release fence from this frame (if any) is
            // signaled.  Always get the release fence from HWC first.
            auto hwcLayer = layer->getHwcLayer(hwcId);
            sp<Fence> releaseFence = getBE().mHwc->getLayerReleaseFence(hwcId, hwcLayer);

            // If the layer was client composited in the previous frame, we
            // need to merge with the previous client target acquire fence.
            // Since we do not track that, always merge with the current
            // client target acquire fence when it is available, even though
            // this is suboptimal.
            if (layer->getCompositionType(hwcId) == HWC2::Composition::Client) {
                releaseFence = Fence::merge("LayerRelease", releaseFence,
                        displayDevice->getClientTargetAcquireFence());
            }
			//根据释放的Fence来回调onLayerDisplayed
            layer->onLayerDisplayed(releaseFence);
        }

        // We've got a list of layers needing fences, that are disjoint with
        // displayDevice->getVisibleLayersSortedByZ.  The best we can do is to
        // supply them with the present fence.
        if (!displayDevice->getLayersNeedingFences().isEmpty()) {
            sp<Fence> presentFence = getBE().mHwc->getPresentFence(hwcId);
            for (auto& layer : displayDevice->getLayersNeedingFences()) {
            	//提供当前Fence给当前需要Fence的图层
                layer->onLayerDisplayed(presentFence);
            }
        }

        if (hwcId >= 0) {
            getBE().mHwc->clearReleaseFences(hwcId);
        }
    }

    mLastSwapBufferTime = systemTime() - now;
    mDebugInSwapBuffers = 0;

    // |mStateLock| not needed as we are on the main thread
    if (getBE().mHwc->isConnected(HWC_DISPLAY_PRIMARY)) {
        uint32_t flipCount = getDefaultDisplayDeviceLocked()->getPageFlipCount();
        if (flipCount % LOG_FRAME_STATS_PERIOD == 0) {
            logFrameStats();
        }
    }
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值