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 中的 E
GLSurface 作为 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。