Android6.0 图像合成过程详解(二) doComposition函数汇总

2018-11-24 18:28

Android6.0 图像合成过程详解(二)

doComposition函数

一、doComposition合成图层

doComposition这个函数就是合成所有层的图像

[cpp] view plain copy 在CODE上查看代码片派生到我的代码片 void SurfaceFlinger::doComposition() { ATRACE_CALL();

const bool repaintEverything = android_atomic_and(0, &mRepaintEverything); for (size_t dpy=0 ; dpy& 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(hw->swapRegion); hw->swapRegion.clear(); }

// inform the h/w that we're done compositing hw->compositionComplete(); }

postFramebuffer(); }

上面函数遍历所有的DisplayDevice然后调用doDisplayComposition函数。然后我们再看看doDisplayComposition函数

[cpp] view plain copy 在CODE上查看代码片派生到我的代码片

void SurfaceFlinger::doDisplayComposition(const sp& hw, const Region& inDirtyRegion) {

bool isHwcDisplay = hw->getHwcDisplayId() >= 0; if (!isHwcDisplay && inDirtyRegion.isEmpty()) { return; }

Region dirtyRegion(inDirtyRegion);

//swapRegion设置为需要更新的区域 hw->swapRegion.orSelf(dirtyRegion);

uint32_t flags = hw->getFlags();//获得显示设备支持的更新方式标志

if (flags & DisplayDevice::SWAP_RECTANGLE) {//支持矩阵更新 dirtyRegion.set(hw->swapRegion.bounds()); } else {

if (flags & DisplayDevice::PARTIAL_UPDATES) {//支持部分更新 dirtyRegion.set(hw->swapRegion.bounds()); } else {

//将更新区域调整为整个窗口大小 dirtyRegion.set(hw->bounds()); hw->swapRegion = dirtyRegion; } }

if (CC_LIKELY(!mDaltonize && !mHasColorMatrix)) { if (!doComposeSurfaces(hw, dirtyRegion)) return;//合成 } else {

RenderEngine& engine(getRenderEngine()); mat4 colorMatrix = mColorMatrix; if (mDaltonize) {

colorMatrix = colorMatrix * mDaltonizer(); }

mat4 oldMatrix = engine.setupColorTransform(colorMatrix); doComposeSurfaces(hw, dirtyRegion);//合成 engine.setupColorTransform(oldMatrix); }

// update the swap region and clear the dirty region hw->swapRegion.orSelf(dirtyRegion);

// swap buffers (presentation)

hw->swapBuffers(getHwComposer());//使用egl将egl中的合成好的图像,输出到DisplayDevice的mSurface中 }

这个函数设置下需要更新的区域,后面调用doComposeSurfaces函数来合成图层,调用完doComposeSurfaces函数后,如果需要egl合成图像话,在这个函数中合成好。而最后调用swapBuffers只是将egl合成好的图像输出到DisplayDevice的mSurface中。

我们再来看看doComposeSurfaces函数,我们先来看一开始的代码,先判断是否有egl合成,然后再看是否有hwc合成(硬件合成)

[cpp] view plain copy 在CODE上查看代码片派生到我的代码片

bool SurfaceFlinger::doComposeSurfaces(const sp& 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) {//是否有egl合成

if (!hw->makeCurrent(mEGLDisplay, mEGLContext)) {

ALOGW(\failed. Aborting surface composition for display %s\

hw->getDisplayName().string());

eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);

if(!getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext)) { ALOGE(\ }

return false; }

// Never touch the framebuffer if we don't have any framebuffer layers const bool hasHwcComposition = hwc.hasHwcComposition(id); if (hasHwcComposition) {//是否有hwc合成

// when using overlays, we assume a fully transparent framebuffer // NOTE: we could reduce how much we need to clear, for instance // remove where there are opaque FB layers. however, on some // GPUs doing a \ // We'll revisit later if needed. engine.clearWithColor(0, 0, 0, 0); } else {

// we start with the whole screen area const Region bounds(hw->getBounds());

// we remove the scissor part

// we're left with the letterbox region

// (common case is that letterbox ends-up being empty) const Region letterbox(bounds.subtract(hw->getScissor()));

// compute the area to clear

Region region(hw->undefinedRegion.merge(letterbox));

// but limit it to the dirty region region.andSelf(dirty);

// screen is already cleared here if (!region.isEmpty()) {

// can happen with SurfaceView drawWormhole(hw, region); } }

if (hw->getDisplayType() != DisplayDevice::DISPLAY_PRIMARY) { // just to be on the safe side, we don't set the

// scissor on the main display. It should never be needed

// anyways (though in theory it could since the API allows it). const Rect& bounds(hw->getBounds()); const Rect& scissor(hw->getScissor()); if (scissor != bounds) {

// scissor doesn't match the screen's dimensions, so we // need to clear everything outside of it and enable

// the GL scissor so we don't draw anything where we shouldn't

// enable scissor for this frame

const uint32_t height = hw->getHeight();

engine.setScissor(scissor.left, height - scissor.bottom, scissor.getWidth(), scissor.getHeight()); } } } ......

我们来看hasGlesComposition函数和hasHwcComposition函数,就是看其对应的DisplayData中是否有hasFbComp和hasOvComp。

[cpp] view plain copy 在CODE上查看代码片派生到我的代码片 bool HWComposer::hasGlesComposition(int32_t id) const {

if (!mHwc || uint32_t(id)>31 || !mAllocatedDisplayIDs.hasBit(id)) return true;

return mDisplayData[id].hasFbComp; }

[cpp] view plain copy 在CODE上查看代码片派生到我的代码片 bool HWComposer::hasHwcComposition(int32_t id) const {

if (!mHwc || uint32_t(id)>31 || !mAllocatedDisplayIDs.hasBit(id)) return false;

return mDisplayData[id].hasOvComp; }

而这两个值是在prepare中调用Hwc的prepare函数之后赋值的 [cpp] view plain copy 在CODE上查看代码片派生到我的代码片 status_t HWComposer::prepare() { ......

int err = mHwc->prepare(mHwc, mNumDisplays, mLists);

ALOGE_IF(err, \

if (err == NO_ERROR) {

// here we're just making sure that \

// to HWC_FRAMEBUFFER and we're also counting how many layers // we have of each type. //

// If there are no window layers, we treat the display has having FB // composition, because SurfaceFlinger will use GLES to draw the // wormhole region.

for (size_t i=0 ; i

for (size_t i=0 ; inumHwLayers ; i++) { hwc_layer_1_t& l = disp.list->hwLayers[i];

//ALOGD(\ // i, l.compositionType, l.handle);

if (l.flags & HWC_SKIP_LAYER) {

l.compositionType = HWC_FRAMEBUFFER; }

if (l.compositionType == HWC_FRAMEBUFFER) {

disp.hasFbComp = true;//只要有一个layer是HWC_FRAMEBUFFER }

if (l.compositionType == HWC_OVERLAY) {

disp.hasOvComp = true;//有一个layer是HWC_OVERLAY }

if (l.compositionType == HWC_CURSOR_OVERLAY) { disp.hasOvComp = true;//有一个layer是HWC_CURSOR_OVERLAY } }

if (disp.list->numHwLayers == (disp.framebufferTarget ? 1 : 0)) {//layer的数量 有framebufferTarget为1 没有为0

disp.hasFbComp = true; } } else {

disp.hasFbComp = true;//没有list } } }


Android6.0 图像合成过程详解(二) doComposition函数汇总.doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:以作业改革 促学生发展

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: