本文共 5049 字,大约阅读时间需要 16 分钟。
SurfaceFlinger
- handleMessageInvalidate
- handlePageFlip (layer->latchBuffer)
Layer
- latchBuffer (mSurfaceFlingerConsumer->updateTexImage)
SurfaceFlingerConsumer
- updateTexImage
- GLConsumer::updateAndReleaseLocked
- Region Layer::latchBuffer(bool& recomputeVisibleRegions)
- {
- Region outDirtyRegion;
- if (mQueuedFrames > 0) {
-
-
- const bool oldOpacity = isOpaque();
- sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
-
- Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions);
-
- status_t updateResult = mSurfaceFlingerConsumer-><strong><span style="color:#ff0000;">updateTexImage</span></strong>(&r);
-
-
- <span style="color:#ff0000;">mActiveBuffer </span>= mSurfaceFlingerConsumer->getCurrentBuffer();
- if (mActiveBuffer == NULL) {
-
- return outDirtyRegion;
- }
-
-
- const Layer::State& s(getDrawingState());
- Region dirtyRegion(Rect(s.active.w, s.active.h));
-
-
- outDirtyRegion = (s.transform.transform(dirtyRegion));
- }
- return outDirtyRegion;
- }
latchBuffer 的作用可以看到更新 mActiveBuffer。 具体是如何来更新 mActiveBuffer 的, 是通过 updateTexImage 方法。
- status_t SurfaceFlingerConsumer::updateTexImage(BufferRejecter* rejecter)
- {
-
- BufferQueue::BufferItem item;
-
-
-
-
- err = <span style="color:#ff0000;">acquireBufferLocked</span>(&item, computeExpectedPresent());
-
-
-
-
- int buf = item.mBuf;
- if (rejecter && rejecter-><span style="color:#ff0000;">reject</span>(mSlots[buf].mGraphicBuffer, item)) {
- releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer, EGL_NO_SYNC_KHR);
- return NO_ERROR;
- }
-
-
- err = <span style="color:#ff0000;">updateAndReleaseLocked</span>(item);
- if (err != NO_ERROR) {
- return err;
- }
-
- return err;
- }
updateTexImage 的作用也很明确, 理解BufferQueue的模型, SurfaceFlinger作为Consumer端, 其主要操作为 acquire 和 release,首先通过 acquireBufferLocked 获取到一个 BufferItem, 然后通过rejecter去确认这个 BufferItem 是否合法, 最后通过 updateAndReleaseLocked 去更新刚才获取的 BufferItem, 并释放之前的 BufferItem。
- status_t GLConsumer::updateAndReleaseLocked(const BufferQueue::BufferItem& item)
- {
- int buf = item.mBuf;
-
-
-
-
-
-
-
-
- if (mEglSlots[buf].mEglImage == EGL_NO_IMAGE_KHR) {
- EGLImageKHR image = <span style="color:#ff0000;">createImage</span>(mEglDisplay,
- mSlots[buf].mGraphicBuffer, item.mCrop);
- mEglSlots[buf].mEglImage = image;
- mEglSlots[buf].mCropRect = item.mCrop;
- }
-
-
- err = <span style="color:#ff0000;">syncForReleaseLocked</span>(mEglDisplay);
-
-
- if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) {
- status_t status = <span style="color:#ff0000;">releaseBufferLocked</span>(
- mCurrentTexture, mCurrentTextureBuf, mEglDisplay,
- mEglSlots[mCurrentTexture].mEglFence);
- if (status < NO_ERROR) {
- ST_LOGE("updateAndRelease: failed to release buffer: %s (%d)",
- strerror(-status), status);
- err = status;
-
- }
- }
-
-
- </span> mCurrentTexture = buf;
- mCurrentTextureBuf = mSlots[buf].mGraphicBuffer;
- mCurrentCrop = item.mCrop;
-
- return err;
- }
updateAndReleaseLocked:
1 : 通过 createImage 生成一个 EGLImageKHR(通过它来生成 Opengl 纹理) 对象。
2 : 通过 syncForReleaseLocked,来向当前的 GraphicBuffer 添加一个 ReleaseFence。 (GraphicBuffer -- GPU同步)
3 : 通过 releaseBufferLocked , 来释放当前的 GraphicBuffer。 (GraphicBuffer -- CPU同步)
4 : 最后更新下当前的状态.
最后做一些扫尾更新当前状态的操作。
- status_t GLConsumer::syncForReleaseLocked(EGLDisplay dpy) {
- if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) {
- if (SyncFeatures::getInstance().useNativeFenceSync()) {
- <span style="color:#000000;">EGLSyncKHR </span>sync = <span style="color:#ff0000;">eglCreateSyncKHR</span>(dpy,
- EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
- glFlush();
- int fenceFd = eglDupNativeFenceFDANDROID(dpy, sync);
- eglDestroySyncKHR(dpy, sync);
- sp<Fence> <span style="color:#ff0000;">fence</span>(new Fence(fenceFd));
- status_t err = <span style="color:#ff0000;">addReleaseFenceLocked</span>(mCurrentTexture,
- mCurrentTextureBuf, fence);
- }
- }
-
- return OK;
- }
syncForReleaseLocked 的作用比较特殊: (实际效果是 给当前的 buf 关联一个 fence, 当屏幕被新的 buf 更新的时候, 这个 fence 被触发。 表现的效果是 dequeueBuffer 的时候会检查这个fence是否被触发)
首先通过 eglCreateSyncKHR,生成一个 EGLSyncKHR 对象, 然后再通过 EGLSyncKHR 对象生成一个Fence对象。
最后通过 addReleaseFenceLocked 把 mCurrentTextureBuf 和 fence对象关联起来。
转载地址:http://xzuun.baihongyu.com/