Discuz! Board

标题: void SurfaceFlinger::postFramebuffer() [打印本页]

作者: zangcf    时间: 2016-4-17 11:00
标题: void SurfaceFlinger::postFramebuffer()
void SurfaceFlinger::postFramebuffer()
{
    ATRACE_CALL();

    const nsecs_t now = systemTime();
    mDebugInSwapBuffers = now;

    HWComposer& hwc(getHwComposer());
    if (hwc.initCheck() == NO_ERROR) {
        if (!hwc.supportsFramebufferTarget()) {
            // EGL spec says:
            //   "surface must be bound to the calling thread's current context,
            //    for the current rendering API."
            getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
        }
        hwc.commit();
    }

    // make the default display current because the VirtualDisplayDevice code cannot
    // deal with dequeueBuffer() being called outside of the composition loop; however
    // the code below can call glFlush() which is allowed (and does in some case) call
    // dequeueBuffer().
    getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);

    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
        sp<const DisplayDevice> hw(mDisplays[dpy]);
#ifdef MTK_AOSP_ENHANCEMENT
        if (!hw->mustRecompose()) continue;
#endif
        const Vector< sp<Layer> >& currentLayers(hw->getVisibleLayersSortedByZ());
        hw->onSwapBuffersCompleted(hwc);
        const size_t count = currentLayers.size();
        int32_t id = hw->getHwcDisplayId();
        if (id >=0 && hwc.initCheck() == NO_ERROR) {
            HWComposer:ayerListIterator cur = hwc.begin(id);
            const HWComposer:ayerListIterator end = hwc.end(id);
            for (size_t i = 0; cur != end && i < count; ++i, ++cur) {
                currentLayers[i]->onLayerDisplayed(hw, &*cur);
            }
        } else {
            for (size_t i = 0; i < count; i++) {
                currentLayers[i]->onLayerDisplayed(hw, NULL);
            }
        }
    }

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

    uint32_t flipCount = getDefaultDisplayDevice()->getPageFlipCount();
    if (flipCount % LOG_FRAME_STATS_PERIOD == 0) {
        logFrameStats();
    }
}


作者: zangcf    时间: 2016-4-17 11:16
另一方面,HWC合成完毕后,SurfaceFlinger会依次调用DisplayDevice:nSwapBuffersCompleted() -> FramebufferSurface:nFrameCommitted()。onFrameCommitted()核心代码如下:
148    sp<Fence> fence = mHwc.getAndResetReleaseFence(mDisplayType);
...
151        status_t err = addReleaseFence(mCurrentBufferSlot,
152                mCurrentBuffer, fence);
此处拿到HWC生成的FramebufferTarget的releaseFence,设到FramebufferSurface中相应的GraphicBuffer Slot中。这样FramebufferSurface对应的GraphicBuffer也可以被释放回BufferQueue了。当将来EGL从中拿到这个buffer时,照例也要先等待这个releaseFence触发才能使用。
作者: zangcf    时间: 2016-4-17 11:17
sp<const DisplayDevice> hw(mDisplays[dpy]);
这个地方是hw的定义




欢迎光临 Discuz! Board (http://47.89.242.157:9000/bbs/discuz/) Powered by Discuz! X3.2