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;
- }
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方法主要工作:
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中。
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<uint32_t>(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 的流程主要做了这三件事情:
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;
- }
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,然后移除对应的队列。
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主要有两种合成方式: