该系列文章总纲链接: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 类作为事件源来处理事件。代码详细解读如下:
- 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内部实现
代码如下所示:
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)与消息队列相关联,并设置事件接收器。这段代码详细解读如下:
- 设置事件线程:通过将传入的 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方法。相关代码整理如下:
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);
}
该部分代码主要是用于等待和处理消息。代码详细解读如下:
- 进入循环:代码进入一个无限循环,通过 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
使用上下文相关代码如下所示:
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中已经进行相关的解读,这里不再赘述。