SurfaceFlinger -- FramebufferSurface 详解
来源:互联网 发布:js添加节点 编辑:程序博客网 时间:2024/06/16 09:12
1: FramebufferSurface 概述
FramebufferSurface 根据名字解析:
1: Surface 说明它是一个Surface, 那么它就会拥有一个 BufferQuere, 用于显示。
2: FrameBuffer 这和 Linux 的 framebuffer 是完全不同的。 但是作用有些类似, SurfaceFlinger 在上面作画, 并把它交给HWC, 最终由HWC负责真正的显示。
2: SurfaceFlinger 如何驱动 FramebufferSurface
2-1: FramebufferSurface 与 DisplayDevice 的关系
FramebufferSurface 作为 BufferQueue 的 Consumer 端
DisplayDevice 中的 EGLSurface 作为 BufferQueue 的Producer 端
2-2: SurfaceFlinger 是如何驱动 FramebufferSurface
void SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw, const Region& inDirtyRegion){ <span style="color:#ff0000;">doComposeSurfaces</span>(hw, dirtyRegion); // swap buffers (presentation) hw-><span style="color:#ff0000;">swapBuffers</span>(getHwComposer());}void 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-><span style="color:#ff0000;">makeCurrent</span>(mEGLDisplay, mEGLContext)) { ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s", hw->getDisplayName().string()); return; } } /* * and then, render the layers targeted at the framebuffer */ const Vector< sp<Layer> >& layers(hw->getVisibleLayersSortedByZ()); const size_t count = layers.size(); const Transform& tr = hw->getTransform(); if (cur != end) { // we're using 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 <span style="color:#ff0000;">HWC_OVERLAY</span>: { const Layer::State& state(layer->getDrawingState()); if ((cur->getHints() & HWC_HINT_CLEAR_FB) && i && layer->isOpaque() && (state.alpha == 0xFF) && hasGlesComposition) { // never clear the very first layer since we're // guaranteed the FB is already cleared layer->clearWithOpenGL(hw, clip); } break; } case <span style="color:#ff0000;">HWC_FRAMEBUFFER</span>: { layer-><span style="color:#ff0000;">draw</span>(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); } } }
SufraceFlinger 的最终调用 doDisplayComposition 来混合指定的硬件显示设备(例如:手机屏幕)
2-2-1: 各图层的操作
HWC_OVERLAY: 由HWC负责
HWC_FRAMEBUFFER:由SurfaceFlinger负责,通过调用 Layer 的 draw 方法, 把各个Layer的信息绘制到 DisplayDevice 的 EGLSufrace 中。
2-2-2: 通过 DisplayDevice 的 swapBuffers 方法来驱动显示
void DisplayDevice::swapBuffers(HWComposer& hwc) const { // We need to call eglSwapBuffers() if: // (1) we don't have a hardware composer, or // (2) we did GLES composition this frame, and either // (a) we have framebuffer target support (not present on legacy // devices, where HWComposer::commit() handles things); or // (b) this is a virtual display if (hwc.initCheck() != NO_ERROR || (hwc.hasGlesComposition(mHwcDisplayId) && (hwc.supportsFramebufferTarget() || mType >= DISPLAY_VIRTUAL))) { EGLBoolean success = <span style="color:#ff0000;">eglSwapBuffers</span>(mDisplay, mSurface); }}
这里通过 eglSwapBuffers 方法, 把刚才绘制好的 EGLSufrace 中的新的 GraphicBuffer 入队。
根据BufferQueue的特性, 这里进行 queue 操作, 那么 FramebufferSurface 的 onFrameAvailable 会被回调。
可以联想到接下来的操作有两个:
1: 释放老的 buffer
2: 更新新的 buffer
代码也验证了这两部操作:
// Overrides ConsumerBase::onFrameAvailable(), does not call base class impl.void FramebufferSurface::onFrameAvailable() { sp<GraphicBuffer> buf; sp<Fence> acquireFence; status_t err = <span style="color:#ff0000;">nextBuffer</span>(buf, acquireFence); err = mHwc.<span style="color:#ff0000;">fbPost</span>(mDisplayType, acquireFence, buf);}status_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence) { Mutex::Autolock lock(mMutex); BufferQueue::BufferItem item; status_t err = <span style="color:#ff0000;">acquireBufferLocked</span>(&item, 0); if (mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT && item.mBuf != mCurrentBufferSlot) { // Release the previous buffer. err = <span style="color:#ff0000;">releaseBufferLocked</span>(mCurrentBufferSlot, mCurrentBuffer, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR); if (err < NO_ERROR) { ALOGE("error releasing buffer: %s (%d)", strerror(-err), err); return err; } } mCurrentBufferSlot = item.mBuf; mCurrentBuffer = mSlots[mCurrentBufferSlot].mGraphicBuffer; outFence = item.mFence; outBuffer = mCurrentBuffer; return NO_ERROR;}
2-2-3: 最终 FramebufferSurface 的显示也是由 HWC 来控制的
int HWComposer::fbPost(int32_t id, const sp<Fence>& acquireFence, const sp<GraphicBuffer>& buffer) { if (mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) { return <span style="color:#ff0000;">setFramebufferTarget</span>(id, acquireFence, buffer); }}status_t HWComposer::setFramebufferTarget(int32_t id, const sp<Fence>& acquireFence, const sp<GraphicBuffer>& buf) { DisplayData& <span style="color:#ff0000;">disp</span>(mDisplayData[id]); int acquireFenceFd = -1; if (acquireFence->isValid()) { acquireFenceFd = acquireFence->dup(); } // ALOGD("fbPost: handle=%p, fence=%d", buf->handle, acquireFenceFd); disp.<span style="color:#ff0000;">fbTargetHandle </span>= buf->handle; disp.<span style="color:#ff0000;">framebufferTarget</span>->handle = disp.fbTargetHandle; disp.<span style="color:#ff0000;">framebufferTarget</span>->acquireFenceFd = acquireFenceFd; return NO_ERROR;}
可以看到 FramebufferSurface 中的 buf 赋值给了 DisplayData 的 framebufferTarget (至此整个GLES操作结束, 最终通过 hwc 的 commit 输出到物理显示设备)。
2-2-4:DisplayData 的 framebufferTarget 如何创建的
SurfaceFlinger::setUpHWComposer 调用 HWComposer::createWorkList
status_t HWComposer::createWorkList(int32_t id, size_t numLayers) { if (mHwc) { DisplayData& disp(mDisplayData[id]); if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) { <span style="color:#ff0000;">disp.framebufferTarget = &disp.list->hwLayers[numLayers - 1];</span> memset(disp.framebufferTarget, 0, sizeof(hwc_layer_1_t)); const hwc_rect_t r = { 0, 0, (int) disp.width, (int) disp.height }; disp.framebufferTarget->compositionType = HWC_FRAMEBUFFER_TARGET; disp.framebufferTarget->hints = 0; disp.framebufferTarget->flags = 0; disp.framebufferTarget->handle = disp.fbTargetHandle; disp.framebufferTarget->transform = 0; disp.framebufferTarget->blending = HWC_BLENDING_PREMULT; if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_3)) { disp.framebufferTarget->sourceCropf.left = 0; disp.framebufferTarget->sourceCropf.top = 0; disp.framebufferTarget->sourceCropf.right = disp.width; disp.framebufferTarget->sourceCropf.bottom = disp.height; } else { disp.framebufferTarget->sourceCrop = r; } disp.framebufferTarget->displayFrame = r; disp.framebufferTarget->visibleRegionScreen.numRects = 1; disp.framebufferTarget->visibleRegionScreen.rects = &disp.framebufferTarget->displayFrame; disp.framebufferTarget->acquireFenceFd = -1; disp.framebufferTarget->releaseFenceFd = -1; disp.framebufferTarget->planeAlpha = 0xFF; } disp.list->retireFenceFd = -1; disp.list->flags = HWC_GEOMETRY_CHANGED; disp.list->numHwLayers = numLayers; } return NO_ERROR;}
从代码中看出, framebufferTarget 其实就是 hwclayers 的最后一个 layer。
0 0
- SurfaceFlinger -- FramebufferSurface 详解
- Android4.2.2 SurfaceFlinger本地的FramebufferSurface实现真正的显示
- Android4.2.2 SurfaceFlinger本地的FramebufferSurface实现真正的显示
- surfaceflinger 详解
- SurfaceFlinger详解
- SurfaceFlinger详解
- Android SurfaceFlinger原理详解 .
- 详解android surfaceflinger三部曲
- Android SurfaceFlinger -- Layer.latchBuffer 详解
- Android 5.1 SurfaceFlinger VSYNC详解
- surfaceflinger
- SurfaceFlinger
- SurfaceFlinger
- SurfaceFlinger
- Android4.2.2 SurfaceFlinger启动流程详解(一)
- Android4.2.2 SurfaceFlinger启动流程详解(二)
- Android4.2.2 SurfaceFlinger启动流程详解(一)
- 学习SurfaceFlinger
- 数据库安装时的log路径
- Error tips:array type has incomplete element type
- javascript判断身份证信息
- Spring Data Neo4j reference文档中关于@RelatedTo注解的注意事项
- spring注解详细介绍
- SurfaceFlinger -- FramebufferSurface 详解
- Apache Maven 入门篇(二)
- Driver for Atmel AT91 / AT32 Serial ports
- 模拟微信浏览器移植微信网页游戏
- Spring3+Hibernate4+JPA2.0整合
- Xcode6中添加pch文件
- 机器学习笔记(一)——机器学习基础
- android--系统jar包引用
- OGG 11.2.1.0.1安装过程及问题解决