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(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主要有两种合成方式: