• Android—Surface,BufferQueue


    Android—Surface,ViewRootImpl.relayoutWindow

    从前文得知在创建SurfaceControl的时候还会创建BufferQueueCore、BufferQueueProducer和BufferQueueConsumer这三者,目前我们还不知道是他们做什么的,相互直接有什么互动关系。

    ViewRootImpl中 performDraw里面会调用draw再调用drawSoftware最后调用View.draw

    注意这里是在relayoutWindow即生成了Surface一些列操作之后。

    我们分析drawSoftware

    1. private boolean drawSoftware(Surface surface, AttachInfo attachInfo, int xoff, int yoff,
    2. boolean scalingRequired, Rect dirty, Rect surfaceInsets) {
    3. // Draw with software renderer.
    4. final Canvas canvas;
    5. ....
    6. canvas = mSurface.lockCanvas(dirty);
    7. ....
    8. mView.draw(canvas);
    9. ....
    10. surface.unlockCanvasAndPost(canvas);
    11. ....
    12. return true;
    13. }
    1. 通过mSurface.lockCanvas获取Canvas
    2. 通过draw方法,将根View及其子View遍历绘制到Canvas上
    3. 通过surface.unlockCanvasAndPost将绘制内容提交给surfaceFlinger进行合成

    1.mSurface.lockCanvas

    frameworks\base\core\java\android\view\Surface.java

    1. public Canvas lockCanvas(Rect inOutDirty)
    2. throws Surface.OutOfResourcesException, IllegalArgumentException {
    3. synchronized (mLock) {
    4. checkNotReleasedLocked();
    5. if (mLockedObject != 0) {
    6. // Ideally, nativeLockCanvas() would throw in this situation and prevent the
    7. // double-lock, but that won't happen if mNativeObject was updated. We can't
    8. // abandon the old mLockedObject because it might still be in use, so instead
    9. // we just refuse to re-lock the Surface.
    10. throw new IllegalArgumentException("Surface was already locked");
    11. }
    12. mLockedObject = nativeLockCanvas(mNativeObject, mCanvas, inOutDirty);
    13. return mCanvas;
    14. }
    15. }

    frameworks\base\core\jni\android_view_Surface.cpp

    1. static jlong nativeLockCanvas(JNIEnv* env, jclass clazz,
    2. jlong nativeObject, jobject canvasObj, jobject dirtyRectObj) {
    3. sp surface(reinterpret_cast(nativeObject));
    4. ....
    5. ANativeWindow_Buffer outBuffer;
    6. status_t err = surface->lock(&outBuffer, dirtyRectPtr);
    7. ....
    8. SkImageInfo info = SkImageInfo::Make(outBuffer.width, outBuffer.height,
    9. convertPixelFormat(outBuffer.format),
    10. outBuffer.format == PIXEL_FORMAT_RGBX_8888
    11. ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
    12. SkBitmap bitmap;
    13. ssize_t bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);
    14. bitmap.setInfo(info, bpr);
    15. if (outBuffer.width > 0 && outBuffer.height > 0) {
    16. bitmap.setPixels(outBuffer.bits);
    17. } else {
    18. // be safe with an empty bitmap.
    19. bitmap.setPixels(NULL);
    20. }
    21. Canvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvasObj);
    22. nativeCanvas->setBitmap(bitmap)
    23. ....
    24. sp lockedSurface(surface);
    25. lockedSurface->incStrong(&sRefBaseOwner);
    26. return (jlong) lockedSurface.get();
    27. }

    frameworks\native\libs\gui\Surface.cpp

    1. status_t Surface::lock(
    2. ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds)
    3. {
    4. ANativeWindowBuffer* out;
    5. status_t err = dequeueBuffer(&out, &fenceFd);
    6. if (err == NO_ERROR) {
    7. sp backBuffer(GraphicBuffer::getSelf(out));
    8. const Rect bounds(backBuffer->width, backBuffer->height);
    9. if (canCopyBack) {
    10. // copy the area that is invalid and not repainted this round
    11. const Region copyback(mDirtyRegion.subtract(newDirtyRegion));
    12. if (!copyback.isEmpty()) {
    13. copyBlt(backBuffer, frontBuffer, copyback, &fenceFd);
    14. }
    15. } else {
    16. ....
    17. }
    18. void* vaddr;
    19. status_t res = backBuffer->lockAsync(
    20. GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
    21. newDirtyRegion.bounds(), &vaddr, fenceFd);
    22. if (res != 0) {
    23. err = INVALID_OPERATION;
    24. } else {
    25. mLockedBuffer = backBuffer;
    26. outBuffer->width = backBuffer->width;
    27. outBuffer->height = backBuffer->height;
    28. outBuffer->stride = backBuffer->stride;
    29. outBuffer->format = backBuffer->format;
    30. outBuffer->bits = vaddr;
    31. }
    32. }
    33. return err;
    34. }

     dequeueBuffer方法中会填充out,outBuffer又是从out对象中获取的内容。

    1. int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
    2. ....
    3. status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, reqWidth, reqHeight,
    4. reqFormat, reqUsage, &mBufferAge,
    5. enableFrameTimestamps ? &frameTimestamps
    6. : nullptr);
    7. ....
    8. result = mGraphicBufferProducer->requestBuffer(buf, &gbuf);
    9. ....
    10. *buffer = gbuf.get();
    11. return OK;
    12. }

    这里我们看到了Producer,看一下这个对象怎么来的

    1. Surface::Surface(const sp& bufferProducer, bool controlledByApp)
    2. : mGraphicBufferProducer(bufferProducer),
    3. ....) {....}

    在创建Surface时一起创建的,我们回顾一下之前创建Surface的时机。

    注意这里的Surface是native层的对象。

     frameworks\base\core\java\android\view\ViewRootImpl.java

    1. private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
    2. boolean insetsPending) throws RemoteException {
    3. .....
    4. int relayoutResult = mWindowSession.relayout(mWindow, mSeq, params,
    5. (int) (mView.getMeasuredWidth() * appScale + 0.5f),
    6. (int) (mView.getMeasuredHeight() * appScale + 0.5f), viewVisibility,
    7. insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, frameNumber,
    8. mTmpFrame, mPendingOverscanInsets, mPendingContentInsets, mPendingVisibleInsets,
    9. mPendingStableInsets, mPendingOutsets, mPendingBackDropFrame, mPendingDisplayCutout,
    10. mPendingMergedConfiguration, mSurfaceControl, mTempInsets);
    11. if (mSurfaceControl.isValid()) {
    12. mSurface.copyFrom(mSurfaceControl);
    13. } else {
    14. destroySurface();
    15. }
    16. ....
    17. }

    这里copyFrom最后会到native层

     frameworks\native\libs\gui\SurfaceControl.cpp 

    1. sp SurfaceControl::getSurface() const
    2. {
    3. Mutex::Autolock _l(mLock);
    4. if (mSurfaceData == nullptr) {
    5. return generateSurfaceLocked();
    6. }
    7. return mSurfaceData;
    8. }
    9. sp SurfaceControl::generateSurfaceLocked() const
    10. {
    11. // This surface is always consumed by SurfaceFlinger, so the
    12. // producerControlledByApp value doesn't matter; using false.
    13. mSurfaceData = new Surface(mGraphicBufferProducer, false);
    14. return mSurfaceData;
    15. }

     SurfaceControl的mGraphicBufferProducer是哪里来的呢?

    frameworks\native\libs\gui\SurfaceControl.cpp

    1. SurfaceControl::SurfaceControl(
    2. const sp& client,
    3. const sp& handle,
    4. const sp& gbp,
    5. bool owned)
    6. : mClient(client), mHandle(handle), mGraphicBufferProducer(gbp), mOwned(owned)
    7. {
    8. }

    也是在构造函数,我们再回顾一下之前创建SurfaceControl的时机。

    frameworks\native\libs\gui\SurfaceComposerClient.cpp

    1. status_t SurfaceComposerClient::createSurfaceChecked(const String8& name, uint32_t w, uint32_t h,
    2. PixelFormat format,
    3. sp* outSurface, uint32_t flags,
    4. SurfaceControl* parent,
    5. LayerMetadata metadata) {
    6. ....
    7. err = mClient->createSurface(name, w, h, format, flags, parentHandle, std::move(metadata),
    8. &handle, &gbp);
    9. ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));
    10. if (err == NO_ERROR) {
    11. *outSurface = new SurfaceControl(this, handle, gbp, true /* owned */);
    12. }
    13. ....
    14. return err;
    15. }

    可以发现我们又回到了之前的mClient->createSurface,这里的gbp就是mGraphicBufferProducer,而gbp是在createSurface方法中填充的。

     frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp

    1. status_t SurfaceFlinger::createBufferQueueLayer(const sp& client, const String8& name,
    2. uint32_t w, uint32_t h, uint32_t flags,
    3. LayerMetadata metadata, PixelFormat& format,
    4. sp* handle,
    5. sp* gbp,
    6. sp* outLayer) {
    7. ....
    8. sp layer = getFactory().createBufferQueueLayer(
    9. LayerCreationArgs(this, client, name, w, h, flags, std::move(metadata)));
    10. status_t err = layer->setDefaultBufferProperties(w, h, format);
    11. if (err == NO_ERROR) {
    12. *handle = layer->getHandle();
    13. *gbp = layer->getProducer();
    14. *outLayer = layer;
    15. }
    16. return err;
    17. }

    layer->getProducer()拿的是什么呢?

    frameworks\native\services\surfaceflinger\BufferQueueLayer.cpp

    1. sp BufferQueueLayer::getProducer() const {
    2. return mProducer;
    3. }
    4. void BufferQueueLayer::onFirstRef() {
    5. BufferLayer::onFirstRef();
    6. // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
    7. sp producer;
    8. sp consumer;
    9. BufferQueue::createBufferQueue(&producer, &consumer, true);
    10. mProducer = new MonitoredProducer(producer, mFlinger, this);
    11. ....
    12. }

    回到frameworks\native\libs\gui\Surface.cpp

    1. int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
    2. ....
    3. status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, reqWidth, reqHeight,
    4. reqFormat, reqUsage, &mBufferAge,
    5. enableFrameTimestamps ? &frameTimestamps
    6. : nullptr);
    7. ....
    8. result = mGraphicBufferProducer->requestBuffer(buf, &gbuf);
    9. ....
    10. *buffer = gbuf.get();
    11. return OK;
    12. }

    所以绕了一圈mGraphicBufferProducer就是SurfaceControl的gbp,Layer的BufferQueueProducer。

    我们就可以继续分析了

    frameworks\native\libs\gui\BufferQueueProducer.cpp

    1. status_t BufferQueueProducer::dequeueBuffer(int* outSlot, sp* outFence,
    2. uint32_t width, uint32_t height, PixelFormat format,
    3. uint64_t usage, uint64_t* outBufferAge,
    4. FrameEventHistoryDelta* outTimestamps) {
    5. status_t returnFlags = NO_ERROR;
    6. EGLDisplay eglDisplay = EGL_NO_DISPLAY;
    7. EGLSyncKHR eglFence = EGL_NO_SYNC_KHR;
    8. bool attachedByConsumer = false;
    9. { // Autolock scope
    10. std::unique_lock lock(mCore->mMutex);
    11. ....
    12. // 如果没有空闲缓冲区,但当前正在分配,我们会等到分配完成,这样就不会并行分配。
    13. if (mCore->mFreeBuffers.empty() && mCore->mIsAllocating) {
    14. mDequeueWaitingForAllocation = true;
    15. mCore->waitWhileAllocatingLocked(lock);
    16. mDequeueWaitingForAllocation = false;
    17. mDequeueWaitingForAllocationCondition.notify_all();
    18. }
    19. ....
    20. // 寻找可用的index
    21. int found = BufferItem::INVALID_BUFFER_SLOT;
    22. while (found == BufferItem::INVALID_BUFFER_SLOT) {
    23. // 获取到可用的index,保存为found
    24. status_t status = waitForFreeSlotThenRelock(FreeSlotCaller::Dequeue, lock, &found);
    25. if (status != NO_ERROR) {
    26. return status;
    27. }
    28. // This should not happen 没有找到可用的
    29. if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
    30. BQ_LOGE("dequeueBuffer: no available buffer slots");
    31. return -EBUSY;
    32. }
    33. ....
    34. }
    35. // 生成found对应index的GraphicBuffer
    36. const sp& buffer(mSlots[found].mGraphicBuffer);
    37. //如果不是共享buffer,就把这个BufferSlot对应的下标,加入到mActiveBuffers中
    38. if (mCore->mSharedBufferSlot != found) {
    39. mCore->mActiveBuffers.insert(found);
    40. }
    41. // outSlot是最终返回给Surface, Surface有了found就能找到对应的GraphicBuffer了
    42. *outSlot = found;
    43. //状态设置为dequeue
    44. mSlots[found].mBufferState.dequeue();
    45. eglDisplay = mSlots[found].mEglDisplay;
    46. // 因为GraphicBuffer 最终是要到Gpu去消费,而当前的操作都是在cpu,
    47. // 为了同步cpu和Gpu对同一数据的使用,产生了这中Fence机制
    48. eglFence = mSlots[found].mEglFence;
    49. ....
    50. } // Autolock scope
    51. ....
    52. return returnFlags;
    53. }
    54. status_t BufferQueueProducer::requestBuffer(int slot, sp* buf) {
    55. ....
    56. mSlots[slot].mRequestBufferCalled = true;
    57. *buf = mSlots[slot].mGraphicBuffer;
    58. return NO_ERROR;
    59. }

     dequeueBuffer方法主要工作:

    1. 寻找状态为FREE的可用的mSlot[index],主要是调用waitForFreeSlotThenRelock,去mFreeBuffers和mFreeSlots中查找;
    2. 找到可用的index后,先把其对应的index添加到mActiveBuffer集合中,标示为活跃状态,并且设置为DEQUEUED状态;
    3. 如果找到的mSlot[index]的GraphicBuffer 为空或者需要重新申请,则把mSlot的参数初始化;

    requestBuffer把mSlot[index]的GraphicBuffer赋值给了buf

    回到frameworks\base\core\jni\android_view_Surface.cpp

    1. static jlong nativeLockCanvas(JNIEnv* env, jclass clazz,
    2. jlong nativeObject, jobject canvasObj, jobject dirtyRectObj) {
    3. sp surface(reinterpret_cast(nativeObject));
    4. ....
    5. ANativeWindow_Buffer outBuffer;
    6. status_t err = surface->lock(&outBuffer, dirtyRectPtr);
    7. ....
    8. SkImageInfo info = SkImageInfo::Make(outBuffer.width, outBuffer.height,
    9. convertPixelFormat(outBuffer.format),
    10. outBuffer.format == PIXEL_FORMAT_RGBX_8888
    11. ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
    12. SkBitmap bitmap;
    13. ssize_t bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);
    14. bitmap.setInfo(info, bpr);
    15. if (outBuffer.width > 0 && outBuffer.height > 0) {
    16. bitmap.setPixels(outBuffer.bits);
    17. } else {
    18. // be safe with an empty bitmap.
    19. bitmap.setPixels(NULL);
    20. }
    21. Canvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvasObj);
    22. nativeCanvas->setBitmap(bitmap)
    23. ....
    24. sp lockedSurface(surface);
    25. lockedSurface->incStrong(&sRefBaseOwner);
    26. return (jlong) lockedSurface.get();
    27. }

    outBuffer的内容被填充到bitmap对象,bitmap被set到canvas中。 

    2.surface.unlockCanvasAndPost

    frameworks\base\core\java\android\view\Surface.java

    1. public void unlockCanvasAndPost(Canvas canvas) {
    2. synchronized (mLock) {
    3. checkNotReleasedLocked();
    4. if (mHwuiContext != null) {
    5. mHwuiContext.unlockAndPost(canvas);
    6. } else {
    7. unlockSwCanvasAndPost(canvas);
    8. }
    9. }
    10. }
    11. private void unlockSwCanvasAndPost(Canvas canvas) {
    12. ....
    13. try {
    14. nativeUnlockCanvasAndPost(mLockedObject, canvas);
    15. } finally {
    16. nativeRelease(mLockedObject);
    17. mLockedObject = 0;
    18. }
    19. }

    frameworks\base\core\jni\android_view_Surface.cpp

    1. static void nativeUnlockCanvasAndPost(JNIEnv* env, jclass clazz,
    2. jlong nativeObject, jobject canvasObj) {
    3. sp surface(reinterpret_cast(nativeObject));
    4. if (!isSurfaceValid(surface)) {
    5. return;
    6. }
    7. // detach the canvas from the surface
    8. Canvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvasObj);
    9. nativeCanvas->setBitmap(SkBitmap());
    10. // unlock surface
    11. status_t err = surface->unlockAndPost();
    12. if (err < 0) {
    13. doThrowIAE(env);
    14. }
    15. }

    frameworks\native\libs\gui\Surface.cpp

    1. status_t Surface::unlockAndPost()
    2. {
    3. if (mLockedBuffer == nullptr) {
    4. ALOGE("Surface::unlockAndPost failed, no locked buffer");
    5. return INVALID_OPERATION;
    6. }
    7. int fd = -1;
    8. status_t err = mLockedBuffer->unlockAsync(&fd);
    9. ALOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle);
    10. err = queueBuffer(mLockedBuffer.get(), fd);
    11. ALOGE_IF(err, "queueBuffer (handle=%p) failed (%s)",
    12. mLockedBuffer->handle, strerror(-err));
    13. mPostedBuffer = mLockedBuffer;
    14. mLockedBuffer = nullptr;
    15. return err;
    16. }
    17. int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
    18. ....
    19. status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output);
    20. ....
    21. return err;
    22. }

    最终又是调用了 BufferQueueProducer的方法

    1. status_t BufferQueueProducer::queueBuffer(int slot,
    2. const QueueBufferInput &input, QueueBufferOutput *output) {
    3. int64_t requestedPresentTimestamp;
    4. bool isAutoTimestamp;
    5. android_dataspace dataSpace;
    6. Rect crop(Rect::EMPTY_RECT);
    7. int scalingMode;
    8. uint32_t transform;
    9. uint32_t stickyTransform;
    10. sp acquireFence;
    11. bool getFrameTimestamps = false;
    12. //将input对象中的参数赋值个这些局部变量,这些局部变量后面会set进item。
    13. input.deflate(&requestedPresentTimestamp, &isAutoTimestamp, &dataSpace,
    14. &crop, &scalingMode, &transform, &acquireFence, &stickyTransform,
    15. &getFrameTimestamps);
    16. const Region& surfaceDamage = input.getSurfaceDamage();
    17. const HdrMetadata& hdrMetadata = input.getHdrMetadata();
    18. BufferItem item;
    19. { // Autolock scope
    20. // 当前queue的具体GraphicBuffer
    21. const sp& graphicBuffer(mSlots[slot].mGraphicBuffer);
    22. // 根据当前的GraphicBufferd的宽高创建矩形区域
    23. Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight());
    24. // 创建裁剪区域
    25. Rect croppedRect(Rect::EMPTY_RECT);
    26. // 放入crop对象
    27. crop.intersect(bufferRect, &croppedRect);
    28. mSlots[slot].mFence = acquireFence;
    29. // 改变入队的BufferSlot的状态为QUEUED
    30. mSlots[slot].mBufferState.queue();
    31. // 把BufferSlot中的信息封装为BufferItem,后续会把这个BufferItem加入到队列中
    32. item.mAcquireCalled = mSlots[slot].mAcquireCalled;
    33. item.mGraphicBuffer = mSlots[slot].mGraphicBuffer;
    34. // crop赋值给了item
    35. item.mCrop = crop;
    36. item.mSlot = slot;
    37. item.mTimestamp = requestedPresentTimestamp;
    38. item.mIsAutoTimestamp = isAutoTimestamp;
    39. ....
    40. if (mCore->mQueue.empty()) {
    41. // 如果mQueue队列为空,则直接push进入这个mQueue,不用考虑阻塞
    42. mCore->mQueue.push_back(item);
    43. //这里会通知Consumer
    44. frameAvailableListener = mCore->mConsumerListener;
    45. } else {
    46. //不为空看是否可以替换最后一个
    47. const BufferItem& last = mCore->mQueue.itemAt(
    48. mCore->mQueue.size() - 1);
    49. ....
    50. }
    51. // 表示 buffer已经queued,此时入队完成
    52. mCore->mBufferHasBeenQueued = true;
    53. // mDequeueCondition是C++条件变量用作等待/唤醒,这里调用notify_all会唤醒调用了wait的线程
    54. mCore->mDequeueCondition.notify_all();
    55. mCore->mLastQueuedSlot = slot;
    56. //output 参数,会在Surface中继续使用
    57. output->width = mCore->mDefaultWidth;
    58. output->height = mCore->mDefaultHeight;
    59. output->transformHint = mCore->mTransformHint;
    60. output->numPendingBuffers = static_cast<uint32_t>(mCore->mQueue.size());
    61. output->nextFrameNumber = mCore->mFrameCounter + 1;
    62. ....
    63. //onFrameAvailable通知Consumer
    64. if (frameAvailableListener != nullptr) {
    65. frameAvailableListener->onFrameAvailable(item);
    66. } else if (frameReplacedListener != nullptr) {
    67. frameReplacedListener->onFrameReplaced(item);
    68. }
    69. }
    70. ....
    71. return NO_ERROR;
    72. }

    queueBuffer 的流程主要做了这三件事情:

    1. 创建 BufferItem 对象,读取input和GraphicBuffer的值,赋值给BufferItem。
    2. BufferItem入队到 BufferQueueCore 的 mQueue 队列中,这样可以方便图像消费者直接按先进先出的顺序从 mQueue 队列取出 GraphicBuffer 使用
    3.  onFrameAvailable的回调接口,来通知consumer消费数据

                frameAvailableListener = mCore->mConsumerListener;
                frameAvailableListener->onFrameAvailable(item);

     mCore是BufferQueueLayer

    frameworks\native\services\surfaceflinger\BufferQueueLayer.cpp

    1. void BufferQueueLayer::onFrameAvailable(const BufferItem& item) {
    2. ....
    3. // If this layer is orphaned, then we run a fake vsync pulse so that
    4. // dequeueBuffer doesn't block indefinitely.
    5. if (isRemovedFromCurrentState()) {
    6. fakeVsync();
    7. } else {
    8. mFlinger->signalLayerUpdate();
    9. }
    10. mConsumer->onBufferAvailable(item);
    11. }

    frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp

    1. void SurfaceFlinger::signalLayerUpdate() {
    2. mScheduler->resetIdleTimer();
    3. mEventQueue->invalidate();
    4. }
    5. SurfaceFlinger::SurfaceFlinger(Factory& factory, SkipInitializationTag)
    6. : mFactory(factory),
    7. ....
    8. mEventQueue(mFactory.createMessageQueue()){}

     invalidate是用handler发起一个message,我们直接看handleMessage逻辑

    frameworks\native\services\surfaceflinger\Scheduler\MessageQueue.cpp

    1. void MessageQueue::Handler::handleMessage(const Message& message) {
    2. switch (message.what) {
    3. case INVALIDATE:
    4. android_atomic_and(~eventMaskInvalidate, &mEventMask);
    5. mQueue.mFlinger->onMessageReceived(message.what);
    6. break;
    7. case REFRESH:
    8. android_atomic_and(~eventMaskRefresh, &mEventMask);
    9. mQueue.mFlinger->onMessageReceived(message.what);
    10. break;
    11. }
    12. }

    frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp 

    1. void SurfaceFlinger::onMessageReceived(int32_t what) NO_THREAD_SAFETY_ANALYSIS {
    2. ATRACE_CALL();
    3. switch (what) {
    4. case MessageQueue::INVALIDATE: {
    5. ....
    6. bool refreshNeeded = handleMessageTransaction();
    7. refreshNeeded |= handleMessageInvalidate();
    8. .....
    9. }
    10. case MessageQueue::REFRESH: {
    11. handleMessageRefresh();
    12. break;
    13. }
    14. }
    15. }
    16. bool SurfaceFlinger::handleMessageInvalidate() {
    17. bool refreshNeeded = handlePageFlip();
    18. ....
    19. return refreshNeeded;
    20. }
    21. bool SurfaceFlinger::handlePageFlip()
    22. {
    23. ....
    24. if (!mLayersWithQueuedFrames.empty()) {
    25. // mStateLock is needed for latchBuffer as LayerRejecter::reject()
    26. // writes to Layer current state. See also b/119481871
    27. Mutex::Autolock lock(mStateLock);
    28. for (auto& layer : mLayersWithQueuedFrames) {
    29. if (layer->latchBuffer(visibleRegions, latchTime)) {
    30. mLayersPendingRefresh.push_back(layer);
    31. }
    32. layer->useSurfaceDamage();
    33. if (layer->isBufferLatched()) {
    34. newDataLatched = true;
    35. }
    36. }
    37. }
    38. ....
    39. // Only continue with the refresh if there is actually new work to do
    40. return !mLayersWithQueuedFrames.empty() && newDataLatched;
    41. }

     对所有有准备好了的buffer的Layer调用了latchBuffer方法

    frameworks\native\services\surfaceflinger\BufferLayer.cpp

    1. bool BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime) {
    2. ....
    3. status_t err = updateTexImage(recomputeVisibleRegions, latchTime);
    4. ....
    5. return true;
    6. }

    frameworks\native\services\surfaceflinger\BufferLayerConsumer.cpp

    1. status_t BufferLayerConsumer::updateTexImage(BufferRejecter* rejecter, nsecs_t expectedPresentTime,
    2. bool* autoRefresh, bool* queuedBuffer,
    3. uint64_t maxFrameNumber) {
    4. BufferItem item;
    5. // Acquire the next buffer.
    6. // In asynchronous mode the list is guaranteed to be one buffer
    7. // deep, while in synchronous mode we use the oldest buffer.
    8. status_t err = acquireBufferLocked(&item, expectedPresentTime, maxFrameNumber);
    9. .....
    10. return err;
    11. }
    12. status_t BufferLayerConsumer::acquireBufferLocked(BufferItem* item, nsecs_t presentWhen,
    13. uint64_t maxFrameNumber) {
    14. status_t err = ConsumerBase::acquireBufferLocked(item, presentWhen, maxFrameNumber);
    15. ....
    16. // Release the previous buffer.
    17. err = updateAndReleaseLocked(item, &mPendingRelease);
    18. return NO_ERROR;
    19. }
    1. 调用acquireBufferLocked函数获取Buffer
    2. 调用updateAndReleaseLocked更新当前Buffer并释放上一个Buffer

    frameworks\native\libs\gui\ConsumerBase.cpp

    1. status_t ConsumerBase::acquireBufferLocked(BufferItem *item,
    2. nsecs_t presentWhen, uint64_t maxFrameNumber) {
    3. if (mAbandoned) {
    4. CB_LOGE("acquireBufferLocked: ConsumerBase is abandoned!");
    5. return NO_INIT;
    6. }
    7. status_t err = mConsumer->acquireBuffer(item, presentWhen, maxFrameNumber);
    8. if (err != NO_ERROR) {
    9. return err;
    10. }
    11. if (item->mGraphicBuffer != nullptr) {
    12. if (mSlots[item->mSlot].mGraphicBuffer != nullptr) {
    13. freeBufferLocked(item->mSlot);
    14. }
    15. mSlots[item->mSlot].mGraphicBuffer = item->mGraphicBuffer;
    16. }
    17. mSlots[item->mSlot].mFrameNumber = item->mFrameNumber;
    18. mSlots[item->mSlot].mFence = item->mFence;
    19. return OK;
    20. }

    frameworks\native\libs\gui\BufferQueueConsumer.cpp 

    1. status_t BufferQueueConsumer::acquireBuffer(BufferItem* outBuffer,
    2. nsecs_t expectedPresent, uint64_t maxFrameNumber) {
    3. ....
    4. if (!outBuffer->mIsStale) {
    5. mSlots[slot].mAcquireCalled = true;
    6. // Don't decrease the queue count if the BufferItem wasn't
    7. // previously in the queue. This happens in shared buffer mode when
    8. // the queue is empty and the BufferItem is created above.
    9. if (mCore->mQueue.empty()) {
    10. mSlots[slot].mBufferState.acquireNotInQueue();
    11. } else {
    12. mSlots[slot].mBufferState.acquire();
    13. }
    14. mSlots[slot].mFence = Fence::NO_FENCE;
    15. }
    16. ....
    17. return NO_ERROR;
    18. }

    BufferQueueConsumer的acquiredBuffer函数从BufferQueue中拿准备好的Buffer数据,拿到需要显示的Buffer,设置需要显示Buffer的状态为ACQUIRED,并且将它从mQueue等待队列移除。 

    接下来看下updateAndReleaseLocked做了什么

    frameworks\native\services\surfaceflinger\BufferLayerConsumer.cpp

    1. status_t BufferLayerConsumer::updateAndReleaseLocked(const BufferItem& item,
    2. PendingRelease* pendingRelease) {
    3. status_t err = NO_ERROR;
    4. int slot = item.mSlot;
    5. std::shared_ptr nextTextureBuffer;
    6. {
    7. std::lock_guard lock(mImagesMutex);
    8. nextTextureBuffer = mImages[slot];
    9. }
    10. // release old buffer
    11. if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) {
    12. if (pendingRelease == nullptr) {
    13. status_t status =
    14. releaseBufferLocked(mCurrentTexture, mCurrentTextureBuffer->graphicBuffer());
    15. if (status < NO_ERROR) {
    16. BLC_LOGE("updateAndRelease: failed to release buffer: %s (%d)", strerror(-status),
    17. status);
    18. err = status;
    19. // keep going, with error raised [?]
    20. }
    21. } else {
    22. pendingRelease->currentTexture = mCurrentTexture;
    23. pendingRelease->graphicBuffer = mCurrentTextureBuffer->graphicBuffer();
    24. pendingRelease->isPending = true;
    25. }
    26. }
    27. // Update the BufferLayerConsumer state.
    28. mCurrentTexture = slot;
    29. mCurrentTextureBuffer = nextTextureBuffer;
    30. mCurrentCrop = item.mCrop;
    31. mCurrentTransform = item.mTransform;
    32. mCurrentScalingMode = item.mScalingMode;
    33. mCurrentTimestamp = item.mTimestamp;
    34. mCurrentDataSpace = static_cast(item.mDataSpace);
    35. mCurrentHdrMetadata = item.mHdrMetadata;
    36. mCurrentFence = item.mFence;
    37. mCurrentFenceTime = item.mFenceTime;
    38. mCurrentFrameNumber = item.mFrameNumber;
    39. mCurrentTransformToDisplayInverse = item.mTransformToDisplayInverse;
    40. mCurrentSurfaceDamage = item.mSurfaceDamage;
    41. mCurrentApi = item.mApi;
    42. computeCurrentTransformMatrixLocked();
    43. return err;
    44. }

    frameworks\native\libs\gui\ConsumerBase.cpp

    1. status_t ConsumerBase::releaseBufferLocked(
    2. int slot, const sp graphicBuffer,
    3. EGLDisplay display, EGLSyncKHR eglFence) {
    4. ....
    5. status_t err = mConsumer->releaseBuffer(slot, mSlots[slot].mFrameNumber,
    6. display, eglFence, mSlots[slot].mFence);
    7. mPrevFinalReleaseFence = mSlots[slot].mFence;
    8. mSlots[slot].mFence = Fence::NO_FENCE;
    9. return err;
    10. }

    frameworks\native\libs\gui\BufferQueueConsumer.cpp

    1. status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber,
    2. const sp& releaseFence, EGLDisplay eglDisplay,
    3. EGLSyncKHR eglFence) {
    4. ....
    5. sp listener;
    6. { // Autolock scope
    7. ....
    8. mSlots[slot].mEglDisplay = eglDisplay;
    9. mSlots[slot].mEglFence = eglFence;
    10. mSlots[slot].mFence = releaseFence;
    11. mSlots[slot].mBufferState.release();
    12. if (!mCore->mSharedBufferMode && mSlots[slot].mBufferState.isFree()) {
    13. mSlots[slot].mBufferState.mShared = false;
    14. }
    15. // Don't put the shared buffer on the free list.
    16. if (!mSlots[slot].mBufferState.isShared()) {
    17. mCore->mActiveBuffers.erase(slot);
    18. mCore->mFreeBuffers.push_back(slot);
    19. }
    20. listener = mCore->mConnectedProducerListener;
    21. BQ_LOGV("releaseBuffer: releasing slot %d", slot);
    22. mCore->mDequeueCondition.notify_all();
    23. VALIDATE_CONSISTENCY();
    24. } // Autolock scope
    25. ....
    26. return NO_ERROR;
    27. }

     releaseBuffer就是把Buffer状态改成release,然后移除对应的队列。

    BufferQueueProducer通过dequeue函数来创建或获取一块可用的GraphicBuffer,并通过queue来归还绘制了数据的Graphicbuffer。

    BufferQueueConsumer即是SurfceFlinger通过acquire来获取GraphicBuffer,通过release来释放该GraphicBuffer。

    BufferQueue 是连接 Surface 和 Layer 的纽带,当上层图形数据渲染到 Surface 时,实际是渲染到了BufferQueue中的一个GraphicBuffer,然后通过Producer 把 GraphicBuffer 提交到 BufferQueue ,让 SurfaceFlinger 进行后续的合成显示工作。

    SurfaceFlinger 负责合成所有的 Layer 并送显到 Display ,这些Layer主要有两种合成方式:

    • OpenGL ES:把这些图层合成到 FrameBuffer,然后把FrameBuffer提交给hwcomposer 完成剩余合成和显示工作。
    • hwcomposer:通过HWC模块合成部分图层和FrameBuffer,并显示到Display。
  • 相关阅读:
    从github下载文件时遇到报错(Unable to render code block)解决办法
    【Android笔记22】Android中四大组件之Activity活动栈以及启动模式
    MySQL 崩溃恢复过程分析
    (持续更新中!)详解【计算机类&面试真题】军队文职考试 ——第二期(真题+解析)| 网络协议的三个核心要素;交互式系统中的非剥夺策略;中断和陷入的区别;可变分区管理中的硬件机制;数据库系统的优点
    IIS6.0 PUT上传漏洞
    CF547E Mike and Friends (AC 自动机+树状数组)
    ChatGPT必应联网功能正式上线
    【微服务|SCG】Spring Cloud Gateway快速入门
    detr目标检测算法源码详解
    JavaScript-day01笔记(变量 语法 事件 文本操作 样式操作)
  • 原文地址:https://blog.csdn.net/weixin_41939525/article/details/126620010