- 从点击桌面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 吧,多亏了这个源码网站强大的检索能力。