Android SurfaceFlinger导读(02)MessageQueue

该系列文章总纲链接:Android GUI系统之SurfaceFlinger 系列文章目录

说明:

  • 关于导读:导读部分主要是方便初学者理解SurfaceFlinger代码中的机制,为后面分析代码打下一个更好的基础,这样就可以把更多的精力放在surfaceFlinger的业务逻辑分析上。
  • 关于代码分支:以下代码分析均在android5.1.1_r3分支上 目录frameworks/native/services/surfaceflinger为root目录

1 MessageQueue解读

在surfaceflinger中,基于最原始的Message handler机制,构建了自己的MessageQueue队列,代码具体实现如下:

cpp 复制代码
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<SurfaceFlinger>& flinger)
{
    mFlinger = flinger;
    mLooper = new Looper(true);
    mHandler = new Handler(*this);
}

void MessageQueue::setEventThread(const sp<EventThread>& 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<MessageBase>& 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<MessageQueue *>(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<n ; 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方法,如下所示:

cpp 复制代码
void SurfaceFlinger::onFirstRef()
{
    mEventQueue.init(this);
}

2.1.2 mEventQueue.init内部实现

在这个init函数中,主要做了一些初始化工作,包括handler、looper和mFlinger成员变量的初始化,如下所示:

cpp 复制代码
void MessageQueue::init(const sp<SurfaceFlinger>& flinger)
{
    mFlinger = flinger;
    mLooper = new Looper(true);
    mHandler = new Handler(*this);
}

2.2 分析mEventQueue.setEventThread

2.2.1 mEventQueue.setEventThread执行的上下文解读

该部分代码主要在SurfaceFlinger::init()中使用,启动EventThread的过程中,如下所示:

cpp 复制代码
    // start the EventThread
    sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,vsyncPhaseOffsetNs, true, "app");
    mEventThread = new EventThread(vsyncSrc);
    sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,sfVsyncPhaseOffsetNs, true, "sf");

    mSFEventThread = new EventThread(sfVsyncSrc);
    mEventQueue.setEventThread(mSFEventThread);

在这段代码中,创建了两个不同的 EventThread 对象,并使用 DispSyncSource 类作为事件源来处理事件。代码详细解读如下:

  1. vsyncSrc 对象的创建:通过 new DispSyncSource(&mPrimaryDispSync, vsyncPhaseOffsetNs, true, "app") 创建了一个 DispSyncSource 对象,作为应用程序相关事件的事件源。vsyncPhaseOffsetNs 是传递的垂直同步相位偏移值,用于控制应用程序事件的触发时机相对于显示刷新。参数中的 "app" 表示该事件源与应用程序相关。
  2. mEventThread 对象的创建:通过 new EventThread(vsyncSrc) 创建了一个 EventThread 对象,并将上述的 vsyncSrc 对象作为参数传递给它。这个 EventThread 对象用于处理应用程序相关的事件。
  3. sfVsyncSrc 对象的创建:通过 new DispSyncSource(&mPrimaryDispSync, sfVsyncPhaseOffsetNs, true, "sf") 创建了另一个 DispSyncSource 对象,作为 SurfaceFlinger 相关事件的事件源。sfVsyncPhaseOffsetNs 是传递的垂直同步相位偏移值,用于控制 SurfaceFlinger 事件的触发时机相对于显示刷新。参数中的 "sf" 表示该事件源与 SurfaceFlinger 相关。
  4. mSFEventThread 对象的创建:通过 new EventThread(sfVsyncSrc) 创建了另一个 EventThread 对象,并将上述的 sfVsyncSrc 对象作为参数传递给它。这个 EventThread 对象用于处理 SurfaceFlinger 相关的事件。
  5. mEventQueue 的设置:通过 mEventQueue.setEventThread(mSFEventThread) 将 mSFEventThread 对象设置为 mEventQueue 的事件线程。这意味着 SurfaceFlinger 相关的事件将由 mSFEventThread 处理。

通过这段代码,为应用程序事件和 SurfaceFlinger 事件创建了独立的 EventThread 对象,并使用不同的 DispSyncSource 对象来控制它们的触发时机。这样可以实现事件的隔离和优先级控制,提高系统的稳定性和响应性。

2.2.2 mEventQueue.setEventThread内部实现

代码如下所示:

cpp 复制代码
void MessageQueue::setEventThread(const sp<EventThread>& eventThread)
{
    mEventThread = eventThread;
    mEvents = eventThread->createEventConnection();
    mEventTube = mEvents->getDataChannel();
    mLooper->addFd(mEventTube->getFd(), 0, Looper::EVENT_INPUT,
            MessageQueue::cb_eventReceiver, this);
}

这里MessageQueue::setEventThread 方法的主要作用是将事件线程(EventThread)与消息队列相关联,并设置事件接收器。这段代码详细解读如下:

  1. 设置事件线程:通过将传入的 eventThread 对象赋值给成员变量 mEventThread,将事件线程与消息队列相关联。事件线程负责接收和处理消息队列中的事件。
  2. 创建事件连接:调用事件线程的 createEventConnection 方法,创建一个事件连接(EventConnection)。事件连接用于将消息队列中的事件传递给事件线程进行处理。
  3. 获取数据通道:通过事件连接的 getDataChannel 方法,获取与事件线程通信的数据通道(EventTube)。数据通道用于传输消息队列中的事件数据。
  4. 注册事件接收器:使用事件循环(Looper)的 addFd 方法,将数据通道的文件描述符(mEventTube->getFd())注册到事件循环中。这样,当事件数据可读时,事件循环会调用 MessageQueue::cb_eventReceiver 方法处理事件。

总结起来,MessageQueue::setEventThread 方法的目的是将事件线程与消息队列关联起来,并设置事件接收器,以便将消息队列中的事件传递给事件线程进行处理。这样可以实现消息队列的异步事件处理机制,提高系统的性能和响应性。

2.3 分析mEventQueue.waitMessage

2.3.1 mEventQueue.waitMessage执行的上下文解读

在SurfaceFlinger执行run方法时,会调用到waitForEvent()方法,进而调用到mEventQueue的waitMessage方法。相关代码整理如下:

cpp 复制代码
void SurfaceFlinger::run() {
    do {
        waitForEvent();
    } while (true);
}

void SurfaceFlinger::waitForEvent() {
    mEventQueue.waitMessage();
}

2.3.2 MessageQueue::waitMessage内部实现

cpp 复制代码
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);
}

该部分代码主要是用于等待和处理消息。代码详细解读如下:

  1. 进入循环:代码进入一个无限循环,通过 do-while 结构实现。
  2. IPCThreadState::self()->flushCommands():在每次循环开始时,调用 IPCThreadState::self()->flushCommands() 来刷新命令队列。这是为了确保在等待消息期间处理任何挂起的 IPC 命令。
  3. mLooper->pollOnce(-1):调用 mLooper->pollOnce(-1) 来等待消息的到达。-1 表示无限等待,直到有消息到达才会返回。
  4. switch 语句:根据 pollOnce 的返回值进行不同的处理。
    1. Looper::POLL_WAKE 或 Looper::POLL_CALLBACK:如果返回值是 POLL_WAKE 或 POLL_CALLBACK,表示有消息到达或有回调触发,代码会继续下一次循环,继续等待和处理消息。
    2. Looper::POLL_ERROR:如果返回值是 POLL_ERROR,打印错误日志信息。
    3. Looper::POLL_TIMEOUT:如果返回值是 POLL_TIMEOUT,表示发生了超时,这里注释写着 "should not happen",意味着理论上不应该发生超时。
    4. 其他情况:如果返回值是其他未知状态,打印错误日志信息。
  5. 继续循环:在 switch 语句的 continue 语句下,继续下一次循环,等待和处理下一条消息。

这段代码的作用是不断等待和处理消息,确保SurfaceFlinger能够及时响应和处理来自系统和应用程序的消息。它使用Looper的pollOnce函数来等待消息的到达,并根据不同的返回状态进行相应的处理。

2.4 分析mEventQueue.invalidate和mEventQueue.refresh

2.4.1 mEventQueue.invalidate和mEventQueue.refresh

使用上下文相关代码如下所示:

cpp 复制代码
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的某个显示区域内容变脏了,该显示区域需要被重新绘制。代码实现如下:

cpp 复制代码
#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方法,如下所示:

cpp 复制代码
void EventThread::Connection::requestNextVsync() {
    mEventThread->requestNextVsync(this);
}

void EventThread::requestNextVsync(
        const sp<EventThread::Connection>& 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的实现

相关代码实现和调用关系如下所示:

cpp 复制代码
#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中进行调用的,使用上下文相关代码如下所示:

cpp 复制代码
status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
        const sp<IGraphicBufferProducer>& 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<IBinder> display;
        sp<IGraphicBufferProducer> 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<IBinder>& display,
                const sp<IGraphicBufferProducer>& 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<GraphicProducerWrapper*>(producer->asBinder().get())->exit(result);
            return true;
        }
    };

   
    mEventQueue.invalidateTransactionNow();
    sp<GraphicProducerWrapper> wrapper = new GraphicProducerWrapper(producer);

    sp<MessageBase> 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内部实现

相关代码和调用流程流程实现如下:

cpp 复制代码
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中已经进行相关的解读,这里不再赘述。

相关推荐
拭心14 分钟前
Google 提供的 Android 端上大模型组件:MediaPipe LLM 介绍
android
带电的小王3 小时前
WhisperKit: Android 端测试 Whisper -- Android手机(Qualcomm GPU)部署音频大模型
android·智能手机·whisper·qualcomm
梦想平凡3 小时前
PHP 微信棋牌开发全解析:高级教程
android·数据库·oracle
元争栈道3 小时前
webview和H5来实现的android短视频(短剧)音视频播放依赖控件
android·音视频
阿甘知识库4 小时前
宝塔面板跨服务器数据同步教程:双机备份零停机
android·运维·服务器·备份·同步·宝塔面板·建站
元争栈道5 小时前
webview+H5来实现的android短视频(短剧)音视频播放依赖控件资源
android·音视频
MuYe5 小时前
Android Hook - 动态加载so库
android
居居飒5 小时前
Android学习(四)-Kotlin编程语言-for循环
android·学习·kotlin
Henry_He8 小时前
桌面列表小部件不能点击的问题分析
android
工程师老罗9 小时前
Android笔试面试题AI答之Android基础(1)
android