八、绘制

ViewRootImpl.performDraw

先看CPU绘制:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
java复制代码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

  • 重点是注册生产者回调
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
c++复制代码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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
c++复制代码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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
c++复制代码// 前置流程:
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
c++复制代码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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
c++复制代码//	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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
c++复制代码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消息了,直接无缝切换
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
c++复制代码//	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 流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
c++复制代码//	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以前逻辑要少很多
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
c++复制代码// 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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
c++复制代码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服务 交互去确认是否有客户端合成,如果没有客户端合成,并可以忽略验证,那么会直接显示。流程到这里基本结束了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
c++复制代码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合成)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
c++复制代码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上填充数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
c++复制代码//先看下结构体 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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
c++复制代码|-->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 PAndroid Q小更新,Android QAndroid R 大的架构更新,

Android R~Android S 机制上的更新(BBQ+BufferStateLayer),Android S ~ Android T 又是大的架构更新,

Google还不断使用最新的c++标准去重构代码,从c11又更新到c20。更新的XX都不认识了。

最后导致能参考的资料基本失效了,只能一个个变量去查,并且都没类注释,要命的工作量啊。

最后不感谢CCTV,感谢 cs.android.com 吧,多亏了这个源码网站强大的检索能力。