该系列文章总纲链接:Android GUI系统之SurfaceFlinger 系列文章目录
说明:
在surfaceflinger中,基于最原始的Message handler机制,构建了自己的MessageQueue队列,代码具体实现如下:
- void MessageQueue::Handler::dispatchRefresh() {
- if ((android_atomic_or(eventMaskRefresh, &mEventMask) & eventMaskRefresh) == 0) {
- mQueue.mLooper->sendMessage(this, Message(MessageQueue::REFRESH));
- }
- }
-
- void MessageQueue::Handler::dispatchInvalidate() {
- if ((android_atomic_or(eventMaskInvalidate, &mEventMask) & eventMaskInvalidate) == 0) {
- mQueue.mLooper->sendMessage(this, Message(MessageQueue::INVALIDATE));
- }
- }
-
- void MessageQueue::Handler::dispatchTransaction() {
- if ((android_atomic_or(eventMaskTransaction, &mEventMask) & eventMaskTransaction) == 0) {
- mQueue.mLooper->sendMessage(this, Message(MessageQueue::TRANSACTION));
- }
- }
-
- void MessageQueue::Handler::handleMessage(const Message& message) {
- switch (message.what) {
- case INVALIDATE:
- android_atomic_and(~eventMaskInvalidate, &mEventMask);
- mQueue.mFlinger->onMessageReceived(message.what);
- break;
- case REFRESH:
- android_atomic_and(~eventMaskRefresh, &mEventMask);
- mQueue.mFlinger->onMessageReceived(message.what);
- break;
- case TRANSACTION:
- android_atomic_and(~eventMaskTransaction, &mEventMask);
- mQueue.mFlinger->onMessageReceived(message.what);
- break;
- }
- }
- // ---------------------------------------------------------------------------
- MessageQueue::MessageQueue(){}
- MessageQueue::~MessageQueue() {}
-
- void MessageQueue::init(const sp
& flinger) - {
- mFlinger = flinger;
- mLooper = new Looper(true);
- mHandler = new Handler(*this);
- }
-
- void MessageQueue::setEventThread(const sp
& eventThread) - {
- mEventThread = eventThread;
- mEvents = eventThread->createEventConnection();
- mEventTube = mEvents->getDataChannel();
- mLooper->addFd(mEventTube->getFd(), 0, Looper::EVENT_INPUT,
- MessageQueue::cb_eventReceiver, this);
- }
-
- void MessageQueue::waitMessage() {
- do {
- IPCThreadState::self()->flushCommands();
- int32_t ret = mLooper->pollOnce(-1);
- switch (ret) {
- case Looper::POLL_WAKE:
- case Looper::POLL_CALLBACK:
- continue;
- case Looper::POLL_ERROR:
- ALOGE("Looper::POLL_ERROR");
- case Looper::POLL_TIMEOUT:
- // timeout (should not happen)
- continue;
- default:
- // should not happen
- ALOGE("Looper::pollOnce() returned unknown status %d", ret);
- continue;
- }
- } while (true);
- }
-
- status_t MessageQueue::postMessage(
- const sp
& messageHandler, nsecs_t relTime) - {
- const Message dummyMessage;
- if (relTime > 0) {
- mLooper->sendMessageDelayed(relTime, messageHandler, dummyMessage);
- } else {
- mLooper->sendMessage(messageHandler, dummyMessage);
- }
- return NO_ERROR;
- }
-
- #define INVALIDATE_ON_VSYNC 1
-
- void MessageQueue::invalidateTransactionNow() {
- mHandler->dispatchTransaction();
- }
-
- void MessageQueue::invalidate() {
- #if INVALIDATE_ON_VSYNC
- mEvents->requestNextVsync();
- #else
- mHandler->dispatchInvalidate();
- #endif
- }
-
- void MessageQueue::refresh() {
- #if INVALIDATE_ON_VSYNC
- mHandler->dispatchRefresh();
- #else
- mEvents->requestNextVsync();
- #endif
- }
-
- int MessageQueue::cb_eventReceiver(int fd, int events, void* data) {
- MessageQueue* queue = reinterpret_cast
(data); - return queue->eventReceiver(fd, events);
- }
-
- int MessageQueue::eventReceiver(int /*fd*/, int /*events*/) {
- ssize_t n;
- DisplayEventReceiver::Event buffer[8];
- while ((n = DisplayEventReceiver::getEvents(mEventTube, buffer, 8)) > 0) {
- for (int i=0 ; i
- if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
- #if INVALIDATE_ON_VSYNC
- mHandler->dispatchInvalidate();
- #else
- mHandler->dispatchRefresh();
- #endif
- break;
- }
- }
- }
- return 1;
- }
2 MessageQueue在SurfaceFlinger中的使用
2.1 分析mEventQueue.init
2.1.1 mEventQueue.init执行的上下文解读
在SurfaceFlinger第一次被创建时会调用mEventQueue的init方法,如下所示:
- void SurfaceFlinger::onFirstRef()
- {
- mEventQueue.init(this);
- }
2.1.2 mEventQueue.init内部实现
在这个init函数中,主要做了一些初始化工作,包括handler、looper和mFlinger成员变量的初始化,如下所示:
- void MessageQueue::init(const sp
& flinger) - {
- mFlinger = flinger;
- mLooper = new Looper(true);
- mHandler = new Handler(*this);
- }
2.2 分析mEventQueue.setEventThread
2.2.1 mEventQueue.setEventThread执行的上下文解读
该部分代码主要在SurfaceFlinger::init()中使用,启动EventThread的过程中,如下所示:
- // start the EventThread
- sp
vsyncSrc = new DispSyncSource(&mPrimaryDispSync,vsyncPhaseOffsetNs, true, "app"); - mEventThread = new EventThread(vsyncSrc);
- sp
sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,sfVsyncPhaseOffsetNs, true, "sf"); -
- mSFEventThread = new EventThread(sfVsyncSrc);
- mEventQueue.setEventThread(mSFEventThread);
在这段代码中,创建了两个不同的 EventThread 对象,并使用 DispSyncSource 类作为事件源来处理事件。代码详细解读如下:
- vsyncSrc 对象的创建:通过 new DispSyncSource(&mPrimaryDispSync, vsyncPhaseOffsetNs, true, "app") 创建了一个 DispSyncSource 对象,作为应用程序相关事件的事件源。vsyncPhaseOffsetNs 是传递的垂直同步相位偏移值,用于控制应用程序事件的触发时机相对于显示刷新。参数中的 "app" 表示该事件源与应用程序相关。
- mEventThread 对象的创建:通过 new EventThread(vsyncSrc) 创建了一个 EventThread 对象,并将上述的 vsyncSrc 对象作为参数传递给它。这个 EventThread 对象用于处理应用程序相关的事件。
- sfVsyncSrc 对象的创建:通过 new DispSyncSource(&mPrimaryDispSync, sfVsyncPhaseOffsetNs, true, "sf") 创建了另一个 DispSyncSource 对象,作为 SurfaceFlinger 相关事件的事件源。sfVsyncPhaseOffsetNs 是传递的垂直同步相位偏移值,用于控制 SurfaceFlinger 事件的触发时机相对于显示刷新。参数中的 "sf" 表示该事件源与 SurfaceFlinger 相关。
- mSFEventThread 对象的创建:通过 new EventThread(sfVsyncSrc) 创建了另一个 EventThread 对象,并将上述的 sfVsyncSrc 对象作为参数传递给它。这个 EventThread 对象用于处理 SurfaceFlinger 相关的事件。
- mEventQueue 的设置:通过 mEventQueue.setEventThread(mSFEventThread) 将 mSFEventThread 对象设置为 mEventQueue 的事件线程。这意味着 SurfaceFlinger 相关的事件将由 mSFEventThread 处理。
通过这段代码,为应用程序事件和 SurfaceFlinger 事件创建了独立的 EventThread 对象,并使用不同的 DispSyncSource 对象来控制它们的触发时机。这样可以实现事件的隔离和优先级控制,提高系统的稳定性和响应性。
2.2.2 mEventQueue.setEventThread内部实现
代码如下所示:
- void MessageQueue::setEventThread(const sp
& eventThread) - {
- mEventThread = eventThread;
- mEvents = eventThread->createEventConnection();
- mEventTube = mEvents->getDataChannel();
- mLooper->addFd(mEventTube->getFd(), 0, Looper::EVENT_INPUT,
- MessageQueue::cb_eventReceiver, this);
- }
这里MessageQueue::setEventThread 方法的主要作用是将事件线程(EventThread)与消息队列相关联,并设置事件接收器。这段代码详细解读如下:
- 设置事件线程:通过将传入的 eventThread 对象赋值给成员变量 mEventThread,将事件线程与消息队列相关联。事件线程负责接收和处理消息队列中的事件。
- 创建事件连接:调用事件线程的 createEventConnection 方法,创建一个事件连接(EventConnection)。事件连接用于将消息队列中的事件传递给事件线程进行处理。
- 获取数据通道:通过事件连接的 getDataChannel 方法,获取与事件线程通信的数据通道(EventTube)。数据通道用于传输消息队列中的事件数据。
- 注册事件接收器:使用事件循环(Looper)的 addFd 方法,将数据通道的文件描述符(mEventTube->getFd())注册到事件循环中。这样,当事件数据可读时,事件循环会调用 MessageQueue::cb_eventReceiver 方法处理事件。
总结起来,MessageQueue::setEventThread 方法的目的是将事件线程与消息队列关联起来,并设置事件接收器,以便将消息队列中的事件传递给事件线程进行处理。这样可以实现消息队列的异步事件处理机制,提高系统的性能和响应性。
2.3 分析mEventQueue.waitMessage
2.3.1 mEventQueue.waitMessage执行的上下文解读
在SurfaceFlinger执行run方法时,会调用到waitForEvent()方法,进而调用到mEventQueue的waitMessage方法。相关代码整理如下:
- void SurfaceFlinger::run() {
- do {
- waitForEvent();
- } while (true);
- }
-
- void SurfaceFlinger::waitForEvent() {
- mEventQueue.waitMessage();
- }
2.3.2 MessageQueue::waitMessage内部实现
- void MessageQueue::waitMessage() {
- do {
- IPCThreadState::self()->flushCommands();
- int32_t ret = mLooper->pollOnce(-1);
- switch (ret) {
- case Looper::POLL_WAKE:
- case Looper::POLL_CALLBACK:
- continue;
- case Looper::POLL_ERROR:
- ALOGE("Looper::POLL_ERROR");
- case Looper::POLL_TIMEOUT:
- // timeout (should not happen)
- continue;
- default:
- // should not happen
- ALOGE("Looper::pollOnce() returned unknown status %d", ret);
- continue;
- }
- } while (true);
- }
该部分代码主要是用于等待和处理消息。代码详细解读如下:
- 进入循环:代码进入一个无限循环,通过 do-while 结构实现。
- IPCThreadState::self()->flushCommands():在每次循环开始时,调用 IPCThreadState::self()->flushCommands() 来刷新命令队列。这是为了确保在等待消息期间处理任何挂起的 IPC 命令。
- mLooper->pollOnce(-1):调用 mLooper->pollOnce(-1) 来等待消息的到达。-1 表示无限等待,直到有消息到达才会返回。
- switch 语句:根据 pollOnce 的返回值进行不同的处理。
- Looper::POLL_WAKE 或 Looper::POLL_CALLBACK:如果返回值是 POLL_WAKE 或 POLL_CALLBACK,表示有消息到达或有回调触发,代码会继续下一次循环,继续等待和处理消息。
- Looper::POLL_ERROR:如果返回值是 POLL_ERROR,打印错误日志信息。
- Looper::POLL_TIMEOUT:如果返回值是 POLL_TIMEOUT,表示发生了超时,这里注释写着 "should not happen",意味着理论上不应该发生超时。
- 其他情况:如果返回值是其他未知状态,打印错误日志信息。
- 继续循环:在 switch 语句的 continue 语句下,继续下一次循环,等待和处理下一条消息。
这段代码的作用是不断等待和处理消息,确保SurfaceFlinger能够及时响应和处理来自系统和应用程序的消息。它使用Looper的pollOnce函数来等待消息的到达,并根据不同的返回状态进行相应的处理。
2.4 分析mEventQueue.invalidate和mEventQueue.refresh
2.4.1 mEventQueue.invalidate和mEventQueue.refresh
使用上下文相关代码如下所示:
- void SurfaceFlinger::signalTransaction() {
- mEventQueue.invalidate();
- }
-
- void SurfaceFlinger::signalLayerUpdate() {
- mEventQueue.invalidate();
- }
-
- void SurfaceFlinger::signalRefresh() {
- mEventQueue.refresh();
- }
3个方法的简要说明如下:
- signalTransaction()方法的目的是发出事务信号。当有新的事务要应用于SurfaceFlinger时,例如添加、删除或修改图层属性,调用此方法会使事件队列无效。通过使事件队列无效,可以触发对应的事件处理,确保新的事务能够及时地被处理(invalidate是废弃、使无效的意思。Android中需要重绘某个视图时就可以调用该函数,表示view的某个显示区域内容变脏了,该显示区域需要被重新绘制)。
- signalLayerUpdate()方法的目的是发出图层更新信号。当某个图层的内容发生更改时,例如图层的绘制内容更新,调用此方法会使事件队列无效。这将通知 SurfaceFlinger 有图层内容需要更新,从而触发相应的渲染和显示操作。
- signalRefresh() 方法的目的是发出刷新信号。调用此方法会直接触发事件队列的刷新操作,而不是简单地使其无效。这通常用于强制立即刷新事件队列,并处理所有待处理的事件。这对于某些需要及时响应的情况非常有用,例如在某些显示刷新时机敏感的应用场景中。
总结来说,这3个方法都与事件队列的处理和刷新相关。signalTransaction和 signalLayerUpdate在发生特定事件时使事件队列无效,以触发相应的事件处理。而 signalRefresh则直接触发对事件队列的立即刷新。这些方法的调用可以保证事件的及时处理和刷新,以确保 SurfaceFlinger 的正常运行和图层的正确显示。
2.4.2 mEventQueue的invalidate和refresh的实现
@1 mEventQueue.invalidate的实现
invalidate是废弃、使无效的意思。Android中需要重绘某个视图时就可以调用该函数,表示view的某个显示区域内容变脏了,该显示区域需要被重新绘制。代码实现如下:
- #define INVALIDATE_ON_VSYNC 1
- void MessageQueue::invalidate() {
- #if INVALIDATE_ON_VSYNC
- mEvents->requestNextVsync();
- #else
- mHandler->dispatchInvalidate();
- #endif
- }
这里的mEvents->requestNextVsync中mEvents是EventThread::Connection类型的,因此这里直接调用EventThread::Connection里的requestNextVsync方法,如下所示:
- void EventThread::Connection::requestNextVsync() {
- mEventThread->requestNextVsync(this);
- }
-
- void EventThread::requestNextVsync(
- const sp
& connection) { - Mutex::Autolock _l(mLock);
- if (connection->count < 0) {
- connection->count = 0;
- mCondition.broadcast();
- }
- }
这里的mCondition.broadcast()如果被执行,则会导致mCondition.wait或mCondition.waitRelative被执行,会直接导致EventThread::waitForEvent()方法不再阻塞。
两者在 EventThread 类的上下文中用于实现事件的同步和处理。它们之间的关系如下:
- EventThread::requestNextVsync() 方法通过请求下一次垂直同步事件,通知系统在下一次垂直同步时发送事件。
- EventThread::waitForEvent() 方法在事件队列中等待事件的到来,并保持线程阻塞状态。当 EventThread 类接收到新的事件连接对象时,会唤醒等待的线程,使其从阻塞状态返回。
通过这种方式,EventThread 类可以与系统的垂直同步信号和事件队列进行同步,以及在事件到来时及时处理和分发事件。
@2 mEventQueue.refresh的实现
相关代码实现和调用关系如下所示:
- #define INVALIDATE_ON_VSYNC 1
- void MessageQueue::refresh() {
- #if INVALIDATE_ON_VSYNC
- mHandler->dispatchRefresh();
- #else
- mEvents->requestNextVsync();
- #endif
- }
-
- //dispatchRefresh实现如下:
- void MessageQueue::Handler::dispatchRefresh() {
- if ((android_atomic_or(eventMaskRefresh, &mEventMask) & eventMaskRefresh) == 0) {
- mQueue.mLooper->sendMessage(this, Message(MessageQueue::REFRESH));
- }
- }
- //消息处理如下:
- void MessageQueue::Handler::handleMessage(const Message& message) {
- switch (message.what) {
- case REFRESH:
- android_atomic_and(~eventMaskRefresh, &mEventMask);
- mQueue.mFlinger->onMessageReceived(message.what);
- break;
- //...
- }
- }
- //onMessageReceived实现如下:
- void SurfaceFlinger::onMessageReceived(int32_t what) {
- ATRACE_CALL();
- switch (what) {
- //...
- case MessageQueue::REFRESH: {
- handleMessageRefresh();
- break;
- }
- }
- //handleMessageRefresh实现如下:
- void SurfaceFlinger::handleMessageRefresh() {
- ATRACE_CALL();
- preComposition();
- rebuildLayerStacks();
- setUpHWComposer();
- doDebugFlashRegions();
- doComposition();
- postComposition();
- }
2.5 分析mEventQueue.invalidateTransactionNow
2.5.1 mEventQueue.invalidateTransactionNow上下文
该部分代码主要是在SurfaceFlinger::captureScreen中进行调用的,使用上下文相关代码如下所示:
- status_t SurfaceFlinger::captureScreen(const sp
& display, - const sp
& producer, - Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
- uint32_t minLayerZ, uint32_t maxLayerZ,
- bool useIdentityTransform, ISurfaceComposer::Rotation rotation) {
- //...
- class MessageCaptureScreen : public MessageBase {
- SurfaceFlinger* flinger;
- sp
display; - sp
producer; - Rect sourceCrop;
- uint32_t reqWidth, reqHeight;
- uint32_t minLayerZ,maxLayerZ;
- bool useIdentityTransform;
- Transform::orientation_flags rotation;
- status_t result;
- public:
- MessageCaptureScreen(SurfaceFlinger* flinger,
- const sp
& display, - const sp
& producer, - Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
- uint32_t minLayerZ, uint32_t maxLayerZ,
- bool useIdentityTransform, Transform::orientation_flags rotation)
- : flinger(flinger), display(display), producer(producer),
- sourceCrop(sourceCrop), reqWidth(reqWidth), reqHeight(reqHeight),
- minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
- useIdentityTransform(useIdentityTransform),
- rotation(rotation),
- result(PERMISSION_DENIED)
- {
- }
- status_t getResult() const {
- return result;
- }
- virtual bool handler() {
- Mutex::Autolock _l(flinger->mStateLock);
- sp<const DisplayDevice> hw(flinger->getDisplayDevice(display));
- result = flinger->captureScreenImplLocked(hw, producer,
- sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
- useIdentityTransform, rotation);
- static_cast
(producer->asBinder().get())->exit(result); - return true;
- }
- };
-
-
- mEventQueue.invalidateTransactionNow();
- sp
wrapper = new GraphicProducerWrapper(producer); -
- sp
msg = new MessageCaptureScreen(this, - display, IGraphicBufferProducer::asInterface( wrapper ),
- sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
- useIdentityTransform, rotationFlags);
-
- status_t res = postMessageAsync(msg);
- if (res == NO_ERROR) {
- res = wrapper->waitForResponse();
- }
- return res;
- }
2.5.2 mEventQueue.invalidateTransactionNow内部实现
相关代码和调用流程流程实现如下:
- void MessageQueue::invalidateTransactionNow() {
- mHandler->dispatchTransaction();
- }
-
- //handler的dispatchTransaction实现如下:
- void MessageQueue::Handler::dispatchTransaction() {
- if ((android_atomic_or(eventMaskTransaction, &mEventMask) & eventMaskTransaction) == 0) {
- mQueue.mLooper->sendMessage(this, Message(MessageQueue::TRANSACTION));
- }
- }
- //消息处理如下:
- void MessageQueue::Handler::handleMessage(const Message& message) {
- switch (message.what) {
- //...
- case TRANSACTION:
- android_atomic_and(~eventMaskTransaction, &mEventMask);
- mQueue.mFlinger->onMessageReceived(message.what);
- break;
- }
- }
- //onMessageReceived实现如下:
- void SurfaceFlinger::onMessageReceived(int32_t what) {
- ATRACE_CALL();
- switch (what) {
- case MessageQueue::TRANSACTION: {
- handleMessageTransaction();
- break;
- }
- //...
- }
- }
- //handleMessageTransaction实现如下:
- bool SurfaceFlinger::handleMessageTransaction() {
- uint32_t transactionFlags = peekTransactionFlags(eTransactionMask);
- if (transactionFlags) {
- handleTransaction(transactionFlags);
- return true;
- }
- return false;
- }
至于mEventQueue.postMessage,在上一章节MessageBase中已经进行相关的解读,这里不再赘述。