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

2018-11-24 18:28

{

Mutex::Autolock lock(mCallbackMutex);

while (callbackTicket != mCurrentCallbackTicket) { mCallbackCondition.wait(mCallbackMutex); }

if (frameAvailableListener != NULL) {

frameAvailableListener->onFrameAvailable(item); } else if (frameReplacedListener != NULL) {

frameReplacedListener->onFrameReplaced(item); }

++mCurrentCallbackTicket;

mCallbackCondition.broadcast(); }

这样就要FramebufferSurface的onFrameAvailable函数中去了,我们来看下这个函数。 [cpp] view plain copy 在CODE上查看代码片派生到我的代码片

void FramebufferSurface::onFrameAvailable(const BufferItem& /* item */) { sp buf; sp acquireFence;

status_t err = nextBuffer(buf, acquireFence); if (err != NO_ERROR) {

ALOGE(\ strerror(-err), err); return; }

err = mHwc.fbPost(mDisplayType, acquireFence, buf); if (err != NO_ERROR) {

ALOGE(\ } }

这个函数先用nextBuffer获取数据,然后调用了HWComposer的fbPost函数。我们先来看下nextBuffer函数,这个函数主要通过acquireBufferLocked获取BufferItem,其中的mBuf就是buffer了。

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

status_t FramebufferSurface::nextBuffer(sp& outBuffer, sp& outFence) {

Mutex::Autolock lock(mMutex);

BufferItem item;

status_t err = acquireBufferLocked(&item, 0);

if (err == BufferQueue::NO_BUFFER_AVAILABLE) { outBuffer = mCurrentBuffer; return NO_ERROR;

} else if (err != NO_ERROR) {

ALOGE(\ return err; }

if (mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT && item.mBuf != mCurrentBufferSlot) {

// Release the prwww.sm136.comevious buffer.

err = releaseBufferLocked(mCurrentBufferSlot, mCurrentBuffer, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR); if (err < NO_ERROR) {

ALOGE(\ return err; } }

mCurrentBufferSlot = item.mBuf;

mCurrentBuffer = mSlots[mCurrentBufferSlot].mGraphicBuffer; outFence = item.mFence; outBuffer = mCurrentBuffer; return NO_ERROR; }

而这个acquireBufferLocked还是用mConsumer的acquireBuffer来获取BufferItem。mConsumer就是BufferQueueConsumer类。

[cpp] view plain copy 在CODE上查看代码片派生到我的代码片 status_t ConsumerBase::acquireBufferLocked(BufferItem *item, nsecs_t presentWhen, uint64_t maxFrameNumber) {

status_t err = mConsumer->acquireBuffer(item, presentWhen, maxFrameNumber); if (err != NO_ERROR) { return err; }

if (item->mGraphicBuffer != NULL) {

mSlots[item->mBuf].mGraphicBuffer = item->mGraphicBuffer; }

mSlots[item->mBuf].mFrameNumber = item->mFrameNumber; mSlots[item->mBuf].mFence = item->mFence;

CB_LOGV(\ item->mBuf, item->mFrameNumber);

return OK; }

回到FramebufferSurface的onFrameAvailable中这样获取了buffer之后,调用了HWComposer的fbPost方法。

三、egl合成数据在HWComposer的处理

继上面调用fbPost方法,我们来看下,这里是调用了setFramebufferTarget方法。 [cpp] view plain copy 在CODE上查看代码片派生到我的代码片 int HWComposer::fbPost(int32_t id,

const sp& acquireFence, const sp& buffer) {

if (mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) { return setFramebufferTarget(id, acquireFence, buffer); } else {

acquireFence->waitForever(\ return mFbDev->post(mFbDev, buffer->handle); } }

我们来看下setFramebufferTarget方法,这里就是把该设备的DisplayData数据中的framebufferTarget填充,主要是其handle数据,这里就是egl合成好的数据buffer。 也就是最终egl合成好的数据放在DisplayData的framebufferTarget变量的handle中。 [cpp] view plain copy 在CODE上查看代码片派生到我的代码片

status_t HWComposer::setFramebufferTarget(iwww.tt951.comnt32_t id,

const sp& acquireFence, const sp& buf) { if (uint32_t(id)>31 || !mAllocatedDisplayIDs.hasBit(id)) { return BAD_INDEX; }

DisplayData& disp(mDisplayData[id]); if (!disp.framebufferTarget) {

// this should never happen, but apparently eglCreateWindowSurface() // triggers a Surface::queueBuffer() on some // devices (!?) -- log and ignore.

ALOGE(\ return NO_ERROR; }

int acquireFenceFd = -1;

if (acquireFence->isValid()) {

acquireFenceFd = acquireFence->dup(); }

// ALOGD(\ disp.fbTargetHandle = buf->handle;//egl合成好的数据

disp.framebufferTarget->handle = disp.fbTargetHandle;//egl合成好的数据,最终是放在这里

disp.framebufferTarget->acquireFenceFd = acquireFenceFd;

return NO_ERROR; }

四、硬件模块合成

这样就剩最后一步了,把不管是普通layer的数据,还是egl合成好的数据发送到硬件模块合成了,最后就到显示设备了。

继第一节分析的doComposition函数最后会调用postFramebuffer函数,我们再来分析下这个函数,这个函数主要是调用了HWComposer的commit函数。 [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(); } ......

我们来看下HWComposer的commit函数,这个函数就是先设置了egl的那个设备的surface和display,然后处理虚拟设备的outbuf等,最后调用了硬件模块合成到显示设备上。 [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 dinc630.comsplay.

mLists[0]->dpy = eglGetCurrentDisplay();//设置下egl相关变量 mLists[0]->sur = eglGetCurrentSurface(EGL_DRAW); }

for (size_t i=VIRTUAL_DISPLAY_ID_BASE; i

if (disp.outbufHandle) {//只有虚拟设备需要设置outbuf mLists[i]->outbuf = disp.outbufHandle; mLists[i]->outbufAcquireFenceFd =

disp.outbufAcquireFence->dup(); } }

err = mHwc->set(mHwc, mNumDisplays, mLists);//调用硬件模块合成 ......


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

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

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

马上注册会员

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