Android—Surface,BufferQueue

Android—Surface,ViewRootImpl.relayoutWindow

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

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

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

我们分析drawSoftware

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

1.mSurface.lockCanvas

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

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

frameworks\base\core\jni\android_view_Surface.cpp

static jlong nativeLockCanvas(JNIEnv* env, jclass clazz,
        jlong nativeObject, jobject canvasObj, jobject dirtyRectObj) {
    sp surface(reinterpret_cast(nativeObject));
    ....
    ANativeWindow_Buffer outBuffer;
    status_t err = surface->lock(&outBuffer, dirtyRectPtr);
    ....
    SkImageInfo info = SkImageInfo::Make(outBuffer.width, outBuffer.height,
                                         convertPixelFormat(outBuffer.format),
                                         outBuffer.format == PIXEL_FORMAT_RGBX_8888
                                                 ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
    SkBitmap bitmap;
    ssize_t bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);
    bitmap.setInfo(info, bpr);
    if (outBuffer.width > 0 && outBuffer.height > 0) {
        bitmap.setPixels(outBuffer.bits);
    } else {
        // be safe with an empty bitmap.
        bitmap.setPixels(NULL);
    }
    Canvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvasObj);
    nativeCanvas->setBitmap(bitmap)
    ....
    sp lockedSurface(surface);
    lockedSurface->incStrong(&sRefBaseOwner);
    return (jlong) lockedSurface.get();
}

frameworks\native\libs\gui\Surface.cpp

status_t Surface::lock(
        ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds)
{
    ANativeWindowBuffer* out;
    status_t err = dequeueBuffer(&out, &fenceFd);
    if (err == NO_ERROR) {
        sp backBuffer(GraphicBuffer::getSelf(out));
        const Rect bounds(backBuffer->width, backBuffer->height);
        if (canCopyBack) {
            // copy the area that is invalid and not repainted this round
            const Region copyback(mDirtyRegion.subtract(newDirtyRegion));
            if (!copyback.isEmpty()) {
                copyBlt(backBuffer, frontBuffer, copyback, &fenceFd);
            }
        } else {
            ....
        }
        void* vaddr;
        status_t res = backBuffer->lockAsync(
                GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
                newDirtyRegion.bounds(), &vaddr, fenceFd);
        if (res != 0) {
            err = INVALID_OPERATION;
        } else {
            mLockedBuffer = backBuffer;
            outBuffer->width  = backBuffer->width;
            outBuffer->height = backBuffer->height;
            outBuffer->stride = backBuffer->stride;
            outBuffer->format = backBuffer->format;
            outBuffer->bits   = vaddr;
        }
    }
    return err;
}

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

int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
    ....
    status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, reqWidth, reqHeight,
                                                            reqFormat, reqUsage, &mBufferAge,
                                                            enableFrameTimestamps ? &frameTimestamps
                                                                                  : nullptr);
    ....
        result = mGraphicBufferProducer->requestBuffer(buf, &gbuf);
    ....
    *buffer = gbuf.get();
    return OK;
}

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

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

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

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

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

    private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
            boolean insetsPending) throws RemoteException {
        .....
        int relayoutResult = mWindowSession.relayout(mWindow, mSeq, params,
                (int) (mView.getMeasuredWidth() * appScale + 0.5f),
                (int) (mView.getMeasuredHeight() * appScale + 0.5f), viewVisibility,
                insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, frameNumber,
                mTmpFrame, mPendingOverscanInsets, mPendingContentInsets, mPendingVisibleInsets,
                mPendingStableInsets, mPendingOutsets, mPendingBackDropFrame, mPendingDisplayCutout,
                mPendingMergedConfiguration, mSurfaceControl, mTempInsets);
        if (mSurfaceControl.isValid()) {
            mSurface.copyFrom(mSurfaceControl);
        } else {
            destroySurface();
        }
        ....
    }

这里copyFrom最后会到native层

 frameworks\native\libs\gui\SurfaceControl.cpp 

sp SurfaceControl::getSurface() const
{
    Mutex::Autolock _l(mLock);
    if (mSurfaceData == nullptr) {
        return generateSurfaceLocked();
    }
    return mSurfaceData;
}

sp SurfaceControl::generateSurfaceLocked() const
{
    // This surface is always consumed by SurfaceFlinger, so the
    // producerControlledByApp value doesn't matter; using false.
    mSurfaceData = new Surface(mGraphicBufferProducer, false);

    return mSurfaceData;
}

 SurfaceControl的mGraphicBufferProducer是哪里来的呢?

frameworks\native\libs\gui\SurfaceControl.cpp

SurfaceControl::SurfaceControl(
        const sp& client,
        const sp& handle,
        const sp& gbp,
        bool owned)
    : mClient(client), mHandle(handle), mGraphicBufferProducer(gbp), mOwned(owned)
{
}

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

frameworks\native\libs\gui\SurfaceComposerClient.cpp

status_t SurfaceComposerClient::createSurfaceChecked(const String8& name, uint32_t w, uint32_t h,
                                                     PixelFormat format,
                                                     sp* outSurface, uint32_t flags,
                                                     SurfaceControl* parent,
                                                     LayerMetadata metadata) {
    ....
        err = mClient->createSurface(name, w, h, format, flags, parentHandle, std::move(metadata),
                                     &handle, &gbp);
        ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));
        if (err == NO_ERROR) {
            *outSurface = new SurfaceControl(this, handle, gbp, true /* owned */);
        }
    ....
    return err;
}

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

 frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp

status_t SurfaceFlinger::createBufferQueueLayer(const sp& client, const String8& name,
                                                uint32_t w, uint32_t h, uint32_t flags,
                                                LayerMetadata metadata, PixelFormat& format,
                                                sp* handle,
                                                sp* gbp,
                                                sp* outLayer) {
    ....
    sp layer = getFactory().createBufferQueueLayer(
            LayerCreationArgs(this, client, name, w, h, flags, std::move(metadata)));
    status_t err = layer->setDefaultBufferProperties(w, h, format);
    if (err == NO_ERROR) {
        *handle = layer->getHandle();
        *gbp = layer->getProducer();
        *outLayer = layer;
    }
    return err;
}

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

frameworks\native\services\surfaceflinger\BufferQueueLayer.cpp

sp BufferQueueLayer::getProducer() const {
    return mProducer;
}

void BufferQueueLayer::onFirstRef() {
    BufferLayer::onFirstRef();
    // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
    sp producer;
    sp consumer;
    BufferQueue::createBufferQueue(&producer, &consumer, true);
    mProducer = new MonitoredProducer(producer, mFlinger, this);
    ....
}

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

int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
    ....
    status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, reqWidth, reqHeight,
                                                            reqFormat, reqUsage, &mBufferAge,
                                                            enableFrameTimestamps ? &frameTimestamps
                                                                                  : nullptr);
    ....
        result = mGraphicBufferProducer->requestBuffer(buf, &gbuf);
    ....
    *buffer = gbuf.get();
    return OK;
}

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

我们就可以继续分析了

frameworks\native\libs\gui\BufferQueueProducer.cpp

status_t BufferQueueProducer::dequeueBuffer(int* outSlot, sp* outFence,
                                            uint32_t width, uint32_t height, PixelFormat format,
                                            uint64_t usage, uint64_t* outBufferAge,
                                            FrameEventHistoryDelta* outTimestamps) {

    status_t returnFlags = NO_ERROR;
    EGLDisplay eglDisplay = EGL_NO_DISPLAY;
    EGLSyncKHR eglFence = EGL_NO_SYNC_KHR;
    bool attachedByConsumer = false;
    { // Autolock scope
        std::unique_lock lock(mCore->mMutex);
        ....
        // 如果没有空闲缓冲区,但当前正在分配,我们会等到分配完成,这样就不会并行分配。
        if (mCore->mFreeBuffers.empty() && mCore->mIsAllocating) {
            mDequeueWaitingForAllocation = true;
            mCore->waitWhileAllocatingLocked(lock);
            mDequeueWaitingForAllocation = false;
            mDequeueWaitingForAllocationCondition.notify_all();
        }
        ....
        // 寻找可用的index
        int found = BufferItem::INVALID_BUFFER_SLOT;
        while (found == BufferItem::INVALID_BUFFER_SLOT) {
            // 获取到可用的index,保存为found
            status_t status = waitForFreeSlotThenRelock(FreeSlotCaller::Dequeue, lock, &found);
            if (status != NO_ERROR) {
                return status;
            }
            // This should not happen 没有找到可用的
            if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
                BQ_LOGE("dequeueBuffer: no available buffer slots");
                return -EBUSY;
            }
            ....
        }
        // 生成found对应index的GraphicBuffer
        const sp& buffer(mSlots[found].mGraphicBuffer);
        //如果不是共享buffer,就把这个BufferSlot对应的下标,加入到mActiveBuffers中
        if (mCore->mSharedBufferSlot != found) {
            mCore->mActiveBuffers.insert(found);
        }
        // outSlot是最终返回给Surface, Surface有了found就能找到对应的GraphicBuffer了
        *outSlot = found;
        //状态设置为dequeue
        mSlots[found].mBufferState.dequeue();
        eglDisplay = mSlots[found].mEglDisplay;
        // 因为GraphicBuffer 最终是要到Gpu去消费,而当前的操作都是在cpu,
        // 为了同步cpu和Gpu对同一数据的使用,产生了这中Fence机制
        eglFence = mSlots[found].mEglFence;
        ....
    } // Autolock scope
    ....
    return returnFlags;
}

status_t BufferQueueProducer::requestBuffer(int slot, sp* buf) {
    ....
    mSlots[slot].mRequestBufferCalled = true;
    *buf = mSlots[slot].mGraphicBuffer;
    return NO_ERROR;
}

 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

static jlong nativeLockCanvas(JNIEnv* env, jclass clazz,
        jlong nativeObject, jobject canvasObj, jobject dirtyRectObj) {
    sp surface(reinterpret_cast(nativeObject));
    ....
    ANativeWindow_Buffer outBuffer;
    status_t err = surface->lock(&outBuffer, dirtyRectPtr);
    ....
    SkImageInfo info = SkImageInfo::Make(outBuffer.width, outBuffer.height,
                                         convertPixelFormat(outBuffer.format),
                                         outBuffer.format == PIXEL_FORMAT_RGBX_8888
                                                 ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
    SkBitmap bitmap;
    ssize_t bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);
    bitmap.setInfo(info, bpr);
    if (outBuffer.width > 0 && outBuffer.height > 0) {
        bitmap.setPixels(outBuffer.bits);
    } else {
        // be safe with an empty bitmap.
        bitmap.setPixels(NULL);
    }
    Canvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvasObj);
    nativeCanvas->setBitmap(bitmap)
    ....
    sp lockedSurface(surface);
    lockedSurface->incStrong(&sRefBaseOwner);
    return (jlong) lockedSurface.get();
}

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

2.surface.unlockCanvasAndPost

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

    public void unlockCanvasAndPost(Canvas canvas) {
        synchronized (mLock) {
            checkNotReleasedLocked();

            if (mHwuiContext != null) {
                mHwuiContext.unlockAndPost(canvas);
            } else {
                unlockSwCanvasAndPost(canvas);
            }
        }
    }

    private void unlockSwCanvasAndPost(Canvas canvas) {
        ....
        try {
            nativeUnlockCanvasAndPost(mLockedObject, canvas);
        } finally {
            nativeRelease(mLockedObject);
            mLockedObject = 0;
        }
    }

frameworks\base\core\jni\android_view_Surface.cpp

static void nativeUnlockCanvasAndPost(JNIEnv* env, jclass clazz,
        jlong nativeObject, jobject canvasObj) {
    sp surface(reinterpret_cast(nativeObject));
    if (!isSurfaceValid(surface)) {
        return;
    }

    // detach the canvas from the surface
    Canvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvasObj);
    nativeCanvas->setBitmap(SkBitmap());

    // unlock surface
    status_t err = surface->unlockAndPost();
    if (err < 0) {
        doThrowIAE(env);
    }
}

frameworks\native\libs\gui\Surface.cpp

status_t Surface::unlockAndPost()
{
    if (mLockedBuffer == nullptr) {
        ALOGE("Surface::unlockAndPost failed, no locked buffer");
        return INVALID_OPERATION;
    }

    int fd = -1;
    status_t err = mLockedBuffer->unlockAsync(&fd);
    ALOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle);

    err = queueBuffer(mLockedBuffer.get(), fd);
    ALOGE_IF(err, "queueBuffer (handle=%p) failed (%s)",
            mLockedBuffer->handle, strerror(-err));

    mPostedBuffer = mLockedBuffer;
    mLockedBuffer = nullptr;
    return err;
}

int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
    ....
    status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output);
    ....
    return err;
}

最终又是调用了 BufferQueueProducer的方法

status_t BufferQueueProducer::queueBuffer(int slot,
        const QueueBufferInput &input, QueueBufferOutput *output) {
    int64_t requestedPresentTimestamp;
    bool isAutoTimestamp;
    android_dataspace dataSpace;
    Rect crop(Rect::EMPTY_RECT);
    int scalingMode;
    uint32_t transform;
    uint32_t stickyTransform;
    sp acquireFence;
    bool getFrameTimestamps = false;
    //将input对象中的参数赋值个这些局部变量,这些局部变量后面会set进item。
    input.deflate(&requestedPresentTimestamp, &isAutoTimestamp, &dataSpace,
            &crop, &scalingMode, &transform, &acquireFence, &stickyTransform,
            &getFrameTimestamps);
    const Region& surfaceDamage = input.getSurfaceDamage();
    const HdrMetadata& hdrMetadata = input.getHdrMetadata();
    BufferItem item;
    { // Autolock scope
        // 当前queue的具体GraphicBuffer
        const sp& graphicBuffer(mSlots[slot].mGraphicBuffer);
        // 根据当前的GraphicBufferd的宽高创建矩形区域
        Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight());
        // 创建裁剪区域
        Rect croppedRect(Rect::EMPTY_RECT);
        // 放入crop对象
        crop.intersect(bufferRect, &croppedRect);
        mSlots[slot].mFence = acquireFence;
        // 改变入队的BufferSlot的状态为QUEUED
        mSlots[slot].mBufferState.queue();
        // 把BufferSlot中的信息封装为BufferItem,后续会把这个BufferItem加入到队列中
        item.mAcquireCalled = mSlots[slot].mAcquireCalled;
        item.mGraphicBuffer = mSlots[slot].mGraphicBuffer;
        // crop赋值给了item
        item.mCrop = crop;
        item.mSlot = slot;
        item.mTimestamp = requestedPresentTimestamp;
        item.mIsAutoTimestamp = isAutoTimestamp;
        ....
        if (mCore->mQueue.empty()) {
            // 如果mQueue队列为空,则直接push进入这个mQueue,不用考虑阻塞
            mCore->mQueue.push_back(item);
            //这里会通知Consumer
            frameAvailableListener = mCore->mConsumerListener;
        } else {
            //不为空看是否可以替换最后一个
            const BufferItem& last = mCore->mQueue.itemAt(
                    mCore->mQueue.size() - 1);
            ....
        }
        // 表示 buffer已经queued,此时入队完成
        mCore->mBufferHasBeenQueued = true;
        // mDequeueCondition是C++条件变量用作等待/唤醒,这里调用notify_all会唤醒调用了wait的线程
        mCore->mDequeueCondition.notify_all();
        mCore->mLastQueuedSlot = slot;
        //output 参数,会在Surface中继续使用
        output->width = mCore->mDefaultWidth;
        output->height = mCore->mDefaultHeight;
        output->transformHint = mCore->mTransformHint;
        output->numPendingBuffers = static_cast(mCore->mQueue.size());
        output->nextFrameNumber = mCore->mFrameCounter + 1;
        ....
        //onFrameAvailable通知Consumer
        if (frameAvailableListener != nullptr) {
            frameAvailableListener->onFrameAvailable(item);
        } else if (frameReplacedListener != nullptr) {
            frameReplacedListener->onFrameReplaced(item);
        }
    }
    ....
    return NO_ERROR;
}

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

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

frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp

void SurfaceFlinger::signalLayerUpdate() {
    mScheduler->resetIdleTimer();
    mEventQueue->invalidate();
}

SurfaceFlinger::SurfaceFlinger(Factory& factory, SkipInitializationTag)
      : mFactory(factory),
        ....
        mEventQueue(mFactory.createMessageQueue()){}

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

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

void MessageQueue::Handler::handleMessage(const Message& message) {
    switch (message.what) {
        case INVALIDATE:
            android_atomic_and(~eventMaskInvalidate, &mEventMask);
            mQueue.mFlinger->onMessageReceived(message.what);
            break;
        case REFRESH:
            android_atomic_and(~eventMaskRefresh, &mEventMask);
            mQueue.mFlinger->onMessageReceived(message.what);
            break;
    }
}

frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp 

void SurfaceFlinger::onMessageReceived(int32_t what) NO_THREAD_SAFETY_ANALYSIS {
    ATRACE_CALL();
    switch (what) {
        case MessageQueue::INVALIDATE: {
            ....
            bool refreshNeeded = handleMessageTransaction();
            refreshNeeded |= handleMessageInvalidate();
            .....
        }
        case MessageQueue::REFRESH: {
            handleMessageRefresh();
            break;
        }
    }
}

bool SurfaceFlinger::handleMessageInvalidate() {
    bool refreshNeeded = handlePageFlip();
    ....
    return refreshNeeded;
}

bool SurfaceFlinger::handlePageFlip()
{
    ....
    if (!mLayersWithQueuedFrames.empty()) {
        // mStateLock is needed for latchBuffer as LayerRejecter::reject()
        // writes to Layer current state. See also b/119481871
        Mutex::Autolock lock(mStateLock);

        for (auto& layer : mLayersWithQueuedFrames) {
            if (layer->latchBuffer(visibleRegions, latchTime)) {
                mLayersPendingRefresh.push_back(layer);
            }
            layer->useSurfaceDamage();
            if (layer->isBufferLatched()) {
                newDataLatched = true;
            }
        }
    }
    ....
    // Only continue with the refresh if there is actually new work to do
    return !mLayersWithQueuedFrames.empty() && newDataLatched;
}

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

frameworks\native\services\surfaceflinger\BufferLayer.cpp

bool BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime) {
    ....
    status_t err = updateTexImage(recomputeVisibleRegions, latchTime);
    ....
    return true;
}

frameworks\native\services\surfaceflinger\BufferLayerConsumer.cpp

status_t BufferLayerConsumer::updateTexImage(BufferRejecter* rejecter, nsecs_t expectedPresentTime,
                                             bool* autoRefresh, bool* queuedBuffer,
                                             uint64_t maxFrameNumber) {
    BufferItem item;
    // Acquire the next buffer.
    // In asynchronous mode the list is guaranteed to be one buffer
    // deep, while in synchronous mode we use the oldest buffer.
    status_t err = acquireBufferLocked(&item, expectedPresentTime, maxFrameNumber);
    .....
    return err;
}

status_t BufferLayerConsumer::acquireBufferLocked(BufferItem* item, nsecs_t presentWhen,
                                                  uint64_t maxFrameNumber) {
    status_t err = ConsumerBase::acquireBufferLocked(item, presentWhen, maxFrameNumber);
    ....
    // Release the previous buffer.
    err = updateAndReleaseLocked(item, &mPendingRelease);
    return NO_ERROR;
}
  1. 调用acquireBufferLocked函数获取Buffer
  2. 调用updateAndReleaseLocked更新当前Buffer并释放上一个Buffer

frameworks\native\libs\gui\ConsumerBase.cpp

status_t ConsumerBase::acquireBufferLocked(BufferItem *item,
        nsecs_t presentWhen, uint64_t maxFrameNumber) {
    if (mAbandoned) {
        CB_LOGE("acquireBufferLocked: ConsumerBase is abandoned!");
        return NO_INIT;
    }
    status_t err = mConsumer->acquireBuffer(item, presentWhen, maxFrameNumber);
    if (err != NO_ERROR) {
        return err;
    }
    if (item->mGraphicBuffer != nullptr) {
        if (mSlots[item->mSlot].mGraphicBuffer != nullptr) {
            freeBufferLocked(item->mSlot);
        }
        mSlots[item->mSlot].mGraphicBuffer = item->mGraphicBuffer;
    }
    mSlots[item->mSlot].mFrameNumber = item->mFrameNumber;
    mSlots[item->mSlot].mFence = item->mFence;
    return OK;
}

frameworks\native\libs\gui\BufferQueueConsumer.cpp 

status_t BufferQueueConsumer::acquireBuffer(BufferItem* outBuffer,
        nsecs_t expectedPresent, uint64_t maxFrameNumber) {
    ....
        if (!outBuffer->mIsStale) {
            mSlots[slot].mAcquireCalled = true;
            // Don't decrease the queue count if the BufferItem wasn't
            // previously in the queue. This happens in shared buffer mode when
            // the queue is empty and the BufferItem is created above.
            if (mCore->mQueue.empty()) {
                mSlots[slot].mBufferState.acquireNotInQueue();
            } else {
                mSlots[slot].mBufferState.acquire();
            }
            mSlots[slot].mFence = Fence::NO_FENCE;
        }
    ....
    return NO_ERROR;
}

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

接下来看下updateAndReleaseLocked做了什么

frameworks\native\services\surfaceflinger\BufferLayerConsumer.cpp

status_t BufferLayerConsumer::updateAndReleaseLocked(const BufferItem& item,
                                                     PendingRelease* pendingRelease) {
    status_t err = NO_ERROR;

    int slot = item.mSlot;
    std::shared_ptr nextTextureBuffer;
    {
        std::lock_guard lock(mImagesMutex);
        nextTextureBuffer = mImages[slot];
    }

    // release old buffer
    if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) {
        if (pendingRelease == nullptr) {
            status_t status =
                    releaseBufferLocked(mCurrentTexture, mCurrentTextureBuffer->graphicBuffer());
            if (status < NO_ERROR) {
                BLC_LOGE("updateAndRelease: failed to release buffer: %s (%d)", strerror(-status),
                         status);
                err = status;
                // keep going, with error raised [?]
            }
        } else {
            pendingRelease->currentTexture = mCurrentTexture;
            pendingRelease->graphicBuffer = mCurrentTextureBuffer->graphicBuffer();
            pendingRelease->isPending = true;
        }
    }

    // Update the BufferLayerConsumer state.
    mCurrentTexture = slot;
    mCurrentTextureBuffer = nextTextureBuffer;
    mCurrentCrop = item.mCrop;
    mCurrentTransform = item.mTransform;
    mCurrentScalingMode = item.mScalingMode;
    mCurrentTimestamp = item.mTimestamp;
    mCurrentDataSpace = static_cast(item.mDataSpace);
    mCurrentHdrMetadata = item.mHdrMetadata;
    mCurrentFence = item.mFence;
    mCurrentFenceTime = item.mFenceTime;
    mCurrentFrameNumber = item.mFrameNumber;
    mCurrentTransformToDisplayInverse = item.mTransformToDisplayInverse;
    mCurrentSurfaceDamage = item.mSurfaceDamage;
    mCurrentApi = item.mApi;
    computeCurrentTransformMatrixLocked();

    return err;
}

frameworks\native\libs\gui\ConsumerBase.cpp

status_t ConsumerBase::releaseBufferLocked(
        int slot, const sp graphicBuffer,
        EGLDisplay display, EGLSyncKHR eglFence) {
    ....
    status_t err = mConsumer->releaseBuffer(slot, mSlots[slot].mFrameNumber,
            display, eglFence, mSlots[slot].mFence);
    mPrevFinalReleaseFence = mSlots[slot].mFence;
    mSlots[slot].mFence = Fence::NO_FENCE;
    return err;
}

frameworks\native\libs\gui\BufferQueueConsumer.cpp

status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber,
        const sp& releaseFence, EGLDisplay eglDisplay,
        EGLSyncKHR eglFence) {
    ....
    sp listener;
    { // Autolock scope
        ....
        mSlots[slot].mEglDisplay = eglDisplay;
        mSlots[slot].mEglFence = eglFence;
        mSlots[slot].mFence = releaseFence;
        mSlots[slot].mBufferState.release();
        if (!mCore->mSharedBufferMode && mSlots[slot].mBufferState.isFree()) {
            mSlots[slot].mBufferState.mShared = false;
        }
        // Don't put the shared buffer on the free list.
        if (!mSlots[slot].mBufferState.isShared()) {
            mCore->mActiveBuffers.erase(slot);
            mCore->mFreeBuffers.push_back(slot);
        }
        listener = mCore->mConnectedProducerListener;
        BQ_LOGV("releaseBuffer: releasing slot %d", slot);
        mCore->mDequeueCondition.notify_all();
        VALIDATE_CONSISTENCY();
    } // Autolock scope
    ....
    return NO_ERROR;
}

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

Android—Surface,BufferQueue_第1张图片

Android—Surface,BufferQueue_第2张图片

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。

你可能感兴趣的:(Android,java,开发语言)