android6.0显示系统 6,Android6.0 显示系统(六) 图像的输出过程

} } }

HWComposer中有一个类型为DisplayData结构的数组mDisplayData,它维护着每个显示设备的信息。DisplayData结构中有一个类型为hwc_display_contents_l字段list,这个字段又有一个hwc_layer_l类型的数组hwLayers,记录该显示设备所有需要输出的Layer信息。 setUpHWComposer函数调用HWComposer的createWorkList函数就是根据每种显示设备的Layer数量,创建和初始化hwc_display_contents_l对象和hwc_layer_l数组

创建完HWComposer中的列表后,接下来是对每个Layer对象调用它的setPerFrameData函数,参数是HWComposer和HWCLayerInterface。setPerFrameData函数将Layer对象的当前图像缓冲区mActiveBuffer设置到HWCLayerInterface对象对应的hwc_layer_l对象中。 HWComposer类中除了前面介绍的Gralloc还管理着Composer模块,这个模块实现了硬件的图像合成功能。setUpHWComposer函数接下来调用HWComposer类的prepare函数,而prepare函数会调用Composer模块的prepare接口。最后到各个厂家的实现hwc_prepare函数将每种HWComposer中的所有图层的类型都设置为HWC_FRAMEBUFFER就结束了。

五、合成所有层的图像 (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));

// 图像合成

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(); }

doComposition函数针对每种显示设备调用doDisplayComposition函数来合成,合成后调用postFramebuffer函数,我们先来看看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());//没有硬件composer的情况,输出图像 }

doDisplayComposition函数根据显示设备支持的更新方式,重新设置需要更新区域的大小。 真正的合成工作是在doComposerSurfaces函数中完成,这个函数在layer的类型为HWC_FRAMEBUFFER,或者不支持硬件的composer的情况下,调用layer的draw函数来一层一层低合成最后的图像。

合成完后,doDisplayComposition函数调用了hw的swapBuffers函数,这个函数前面介绍过了,它将在系统不支持硬件的composer情况下调用eglSwapBuffers来输出图像到显示设备。

六、postFramebuffer函数

上一节的doComposition函数最后调用了postFramebuffer函数,代码如下: [cpp] view plain copy 在CODE上查看代码片派生到我的代码片 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:

// \ // for the current rendering API.\

getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext); }

hwc.commit(); }

...... }

postFramebuffer先判断系统是否支持composer,如果不支持,我们知道图像已经在doComposition函数时调用hw->swapBuffers输出了,就返回了。如果支持硬件composer,postFramebuffer函数将调用HWComposer的commit函数继续执行。 [cpp] view plain copy 在CODE上查看代码片派生到我的代码片 status_t HWComposer::commit() { int err = NO_ERROR; if (mHwc) {

if (!hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) { // On version 1.0, the OpenGL ES target surface is communicated // by the (dpy, sur) fields and we are guaranteed to have only // a single disnc630.complay.

mLists[0]->dpy = eglGetCurrentDisplay();

mLists[0]->sur = eglGetCurrentSurface(EGL_DRAW); }

for (size_t i=VIRTUAL_DISPLAY_ID_BASE; imLists[i]->outbuf = disp.outbufHandle; mLists[i]->outbufAcquireFenceFd =

disp.outbufAcquireFence->dup(); } }

err = mHwc->set(mHwc, mNumDisplays, mLists); ...... }

return (status_t)err; }

commit函数又调用了composer模块的set接口来完成工作,这就到HAL层的代码了,最后输出到显示屏上。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值