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

相关推荐
百锦再29 分钟前
Android Studio开发 SharedPreferences 详解
android·ide·android studio
青春给了狗41 分钟前
Android 14 修改侧滑手势动画效果
android
CYRUS STUDIO1 小时前
Android APP 热修复原理
android·app·frida·hotfix·热修复
火柴就是我2 小时前
首次使用Android Studio时,http proxy,gradle问题解决
android
limingade2 小时前
手机打电话时电脑坐席同时收听对方说话并插入IVR预录声音片段
android·智能手机·电脑·蓝牙电话·电脑打电话
浩浩测试一下2 小时前
计算机网络中的DHCP是什么呀? 详情解答
android·网络·计算机网络·安全·web安全·网络安全·安全架构
青春给了狗4 小时前
Android 14 系统统一修改app启动时图标大小和圆角
android
pengyu4 小时前
【Flutter 状态管理 - 柒】 | InheritedWidget:藏在组件树里的"魔法"✨
android·flutter·dart
居然是阿宋6 小时前
Kotlin高阶函数 vs Lambda表达式:关键区别与协作关系
android·开发语言·kotlin
凉、介6 小时前
PCI 总线学习笔记(五)
android·linux·笔记·学习·pcie·pci