- 从点击桌面APP图标,到APP界面显示的全流程(一)-基于Android 13(Android T)
- 从点击桌面APP图标,到APP界面显示的全流程(二)-基于Android 13(Android T)
八、绘制
ViewRootImpl.performDraw
先看CPU绘制:
ViewRootImpl.mTraversalRunnable.run()
| doTraversal();
| performTraversals();
| relayoutWindow //创建surface流程 + sf 创建layer流程
| hwInitialized = mAttachInfo.mThreadedRenderer.initialize(mSurface);
| mAttachInfo.mThreadedRenderer.allocateBuffers();//硬件绘制,预分配内存
| performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
| mView.measure(childWidthMeasureSpec, childHeightMeasureSpec); // measure 流程
| performLayout(lp, mWidth, mHeight);
| mView.layout(0, 0, host.getMeasuredWidth(), host.getMeasuredHeight()); // layout 流程
| mAttachInfo.mTreeObserver.dispatchOnGlobalLayout();//分发OnGlobalLayout事件
| View focused = mView.findFocus(); focused.restoreDefaultFocus(); //插眼WYF,这块逻辑以后再看
// 分发OnPreDraw事件
| boolean cancelDraw = mAttachInfo.mTreeObserver.dispatchOnPreDraw() || !isViewVisible; //不拦截的话 cancelDraw = FALSE
| performDraw();
| Trace.traceBegin(Trace.TRACE_TAG_VIEW, "draw");
| boolean canUseAsync = draw(fullRedrawNeeded);
| mAttachInfo.mTreeObserver.dispatchOnDraw();// 分发OnDraw,回调OnDrawListener中的onDraw()方法。
// 硬件绘制
| isHardwareEnabled()
| mAttachInfo.mThreadedRenderer.draw(mView, mAttachInfo, this);
// 如果未开启硬件绘制使用软件绘制:
| drawSoftware(surface, mAttachInfo, xOffset, yOffset, scalingRequired, dirty, surfaceInsets)
| Canvas canvas = mSurface.lockCanvas(dirty);
// /frameworks/base/core/java/android/view/Surface.java
|-->Canvas lockCanvas(Rect inOutDirty)
| | private final Canvas mCanvas = new CompatibleCanvas(); // 初始化 Canvas.mNativeCanvasWrapper
| // 把 native lock 的Surface地址保存到mLockedObject,这个mLockedObject通常情况和mNativeObject是一个地址
| | mLockedObject = nativeLockCanvas(mNativeObject, mCanvas, inOutDirty);
| | // /frameworks/base/core/jni/android_view_Surface.cpp
| |-->nativeLockCanvas(JNIEnv* env, jclass clazz, jlong nativeObject, jobject canvasObj, jobject dirtyRectObj)
| | // 把Java层保存的地址转换为 native Surface
| | sp<Surface> surface(reinterpret_cast<Surface *>(nativeObject));
| | ANativeWindow_Buffer buffer;
| | surface->lock(&buffer, dirtyRectPtr);
|-->Surface::lock(ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds)
| // 1、需要先连接到SurfaceFlinger端的BufferQueueProducer,会返回宽高数据,SurfaceFlinger端的BufferQueueCore也会设置一些属性
| // 注释说在调用dequeueBuffer前,必须先调用connect,是传入生产者监听,接收 onBufferReleased 回调。
| // 但是软绘,传入的监听是StubProducerListener,onBufferReleased是个空函数
| int err = Surface::connect(NATIVE_WINDOW_API_CPU);
| | ANativeWindowBuffer* out;
| int fenceFd = -1;
| | // 2、调用dequeueBuffer获取 ANativeWindowBuffer 对象 和 fenceFd。
| | status_t err = dequeueBuffer(&out, &fenceFd); // 【进入 dequeueBuffer 章节】
| | // 3、使用ANativeWindowBuffer创建后台 GraphicBuffer 对象
| | sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out)); // GraphicBuffer 继承 ANativeWindowBuffer
| // 4、获取前台buffer
| const sp<GraphicBuffer>& frontBuffer(mPostedBuffer);
| // 宽高格式都相同时,可以把前台的buffer的 Region 复制给后台buffer
| const bool canCopyBack = (frontBuffer != nullptr && backBuffer->width == frontBuffer->width &&...);
| // 干净区域 = 上一次所重绘的区域减去接下来需要重绘的脏区域newDirtyRegion,
| // copyBlt 把干净的区域从frontBuffer拷贝到backBuffer
| if (canCopyBack) const Region copyback(mDirtyRegion.subtract(newDirtyRegion));copyBlt(...);
| // 5、锁定 GraphicBuffer,获取buffer地址
| void* vaddr; // 这变量会携带图形buffer的地址回来,图形库,其实就是在这个地址上做像素操作
| // 调用 GraphicBufferMapper::lockAsync
| backBuffer->lockAsync(...,newDirtyRegion.bounds(), &vaddr, fenceFd);
| mLockedBuffer = backBuffer; // 后台buffer变为已经lock的buffer,入队后变为 mPostedBuffer
| // 6、把获取到的这些信息,存储到 ANativeWindow_Buffer,函数返回后,会把这对象传给图形库
| outBuffer->width = backBuffer->width;
| outBuffer->height = backBuffer->height;
| outBuffer->stride = backBuffer->stride;
| outBuffer->format = backBuffer->format;
| outBuffer->bits = vaddr; // 把图形buffer的地址赋值给 ANativeWindow_Buffer.bits
| // graphics::Canvas.mCanvas = native 层的 SkiaCanvas
| | graphics::Canvas canvas(env, canvasObj);
| // 把图形缓存的地址,宽高格式啊这些,设置进图形库的 SkiaCanvas,有了这些,图形库就专注画图就行了
| canvas.setBuffer(&buffer, static_cast<int32_t>(surface->getBuffersDataSpace()));
| sp<Surface> lockedSurface(surface); // 创建新的sp引用
| lockedSurface->incStrong(&sRefBaseOwner); // 引用加一
| return (jlong) lockedSurface.get(); // 返回地址,传入Java 层的 mLockedObject
| | return mCanvas;
| mView.draw(canvas); //[View的绘制流程]
| surface.unlockCanvasAndPost(canvas); // queueBuffer流程起始
| if (mHwuiContext != null) mHwuiContext.unlockAndPost(canvas);
| else unlockSwCanvasAndPost(canvas);
| nativeUnlockCanvasAndPost(mLockedObject, canvas);
|-->nativeUnlockCanvasAndPost(JNIEnv* env, jclass clazz, jlong nativeObject, jobject canvasObj)
| sp<Surface> surface(reinterpret_cast<Surface *>(nativeObject));
| graphics::Canvas canvas(env, canvasObj);
| canvas.setBuffer(nullptr, ADATASPACE_UNKNOWN);// detach the canvas from the surface
| status_t err = surface->unlockAndPost();
|-->Surface::unlockAndPost()
| int fd = -1;
| status_t err = mLockedBuffer->unlockAsync(&fd);
| err = queueBuffer(mLockedBuffer.get(), fd); // 【进入 queueBuffer 章节】
| mPostedBuffer = mLockedBuffer; // 把锁定状态的buffer转换为 已经入队的 buffer
| mLockedBuffer = nullptr;
Surface.connect-->BBQBufferQueueProducer.connect
- 重点是注册生产者回调
status_t Surface::lock(ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds);
| if (!mConnectedToCpu) // 没调用过 connect 时,false
| Surface::connect(NATIVE_WINDOW_API_CPU);
|-->Surface::connect(int api)
| // StubProducerListener 就是个虚假的实现,重载函数都为空函数
| static sp<IProducerListener> listener = new StubProducerListener();
| return connect(api, listener);
|-->Surface::connect(int api, const sp<IProducerListener>& listener)
| return connect(api, listener, false);
| //参数 reportBufferRemoval = false
|-->Surface::connect( int api, const sp<IProducerListener>& listener, bool reportBufferRemoval)
| IGraphicBufferProducer::QueueBufferOutput output;
| mReportRemovedBuffers = reportBufferRemoval; // false
| // mProducerControlledByApp = true; BBQSurface 创建时,传入的是 true
| int err = mGraphicBufferProducer->connect(listener, api, mProducerControlledByApp, &output);
|-->BBQBufferQueueProducer.connect(IProducerListener& listener,int api,bool producerControlledByApp QueueBufferOutput* output)
| return BufferQueueProducer::connect(listener, api, producerControlledByApp, output);
|-->BufferQueueProducer::connect(IProducerListener& listener,int api, bool producerControlledByApp, QueueBufferOutput *output)
| mConsumerName = mCore->mConsumerName;//mConsumerName = "ViewRootImpl#[id](BLAST Consumer)[id]"
| // 中间有一段代码,会依据擦混入的参数producerControlledByApp再调整一次 BufferQueueCore的 mFreeSlots mUnusedSlots
| // 目前的参数为无效代码,不贴代码了
| | switch (api) {
case NATIVE_WINDOW_API_EGL:
| case NATIVE_WINDOW_API_CPU:
| case NATIVE_WINDOW_API_MEDIA:
case NATIVE_WINDOW_API_CAMERA:
| mCore->mConnectedApi = api;
// 返回给 Surface 的属性
// 这些值,在 BLASTBufferQueue.update 把SurfaceContrl的值传到BufferQueueCore,现在又从 BufferQueueCore 传回Surface
| output->width = mCore->mDefaultWidth;
| output->height = mCore->mDefaultHeight;
// 用于优化旋转。预旋转
| output->transformHint = mCore->mTransformHintInUse = mCore->mTransformHint;//初始化时为 0
// 返回当前 处于 QUEUEED 状态的 buffer 数量
| output->numPendingBuffers = static_cast<uint32_t>(mCore->mQueue.size());
output->nextFrameNumber = mCore->mFrameCounter + 1;
| output->bufferReplaced = false;
output->maxBufferCount = mCore->mMaxBufferCount;
| // 【注册生产者回调--onBufferReleased】
| mCore->mConnectedProducerListener = listener;// CPU绘制传入的 StubProducerListener,没啥用
// 用于触发 onBufferReleased 回调, mBufferReleasedCbEnabled 为true的时候才能触发
| mCore->mBufferReleasedCbEnabled = listener->needsReleaseNotify(); // CPU 绘制返回false
| // 再刷一遍 BufferQueueCore 的属性,其实这些属性 BufferQueueCore 初始化时设置的也是这些值
| mCore->mConnectedPid = BufferQueueThreadState::getCallingPid();
| mCore->mBufferHasBeenQueued = false; mCore->mDequeueBufferCannotBlock = false;
| | mCore->mQueueBufferCanDrop = false; mCore->mLegacyBufferDrop = true;
| mCore->mAllowAllocation = true; // 允许分配内存
| // 使用请求到的数据,设置 Surface 属性
| mDefaultWidth = output.width; mDefaultHeight = output.height;
| mNextFrameNumber = output.nextFrameNumber; mMaxBufferCount = output.maxBufferCount;
| mTransformHint = output.transformHint;// 这只是一个提示,实际的转换可能会有所不同。被用来提高layer的系统性能
| mConsumerRunningBehind = (output.numPendingBuffers >= 2);
| if (!err && api == NATIVE_WINDOW_API_CPU) mConnectedToCpu = true; // CPU绘制
else mDirtyRegion = Region::INVALID_REGION;
-
Surface继承 ANativeWindow
- ANativeWindow 图形库的各种函数
-
ANativeWindow_Buffer ANativeWindow_Buffer.bits 存储图形buffer的地址
- 用于 Surface::lock 的参数,用于图形库。
-
GraphicBuffer 继承 ANativeWindowBuffer
-
封装图形内存分配接口 GraphicBufferMapper GraphicBufferAllocator ,以及进程间传递的序列化接口
-
ANativeWindowBuffer
-
typedef ANativeWindowBuffer ANativeWindowBuffer_t
-
typedef ANativeWindowBuffer_t android_native_buffer_t;
-
内部有个成员 native_handle_t* handle; 存储buffer的fd
-
-
Surface.dequeueBuffer-->BufferQueueProducer.dequeueBuffer
BBQBufferQueueProducer 没有重载 BufferQueueProducer.dequeueBuffer
直接调用父类 BufferQueueProducer.dequeueBuffer
status_t Surface::lock(ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds);
| if (!mConnectedToCpu) // 没调用过 connect 时,false
| Surface::connect(NATIVE_WINDOW_API_CPU);
| ANativeWindowBuffer* out;
| int fenceFd = -1;
| status_t err = dequeueBuffer(&out, &fenceFd);
|-->Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd);
| | getDequeueBufferInputLocked(&dqInput);
|-->Surface::getDequeueBufferInputLocked(IGraphicBufferProducer::DequeueBufferInput* dequeueInput)
| // Req 前缀表示 request,用于请求使用的参数,软绘应该全使用的默认值
| dequeueInput->width = mReqWidth ? mReqWidth : mUserWidth;// 默认 mReqWidth = mUserWidth = 0
| dequeueInput->height = mReqHeight ? mReqHeight : mUserHeight;// 默认 mReqHeight = mUserHeight = 0
| dequeueInput->format = mReqFormat;// 默认 0
| dequeueInput->usage = mReqUsage;// 默认 0
| dequeueInput->usage = mReqUsage;// mEnableFrameTimestamps 默认false
| dequeueInput->getTimestamps = mEnableFrameTimestamps;// mEnableFrameTimestamps 默认false
| int buf = -1;
| sp<Fence> fence;
| nsecs_t startTime = systemTime();// 当前时间
| FrameEventHistoryDelta frameTimestamps;
| status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, dqInput.width,dqInput.height, dqInput.format,
dqInput.usage, &mBufferAge,dqInput.getTimestamps ? &frameTimestamps : nullptr);
|-->BufferQueueProducer.dequeueBuffer(int* outSlot, sp<android::Fence>* outFence, uint32_t width, uint32_t height,
PixelFormat format, uint64_t usage, uint64_t* outBufferAge, FrameEventHistoryDelta* outTimestamps)
| mConsumerName = mCore->mConsumerName; // consumerName = "ViewRootImpl#[id](BLAST Consumer)[id]"
| //width、height 可以都为0,但是不能一个是0,一个非零。
| if ((width && !height) || (!width && height)) return BAD_VALUE;
| if (mCore->mFreeBuffers.empty() && mCore->mIsAllocating) mCore->waitWhileAllocatingLocked(lock);//正在分配buffer,自旋等待
| if (format == 0) format = mCore->mDefaultBufferFormat; // mDefaultBufferFormat = PIXEL_FORMAT_RGBA_8888
| // mConsumerUsageBits 在BLASTBufferItemConsumer构造是赋值为 GraphicBuffer::USAGE_HW_COMPOSER |GraphicBuffer::USAGE_HW_TEXTURE
| usage |= mCore->mConsumerUsageBits
| const bool useDefaultSize = !width && !height; // 宽高都为0,使用默认尺寸
| if (useDefaultSize)
| //默认宽高在 BLASTBufferQueue.update 把SurfaceContrl的宽高值传到BufferQueueCore
| width = mCore->mDefaultWidth; height = mCore->mDefaultHeight;
| if (mCore->mAutoPrerotation && (mCore->mTransformHintInUse & NATIVE_WINDOW_TRANSFORM_ROT_90))
| std::swap(width, height); // mAutoPrerotation自动预旋转默认false,mTransformHintInUse 90度时宽高互换
| int found = BufferItem::INVALID_BUFFER_SLOT;
| //【获取可用的 BufferSlot 索引】
| waitForFreeSlotThenRelock(FreeSlotCaller::Dequeue, lock, &found);
|-->BufferQueueProducer::waitForFreeSlotThenRelock(FreeSlotCaller caller, std::unique_lock<std::mutex>& lock, int* found)
| bool tryAgain = true;
| while (tryAgain)
| *found = BufferQueueCore::INVALID_BUFFER_SLOT;
| // 首先从list链表 BufferQueueCore->mFreeBuffers 拿 BufferSlot,如果集合是空的,会返回BufferQueueCore::INVALID_BUFFER_SLOT
| int slot = getFreeBufferLocked();
| if (slot != BufferQueueCore::INVALID_BUFFER_SLOT)
| *found = slot;
| else if (mCore->mAllowAllocation)
| // mFreeBuffers没有,就从set集合 BufferQueueCore->mFreeSlots 拿 BufferSlot,如果集合是空的,返回BufferQueueCore::INVALID_BUFFER_SLOT
| *found = getFreeSlotLocked();
| tryAgain = (*found == BufferQueueCore::INVALID_BUFFER_SLOT) || tooManyBuffers;
| // 没有 buffer了,或者 queue 太多了(这个可能性不大,mFreeSlots 这个set就三个数据,dequeue不出来那么多,queue就更不可能),
| if (tryAgain)
| if (mDequeueTimeout >= 0)// BBQ 设置的mDequeueTimeout=int64.max
| // 等待buffer(有可能是buffer被释放了,小概率因为mFreeSlots集合增加了)
| mCore->mDequeueCondition.wait_for(lock, std::chrono::nanoseconds(mDequeueTimeout));
| //拿到可用的索引found对应的 BufferSlot 的 GraphicBuffer
| const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer);
| //【把找到的buffer,插入到set集合 mActiveBuffers 中】
| mCore->mActiveBuffers.insert(found);
| //把索引值返回
| *outSlot = found;
| // 【把找到的 BufferSlot buffer状态转为 dequeue】
| mSlots[found].mBufferState.dequeue();
| //找到的 BufferSlot 没有关联GraphicBuffer,或者 GraphicBuffer 宽高,格式、usage、layerCount 和需求不相等的话,需要重新分配
| if ((buffer == nullptr) || buffer->needsReallocation(width, height, format, BQ_LAYER_COUNT, usage))
| mSlots[found].mAcquireCalled = false; mSlots[found].mGraphicBuffer = nullptr;
| mSlots[found].mRequestBufferCalled = false; mSlots[found].mEglDisplay = EGL_NO_DISPLAY;
| mSlots[found].mEglFence = EGL_NO_SYNC_KHR; mSlots[found].mFence = Fence::NO_FENCE;
| mCore->mBufferAge = 0; // 设置 mBufferAge 为0,新鲜的buffer啊,还没有被queue过
| mCore->mIsAllocating = true; // 设置为正在分配内存
| //【 添加 “需要重新分配buffer” flag】
| returnFlags |= BUFFER_NEEDS_REALLOCATION;
|else // 计算buffer年龄
| // mBufferAge: [(自从当前的 BufferSlot 上次被 queueBuffer 后,又queue了多少个BufferSlot) + 1]
| mCore->mBufferAge = mCore->mFrameCounter + 1 - mSlots[found].mFrameNumber;
| // 非共享内存模式下, 把当前的 buffer Fence ,传到外部参数 outFence
| *outFence = (mCore->mSharedBufferMode && mCore->mSharedBufferSlot == found) ? Fence::NO_FENCE : mSlots[found].mFence;
| // BufferSlot的Fence重新赋值为 NO_FENCE
| mSlots[found].mEglFence = EGL_NO_SYNC_KHR;
| mSlots[found].mFence = Fence::NO_FENCE;
| // 【需要重新分配buffer情况,分配新的buffer】
| if (returnFlags & BUFFER_NEEDS_REALLOCATION)
| //GraphicBuffer构造函数中调用 GraphicBufferAllocator.allocate 分配图形buffer,并映射内存到当前进程
| sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(width, height, format, BQ_LAYER_COUNT, usage,mConsumerName);
| mCore->mIsAllocating = false; // 分配完了,要重新设置回 false 啊
| mCore->mIsAllocatingCondition.notify_all(); // 唤醒那些因为 正在分配buffer 而等待的线程
| // 如果需要等待 eglFence 释放 Fence
| if (eglFence != EGL_NO_SYNC_KHR)
| EGLint result = eglClientWaitSyncKHR(eglDisplay, eglFence, 0,1000000000);// 等待B
| eglDestroySyncKHR(eglDisplay, eglFence);
| *outBufferAge = mCore->mBufferAge; // buffer年龄传到外部
| addAndGetFrameTimestamps(nullptr, outTimestamps);// BBQ 没有实现这方法,是个空实现。只有 BufferQueue 在消费者进程里,才会被调用。
| return returnFlags;
| //继续 Surface::dequeueBuffer
| mLastDequeueDuration = systemTime() - startTime;// 计算 dequeue 时间
| mLastDequeueStartTime = startTime;// 记录上次 dequeue 开始时间
| // 根据拿到的 slolt 下标,获取本地Surface自己的 GraphicBuffer
| sp<GraphicBuffer>& gbuf(mSlots[buf].buffer);
| if (result & IGraphicBufferProducer::RELEASE_ALL_BUFFERS) freeAllBuffers();
| if (dqInput.getTimestamps) mFrameEventHistory->applyDelta(frameTimestamps);
| // dequeueBuffer返回值 带有 BUFFER_NEEDS_REALLOCATION 标记,并且 gbuf == nullptr 的时候 进入此分支
| if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == nullptr)
| //【请求 GraphicBuffer】
| // requestBuffer接口很简单,直接返回 dequeueBuffer时关联/创建的 GraphicBuffer对象。
| // S版本以前,需要跨进程传递GraphicBuffer对象,反序列化时,会调用GraphicBufferMapper.importBuffer映射内存
| result = mGraphicBufferProducer->requestBuffer(buf, &gbuf);
| if (fence->isValid()) *fenceFd = fence->dup();
| // 赋值外部的 android_native_buffer_t** buffer
| *buffer = gbuf.get();
| // std::unordered_set<int> mDequeuedSlots;
| mDequeuedSlots.insert(buf); // Dequeued 的buffer的 下标 存入 mDequeuedSlots
Surface.queueBuffer
// 前置流程:
surface.unlockCanvasAndPost(canvas); // queueBuffer
| if (mHwuiContext != null) mHwuiContext.unlockAndPost(canvas);
| else unlockSwCanvasAndPost(canvas);
| nativeUnlockCanvasAndPost(mLockedObject, canvas);
|-->nativeUnlockCanvasAndPost(JNIEnv* env, jclass clazz, jlong nativeObject, jobject canvasObj)
| sp<Surface> surface(reinterpret_cast<Surface *>(nativeObject));
| graphics::Canvas canvas(env, canvasObj);
| canvas.setBuffer(nullptr, ADATASPACE_UNKNOWN);// detach the canvas from the surface
| status_t err = surface->unlockAndPost();
|-->Surface::unlockAndPost()
| | int fd = -1;
| | status_t err = mLockedBuffer->unlockAsync(&fd);
| GraphicBuffer::getBufferMapper().unlockAsync(handle, fenceFd);
| | err = queueBuffer(mLockedBuffer.get(), fd); // 进入【queueBuffer 章节】
| | mPostedBuffer = mLockedBuffer; // 把锁定的buffer转换为 已经入队的 buffer
| | mLockedBuffer = nullptr;
| nativeRelease(mLockedObject);
| mLockedObject = 0;
//【queueBuffer 章节】
Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd)
| int i = getSlotFromBufferLocked(buffer);
| // 遍历 Surface.mSlots 数组,找到 GraphicBuffer.handle 相同的 BufferSlot 索引
|-->Surface::getSlotFromBufferLocked(android_native_buffer_t* buffer)
| for (int i = 0; i < NUM_BUFFER_SLOTS; i++)
| if (mSlots[i].buffer != nullptr && mSlots[i].buffer->handle == buffer->handle)
| return i;
| IGraphicBufferProducer::QueueBufferOutput output;
| IGraphicBufferProducer::QueueBufferInput input;
| /*
Surface.mTimestamp 使用默认的 NATIVE_WINDOW_TIMESTAMP_AUTO 时,
QueueBufferInput.timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
QueueBufferInput.isAutoTimestamp = true; // 这个参数标明是否在入队时,自动生成时间戳
| */
| getQueueBufferInputLocked(buffer, fenceFd, mTimestamp, &input);
| // 一些 Gralloc 的元数据 mapper.setDataspace,HdrMetadata 设置
| applyGrallocMetadataLocked(buffer, input);
| sp<Fence> fence = input.fence;
| nsecs_t now = systemTime();
| status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output);
|-->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<Fence> acquireFence; bool getFrameTimestamps = false;
| // 读取输入参数的数据
| input.deflate(&requestedPresentTimestamp, &isAutoTimestamp, &dataSpace,
&crop, &scalingMode, &transform, &acquireFence, &stickyTransform, &getFrameTimestamps);
| const Region& surfaceDamage = input.getSurfaceDamage();
| const HdrMetadata& hdrMetadata = input.getHdrMetadata();
| sp<IConsumerListener> frameAvailableListener;// buffer 可用通知
| sp<IConsumerListener> frameReplacedListener;//buffer被替换通知
| BufferItem item; // 创建 BufferItem
| // 拿到 slot 对应的 GraphicBuffer
| const sp<GraphicBuffer>& graphicBuffer(mSlots[slot].mGraphicBuffer);
| // 裁剪区域
| Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight());
| Rect croppedRect(Rect::EMPTY_RECT);
| // crop 和 bufferRect 的交集,结果存入 croppedRect
| crop.intersect(bufferRect, &croppedRect);
| mSlots[slot].mFence = acquireFence;
| //【设置为 QUEUED 状态】
| mSlots[slot].mBufferState.queue();
| ++mCore->mFrameCounter;// 每次 queueBuffer 都+1
| currentFrameNumber = mCore->mFrameCounter;
| mSlots[slot].mFrameNumber = currentFrameNumber;//存储当前BufferSlot的帧号
| // 封装 BufferItem 信息
| item.mAcquireCalled = mSlots[slot].mAcquireCalled;
| item.mGraphicBuffer = mSlots[slot].mGraphicBuffer; //图形buffer
| item.mCrop = crop;//裁切矩形
| item.mTransform = transform & ~static_cast<uint32_t>(NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY);// 旋转变换
| item.mTransformToDisplayInverse = (transform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) != 0;
| item.mScalingMode = static_cast<uint32_t>(scalingMode);//缩放模式
| item.mTimestamp = requestedPresentTimestamp;//时间戳
| item.mIsAutoTimestamp = isAutoTimestamp;// 是否在入队时,自动生成时间戳,默认情况下 true
| item.mDataSpace = dataSpace;// 描述图像内容,依赖于图像格式
| item.mHdrMetadata = hdrMetadata;// HDR metadata 不懂
| item.mFrameNumber = currentFrameNumber;//帧号
| item.mSlot = slot;/*索引*/ item.mFence = acquireFence;/*fence*/ item.mFenceTime = acquireFenceTime;/*FenceTime*/
| // mIsDroppable 如果为true,则 queuebuffer 时,可以替换旧的buffer。
| item.mIsDroppable = mCore->mAsyncMode || ...;// 当前 mIsDroppable = false
| item.mSurfaceDamage = surfaceDamage;//已经被修改的区域
| item.mQueuedBuffer = true;// 标明buffer已经被生产者 queued,acquireBuffer后设置为false
| item.mAutoRefresh = mCore->mSharedBufferMode && mCore->mAutoRefresh;// 仅仅在共享buffer下有用,标明消费者应该尽快 acquire 下一帧
| item.mApi = mCore->mConnectedApi;//表明是 CPU还是GPU queue的buffer
| output->bufferReplaced = false;
| //【BufferItem入队】
| mCore->mQueue.push_back(item);
| // BufferQueueCore.mConsumerListener = ConsumerBase(BLASTBufferItemConsumer的父类)
| frameAvailableListener = mCore->mConsumerListener;
| mCore->mBufferHasBeenQueued = true;// 每次queueBuffer后都设置为true
| mCore->mDequeueCondition.notify_all();// 唤醒等待的线程
| mCore->mLastQueuedSlot = slot;// 赋值最新queue的 BufferSlot 索引
| // 返回给Surface的数据
| output->width = mCore->mDefaultWidth; output->height = mCore->mDefaultHeight;
| output->transformHint = mCore->mTransformHintInUse = mCore->mTransformHint;
| output->numPendingBuffers = static_cast<uint32_t>(mCore->mQueue.size());// 返回当前已经Queue的数量,代表还未被消费的数量
| output->nextFrameNumber = mCore->mFrameCounter + 1;// 返回下一帧的帧号
| // atrace 记录 mQueue 大小
| ATRACE_INT(mCore->mConsumerName.string(), static_cast<int32_t>(mCore->mQueue.size()));
| // BBQ生产者构造函数设置 mConsumerIsSurfaceFlinger = false
| if (!mConsumerIsSurfaceFlinger)
| // 清理 GraphicBuffer 指针【TODO:这里的一些比较重要联动细节待研究】
| item.mGraphicBuffer.clear();
| int connectedApi = mCore->mConnectedApi;
| sp<Fence> lastQueuedFence = std::move(mLastQueueBufferFence);
| mLastQueueBufferFence = std::move(acquireFence);
| //【消费者回调】
| // 回调到 ConsumerBase.onFrameAvailable ,再回调到 BLASTBufferQueue.onFrameAvailable
| frameAvailableListener->onFrameAvailable(item);//【转入“BufferQueueConsumer::acquireBuffer”章节】
| // 如果是 GPU 绘制,最多queueBuffer两个buffer,第二个buffer没有绘制完成,就需要等待 fence
| if (connectedApi == NATIVE_WINDOW_API_EGL)
| lastQueuedFence->waitForever("Throttling EGL Production");
| mLastQueueDuration = systemTime() - now; // 记录 queueBuffer 时间
| // 更新Surface的一些成员属性
| onBufferQueuedLocked(i, fence, output);
BufferQueueConsumer::acquireBuffer
BLASTBufferQueue::onFrameAvailable(const BufferItem& item)
| acquireNextBufferLocked(std::nullopt);
|-->BLASTBufferQueue::acquireNextBufferLocked(const std::optional<SurfaceComposerClient::Transaction*> transaction)
| // 参数 transaction = nullopt
| const bool includeExtraAcquire = !transaction;// includeExtraAcquire = true
| // 判断 mNumAcquired 是否大于等于 mMaxAcquiredBuffers + (includeExtraAcquire ? 2 : 1)
| const bool maxAcquired = maxBuffersAcquired(includeExtraAcquire);
| // Transaction 一个事务里边会填充各种需要执行的业务和业务数据,最终传递到 SurfaceFlinger,SF对事务解析的结果通常是设置Layer的各种属性
| // 每设置一种数据,都会存到ComposerState中,并添加对应的flag,SF端根据flag解析数据
| SurfaceComposerClient::Transaction localTransaction;
| bool applyTransaction = true;
| SurfaceComposerClient::Transaction* t = &localTransaction;
| BufferItem bufferItem; // 创建一个未填充数据的的栈对象 BufferItem
| //【acquireBuffer流程!!!!!!!!!!!!!!!!】
| status_t status = mBufferItemConsumer->acquireBuffer(&bufferItem, 0 /* expectedPresent */, false);
|-->BufferItemConsumer::acquireBuffer(BufferItem *item, nsecs_t presentWhen, bool waitForFence)
| acquireBufferLocked(item, presentWhen); // presentWhen = 0
|-->ConsumerBase::acquireBufferLocked(BufferItem *item, nsecs_t presentWhen, uint64_t maxFrameNumber)
| // 调用消费者的 acquireBuffer, mConsumer 为 BufferQueueConsumer
| mConsumer->acquireBuffer(item, presentWhen, maxFrameNumber);
|-->BufferQueueConsumer::acquireBuffer(BufferItem* outBuffer, nsecs_t expectedPresent, uint64_t maxFrameNumber)
| // 参数: outBuffer 是个需要带回数据的指针; expectedPresent = 0; maxFrameNumber = 0
| // 拿到队列的迭代指针
| BufferQueueCore::Fifo::iterator front(mCore->mQueue.begin());
| // 忽略一大段不执行的分支:作用就是丢弃buffer的操作、共享buffer
| int slot = front->mSlot; // 把 mQueue 队列里的第一个 BufferItem 的mSlot,赋值给 slot
| // 【把拿到的 BufferItem 通过指针参数带回】
| *outBuffer = *front;
| ATRACE_BUFFER_INDEX(slot);// trace 记录 BufferSlot 的索引值
| if (!outBuffer->mIsStale) // 如果buffer没有过时
| mSlots[slot].mAcquireCalled = true;// 设置状态为已经被acquire过了
| // 【切换状态为 acquired 状态】
| mSlots[slot].mBufferState.acquire();
| mSlots[slot].mFence = Fence::NO_FENCE; // 设置为 NO_FENCE
| if (outBuffer->mAcquireCalled) // 已经被消费过了,需要设置 GraphicBuffer 为 nullptr,避免 remapping
| outBuffer->mGraphicBuffer = nullptr;
| //【把 BufferItem 从队queued列中移除】
| mCore->mQueue.erase(front);
| mCore->mDequeueCondition.notify_all();// 唤醒等待的线程
| // atrace 记录此时的队列长度
| ATRACE_INT(mCore->mConsumerName.string(), static_cast<int32_t>(mCore->mQueue.size()));
| //返回到 ConsumerBase::acquireBufferLocked
| //BBQ生产者 BufferQueueProducer::queueBuffer 时,把 mGraphicBuffer 指针清空了,这个分支不走的
| if (item->mGraphicBuffer != nullptr)
| if (mSlots[item->mSlot].mGraphicBuffer != nullptr)
| freeBufferLocked(item->mSlot);
| mSlots[item->mSlot].mGraphicBuffer = item->mGraphicBuffer;
| // 这里的 BufferItemConsumer.mSlots 和 BufferQueueConsumer.mSlots 不是同一个对象
| mSlots[item->mSlot].mFrameNumber = item->mFrameNumber;// 帧号存到 BufferItemConsumer.mSlots 里
| mSlots[item->mSlot].mFence = item->mFence; // Fence存到 BufferItemConsumer.mSlots 里
| //返回到 BufferItemConsumer::acquireBuffer
| if (waitForFence) // waitForFence = false ,无需等待fence
| item->mFence->waitForever("BufferItemConsumer::acquireBuffer");
| // 返回的 GraphicBuffer 为 BLASTBufferItemConsumer.mSlots 的 GraphicBuffer
| item->mGraphicBuffer = mSlots[item->mSlot].mGraphicBuffer;
| //返回到BLASTBufferQueue::acquireNextBufferLocked
| auto buffer = bufferItem.mGraphicBuffer;
| mNumFrameAvailable--;
| if (buffer == nullptr) //TODO:流程上,应该是进入了此分支,现实是不可能,这里看了好几遍也没找到问题出哪里了,以后再重新分析一下吧
| mBufferItemConsumer->releaseBuffer(bufferItem, Fence::NO_FENCE);
| return;
| // 如果buffer的尺寸不匹配,直接释放buffer,请求下一个
| if (rejectBuffer(bufferItem))
| mBufferItemConsumer->releaseBuffer(bufferItem, Fence::NO_FENCE);
| acquireNextBufferLocked(transaction);
| return;
| mNumAcquired++; // Acquired数量加一,release 时减一
| mLastAcquiredFrameNumber = bufferItem.mFrameNumber;// 记录当前的帧号
| // 创建 ReleaseCallbackId ,加入到map mSubmitted,SurfaceFlinger 释放buffer,回调回来时会通过ReleaseCallbackId查找BufferItem
| ReleaseCallbackId releaseCallbackId(buffer->getId(), mLastAcquiredFrameNumber);
| mSubmitted[releaseCallbackId] = bufferItem;
| mSize = mRequestedSize;
| Rect crop = computeCrop(bufferItem);// 裁剪矩形
| //【 releaseBuffer 回调函数 !!!!!!!!!!!!!!!!】,SurfaceFlinger合成完后,就是回调的 releaseBufferCallbackThunk函数
| auto releaseBufferCallback = std::bind(releaseBufferCallbackThunk, wp<BLASTBufferQueue>(this),...);
| sp<Fence> fence = bufferItem.mFence ? new Fence(bufferItem.mFence->dup()) : Fence::NO_FENCE;//GPU绘制的fence
| //【把buffer、fence、释放buffer的回调函数 都传入事务,通过事务传递给SurfaceFlinger】
| t->setBuffer(mSurfaceControl, buffer, fence, bufferItem.mFrameNumber, releaseBufferCallback);
| // 使用 bufferItem中的数据,填充事务的其他各种数据...
| t->setDataspace(mSurfaceControl, static_cast<ui::Dataspace>(bufferItem.mDataSpace));
| t->setHdrMetadata(mSurfaceControl, bufferItem.mHdrMetadata);
| t->setBufferCrop(mSurfaceControl, crop);
| t->setAutoRefresh(mSurfaceControl, bufferItem.mAutoRefresh);
| t->setSurfaceDamageRegion(mSurfaceControl, bufferItem.mSurfaceDamage);
| //....
| // 最后调用apply,把事务传递到SurfaceFlinger
| t->setApplyToken(mApplyToken).apply(false, true);
| SurfaceComposerClient::Transaction::apply(bool synchronous, bool oneWay)
| sp<ISurfaceComposer> sf(ComposerService::getComposerService());
| sf->setTransactionState(mFrameTimelineInfo, composerStates, displayStates, flags, applyToken,...)
九、SurfaceFlinger 合成--- Android 13 (Android T)
相对于Android 12,Android13在架构上做了微调
-
SurfaceFlinger::onMessageInvalidate 对应于 SurfaceFlinger::commit,但是结构上做了大量的调整
一些函数像 handleMessageTransaction、handleTransaction、handleMessageInvalidate、handlePageFlip 这些都不见了
-
SurfaceFlinger::onMessageRefresh 对应于 SurfaceFlinger::composite
然后Android13 还做了GPU合成的优化
- 对GPU合成进行预测,如果有GPU合成,那么 chooseCompositionStrategy 和 GPU合成 并行执行。用以节约时间。
SurfaceComposerClient::Transaction::apply-->SurfaceFlinger::setTransactionState
- 事务入队。加入到队列 SurfaceFlinger.mTransactionQueue
// frameworks/native/libs/gui/SurfaceComposerClient.cpp
SurfaceComposerClient::Transaction::apply(bool synchronous, bool oneWay)
| // applyToken 来源于 BLASTBufferQueue.h
| // const sp<IBinder> mApplyToken GUARDED_BY(mMutex) = new BBinder();
| sf->setTransactionState(mFrameTimelineInfo, composerStates, displayStates, flags, applyToken,
mInputWindowCommands, mDesiredPresentTime, mIsAutoTimestamp,
{} /*uncacheBuffer - only set in doUncacheBufferTransaction*/,
hasListenerCallbacks, listenerCallbacks, mId);
//进入 SurfaceFlinger 进程
// frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
SurfaceFlinger::setTransactionState(const FrameTimelineInfo& frameTimelineInfo, const Vector<ComposerState>& states,
const Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken,
const InputWindowCommands& inputWindowCommands, int64_t desiredPresentTime,
bool isAutoTimestamp, const client_cache_t& uncacheBuffer, bool hasListenerCallbacks,
const std::vector<ListenerCallbacks>& listenerCallbacks, uint64_t transactionId)
| //...
| const int64_t postTime = systemTime();
| IPCThreadState* ipc = IPCThreadState::self();
| const int originPid = ipc->getCallingPid();
| const int originUid = ipc->getCallingUid();
| // 主要逻辑就是把这个 TransactionState 对象入队。然后请求 SF-vsync
| TransactionState state{frameTimelineInfo, states, displays, flags, applyToken, inputWindowCommands,
desiredPresentTime, isAutoTimestamp, uncacheBuffer, postTime, permissions,
hasListenerCallbacks,listenerCallbacks, originPid, originUid, transactionId};
| //...
| queueTransaction(state);
|-->SurfaceFlinger::queueTransaction(TransactionState& state)
| state.queueTime = systemTime();
| // std::deque<TransactionState> mTransactionQueue; 双端队列
| //【把 TransactionState 入队】
| // 在 SurfaceFlinger::flushTransactions() 函数中会出队
| mTransactionQueue.emplace_back(state);
| ATRACE_INT("TransactionQueue", mTransactionQueue.size());
| const auto schedule = ...;
| const auto frameHint = state.isFrameActive() ? FrameHint::kActive : FrameHint::kNone;
| // 传入的事务flag是枚举类型 eTransactionFlushNeeded = 0x10;
| setTransactionFlags(eTransactionFlushNeeded, schedule, state.applyToken, frameHint);
|-->SurfaceFlinger::setTransactionFlags(uint32_t mask, TransactionSchedule schedule, IBinder& applyToken, FrameHint frameHint)
| // 调整vsync一些时间配置
| modulateVsync(&VsyncModulator::setTransactionSchedule, schedule, applyToken);
/*
1、mTransactionFlags 添加 eTransactionFlushNeeded 标记
2、mTransactionFlags原值 同 mask 相与, 表示原先有没有这个标记。并把结果存储 scheduled
3、!scheduled 取非,表示如果原先没有这个标记,就进入此分支,执行 scheduleCommit
*/
| if (const bool scheduled = mTransactionFlags.fetch_or(mask) & mask; !scheduled)
| scheduleCommit(frameHint);
|-->SurfaceFlinger::scheduleCommit(FrameHint hint)
| if (hint == FrameHint::kActive)
| mScheduler->resetIdleTimer();
| mPowerAdvisor->notifyDisplayUpdateImminent();
| // 这个函数的调用链很长,知道这个代码是请求 SurfaceFlinger 的 vsync 就行了
| mScheduler->scheduleFrame();
MessageQueue::scheduleFrame() --- 请求vsync
MessageQueue::scheduleFrame()
| mVsync.registration->schedule({.workDuration = mVsync.workDuration.get().count(),
.readyDuration = 0,
.earliestVsync = mVsync.lastCallbackTime.count()});
|-->VSyncCallbackRegistration::schedule(VSyncDispatch::ScheduleTiming scheduleTiming)
| if (!mValidToken) return std::nullopt;
| // mDispatch 是 VSyncDispatchTimerQueue
| return mDispatch.get().schedule(mToken, scheduleTiming);
| VSyncDispatchTimerQueue::schedule(CallbackToken token, ScheduleTiming scheduleTiming)
| ScheduleResult result;
| // VSyncCallbackRegistration 构造的时候,调用registerCallback生成了一个 token ,这个token存储到了 map 对象 mCallbacks
| // 现在拿出来
| auto it = mCallbacks.find(token);
| auto& callback = it->second; // map 迭代器 second 中存储 VSyncDispatchTimerQueueEntry
| // VSyncDispatchTimerQueueEntry 中存储真正的回调函数 MessageQueue::vsyncCallback
| result = callback->schedule(scheduleTiming, mTracker, now);
| // 这里步骤还很多。大概是更新vsync的时间配置啥的
|-->VSyncDispatchTimerQueueEntry::schedule(VSyncDispatch::ScheduleTiming timing, VSyncTracker& tracker, nsecs_t now)
| //省略VSyncDispatchTimerQueueEntry函数内XXXX,太长了。抽空再研究
| //.........
| if (callback->wakeupTime() < mIntendedWakeupTime - mTimerSlack)
| // 启动vsync的定时器
| rearmTimerSkippingUpdateFor(now, it);
| return result;
sf-vsync事件分发流程
- Android 13 把用了好多年的 onMessageInvalidate()、onMessageRefresh 体系给改了
- 变成了 SurfaceFlinger::commit 和 SurfaceFlinger::composite ,中间不post消息了,直接无缝切换
// frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.cpp
MessageQueue::vsyncCallback(nsecs_t vsyncTime, nsecs_t targetWakeupTime, nsecs_t readyTime)
| mHandler->dispatchFrame(vsyncId, vsyncTime);
|-->MessageQueue::Handler::dispatchFrame(int64_t vsyncId, nsecs_t expectedVsyncTime)
| mQueue.mLooper->sendMessage(this, Message())
void MessageQueue::Handler::handleMessage(const Message&) {
mFramePending.store(false);
const nsecs_t frameTime = systemTime();
// mQueue 类型android::impl::MessageQueue
// android::impl::MessageQueue.mCompositor 类型 ICompositor
// SurfaceFlinger 继承 ICompositor
// mQueue.mCompositor 其实就是 SurfaceFlinger
auto& compositor = mQueue.mCompositor;
// 【流程1,返回false的话,直接返回,不会执行后面的合成流程composite】
if (!compositor.commit(frameTime, mVsyncId, mExpectedVsyncTime)) {
return;
}
// 【流程2,合成】
compositor.composite(frameTime, mVsyncId);
// 通过RegionSamplingThread对合成帧进行采样
compositor.sample();
}
SurfaceFlinger::commit 流程
// frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
SurfaceFlinger::commit(nsecs_t frameTime, int64_t vsyncId, nsecs_t expectedVsyncTime)
| // 返回 SurfaceFlinger.mTransactionFlags 是否携带 eTransactionFlushNeeded 标记。同时清除这个标记
| // eTransactionFlushNeeded 是由 queueTransaction 流程中设置的
| if (clearTransactionFlags(eTransactionFlushNeeded))
| //【1】、flushTransactions(),核心是获取所有的TransactionState,之后将作为 applyTransactions流程 的参数】
| // 把 Transaction::apply 流程中,加入 mTransactionQueue 队列的 TransactionState 出队
| std::vector<TransactionState> transactions = flushTransactions();
| // 这个函数核心就是把 mTransactionQueue 队列的数据转移到一个 vector 中返回
// 中间处理一些还没有处理完的事务。具体代码待研究
|-->SurfaceFlinger::flushTransactions()
| std::vector<TransactionState> transactions;
| while (!mTransactionQueue.empty())// 【取出setTransactionState流程中入队的所有事务】
| auto& transaction = mTransactionQueue.front();
| // 省略 X 行代码
| transactions.emplace_back(std::move(transaction));// 把事务转入向量集合 vector<TransactionState> transactions
| mTransactionQueue.pop_front();
| ATRACE_INT("TransactionQueue", mTransactionQueue.size());
| return transactions;
| // 【2】、处理以前创建的layer,核心就是把新创建的layer加入到Z轴排序集合体系 mCurrentState.layersSortedByZ 】
| // Android12以前layersSortedByZ不是在这里添加的。或许谷歌以后想仅仅通过事务的接口创建layer??
| needsTraversal |= commitCreatedLayers();
|-->SurfaceFlinger::commitCreatedLayers()
| std::vector<LayerCreatedState> createdLayers;
/* mCreatedLayers: 创建layer流程中,通过 SurfaceFlinger::addClientLayer 把layer添加到了 mCreatedLayers 这个vector中
现在开始拿来使用了 */
| createdLayers = std::move(mCreatedLayers); //数据转移到新的对象createdLayers中
| mCreatedLayers.clear();//清除mCreatedLayers所有的数据
| if (createdLayers.size() == 0)
| return false; // 如果没有新增的Layer,直接返回,那么 mLayersAdded 就不会被设置为 true
| for (const auto& createdLayer : createdLayers)
| handleLayerCreatedLocked(createdLayer);
|-->SurfaceFlinger::handleLayerCreatedLocked(const LayerCreatedState& state)
| sp<Layer> layer = state.layer.promote();
| bool addToRoot = state.addToRoot;
| sp<Layer> parent = state.initialParent.promote();
| // 如果没有父layer的话,执行以下代码。
| if (parent == nullptr && addToRoot)
| layer->setIsAtRoot(true);
| //【添加到 mCurrentState.layersSortedByZ 这个以Z轴排序的集合中】
| mCurrentState.layersSortedByZ.add(layer);
| else if (parent == nullptr)
| layer->onRemovedFromCurrentState();// Layer删除处理
| else if (parent->isRemovedFromCurrentState())
| parent->addChild(layer);
| layer->onRemovedFromCurrentState();// Layer删除处理
| else// TODO: 待验证 parent 为 ContainerLayer, addToRoot=true
| parent->addChild(layer);// BufferStateLayer 应该走这里。添加到 Layer.mCurrentChildren 集合中
| layer->updateTransformHint(mActiveDisplayTransformHint);
| mInterceptor->saveSurfaceCreation(layer);
| // 在之后的流程 commitTransactionsLocked 函数中会设置回 false
| mLayersAdded = true;
| return true;//如果有新创建的layer,需要执行合成步骤 SurfaceFlinger.composite 函数
| needsTraversal |= applyTransactions(transactions, vsyncId);
| // 因图形buffer更新放到事务中来了,所以事务这里重点关注 eBufferChanged
| //【3】、applyTransactions流程: 把事务中的对于flag的数据存入Layer.mDrawingState对应的属性
| // 对于Layer删除、调整Z轴,则是把相关数据存入 SurfaceFlinger.mCurrentState.layersSortedByZ
| // 对于图形buffer更新而言,核心就是赋值 mDrawingState.buffer
|-->SurfaceFlinger::applyTransactions(std::vector<TransactionState>& transactions,int64_t vsyncId)
| return applyTransactionsLocked(transactions, vsyncId);
|-->SurfaceFlinger::applyTransactionsLocked(std::vector<TransactionState>& transactions, int64_t vsyncId)
| bool needsTraversal = false;
| // 【遍历步骤1中flushTransactions()返回的 transactions】
| for (auto& transaction : transactions)
| needsTraversal |= applyTransactionState(...)
|-->SurfaceFlinger::applyTransactionState(..)
| uint32_t transactionFlags = 0;
| uint32_t clientStateFlags = 0;
| // 省略一大堆内容
| clientStateFlags = setClientStateLocked(frameTimelineInfo, state, desiredPresentTime,isAutoTimestamp, postTime, permissions);
|-->SurfaceFlinger::setClientStateLocked(const FrameTimelineInfo& frameTimelineInfo,ComposerState& composerState,...)
| //省略一大堆内容
| layer_state_t& s = composerState.state;
| // BLASTBufferQueue 传递buffer到SF的时候,调用Transaction::setBuffer 添加 eBufferChanged 标记
| if (what & layer_state_t::eBufferChanged)
| layer->setBuffer(buffer, *s.bufferData, postTime, desiredPresentTime,
isAutoTimestamp, dequeueBufferTimestamp, frameTimelineInfo)
| // 只有 BufferStateLayer 覆写了setBuffer,其他layer使用父类Layer.setBuffer,父类的函数直接返回false
|-->BufferStateLayer::setBuffer(std::shared_ptr<renderengine::ExternalTexture>& buffer,const BufferData& bufferData,...)
| // 省略一大堆
| // 这里的 mDrawingState 是 Layer 的,和SurfaceFlinger的 mDrawingState 不是一个类
| // 以前 Layer也有一个 mCurrentState 对象,现在没有了
| mDrawingState.frameNumber = frameNumber;
| mDrawingState.releaseBufferListener = bufferData.releaseBufferListener;
| mDrawingState.buffer = std::move(buffer);//【把buffer给到 mDrawingState.buffer】
| mDrawingState.acquireFence = ... bufferData.acquireFence;
| mDrawingState.modified = true; // 表示是否有状态被修改,几乎所有Layer事务都会设置这个变量为true
| mFlinger->mTimeStats->setPostTime(layerId, mDrawingState.frameNumber, getName().c_str(),mOwnerUid, postTime,...);
| mDrawingState.isAutoTimestamp = isAutoTimestamp;
| mDrawingState.releaseBufferEndpoint = bufferData.releaseBufferEndpoint;
| // 每次vsync事件都会伴随生成一个 vsyncId。TODO:通常情况可能没有 frameTimelineInfo,,没找到赋值过程,待研究
| else if (frameTimelineInfo.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID)
| layer->setFrameTimelineVsyncForBufferlessTransaction(frameTimelineInfo, postTime);
| transactionFlags |= clientStateFlags;// 添加 setClientStateLocked 返回的flag
| bool needsTraversal = false;
| if (transactionFlags & eTraversalNeeded)
| transactionFlags = transactionFlags & (~eTraversalNeeded);
| needsTraversal = true;
| if (transactionFlags) setTransactionFlags(transactionFlags); //如果还有eTraversalNeeded以外的flag,请求vsync
| return needsTraversal;
| if (mTransactionTracing)
| mTransactionTracing->addCommittedTransactions(transactions, vsyncId);
| return needsTraversal;//返回最终的 needsTraversal,这个为true的话,会执行 commitTransactions、composite
| // 是否需要执行事务提交。【提交的核心就是把 mCurrentState 赋值给 mDrawingState】
| // mCurrentState 保存APP传来的数据,mDrawingState 用于合成
| const bool shouldCommit = (getTransactionFlags() & ~eTransactionFlushNeeded) || needsTraversal;
| //【4】、commitTransactions()流程:核心是把mCurrentState转移到 mDrawingState
| if(shouldCommit)
| commitTransactions();
|-->SurfaceFlinger:::commitTransactions()
| State drawingState(mDrawingState);
| mDebugInTransaction = systemTime();
| modulateVsync(&VsyncModulator::onTransactionCommit);
| commitTransactionsLocked(clearTransactionFlags(eTransactionMask));
|-->SurfaceFlinger::commitTransactionsLocked(uint32_t transactionFlags);
| // 屏幕的热插拔SurfaceFlinger::onComposerHalHotplug会调用 setTransactionFlags(eDisplayTransactionNeeded),然后到这里处理
| // TODO:主线程中接收到的热插拔,不会走到这里。这里处理的可能是非主屏的热插拔,待验证。
| const bool displayTransactionNeeded = transactionFlags & eDisplayTransactionNeeded;
| // 处理显示器的事务,显示屏幕增删,显示器的尺寸变化
| if (displayTransactionNeeded)
| processDisplayChangesLocked();
| processDisplayHotplugEventsLocked();
| mCurrentState.traverse(...)
| layer->updateTransformHint(hintDisplay->getTransformHint());//更新旋转提示
| if (mLayersAdded) // 在此之前的步骤[2] commitCreatedLayers 中设置的 true
| mLayersAdded = false;
| mVisibleRegionsDirty = true;//有脏区域,【用于步骤6计算脏区域】
| if (mLayersRemoved)// 处理被移除的Layer
| mLayersRemoved = false;
| mVisibleRegionsDirty = true;
| mDrawingState.traverseInZOrder(...)
| Region visibleReg;
| visibleReg.set(layer->getScreenBounds());
| invalidateLayerStack(layer, visibleReg);//更新DisplayDevice中原有的可视脏区
| //把Layer的添加以及删除从Current状态转为Drawing状态
| doCommitTransactions();
|-->SurfaceFlinger::doCommitTransactions()
| // 处理以及被移除的layer集合 mLayersPendingRemoval。释放buffer,从layersSortedByZ移除,加入到mOffscreenLayers
| for (const auto& l : mLayersPendingRemoval)
| l->latchAndReleaseBuffer();
| mCurrentState.layersSortedByZ.remove(l);
| mOffscreenLayers.emplace(l.get());
| mLayersPendingRemoval.clear();
| //【核心步骤】
| mDrawingState = mCurrentState;
| mCurrentState.colorMatrixChanged = false;
| if (mVisibleRegionsDirty)
| for (const auto& rootLayer : mDrawingState.layersSortedByZ)
| // 遍历所有的根layer,把所有子Layer的mCurrentChildren赋值给mDrawingChildren
| rootLayer->commitChildList();
| mDrawingChildren = mCurrentChildren;
| mDrawingParent = mCurrentParent;
| mDebugInTransaction = 0;
| // 如果还有待处理的事务,请求下一个SF vsync
| if (transactionFlushNeeded())
| setTransactionFlags(eTransactionFlushNeeded);
| mustComposite |= shouldCommit;
| //【5】、latchBuffers 相当于以前的handlePageFlip 流程
| //【如果有新的buffer的layer大于0,并且拿到了buffer,SurfaceFlinger::latchBuffers()函数返回true,执行 SurfaceFlinger::composite 】
| mustComposite |= latchBuffers();
|-->SurfaceFlinger::latchBuffers() //【详细内容,见 latchBuffers() 章节】
| layer->latchBuffer(visibleRegions, latchTime, expectedPresentTime)
| //父类Layer的 latchBuffer 返回 false, 子类只有 BufferLayer 重载了 latchBuffer
|-->BufferLayer.latchBuffer(bool& /*recomputeVisibleRegions*/, nsecs_t /*latchTime*/, nsecs_t /*expectedPresentTime*/)
| updateTexImage(recomputeVisibleRegions, latchTime, expectedPresentTime);
|-->BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nsecs_t latchTime,nsecs_t /*expectedPresentTime*/)
| //【6】、计算边界、脏区域
| updateLayerGeometry();
|-->SurfaceFlinger::updateLayerGeometry()
| if (mVisibleRegionsDirty) //【mVisibleRegionsDirty在有新的Layer增加时设置为 true 】
| /* 调用每个Layer的 computeBounds 方法
计算每个Layer的以下边界:
mSourceBounds 应用任何变换之前以及由其父对象裁剪之前的Layer边界。
mBounds Layer空间中的Layer边界。mSourceBounds 和 Layer的裁剪矩形的交集,再和其父空间交集
mScreenBounds Layer在屏幕上的空间。由 mBounds transform转换而来 */
| computeLayerBounds();
|-->SurfaceFlinger::computeLayerBounds()
| const FloatRect maxBounds = getMaxDisplayBounds();
| for (const auto& layer : mDrawingState.layersSortedByZ)
| layer->computeBounds(maxBounds, ui::Transform(), 0.f /* shadowRadius */);
| // mLayersPendingRefresh 参见步骤[5] latchBuffers()
| for (auto& layer : mLayersPendingRefresh)// mLayersPendingRefresh 存储中能拿到 buffer的layer
| Region visibleReg;
| visibleReg.set(layer->getScreenBounds());
| // 对每个包含当前layer的显示器的脏区域初始化为 Layer.mScreenBounds
| invalidateLayerStack(layer, visibleReg);
| // mLayersPendingRefresh这个集合表示有新的buffer更新,并且能拿到buffer的layer。
| // 在 SurfaceFlinger::latchBuffers()流程中添加,此时清空此集合
| mLayersPendingRefresh.clear();
| // 非开机阶段,mustComposite==true情况下将执行合成步骤 SurfaceFlinger::composite
| return mustComposite && CC_LIKELY(mBootStage != BootStage::BOOTLOADER);
latchBuffers()
- 因为使用 BufferStateLayer + BBQ , latchBuffer 流程相比Android12以前逻辑要少很多
// SurfaceFlinger.mLayersWithQueuedFrames 存储有新buffer的layer
// SurfaceFlinger.mLayersPendingRefresh 存储mLayersWithQueuedFrames中能拿到 buffer的layer。用于更新显示设备的脏区域
|-->SurfaceFlinger::latchBuffers()
| const nsecs_t latchTime = systemTime();// perfetto 会记录这个时间
| bool visibleRegions = false;// 用于 latchBuffer 的参数
| bool newDataLatched = false;
| // 【1、核心逻辑是把 有buffer更新的layer存储到set集合 mLayersWithQueuedFrames】
| mDrawingState.traverse(...)
| // layer 各种属性变化后都会设置 eTransactionNeeded 这个flag,比如尺寸,背景,位置,inputInfo、刷新率等等,几乎所有的变化都会设置eTransactionNeeded。
| if (layer->clearTransactionFlags(eTransactionNeeded) || mForceTransactionDisplayChange)
| // 赋值 mDrawingState.transform
| // mDrawingStateModified = mDrawingState.modified; mDrawingState.modified = false;
| const uint32_t flags = layer->doTransaction(0);
| if (flags & Layer::eVisibleRegion)
| mVisibleRegionsDirty = true;
| // layer有新buffer时,hasReadyFrame() 返回true
| if (layer->hasReadyFrame())
| // shouldPresentNow函数,对于 BufferStateLayer 而言,有buffer的来了,就返回true
| if (layer->shouldPresentNow(expectedPresentTime))
| //【2、把有新buffer的layer,加入set集合 mLayersWithQueuedFrames】
| mLayersWithQueuedFrames.emplace(layer);
| mForceTransactionDisplayChange = false;
| // 【3、mLayersWithQueuedFrames不为空,则调用集合中每个layer的 latchBuffer 函数】
| if (!mLayersWithQueuedFrames.empty())
| for (const auto& layer : mLayersWithQueuedFrames)
| // latchBuffer 判断是否需要重新计算显示区域,由参数visibleRegions带回结果
| //【4、获取buffer,并把 Layer.mDrawingState 中的属性变量转移到 BufferLayer.mBufferInfo 】
| // mBufferInfo 用于 Layer中获取各种buffer信息相关的get方法
| if (layer->latchBuffer(visibleRegions, latchTime, expectedPresentTime))
|-->BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime, nsecs_t expectedPresentTime)
| if (!fenceHasSignaled())
| // 【如果Fence还没有发送信号,请求 SF-vsync,并且函数返回,等一下次的vsync再处理这个buffer】
| mFlinger->onLayerUpdate();
| return false;
| BufferInfo oldBufferInfo = mBufferInfo;
| updateTexImage(recomputeVisibleRegions, latchTime, expectedPresentTime);
| // BufferStateLayer 和 以前使用的 BufferQueueLayer 是完全不同的步骤。大部分内容是debug用的
|-->BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nsecs_t latchTime, nsecs_t /*expectedPresentTime*/)
| const int32_t layerId = getSequence();// sequence,每个layer唯一,是个递增int
| //把 acquireFence 存储到 mFlinger->mTimeStats->mTimeStatsTracker[layerId].timeRecords[layerRecord.waitData].acquireFence
| mFlinger->mTimeStats->setAcquireFence(layerId, frameNumber, acquireFence);
| mFlinger->mTimeStats->setLatchTime(layerId, frameNumber, latchTime);
| // perfetto 相应的数据源配置启用的情况下,记录 Fence 和 latchTime
| mFlinger->mFrameTracer->traceFence(...);
| mFlinger->mFrameTracer->traceTimestamp(...);
| mDrawingStateModified = false;// 修改为false,对应于步骤1中 Layer.doTransaction
| updateActiveBuffer();
|-->BufferStateLayer::updateActiveBuffer()
| const State& s(getDrawingState());
| //mPendingBufferTransactions--
| // 调用到 latchBuffer 阶段,setBuffer 的事务就算处理完了,待处理的buffer数量计数器 mPendingBufferTransactions要减一
| //这里对应于SurfaceFlinger::setTransactionState函数中:mBufferCountTracker.increment(state.surface->localBinder());
| // mBufferCountTracker.increment 函数使 mPendingBufferTransactions 自增1
| decrementPendingBufferCount();
| // 把 mDrawingState 中的buffer、acquireFence、frameNumber 转移到 mBufferInfo
| mBufferInfo.mBuffer = s.buffer;
| mBufferInfo.mFence = s.acquireFence;
| mBufferInfo.mFrameNumber = s.frameNumber;
| // mCurrentFrameNumber = mDrawingState.frameNumber; mPreviousFrameNumber = mCurrentFrameNumber;
| updateFrameNumber();
|-->BufferStateLayer::updateFrameNumber()
| mPreviousFrameNumber = mCurrentFrameNumber;
| mCurrentFrameNumber = mDrawingState.frameNumber; return NO_ERROR;
| // 这个函数就是把 mDrawingState 中buffer相关信息的各种变量转移到 mBufferInfo 中
| // mBufferInfo.mDesiredPresentTime、mFenceTime、mFence、mTransform、mDataspace、mCrop、mScaleMode、mSurfaceDamage
| // mHdrMetadata、mApi、mTransformToDisplayInverse、mBufferSlot等等赋值
| gatherBufferInfo();
|-->BufferStateLayer::gatherBufferInfo()
| BufferLayer::gatherBufferInfo();
| const State& s(getDrawingState());
| mBufferInfo.mFence = s.acquireFence;
| mBufferInfo.mCrop = computeBufferCrop(s);
| mBufferInfo.mScaleMode = NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW;
| mBufferInfo.mBufferSlot = mHwcSlotGenerator->getHwcCacheSlot(s.clientCacheId);
| //....
| // 后边的代码是判断 是否需要重新计算显示区域
| // 大致情况是:当前是第一个buffer、裁剪区域变化了,旋转变了,缩放变了,宽高变了,透明度变了,mTransformToDisplayInverse变了
| // 以上情况都需要重新计算显示区域
| if(oldBufferInfo.mBuffer == nullptr || mBufferInfo.mCrop != oldBufferInfo.mCrop ....)
| | recomputeVisibleRegions = true;
| return true;
| //【5、如果 latchBuffer 返回true,把layer加入向量集合 mLayersPendingRefresh 】
| // 依据 latchBuffer 逻辑,latchBuffer 返回false,通常是由于 Fence 还没有发送信号。当然还有其他细节原因,这里未贴出代码。
| //【可以说,mLayersPendingRefresh 保存了GPU绘制已经完成的layer】
| mLayersPendingRefresh.push_back(layer);
| newDataLatched = true;
| // Layer.surfaceDamageRegion = mBufferInfo.mSurfaceDamage;
| layer->useSurfaceDamage();
| //回到 SurfaceFlinger::latchBuffers() 函数
| // latchBuffer 函数,由参数 visibleRegions 返回 是否需要重新计算显示区域
| // 这里把结果添加到 mVisibleRegionsDirty 变量中
| mVisibleRegionsDirty |= visibleRegions;
| // 如果有新的buffer的layer大于0,并且 拿到了buffer,
| // 那么SurfaceFlinger::latchBuffers()函数返回true,表示需要执行合成步骤 SurfaceFlinger::composite
| //【6、如果有新的buffer的layer数量大于0,并且 拿到了buffer,SurfaceFlinger::latchBuffers()函数返回true,执行 SurfaceFlinger::composite 】
| return !mLayersWithQueuedFrames.empty() && newDataLatched;
SurfaceFlinger::composite
SurfaceFlinger::composite(nsecs_t frameTime, int64_t vsyncId)
| // 【1】准备合成的参数
| compositionengine::CompositionRefreshArgs refreshArgs;
| /*
SmallMap<IBinder, DisplayDevice> mDisplays;
合成是以 mDisplays 元素中的顺序去合成的
内置的显示器,是在开机的时候加入的,因此按照顺序合成的话,内置显示器要优先于 外部显示器 和 虚拟显示器
*/
| const auto& displays = FTL_FAKE_GUARD(mStateLock, mDisplays);
| // outputs 为Output的vector
| refreshArgs.outputs.reserve(displays.size());// 增加容器的大小为显示屏的大小
| // 遍历显示设备
| for (const auto& [_, display] : displays)
| // DisplayDevice.mCompositionDisplay 类型 android::compositionengine::Display,继承 Output
| // outputs 代表所有需要合成的显示器
| refreshArgs.outputs.push_back(display->getCompositionDisplay());//【所有需要合成工作的显示设备】
| // 遍历 mDrawingState.layersSortedByZ,这个 layersSortedByZ 存储了所有的的layer
| // 以Z轴顺序遍历 mDrawingState.layersSortedByZ ,从底层开始遍历
| mDrawingState.traverseInZOrder(...)
| // 并非所有种类的layer都能通过 Layer.getCompositionEngineLayerFE() 拿到LayerFE对象。是有显示界面的才有返回对象
| // 父类 Layer.getCompositionEngineLayerFE() 返回 nullptr
| // 只有 BufferLayer 和 EffectLayer 实现了这个方法
| // getCompositionEngineLayerFE 这个函数就是返回layer自身,并强转为Layer父类 compositionengine::LayerFE 类型
| if (auto layerFE = layer->getCompositionEngineLayerFE())
| // refreshArgs.layers 是 std::vector<sp<compositionengine::LayerFE>> 类型
| // 这个是以 Z 轴顺序添加到 layers 中的
| refreshArgs.layers.push_back(layerFE);//【添加所有参与合成的layer】
| // mLayersWithQueuedFrames 是有新的帧数据的Layer
| // 把有帧数据的Layer转移到 refreshArgs.layersWithQueuedFrames
| refreshArgs.layersWithQueuedFrames.reserve(mLayersWithQueuedFrames.size());
| mCompositionEngine->present(refreshArgs);
| for (auto layer : mLayersWithQueuedFrames)
| if (auto layerFE = layer->getCompositionEngineLayerFE())
| refreshArgs.layersWithQueuedFrames.push_back(layerFE);
| // 把准备好的合成的参数,传入 CompositionEngine 开始合成工作
| mCompositionEngine->present(refreshArgs);
|-->CompositionEngine::present(CompositionRefreshArgs& args)
| // 【2】如果存在新的buffer处理,mNeedsAnotherUpdate设置为true,
| preComposition(args);
| // LayerFESet 是 unordered_set 类型
| LayerFESet latchedLayers; // using LayerFESet = std::unordered_set<sp<LayerFE>, LayerFESpHash>;
| // 【3】遍历所有需要合成输出的显示设备 【核心是把显示区域相关数据转存到 OutputLayer 的mState对象】
| for (const auto& output : args.outputs)// 第一层循环,遍历所有的显示设备
| // 调用每个显示设备的 prepare 方法
| output->prepare(args, latchedLayers);
|-->Output::prepare(const compositionengine::CompositionRefreshArgs& refreshArgs, LayerFESet& geomSnapshots)
| rebuildLayerStacks(refreshArgs, geomSnapshots);
|-->Output::rebuildLayerStacks(const compositionengine::CompositionRefreshArgs& refreshArgs, LayerFESet& layerFESet)
| auto& outputState = editState();// editState() 返回 OutputCompositionState 类型的 Output.mState;
| compositionengine::Output::CoverageState coverage{layerFESet};
| // 1、从顶层到底层遍历所有参与合成的Layer,累积计算 覆盖区域、完全不透明区域、脏区域
| // 2、存储当前层的显示区域、排除透明区域的显示区域、被覆盖区域、显示器空间显示区域、阴影区域等到 当前显示设备上的OutputLayer的mState对象
| collectVisibleLayers(refreshArgs, coverage);
|-->Output::collectVisibleLayers(CompositionRefreshArgs& refreshArgs,Output::CoverageState& coverage)
| // 从顶层到底层开始遍历所有Layer,以便于计算哪些可以显示。 这个过程中,每层的显示区域是不断减少的,相反,覆盖区域是不断增大的
| for (auto layer : reversed(refreshArgs.layers))
| // 1、从顶层到底层遍历所有参与合成的Layer,累积计算 覆盖区域、完全不透明区域、脏区域
| // 2、【如果显示设备没有对应的 OutputLayer,创建 OutputLayer 同时创建 HWCLayer,并作为 OutputLayer.mState 的成员】
| // 3、存储当前层的显示区域、排除透明区域的显示区域、被覆盖区域、显示器空间显示区域、阴影区域等到 当前显示设备上的 OutputLayer 的mState对象
| //OutputLayer.mState.visibleRegion、visibleNonTransparentRegion、coveredRegion、outputSpaceVisibleRegion、shadowRegion
| //outputSpaceBlockingRegionHint
| // 4、Output.mPendingOutputLayersOrderedByZ.emplace_back(std::move(outputLayer));
| ensureOutputLayerIfVisible(layer, coverage);
| // setReleasedLayers 函数会遍历 Output.mCurrentOutputLayersOrderedByZ
| // 此时 Output.mCurrentOutputLayersOrderedByZ 中会在当前vsync显示的layer都转移到了mPendingOutputLayersOrderedByZ
| // 这里会把mCurrentOutputLayersOrderedByZ余下的Layer中,在当前vsync,入队新的buffer的layer放入到 Output.mReleasedLayers 中
| // 就是说,mReleasedLayers是一些即将移除的的layer,但是当前vsync还在生产帧数据的layer
| setReleasedLayers(refreshArgs);
| // 把 Output.mPendingOutputLayersOrderedByZ 转到 Output.mCurrentOutputLayersOrderedByZ //使用的move赋值
| // 【每个vsync内,Output中存储的OutputLayer,都是最新即将要显示的Layer】
| finalizePendingOutputLayers();
| const ui::Transform& tr = outputState.transform;
| Region undefinedRegion{outputState.displaySpace.getBoundsAsRect()};
| // 整个显示空间 减去 所有Layer的不透明覆盖区域 为未定义的区域
| undefinedRegion.subtractSelf(tr.transform(coverage.aboveOpaqueLayers));
| outputState.undefinedRegion = undefinedRegion;
| // 把计算好的脏区域传入 outputState.dirtyRegion // Output::postFramebuffer() 中被清空
| outputState.dirtyRegion.orSelf(coverage.dirtyRegion);
| // 【4】把状态属性转移到 BufferLayer.mCompositionState。这个对象是 compositionengine::LayerFECompositionState 类型
| // 可以通过 LayerFE.getCompositionState() 获取合成状态对象。不算EffectLayer的话,其实就是就是获取 BufferLayer.mCompositionState
| updateLayerStateFromFE(args);
|-->CompositionEngine::updateLayerStateFromFE(CompositionRefreshArgs& args)
| // 从前端layer中更新合成状态
| for (const auto& output : args.outputs)
| output->updateLayerStateFromFE(args);
|-->Output::updateLayerStateFromFE(const CompositionRefreshArgs& args)
| // SurfaceFlinger.mVisibleRegionsDirty 为true时, args.updatingGeometryThisFrame=true
| // 有新的Layer增加时 mVisibleRegionsDirty 为true
| layer->getLayerFE().prepareCompositionState(args.updatingGeometryThisFrame ? LayerFE::StateSubset::GeometryAndContent
: LayerFE::StateSubset::Content);
|-->Layer::prepareCompositionState(compositionengine::LayerFE::StateSubset subset)
| // 根据 StateSubset 的类型选择以下函数的几种组合去执行
| /* prepareBasicGeometry更新BufferLayer状态对象LayerFECompositionState(mCompositionState)的以下属性:
outputFilter、isVisible、isOpaque、shadowRadius、contentDirty、geomLayerBounds、geomLayerTransform、
geomInverseLayerTransform、transparentRegionHint、blendMode、alpha、backgroundBlurRadius、blurRegions、stretchEffect
同时设置 Layer.contentDirty = false;*/
| prepareBasicGeometryCompositionState();
/*更新BufferLayer状态对象mCompositionState的以下属性:
geomBufferSize、geomContentCrop、geomCrop、geomBufferTransform、
geomBufferUsesDisplayInverseTransform|geomUsesSourceCrop、isSecure、metadata
就是集合图形相关的属性*/
| prepareGeometryCompositionState();
/* preparePerFrameCompositionState更新BufferLayer状态对象mCompositionState的以下属性:
compositionType、hdrMetadata、compositionType、buffer、bufferSlot、acquireFence、frameNumber、sidebandStreamHasFrame
forceClientComposition、isColorspaceAgnostic、dataspace、colorTransform、colorTransformIsIdentity、surfaceDamage
hasProtectedContent、dimmingEnabled、isOpaque、stretchEffect、blurRegions、backgroundBlurRadius、fps
就是帧数据相关的属性*/
| preparePerFrameCompositionState();
|
| // 调用每个显示设备的 present 方法
| for (const auto& output : args.outputs)
| output->present(args);
|-->Output::present(const compositionengine::CompositionRefreshArgs& refreshArgs)
| // 2.4.1 更新Output合成状态对象OutputCompositionState
| // Output.mState的 colorMode、dataspace、renderIntent、targetDataspace 属性
| updateColorProfile(refreshArgs);
| // 2.4.2 更新 OutputLayer.mState.forceClientComposition、displayFrame、sourceCrop、bufferTransform、dataspace
| // 【显示区域相关属性已经在rebuildLayerStacks阶段更新完成,至此OutputLayer.mState的属性基本全更新完了】
| updateCompositionState(refreshArgs);
|-->Output::updateCompositionState(const compositionengine::CompositionRefreshArgs& refreshArgs)
| // 查找最顶层使用背景模糊的 OutputLayer
| mLayerRequestingBackgroundBlur = findLayerRequestingBackgroundComposition();
| // 如果有 OutputLayer 使用了背景模糊,则必须使用 GPU 合成
| bool forceClientComposition = mLayerRequestingBackgroundBlur != nullptr;
| for (auto* layer : getOutputLayersOrderedByZ())
| /* 更新每个OutputLayer OutputLayerState 的以下属性
| forceClientComposition、displayFrame、sourceCrop、bufferTransform、bufferTransform、dataspace */
| layer->updateCompositionState(refreshArgs.updatingGeometryThisFrame,refreshArgs.devOptForceClientComposition ||
| forceClientComposition, refreshArgs.internalDisplayRotationFlags)
| // 到最顶层使用背景模糊的 OutputLayer 之前都强制使用 GPU 合成
| if (mLayerRequestingBackgroundBlur == layer)
| | forceClientComposition = false;
| // 2.4.3
| planComposition();
|-->Output::planComposition()
| // 需要 ro.surface_flinger.enable_layer_caching 这个属性为true,mLayerCachingEnabled=true,然后才会启用 Planner
| // Planner 似乎还未启用,目前查几台机器都未启用
| if (!mPlanner || !getState().isEnabled)
| return;
| // 把Layer扁平化到数据结构 compositionengine::impl::OutputLayerCompositionState.overrideInfo
| // 缓存layer,扁平化到override中,下次再用其中的数据。TODO:似乎还未启用,暂时忽略
| mPlanner->plan(getOutputLayersOrderedByZ());
| // 2.4.4 把状态属性写入HWC待执行的缓存,等待执行
| writeCompositionState(refreshArgs);
|-->Output::writeCompositionState(const compositionengine::CompositionRefreshArgs& refreshArgs)
| // 遍历当前显示器的 OutputLayer
| for (auto* layer : getOutputLayersOrderedByZ())
| // 前边一大段是 透视图层 的处理
| // 如果上一个Layer的buffer和当前的Layer的buffer一样,那么忽略当前Layer
| // 下面直接看主逻辑
| layer->writeStateToHWC(includeGeometry, skipLayer, z++, overrideZ, isPeekingThrough);
|-->OutputLayer::writeStateToHWC(bool includeGeometry, bool skipLayer, uint32_t z,bool zIsOverridden, bool isPeekingThrough)
| const auto& state = getState();
| if (!state.hwc) return; //如果没有HWC接口,直接返回
| auto& hwcLayer = (*state.hwc).hwcLayer;
| if (!hwcLayer) return; // 如果没有 hwcLayer 直接返回
| // 获取 Layer 的 LayerFECompositionState ,只有 BufferLayer和 EffectLayer 有
| const auto* outputIndependentState = getLayerFE().getCompositionState();
| if (!outputIndependentState) return;
| // 合成类型
| auto requestedCompositionType = outputIndependentState->compositionType;
| // 有忽略的layer,新增的layer
| if (... skipLayer || includeGeometry)
| // 写入HWC依赖显示设备的几何图形信息
| // HWC2::Layer.setDisplayFrame、setSourceCrop、setZOrder、setTransform
| writeOutputDependentGeometryStateToHWC(hwcLayer.get(), requestedCompositionType, z);
| // 写入HWC不依赖显示设备的几何图形信息
| // HWC2::Layer.setBlendMode、setPlaneAlpha、setLayerGenericMetadata
| // skipLayer 为true的话,alpha=0.0f 颜色设置为完全透明
| writeOutputIndependentGeometryStateToHWC(hwcLayer.get(), *outputIndependentState, skipLayer);
| // 写入HWC依赖显示设备的每个帧状态
| // HWC2::Layer.etVisibleRegion、setBlockingRegion、setDataspace、setBrightness
| writeOutputDependentPerFrameStateToHWC(hwcLayer.get());
| // 写入HWC不依赖显示设备的每帧状态
| // HWC2::Layer.setColorTransform、setSurfaceDamage、setPerFrameMetadata、setBuffer
| writeOutputIndependentPerFrameStateToHWC(hwcLayer.get(), *outputIndependentState, requestedCompositionType, skipLayer);
| // 写入合成类型 HWC2::Layer.setCompositionType
| writeCompositionTypeToHWC(hwcLayer.get(), requestedCompositionType, isPeekingThrough, skipLayer);
| // 2.4.5 设置显示设备的颜色矩阵,做颜色变换,色盲、护眼模式等
| setColorTransform(refreshArgs);
| // 2.4.6 给虚拟显示屏用的。正常主屏使用 FramebufferSurface ,啥事也不做
| beginFrame();
| GpuCompositionResult result;
| // 是否可以预测合成策略--Android 13 新增
| // 去掉一些小概率原因,总结:如果上次不全是硬件合成,且存在GPU合成Layer时,返回true
| const bool predictCompositionStrategy = canPredictCompositionStrategy(refreshArgs);
| if (predictCompositionStrategy)
| // 异步执行 chooseCompositionStrategy --Android 13 新增
| // 就是 chooseCompositionStrategy 和 GPU合成 并行执行。用以节约时间
| result = prepareFrameAsync(refreshArgs);
| else
| //核心逻辑还是确认使用 客户端合成 还是 使用硬件合成
| prepareFrame();//【转“Output::prepareFrame()”章节】
|-->Output::prepareFrame()// 详情参见:prepareFrame() 章节
| auto& outputState = editState();
| std::optional<android::HWComposer::DeviceRequestedChanges> changes;
| bool success = chooseCompositionStrategy(&changes);//选择合成策略
| resetCompositionStrategy();// 重置合成策略的变量
| outputState.previousDeviceRequestedChanges = changes;
| outputState.previousDeviceRequestedSuccess = success;
| if (success)
| applyCompositionStrategy(changes);//应用合成策略
| finishPrepareFrame();// 用于虚拟屏
| //继续 Output::present(const compositionengine::CompositionRefreshArgs& refreshArgs)
| devOptRepaintFlash(refreshArgs);// doDebugFlashRegions当打开开发者选项中的“显示Surface刷新”时,额外为产生变化的图层绘制闪烁动画
| // GPU 合成,新增了一些对 prepareFrameAsync 结果的处理逻辑
| finishFrame(refreshArgs, std::move(result));//【转“Output::finishFrame”章节】
| //【转“Output::postFramebuffer()”】
| postFramebuffer();// postFramebuffer 函数就是告诉HWC开始做最后的合成了,并显示。获取释放fence,
| // 渲染最新的 cached sets,需要开启了Planner。TODO:渲染设置了预期显示时间的buffer?
| renderCachedSets(refreshArgs);
| postFrame();// 没啥东西输出log
| postComposition();// 杂七杂八的合成后处理,对于 BufferStateLayer 最终要的是 releasePendingBuffer
|-->SurfaceFlinger::postComposition()
| // 省略一大段内容
| for (const auto& layer: mLayersWithQueuedFrames)
| // 都是更新 FrameTracker、TimeStats 这些
| layer->onPostComposition(display, glCompositionDoneFenceTime,mPreviousPresentFences[0].fenceTime, compositorTiming);
| layer->releasePendingBuffer(/*dequeueReadyTime*/ now);
|-->BufferStateLayer::releasePendingBuffer(nsecs_t dequeueReadyTime)
| for (auto& handle : mDrawingState.callbackHandles)
| if (handle->releasePreviousBuffer && mDrawingState.releaseBufferEndpoint == handle->listener)
| // 这个 mPreviousReleaseCallbackId 在 BufferStateLayer::updateActiveBuffer() 赋值
| // mPreviousReleaseCallbackId = {getCurrentBufferId(), mBufferInfo.mFrameNumber};
| handle->previousReleaseCallbackId = mPreviousReleaseCallbackId;
| break;
| // 把 callback 加入 TransactionCallbackInvoker::mCompletedTransactions
| mFlinger->getTransactionCallbackInvoker().addCallbackHandles(mDrawingState.callbackHandles, jankData);
| //【这里就是通过binder通信,回调到 APP 端BBQ执行 releaseBuffer 了】
| mTransactionCallbackInvoker.sendCallbacks(false /* onCommitOnly */);
|-->BpTransactionCompletedListener::onTransactionCompleted(android::ListenerStats)
| // 如果还有新的buffer,需要请求新的vsync
| if (mCompositionEngine->needsAnotherUpdate())
| scheduleCommit(FrameHint::kNone)
Output::prepareFrame()
- 所谓 Client 合成,就是 HWC 的客户端 SurfaceFlinger 去合成,SurfaceFlinger 合成的话使用GPU合成,因此 Client 合成,即GPU合成
- prepareFrame 核心逻辑是确认使用 客户端合成 还是 使用硬件合成
- prepareFrame 函数中同 HWC服务 交互去确认是否有客户端合成,如果没有客户端合成,并可以忽略验证,那么会直接显示。流程到这里基本结束了
CompositionEngine::present(CompositionRefreshArgs& args)
| //....
|-->Output::prepareFrame()
| auto& outputState = editState();
| std::optional<android::HWComposer::DeviceRequestedChanges> changes;
| bool success = chooseCompositionStrategy(&changes);
|-->Display::chooseCompositionStrategy(std::optional<android::HWComposer::DeviceRequestedChanges>* outChanges)
| // 在最近的一次合成中如果有任意一个layer是 GPU 合成,则返回true
| const bool requiresClientComposition = anyLayersRequireClientComposition();
| status_t result = hwc.getDeviceCompositionChanges(*halDisplayId, requiresClientComposition,...outChanges);
|-->HWComposer::getDeviceCompositionChanges(HalDisplayId displayId, bool frameUsesClientComposition,...outChanges)
| // 如果有需要GPU合成的layer, canSkipValidate=false;
| // 没有需要GPU合成的layer,如果Composer支持获得预期的展示时间,canSkipValidate=true;
| // 没有需要GPU合成的layer,Composer 也不支持获得预期的当前时间,只有当我们知道我们不会提前呈现时,我们才能跳过验证。
| const bool canSkipValidate = {...};
| if (canSkipValidate)
| sp<Fence> outPresentFence;
| uint32_t state = UINT32_MAX;
| //如果可以跳过验证,则直接在屏幕上显示内容,否则执行 validate(HWC 检查各个图层的状态,并确定如何进行合成)
| // numTypes返回合成类型需要变更的layer数量,numRequests 返回需要做getDisplayRequests请求的layer数量
| hwcDisplay->presentOrValidate(expectedPresentTime, &numTypes, &numRequests, &outPresentFence, &state);
| if (state == 1)
| // 跳过了验证环节,直接显示了。这时直接返回
| std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
| hwcDisplay->getReleaseFences(&releaseFences);// 显示成功,会返回 Fence fd
| displayData.releaseFences = std::move(releaseFences);
| displayData.lastPresentFence = outPresentFence;
| displayData.validateWasSkipped = true;
| displayData.presentError = error;
| return NO_ERROR;
| else
| // HWC 检查各个图层的状态,并确定如何进行合成
| // numTypes返回合成类型需要变更的layer数量,numRequests 返回需要做getDisplayRequests请求的layer数量
| hwcDisplay->validate(expectedPresentTime, &numTypes, &numRequests);
| // composer3::Composition 为枚举类型:
| //{ INVALID = 0, CLIENT = 1, DEVICE = 2, SOLID_COLOR = 3, CURSOR = 4, SIDEBAND = 5, DISPLAY_DECORATION = 6,};
| std::unordered_map<HWC2::Layer*, composer3::Composition> changedTypes;
| changedTypes.reserve(numTypes);// map扩容为numTypes
| // changedTypes 返回 map<Layer,Composition> 包含所有 与上次调用validateDisplay之前设置的合成类型不同的合成类型的Layer
| hwcDisplay->getChangedCompositionTypes(&changedTypes);
| // 枚举 hal::DisplayRequest{FLIP_CLIENT_TARGET = 1u , WRITE_CLIENT_TARGET_TO_OUTPUT = 2u ,}
| // 0 表示:指示客户端提供新的客户端目标缓冲区,即使没有为客户端合成标记任何layers。
| // 1 表示:指示客户端将客户端合成的结果直接写入虚拟显示输出缓冲区。
| auto displayRequests = static_cast<hal::DisplayRequest>(0);
| // 枚举 hal::LayerRequest{CLEAR_CLIENT_TARGET = 1 << 0, }
| // 1表示:客户端必须在该layer所在的位置使用透明像素清除其目标。如果必须混合该层,客户端可能会忽略此请求。
| std::unordered_map<HWC2::Layer*, hal::LayerRequest> layerRequests;
| layerRequests.reserve(numRequests); // map扩容为 numRequests
| // 返回 hal::DisplayRequest 和 每个Layer的 hal::LayerRequest 类型,用于指导 SurfaceFlinger 的GPU合成
| hwcDisplay->getRequests(&displayRequests, &layerRequests);
| // 返回client target属性,这个新增的,目前可能仅仅实现了亮度、调光、数据格式、数据空间相关属性
| DeviceRequestedChanges::ClientTargetProperty clientTargetProperty;
| hwcDisplay->getClientTargetProperty(&clientTargetProperty);
| // 组合成 DeviceRequestedChanges 结构体,返回
| outChanges->emplace(DeviceRequestedChanges{std::move(changedTypes), std::move(displayRequests),
std::move(layerRequests), std::move(clientTargetProperty)});
| // 注释这么说的:此函数相当于从getChangedCompositionTypes请求更改后的类型,在相应的层上设置这些类型,然后再次调用validateDisplay。
| // 但是,看源码感觉注释说的不大对,这里仅仅是把这个成员设为true: DisplayCommand::acceptDisplayChanges = true
| // 注释说的应该是命令缓存发送到HWC后,执行的流程
| hwcDisplay->acceptChanges();
| //只有正常执行会返回 true,其他,显示设备未连接、没有硬件合成、getDeviceCompositionChanges返回false,那么会 return false;
| return true;
| resetCompositionStrategy();
|-->Output::resetCompositionStrategy()
| auto& outputState = editState();
| // 先重置这些变量,在后续的流程中会使用。相当于设置默认值,因为对基本的Output实现只能进行客户端合成
| outputState.usesClientComposition = true;
| outputState.usesDeviceComposition = false;
| outputState.reusedClientComposition = false;
| // 这个previousDeviceRequestedChanges变量在 Output::canPredictCompositionStrategy 函数中用来判断是否预测合成策略
| outputState.previousDeviceRequestedChanges = changes;
| outputState.previousDeviceRequestedSuccess = success;
| if (success)// HWComposer::getDeviceCompositionChanges 执行错误,不会进入到这里。比如IComposer任意一接口调用失败
| applyCompositionStrategy(changes);
|-->Display::applyCompositionStrategy(const std::optional<DeviceRequestedChanges>& changes)
| if (changes)
| // 对每个 OutputLayer 应用HWC设备要求的合成类型更改
| applyChangedTypesToLayers(changes->changedTypes);
|-->Display::applyChangedTypesToLayers(const ChangedTypes& changedTypes)
| for (auto* layer : getOutputLayersOrderedByZ())
| auto hwcLayer = layer->getHwcLayer();// 获取 OutputLayer中存储的 HWC::Layer
| auto it = changedTypes.find(hwcLayer);
| if (it == changedTypes.end()) continue;
| layer->applyDeviceCompositionTypeChange(
static_cast<aidl::android::hardware::graphics::composer3::Composition>(it->second));
| // 应用HWC设备要求的合成类型更改
|-->OutputLayer::applyDeviceCompositionTypeChange(Composition compositionType)
| auto& state = editState();
| auto& hwcState = *state.hwc;
| // 这个 OutputLayerCompositionState::Hwc.hwcCompositionType 用于预测合成策略 Output::canPredictCompositionStrategy
| hwcState.hwcCompositionType = compositionType;//这个代表最近使用的合成类型
| applyDisplayRequests(changes->displayRequests);
|-->Display::applyDisplayRequests(const DisplayRequests& displayRequests)
| auto& state = editState();
| // 如果 displayRequests 包含flag FLIP_CLIENT_TARGET,则 flipClientTarget=true
| // 如果为true,则在执行客户端合成时应提供新的客户端目标(client target)缓冲区
| state.flipClientTarget = (static_cast<uint32_t>(displayRequests)
& static_cast<uint32_t>(hal::DisplayRequest::FLIP_CLIENT_TARGET)) != 0;
| applyLayerRequestsToLayers(changes->layerRequests);
|-->Display::applyLayerRequestsToLayers(const LayerRequests& layerRequests)
| for (auto* layer : getOutputLayersOrderedByZ())
| // OutputLayer.editState().clearClientTarget = false;
| layer->prepareForDeviceLayerRequests();
| auto hwcLayer = layer->getHwcLayer();
| if (auto it = layerRequests.find(hwcLayer); it != layerRequests.end())
| // 应用HWC的layer请求
| layer->applyDeviceLayerRequest(static_cast<Hwc2::IComposerClient::LayerRequest>(it->second));
|-->OutputLayer::applyDeviceLayerRequest(hal::LayerRequest request)
| if(request== hal::LayerRequest::CLEAR_CLIENT_TARGET:)
| // 客户端合成时,该layer所在的位置使用透明像素清除其目标
| editState().clearClientTarget = true;
| applyClientTargetRequests(changes->clientTargetProperty);
|-->Display::applyClientTargetRequests(const ClientTargetProperty& clientTargetProperty)
| editState().dataspace = static_cast<ui::Dataspace>(clientTargetProperty.clientTargetProperty.dataspace);
| editState().clientTargetBrightness = clientTargetProperty.brightness;
| editState().clientTargetDimmingStage = clientTargetProperty.dimmingStage;
| getRenderSurface()->setBufferDataspace(editState().dataspace);
| getRenderSurface()->setBufferPixelFormat(static_cast<ui::PixelFormat>(clientTargetProperty.clientTargetProperty.pixelFormat));
| auto& state = editState();
| // anyLayersRequireClientComposition:
| // Output 中有任意一个 OutputLayer 状态对象的 hwc->hwcCompositionType 为 Composition::CLIENT,则返回true
| // 就是 OutputLayer.getState().hwc->hwcCompositionType == Composition::CLIENT
| // 即,当前显示设备中有任意一个Layer的合成为 客户端合成,则 Output.getState().usesClientComposition = true;
| state.usesClientComposition = anyLayersRequireClientComposition();// true表示有使用客户端合成
| // 当前显示设备的当前帧中,不是全部使用了客户端合成,则 usesDeviceComposition = true;
| // 表示当前显示设备的当前帧可能完使用硬件合成,也可能是两者都有
| state.usesDeviceComposition = !allLayersRequireClientComposition();// true表示有使用硬件合成
| // 以上两个变量将用于接下来的 Output::finishPrepareFrame()流程,虚拟屏的prepareFrame方法 和 finishFrame 流程
| finishPrepareFrame();
| // 用于虚拟屏
|-->Output::finishPrepareFrame()
| const auto& state = getState();
| if (mPlanner)
| mPlanner->reportFinalPlan(getOutputLayersOrderedByZ());
| // 准备帧进行渲染----这里只有 虚拟屏幕 实现了prepareFrame,其他什么也不做
| mRenderSurface->prepareFrame(state.usesClientComposition, state.usesDeviceComposition);
Output::finishFrame
- 处理Client合成(GPU合成)
Output::present(const compositionengine::CompositionRefreshArgs& refreshArgs)
//...
finishFrame(refreshArgs, std::move(result));// GPU 合成
// result 为 prepareFrameAsync 的执行结果
|-->Output::finishFrame(const CompositionRefreshArgs& refreshArgs, GpuCompositionResult&& result)
| const auto& outputState = getState();
/*
outputState.strategyPrediction
走 prepareFrame() 为 DISABLED,表示不使用预测合成策略
走 prepareFrameAsync() 为 SUCCESS 或者 FAIL 表示合预测成功或者失败
*/
| if (outputState.strategyPrediction == CompositionStrategyPredictionState::SUCCESS)
| //如果预测成功,则已经执行完 GPU 合成了,不必再dequeueRenderBuffer了
| optReadyFence = std::move(result.fence);
| else // prepareFrameAsync 中预测失败了
| // 虽然预测失败了,但是已经dequeued的buffer,会通过GpuCompositionResult传送过来,拿来复用
| if (result.bufferAvailable())
| buffer = std::move(result.buffer);
| bufferFence = std::move(result.fence);
| else // dequeueRenderBuffer失败,连dequeued的buffer都没有,那就重走一遍 prepareFrameAsync GPU 合成的那块逻辑。当然,也可能就没有执行 prepareFrameAsync
| // BufferQueue熟悉的配方 dequeueBuffer
| dequeueRenderBuffer(&bufferFence, &buffer))
|-->Output::dequeueRenderBuffer(unique_fd* bufferFence, std::shared_ptr<ExternalTexture>* tex)
| const auto& outputState = getState();
| // 有使用客户端合成 或者 设置了 flipClientTarget 都需要进行 GPU 合成
| if (outputState.usesClientComposition || outputState.flipClientTarget)
| //【dequeueBuffer,然后把dequeue的Buffer包装为 ExternalTexture】
| *tex = mRenderSurface->dequeueBuffer(bufferFence);
|-->RenderSurface::dequeueBuffer(base::unique_fd* bufferFence)
| int fd = -1;
| ANativeWindowBuffer* buffer = nullptr;
| // 调用 Surface.dequeueBuffer
| mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buffer, &fd);
| // GraphicBuffer 继承 ANativeWindowBuffer
| // GraphicBuffer::from 把父类ANativeWindowBuffer强制转换为子类 GraphicBuffer
| sp<GraphicBuffer> newBuffer = GraphicBuffer::from(buffer);
| // ExternalTexture 使用 RenderEngine 代表客户端管理GPU图像资源。
| // 渲染引擎不是GLES的话,在 ExternalTexture 构造函数中把GraphicBuffer映射到RenderEngine所需的GPU资源中。
| mTexture = new ExternalTexture(newBuffer,mCompositionEngine.getRenderEngine(),WRITEABLE)
| *bufferFence = base::unique_fd(fd);//返回fence fd
| return mTexture;// 返回纹理类
| // 执行GPU合成
| optReadyFence = composeSurfaces(Region::INVALID_REGION, refreshArgs, buffer, bufferFence);
| // BufferQueue熟悉的配方 queueBuffer
| mRenderSurface->queueBuffer(std::move(*optReadyFence));
|-->RenderSurface::queueBuffer(base::unique_fd readyFence)
| // 调用 Surface.queueBuffer
| mNativeWindow->queueBuffer(mNativeWindow.get(),mTexture->getBuffer()->getNativeBuffer(),dup(readyFence));
| // mDisplaySurface:
| // 对于非虚拟屏是 FramebufferSurface,其包装消费者、继承 DisplaySurface;对于虚拟屏是 VirtualDisplaySurface
| mDisplaySurface->advanceFrame();
|-->FramebufferSurface::advanceFrame()//就是调用 FramebufferSurface::nextBuffer
| uint32_t slot = 0;
| sp<GraphicBuffer> buf;
| sp<Fence> acquireFence(Fence::NO_FENCE);
| Dataspace dataspace = Dataspace::UNKNOWN;
| nextBuffer(slot, buf, acquireFence, dataspace);
| // 这里核心是调用 setClientTarget ,把 客户端合成输出的缓冲区句柄 传递给 HWC。
| // 当然,目前还未真正传递到HWC,只是写到命令缓冲区。需要等待执行 present 才执行传递
|-->FramebufferSurface::nextBuffer(uint32_t& outSlot,sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence,Dataspace& outDataspace)
| mHwc.setClientTarget(mDisplayId, outSlot, outFence, outBuffer, outDataspace);
Output::postFramebuffer()
- 送显 + 获取 Layer releaseFence
- 这个 releaseFence 并不是当前送显的fence,是上一帧的
- Layer releaseFence 会合并 GPU合成的fence
- 就是说APP dequeuebuffer拿到新buffer后,需要等待GPU合成完成 + HWC使用当前Layer buffer替换上一个buffer(app dequque的buffer)后,才能在这个新buffer上填充数据
//先看下结构体 FrameFences
/*
struct FrameFences {
// 这个fence,在当前帧在屏幕上显现,或者发送到面板内存时,会发送信号
sp<Fence> presentFence{Fence::NO_FENCE};
// GPU 合成的buffer的消费者 acquire fence;代表GPU合成是否完成;(注:GPU绘制的acquire fence,在latchBuffer阶段已经判断了。)
sp<Fence> clientTargetAcquireFence{Fence::NO_FENCE};
// 所有Layer的fence;在先前呈现的buffer被读取完成后发送信息;HWC生成
std::unordered_map<HWC2::Layer*, sp<Fence>> layerFences;
};
*/
Output::postFramebuffer()
| auto frame = presentAndGetFrameFences();
|-->Display::presentAndGetFrameFences()
| // 【1】这里就是赋值 FrameFences.clientTargetAcquireFence
| auto fences = impl::Output::presentAndGetFrameFences();
|-->Output::presentAndGetFrameFences()
| if (getState().usesClientComposition)
| result.clientTargetAcquireFence = mRenderSurface->getClientTargetAcquireFence();
| // 1、【在屏幕上呈现当前显示内容(如果是虚拟显示,则显示到输出缓冲区中)】
| // 2、获取device上所有layer的 ReleaseFence
| hwc.presentAndGetReleaseFences(*halDisplayIdOpt, getState().earliestPresentTime, getState().previousPresentFence);
| // getPresentFence返回 HWComposer.mDisplayData.at(displayId).lastPresentFence;
| // 这个fence,在当前帧在屏幕上显现,或者发送到面板内存时,会发送信号
| // 【2】赋值 FrameFences.presentFence
| fences.presentFence = hwc.getPresentFence(*halDisplayIdOpt);
| for (const auto* layer : getOutputLayersOrderedByZ())
| auto hwcLayer = layer->getHwcLayer();
| // 从HWC显示设备上所有Layer的fence
| // 【3】赋值 FrameFences.layerFences
| fences.layerFences.emplace(hwcLayer, hwc.getLayerReleaseFence(*halDisplayIdOpt, hwcLayer));
| // 释放GPU合成使用的buffer
| mRenderSurface->onPresentDisplayCompleted();
| for (auto* layer : getOutputLayersOrderedByZ())
| sp<Fence> releaseFence = Fence::NO_FENCE;
| // 获取HWC每个layer的releaseFence
| if (auto hwcLayer = layer->getHwcLayer())
| if (auto f = frame.layerFences.find(hwcLayer); f != frame.layerFences.end())
| releaseFence = f->second;
| // 如果有客户端合成,merge GPUbuffer的fence
| if (outputState.usesClientComposition)
| releaseFence = Fence::merge("LayerRelease", releaseFence, frame.clientTargetAcquireFence);
| //同步Fence到Layer中
| // 如果是 BufferQueueLayer 设置 mSlots[slot].mFence;
| // 如果是 BufferStateLayer 把fence关联到回调类中
| layer->getLayerFE().onLayerDisplayed(ftl::yield<FenceResult>(std::move(releaseFence)).share());
| // mReleasedLayers是一些即将移除的的layer,但是当前vsync还在生产帧数据的layer
| // 把presentFence传给这些layer使用,毕竟他们不参与合成了
| for (auto& weakLayer : mReleasedLayers)
| if (const auto layer = weakLayer.promote())
| layer->onLayerDisplayed(ftl::yield<FenceResult>(frame.presentFence).share());
| mReleasedLayers.clear();//清空 mReleasedLayers
再回到APP进程端 releaseBuffer
|-->SurfaceFlinger::postComposition()
| // 省略一大段内容
| for (const auto& layer: mLayersWithQueuedFrames)
| // 更新FrameTracker、TimeStats这些
| layer->onPostComposition(display, glCompositionDoneFenceTime,mPreviousPresentFences[0].fenceTime, compositorTiming);
| layer->releasePendingBuffer(/*dequeueReadyTime*/ now);
|-->BufferStateLayer::releasePendingBuffer(nsecs_t dequeueReadyTime)
| for (auto& handle : mDrawingState.callbackHandles)
| if (handle->releasePreviousBuffer && mDrawingState.releaseBufferEndpoint == handle->listener)
| // 这个 mPreviousReleaseCallbackId 在 BufferStateLayer::updateActiveBuffer() 赋值
| // mPreviousReleaseCallbackId = {getCurrentBufferId(), mBufferInfo.mFrameNumber};
| handle->previousReleaseCallbackId = mPreviousReleaseCallbackId;
| break;
| // 把 callback 加入 TransactionCallbackInvoker::mCompletedTransactions
| mFlinger->getTransactionCallbackInvoker().addCallbackHandles(mDrawingState.callbackHandles, jankData);
| //【这里就是通过binder通信,回调到 APP 端BBQ执行 releaseBuffer 了】
| mTransactionCallbackInvoker.sendCallbacks(false /* onCommitOnly */);
|-->BpTransactionCompletedListener::onTransactionCompleted(android::ListenerStats)
// 跨进程进入到APP端
// frameworks/native/libs/gui/BLASTBufferQueue.cpp
releaseBufferCallbackThunk(wp<BLASTBufferQueue> context, ReleaseCallbackId& id,Fence& releaseFence, uint32_t currentMaxAcquiredBufferCount)
| sp<BLASTBufferQueue> blastBufferQueue = context.promote();
| blastBufferQueue->releaseBufferCallback(id, releaseFence, currentMaxAcquiredBufferCount);
|-->BLASTBufferQueue::releaseBufferCallback(const ReleaseCallbackId& id,Fence& releaseFence,uint32_t currentMaxAcquiredBufferCount)
| releaseBufferCallbackLocked(id, releaseFence, currentMaxAcquiredBufferCount,false /* fakeRelease */);
|-->BLASTBufferQueue::releaseBufferCallbackLocked(ReleaseCallbackId& id,Fence& releaseFence,uint32_t currentMaxAcquiredBufferCount, bool fakeRelease)
| // ReleaseCallbackId 是个包含 bufferId 和 帧号 的Parcelable, ReleasedBuffer结构体又把 releaseFence 包含进来
| auto rb = ReleasedBuffer{id, releaseFence};
| if (std::find(mPendingRelease.begin(), mPendingRelease.end(), rb) == mPendingRelease.end())
| // 队列里边没有的话,就加入队列
| mPendingRelease.emplace_back(rb);// mPendingRelease 是个 std::deque
| while (mPendingRelease.size() > numPendingBuffersToHold) // numPendingBuffersToHold 是需要保留的buffer数量
| const auto releasedBuffer = mPendingRelease.front();
| mPendingRelease.pop_front();
| releaseBuffer(releasedBuffer.callbackId, releasedBuffer.releaseFence);
|-->BLASTBufferQueue::releaseBuffer(const ReleaseCallbackId& callbackId,const sp<Fence>& releaseFence)
| // mSubmitted 是个map<ReleaseCallbackId, BufferItem>,从这个map中查找对应的 BufferItem
| auto it = mSubmitted.find(callbackId);
| mNumAcquired--;
| mBufferItemConsumer->releaseBuffer(it->second, releaseFence);
|-->BufferItemConsumer::releaseBuffer(const BufferItem &item, const sp<Fence>& releaseFence)
| // mSlots[slot].mFence = fence; 赋值releaseFence,并处理 Fence 合并情况
| addReleaseFenceLocked(item.mSlot, item.mGraphicBuffer, releaseFence);
| releaseBufferLocked(item.mSlot, item.mGraphicBuffer, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR);
|-->ConsumerBase::releaseBufferLocked(int slot, const sp<GraphicBuffer> graphicBuffer, EGLDisplay display, EGLSyncKHR eglFence)
| // 调用消费者的 releaseBuffer 方法
| status_t err = mConsumer->releaseBuffer(slot, mSlots[slot].mFrameNumber, display, eglFence, mSlots[slot].mFence);
|-->BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber, const sp<Fence>& releaseFence,...)
| // 忽略一些容错处理
| sp<IProducerListener> listener;
| mSlots[slot].mEglDisplay = eglDisplay; // display = EGL_NO_DISPLAY;
| mSlots[slot].mEglFence = eglFence; // EGLSyncKHR eglFence = EGL_NO_SYNC_KHR
| mSlots[slot].mFence = releaseFence; // SurfaceFlinger 传递过来的 releaseFence
| mSlots[slot].mBufferState.release(); // 状态转为 released
| mCore->mActiveBuffers.erase(slot);// 从激活状态set中删除
| mCore->mFreeBuffers.push_back(slot); // 放回 Free list 中
| if (mCore->mBufferReleasedCbEnabled)
| // mConnectedProducerListener 是 BufferQueueProducer::connect 时传入的
| // CPU绘制传入的 StubProducerListener,没啥用
| listener = mCore->mConnectedProducerListener;
| // 如果有阻塞在dequeuebuffer的线程,此时会被唤醒,有新的buffer可以 Dequeue 了
| mCore->mDequeueCondition.notify_all();
| if (listener != nullptr)
| listener->onBufferReleased();// 对于CPU绘制,这个是空函数没啥
| // 如果返回 buffer过时了,需要清空这个slot的 GraphicBuffer
| if (err == IGraphicBufferConsumer::STALE_BUFFER_SLOT)
| mSlots[slotIndex].mGraphicBuffer = nullptr;
| mSlots[slotIndex].mFence = Fence::NO_FENCE;
| mSlots[slotIndex].mFrameNumber = 0;
| mPrevFinalReleaseFence = mSlots[slot].mFence;
| // 这里的mSlots是BufferItem的,和 BufferQueue 的不是一个变量
| // BufferItem 的Fence设置为 NO_FENCE
| mSlots[slot].mFence = Fence::NO_FENCE;
| mSubmitted.erase(it);
后记:
对于 Android 13 的 SurfaceFlinger 而言,参考资料真的是非常有限。
从 Android P~Android Q小更新,Android Q~Android R 大的架构更新,
Android R~Android S 机制上的更新(BBQ+BufferStateLayer),Android S ~ Android T 又是大的架构更新,
Google还不断使用最新的c++标准去重构代码,从c11又更新到c20。更新的XX都不认识了。
最后导致能参考的资料基本失效了,只能一个个变量去查,并且都没类注释,要命的工作量啊。
最后不感谢CCTV,感谢 cs.android.com 吧,多亏了这个源码网站强大的检索能力。