上篇分析完了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();
}
找到发生变化的区域
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;
}
上面获取到了显示区域,现在需要做显示合成了
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对列。
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();
}
}
}