AndroidQ 图形系统(4)queueBuffer函数分析我们知道一块buffer被queue
到buffer队列之后就会回调onFrameAvailable
函数通知SurfaceFlinger
进行消费:
if (frameAvailableListener != nullptr) {
frameAvailableListener->onFrameAvailable(item);
} else if (frameReplacedListener != nullptr) {
frameReplacedListener->onFrameReplaced(item);
}
我们先来看看onFrameAvailable
调用流程:
frameAvailableListener
是BufferQueueCore
的mConsumerListener
。BufferQueueCore
的mConsumerListener
是ConsumerBase
构造函数传过来的BufferQueue::ProxyConsumerListener
。BufferQueue::ProxyConsumerListener
中的listener
又是ConsumerBase
。ConsumerBase
中又有一个mFrameAvailableListener
,这又是通过外部调用ConsumerBase
的setFrameAvailableListener
函数传递过来的BufferQueueLayer
。所以最终onFrameAvailable
函数就是调到BufferQueueLayer
中,这是Layer
的子类,是SurfaceFlinger
进程对Surface
的描述。
直接到BufferQueueLayer
中来看
void BufferQueueLayer::onFrameAvailable(const BufferItem& item) {
ATRACE_CALL();
// Add this buffer from our internal queue tracker
{ // Autolock scope
......
Mutex::Autolock lock(mQueueItemLock);
.....
mQueueItems.push_back(item);
mQueuedFrames++;
......
if (isRemovedFromCurrentState()) {
....
} else {
.....
mFlinger->signalLayerUpdate();
}
mConsumer->onBufferAvailable(item);
}
这个函数其他内容暂时不管,我们主要来看mFlinger->signalLayerUpdate()
,这个函数是请求更新Layer
的核心。
void SurfaceFlinger::signalLayerUpdate() {
mScheduler->resetIdleTimer();
mEventQueue->invalidate();
}
mEventQueue
是一个MessageQueue
对象,在SurfaceFlinger
初始化的时候创建的,和java层的MessageQueue
对应的,是属于native层消息机制,它在初始化时同样会有Looper
和Handler
:
void MessageQueue::init(const sp<SurfaceFlinger>& flinger) {
mFlinger = flinger;
mLooper = new Looper(true);
mHandler = new Handler(*this);
}
来看它的invalidate
函数,记得java层View中也有一个invalidate
方法吗,作用是什么?是用来触发View的绘制的,如何触发?其实就是向底层请求Vsync
,等到下一个Vsync
到了之后就开始绘制,同样这里的invalidate
函数也是类似的功能,也会请求Vsync
,收到Vsync
之后开始合成,这里的Vsync
是SurfaceFlinger
进程的,顺便提一句,一个Vsync
会被分成两部分,一个用于APP绘制,一个用于SurfaceFlinger
合成,对应就有两个处理Vsync
的线程EventThread
,如下就是创建的两个EventThread
,一个名为"app",一个名为"sf"。
void SurfaceFlinger::init() {
......
mAppConnectionHandle =
mScheduler->createConnection("app", mVsyncModulator.getOffsets().app,
mPhaseOffsets->getOffsetThresholdForNextVsync(),
resyncCallback,
impl::EventThread::InterceptVSyncsCallback());
mSfConnectionHandle =
mScheduler->createConnection("sf", mVsyncModulator.getOffsets().sf,
mPhaseOffsets->getOffsetThresholdForNextVsync(),
resyncCallback, [this](nsecs_t timestamp) {
mInterceptor->saveVSyncEvent(timestamp);
});
我们继续看MessageQueue
的invalidate
函数
void MessageQueue::invalidate() {
mEvents->requestNextVsync();
}
这个mEvents
是什么呢?它是一个EventThreadConnection
对象,EventThreadConnection
是一个很重要的对象,是在SurfaceFlinger
的init中创建的:
void SurfaceFlinger::init() {
......
mAppConnectionHandle =
mScheduler->createConnection("app", mVsyncModulator.getOffsets().app,
mPhaseOffsets->getOffsetThresholdForNextVsync(),
resyncCallback,
impl::EventThread::InterceptVSyncsCallback());
mSfConnectionHandle =
mScheduler->createConnection("sf", mVsyncModulator.getOffsets().sf,
mPhaseOffsets->getOffsetThresholdForNextVsync(),
resyncCallback, [this](nsecs_t timestamp) {
mInterceptor->saveVSyncEvent(timestamp);
});
}
调用mScheduler->createConnection
创建,
sp<Scheduler::ConnectionHandle> Scheduler::createConnection(
const char* connectionName, nsecs_t phaseOffsetNs, nsecs_t offsetThresholdForNextVsync,
ResyncCallback resyncCallback,
impl::EventThread::InterceptVSyncsCallback interceptCallback) {
const int64_t id = sNextId++;
ALOGV("Creating a connection handle with ID: %" PRId64 "\n", id);
std::unique_ptr<EventThread> eventThread =
makeEventThread(connectionName, mPrimaryDispSync.get(), phaseOffsetNs,
offsetThresholdForNextVsync, std::move(interceptCallback));
auto eventThreadConnection =
createConnectionInternal(eventThread.get(), std::move(resyncCallback),
ISurfaceComposer::eConfigChangedSuppress);
mConnections.emplace(id,
std::make_unique<Connection>(new ConnectionHandle(id),
eventThreadConnection,
std::move(eventThread)));
return mConnections[id]->handle;
}
这个函数里面分别创建了APP和SF的EventThread
,以及APP和SF的EventThreadConnection
,用一个ConnectionHandle
来封装EventThread
和EventThreadConnection
,通过id进行标识,将它们保存在mConnections
中。
其实创建EventThread
和EventThreadConnection
都做了非常多的事情,在前面分析Vsync
的分发和接收时都分析过,这里我们总结一下,首先说EventThread
的初始化:
EventThread
创建时接收了一个VSyncSource
对象,这也是个很重要的对象,主要负责接收硬件的VSync
并分发到APP或者SF,使用的是它的子类DispSyncSource
,VSyncSource
中有一个callback,这个callback的具体实现类是EventThread
,并且这个callback会被设置到DispSyncSource
中去,也就是说某些情况发生之后(收到Vsync),会在DispSyncSource
中调用EventThread
的onVSyncEvent
函数。class VSyncSource {
public:
class Callback {
public:
virtual ~Callback() {}
virtual void onVSyncEvent(nsecs_t when) = 0;
};
....
};
DispSyncSource
,它创建时又接收了一个DispSync
对象,这个对象才是真正做Vsync
的分发和接收的,依靠的是它内部的一个线程DispSyncThread
,并且DispSync
内部也有一个callback,这个callback是被DispSyncSource
实现的,那这个callback会往哪里传呢?class DispSync {
public:
class Callback {
public:
Callback() = default;
virtual ~Callback();
virtual void onDispSyncEvent(nsecs_t when) = 0;
......
};
其实它的传递是从EventThread
的内部线程开始的,EventThread
内部有两个变量mState和nextState,表示请求Vsync
的当前状态和下一次状态,如果两次状态不等并且下一次的状态为State::VSync
(代表请求VSync
),则调用DispSyncSource
的setVSyncEnabled(true)
函数,这个函数会将callback传递到DispSync
中去,前面不是说了真正做Vsync接收分发的是DispSync
吗,所以当DispSync
接收到Vsync就会回调DispSyncSource
的onDispSyncEvent
函数,onDispSyncEvent
中又会回调EventThread
的onVSyncEvent
函数,然后再看当前EventThread
是属于APP还是SF来决定此Vsync到底是发给谁。
if (mState != nextState) {
if (mState == State::VSync) {
mVSyncSource->setVSyncEnabled(false);
} else if (nextState == State::VSync) {
mVSyncSource->setVSyncEnabled(true);
}
mState = nextState;
}
Vsync
是由DispSync
进行管理,DispSync
接收来自硬件的Vsync
然后一分为二,VSYNC
的最终处理者是应用层的Choreographer
(绘制),SF_VSYNC
的处理者是SurfaceFlinger
(合成)。
EventThread
的总结就说完了,接着来看看EventThreadConnection
,这个类创建过程中最重要的事情就是创建了BitTube
EventThreadConnection::EventThreadConnection(EventThread* eventThread,
ResyncCallback resyncCallback,
ISurfaceComposer::ConfigChanged configChanged)
: resyncCallback(std::move(resyncCallback)),
configChanged(configChanged),
mEventThread(eventThread),
mChannel(gui::BitTube::DefaultSize) {}
BitTube
初始化时又创建了一对非常重要的socket
:
void BitTube::init(size_t rcvbuf, size_t sndbuf) {
int sockets[2];
if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets) == 0) {
size_t size = DEFAULT_SOCKET_BUFFER_SIZE;
setsockopt(sockets[0], SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf));
setsockopt(sockets[1], SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf));
// since we don't use the "return channel", we keep it small...
setsockopt(sockets[0], SOL_SOCKET, SO_SNDBUF, &size, sizeof(size));
setsockopt(sockets[1], SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
fcntl(sockets[0], F_SETFL, O_NONBLOCK);
fcntl(sockets[1], F_SETFL, O_NONBLOCK);
mReceiveFd.reset(sockets[0]);
mSendFd.reset(sockets[1]);
} else {
mReceiveFd.reset();
ALOGE("BitTube: pipe creation failed (%s)", strerror(errno));
}
}
这对socket
可以用于全双工通信,每一个socket
既可以读也可以写。例如,可以往socket[0]
中写,从socket[1]
中读,或者从socket[1]
中写,从socket[0]
中读。
读、写操作可以位于同一个进程,也可以分别位于不同的进程。
通过socketpair
创建好了一对socket
之后,再通过setsockopt
对socket
进行设置,再调用fcntl
函数针对socket
描述符提供控制,
最后mReceiveFd.reset(sockets[0]),mSendFd.reset(sockets[1])
建立Fd与socket
的关联,很明显这一对socket
一个用来接收消息,一个用来发送消息,那到底是接收和发送什么消息,其实就是Vsync
,当Vsync
到来的时候通过mSendFd
写入消息,然后APP或者SF监听mReceiveFd
接受消息,就完成了对Vsync
的接收,而完成监听mReceiveFd
,就能够收到mSendFd
的发送的消息依靠的是Handler
消息机制,Handler
处理消息的顺序是先处理native层message,再处理request,最后处理java层消息,这个request其实监听的各种fd。
当我们需要监听一对fd时,首先需要调用Looper的addFd
函数将fd添加到Handler
监听,addFd
这个函数会将fd的以及一系列和此fd有关的信息封装为request,然后加入监听,其中比较重要的除了fd还有一个就是callback,即收到此fd对端的消息之后要回调的函数。
for (size_t i = 0; i < mResponses.size(); i++) {
Response& response = mResponses.editItemAt(i);
if (response.request.ident == POLL_CALLBACK) {
int fd = response.request.fd;
int events = response.events;
void* data = response.request.data;
int callbackResult = response.request.callback->handleEvent(fd, events, data);
if (callbackResult == 0) {
removeFd(fd, response.request.seq);
}
response.request.callback.clear();
result = POLL_CALLBACK;
}
}
上面这一段代码就是Handler
收到消息之后会找到对应处理此消息的request,然后调用通过addFd
传递过来的callback的handleEvent
回调函数。
我们继续来看SurfaceFlinger
进程注册监听Vsync的fd的过程
void SurfaceFlinger::init() {
......
mSfConnectionHandle =
mScheduler->createConnection("sf", mVsyncModulator.getOffsets().sf,
mPhaseOffsets->getOffsetThresholdForNextVsync(),
resyncCallback, [this](nsecs_t timestamp) {
mInterceptor->saveVSyncEvent(timestamp);
});
mEventQueue->setEventConnection(mScheduler->getEventConnection(mSfConnectionHandle));
......
}
注意这里只注册了SurfaceFlinger
进程监听Vsync的fd,APP进程是在其他地方注册的,AndroidQ 应用层Vsync信号的注册与接收(上)这篇文章分析过了。
void MessageQueue::setEventConnection(const sp<EventThreadConnection>& connection) {
if (mEventTube.getFd() >= 0) {
mLooper->removeFd(mEventTube.getFd());
}
mEvents = connection;
mEvents->stealReceiveChannel(&mEventTube);
mLooper->addFd(mEventTube.getFd(), 0, Looper::EVENT_INPUT, MessageQueue::cb_eventReceiver,
this);
}
看到了吗,这里调用了mLooper->addFd
,第一个参数就是BitTube
中的mReceiveFd
,再看第四个参数,这就是callback,等会儿回来看。
int Looper::addFd(int fd, int ident, int events, Looper_callbackFunc callback, void* data) {
return addFd(fd, ident, events, callback ? new SimpleLooperCallback(callback) : nullptr, data);
}
我们发现Looper
的addFd
中接收的callback是一个Looper_callbackFunc
类型:
typedef int (*Looper_callbackFunc)(int fd, int events, void* data);
其实就是个int型函数指针,接着我们从MessageQueue
传过来的callback会被封装成一个SimpleLooperCallback
,它继承LooperCallback
,并且callback赋值给了SimpleLooperCallback
的mCallback
,它的handleEvent
函数直接调用的我们传递过来的这个callback,所以我们会发现Handler
收到消息是回调的handleEvent
函数,而MessageQueue
中确找不到这个函数的实现,其实中间有了这一层转换。
SimpleLooperCallback::SimpleLooperCallback(Looper_callbackFunc callback) :
mCallback(callback) {
}
SimpleLooperCallback::~SimpleLooperCallback() {
}
int SimpleLooperCallback::handleEvent(int fd, int events, void* data) {
return mCallback(fd, events, data);
}
好了我们再来看看MessageQueue
中这个callback的实现:
int MessageQueue::cb_eventReceiver(int fd, int events, void* data) {
MessageQueue* queue = reinterpret_cast<MessageQueue*>(data);
return queue->eventReceiver(fd, events);
}
记得addFd最后一个参数传了个this吗,这里this又被传回来了,接着调用MessageQueue
的eventReceiver
函数:
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) {
mFlinger->mVsyncTimeStamp = systemTime(SYSTEM_TIME_MONOTONIC);
mHandler->dispatchInvalidate();
break;
}
}
}
return 1;
}
这里while
循环中先调用DisplayEventReceiver
的getEvents
函数其实最终调到了BitTube
中,其目的就是去读mSendFd
写的数据,这里只处理类型为DISPLAY_EVENT_VSYNC
也就是Vsync的事件,一共有这么几个类型:
enum {
DISPLAY_EVENT_VSYNC = fourcc('v', 's', 'y', 'n'),
DISPLAY_EVENT_HOTPLUG = fourcc('p', 'l', 'u', 'g'),
DISPLAY_EVENT_CONFIG_CHANGED = fourcc('c', 'o', 'n', 'f'),
};
然后调用mHandler->dispatchInvalidate
函数进一步处理,
void MessageQueue::Handler::dispatchInvalidate() {
if ((android_atomic_or(eventMaskInvalidate, &mEventMask) & eventMaskInvalidate) == 0) {
mQueue.mLooper->sendMessage(this, Message(MessageQueue::INVALIDATE));
}
}
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;
}
}
其实就是发送一个INVALIDATE
消息,然后自己的handleMessage
进行处理。
到此我们已经了解了Vsync是怎么接收的以及接收之后干什么,我们先不继续往下分析,回到最开始去看看Vsync是怎么发送出来的,来看开始的onFrameAvailable
中调用的SurfaceFlinger::signalLayerUpdate
void SurfaceFlinger::signalLayerUpdate() {
mScheduler->resetIdleTimer();
mEventQueue->invalidate();
}
void MessageQueue::invalidate() {
mEvents->requestNextVsync();
}
看到了吗,这代码多明显,请求Vsync,Vsync是请求一次才能接收一次,所以当APP每绘制完一帧交给SurfaceFlinger
,SurfaceFlinger
都会请求Vsync然后进行合成,其实SF的requestNextVsync
和APP的执行流程差不多,只是EventThread
和EventThreadConnection
分属不同,这里调用EventThreadConnection
的requestNextVsync
函数直接调用的EventThread
的同名函数:
void EventThread::requestNextVsync(const sp<EventThreadConnection>& connection) {
if (connection->resyncCallback) {
connection->resyncCallback();
}
std::lock_guard<std::mutex> lock(mMutex);
if (connection->vsyncRequest == VSyncRequest::None) {
connection->vsyncRequest = VSyncRequest::Single;
mCondition.notify_all();
}
}
VSyncRequest定义在EventThread.h中:
enum class VSyncRequest {
None = -1,
Single = 0,
Periodic = 1,
// Subsequent values are periods.
};
代表了当前VSync
请求的三种状态,None
为初始值,Single
代表已经请求了一个VSync
,是一次性的,Periodic
代表请求的是周期性信号。
我们收到VSync
是需要自己请求的,请求一次,接收一次,而底层的VSync是以周期性在发送的,通常情况为16.6ms一次.
看到这里就能够知道为什么APP和SF请求的Vsync
是一次性的了
当VSyncRequest
为none时,给它赋值为Single,同一时间多次请求无效,接着调用 mCondition.notify_all()
函数,mCondition
定义在EventThread.h
中,类型为std::condition_variable
,这是一个条件变量,它在这里最大的用处就是唤醒/等待,那它唤醒的是什么呢?
唤醒的是EventThread
内部线程,EventThread
内部线程是一个死循环,主要用于处理Vsync
接收和分发,接收来自DispSync
的Vsync
,分发给APP或者SF,这个线程我前面这篇文章有详细分析过
AndroidQ SurfaceFlinger进程对Vsync的接收与分发(上)
我这里贴一下对此函数分析的总结:
threadMain
首先会开启一个死循环,这个循环会一直处理事件。mPendingEvents
头部获取 VSYNC
事件 Event
。mDisplayEventConnections
,找到其中所有 vsyncRequest
不为None的 connection
,并将这些 connection
放入 consumers
。dispatchEvent(*event, consumers)
分发事件,事件会分发给 consumers
中的所有 connection
。mState
和 nextState
的对比,选择 setVSyncEnabled(false)
还是 (true)
,当从State::VSync变为其他状态时调用setVSyncEnabled(false),当从其他状态变为State::VSync时调用setVSyncEnabled(true),mState和nextState的对比其实是起到一个开关作用。这里面最重要的
setVSyncEnabled(true)
函数,这个函数会将DispSync::Callback
传递到DispSync
中去,传过去干什么?去接收Vsync
,然后回调onDispSyncEvent
函数。onDispSyncEvent
又会回调EventThread
实现的callback onVSyncEvent
函数,从而将Vsync
一步一步送到了EventThread
中。onVSyncEvent
收到Vsync
之后会调用dispatchEvent
函数分发Vsync
,分发的实质就是向mSendFd
写入消息,这样我们监听的mReceiveFd
就收到了。而DispSync
的Vsync
又是来自哪里呢?调用栈如下:
BHwBinder->BnHwComposerCallback::onTransact
->BnHwComposerCallback::_hidl_onVsync
->ComposerCallbackBridge::onVsync
->SurfaceFlinger::onVsyncReceived
到了SurfaceFlinger::onVsyncReceived之后再传给DispSync
的。
这很明显就是HAL层回调过来的,具体就不详细看了,到此我们已经知道了当APP绘制好一帧之后queue
到BufferQueue
中,并调用onFrameAvailable
函数通知SurfaceFlinger
去取,之后就是调用SurfaceFlinger
的signalLayerUpdate
函数,此函数的目的就是请求SurfaceFlinger
进程的Vsync
,在收到Vsync
之后在MessageQueue
中通过Handler
发送INVALIDATE
的消息,接下来就是处理INVALIDATE
了,本篇文章暂时就不继续分析了,后面再详细看处理INVALIDATE
的过程。