SurfaceFlinger是一个独立的进程,我们来看下init.rc关于SurfaceFlinger的代码,我们可以看到SurfaceFlinger是属于core服务的。
- service surfaceflinger /system/bin/surfaceflinger
- class core
- user system
- group graphics drmrpc
- onrestart restart zygote
- writepid /dev/cpuset/system-background/tasks
service surfaceflinger /system/bin/surfaceflinger
class core
user system
group graphics drmrpc
onrestart restart zygote
writepid /dev/cpuset/system-background/tasks
一、SurfaceFlinger的启动过程
SurfaceFlinger的main函数在framework/native/services/surfaceflinger/main_surfaceflinger.cpp中
- int main(int, char**) {
- // When SF is launched in its own process, limit the number of
- // binder threads to 4.
- ProcessState::self()->setThreadPoolMaxThreadCount(4);//设置了Binder线程池最大线程为4
- // start the thread pool
- sp<ProcessState> ps(ProcessState::self());
- ps->startThreadPool();
- // instantiate surfaceflinger
- sp<SurfaceFlinger> flinger = new SurfaceFlinger();//创建SurfaceFlinger对象
- setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);
- set_sched_policy(0, SP_FOREGROUND);
- // initialize before clients can connect
- flinger->init();//调用SurfaceFlinger的init函数
- // publish surface flinger
- sp<IServiceManager> sm(defaultServiceManager());
- sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);//像serviceManager注册SurfaceFlinger服务
- // run in this thread
- flinger->run();//运行
- return 0;
- }
int main(int, char**) {
// When SF is launched in its own process, limit the number of
// binder threads to 4.
ProcessState::self()->setThreadPoolMaxThreadCount(4);//设置了Binder线程池最大线程为4
// start the thread pool
sp<ProcessState> ps(ProcessState::self());
ps->startThreadPool();
// instantiate surfaceflinger
sp<SurfaceFlinger> flinger = new SurfaceFlinger();//创建SurfaceFlinger对象
setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);
set_sched_policy(0, SP_FOREGROUND);
// initialize before clients can connect
flinger->init();//调用SurfaceFlinger的init函数
// publish surface flinger
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);//像serviceManager注册SurfaceFlinger服务
// run in this thread
flinger->run();//运行
return 0;
}
在主函数中先设置了该进程的binder线程池最大数为4,然后创建了SurfaceFlinger对象,并且调用了其init函数,接着把SurfaceFlinger服务注册到ServiceManager中,然后调用了run方法。
我们先来看下init函数
- void SurfaceFlinger::init() {
- ALOGI( "SurfaceFlinger's main thread ready to run. "
- "Initializing graphics H/W...");
- Mutex::Autolock _l(mStateLock);
- // initialize EGL for the default display 将EGL初始化成缺省的显示
- mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- eglInitialize(mEGLDisplay, NULL, NULL);
- // 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);
- // Initialize the H/W composer object. There may or may not be an
- // actual hardware composer underneath.
- mHwc = new HWComposer(this,//显示硬件抽象类
- *static_cast<HWComposer::EventHandler *>(this));
- // get a RenderEngine for the given display / config (can't fail)
- mRenderEngine = RenderEngine::create(mEGLDisplay, mHwc->getVisualID());
- // retrieve the EGL context that was selected/created
- mEGLContext = mRenderEngine->getEGLContext();
- LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
- "couldn't create EGLContext");
- // initialize our non-virtual displays 初始化显示设备
- for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
- DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);
- // set-up the displays that are already connected
- if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) {
- // All non-virtual displays are currently considered secure.
- bool isSecure = true;
- createBuiltinDisplayLocked(type);
- wp<IBinder> token = mBuiltinDisplays[i];
- sp<IGraphicBufferProducer> producer;
- sp<IGraphicBufferConsumer> consumer;
- BufferQueue::createBufferQueue(&producer, &consumer,
- new GraphicBufferAlloc());
- sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i,
- consumer);
- int32_t hwcId = allocateHwcDisplayId(type);
- sp<DisplayDevice> hw = new DisplayDevice(this,
- type, hwcId, mHwc->getFormat(hwcId), isSecure, token,
- fbs, producer,
- mRenderEngine->getEGLConfig());
- if (i > DisplayDevice::DISPLAY_PRIMARY) {
- // FIXME: currently we don't get blank/unblank requests
- // for displays other than the main display, so we always
- // assume a connected display is unblanked.
- ALOGD("marking display %zu as acquired/unblanked", i);
- hw->setPowerMode(HWC_POWER_MODE_NORMAL);
- }
- mDisplays.add(token, hw);
- }
- }
- // make the GLContext current so that we can create textures when creating Layers
- // (which may happens before we render something)
- getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
- mEventControlThread = new EventControlThread(this);
- mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
- // set a fake vsync period if there is no HWComposer
- if (mHwc->initCheck() != NO_ERROR) {
- mPrimaryDispSync.setPeriod(16666667);
- }
- // initialize our drawing state
- mDrawingState = mCurrentState;
- // set initial conditions (e.g. unblank default device)
- initializeDisplays();//初始化显示设备
- // start boot animation
- startBootAnim();//启动开机动画
- }
void SurfaceFlinger::init() {
ALOGI( "SurfaceFlinger's main thread ready to run. "
"Initializing graphics H/W...");
Mutex::Autolock _l(mStateLock);
// initialize EGL for the default display 将EGL初始化成缺省的显示
mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(mEGLDisplay, NULL, NULL);
// 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);
// Initialize the H/W composer object. There may or may not be an
// actual hardware composer underneath.
mHwc = new HWComposer(this,//显示硬件抽象类
*static_cast<HWComposer::EventHandler *>(this));
// get a RenderEngine for the given display / config (can't fail)
mRenderEngine = RenderEngine::create(mEGLDisplay, mHwc->getVisualID());
// retrieve the EGL context that was selected/created
mEGLContext = mRenderEngine->getEGLContext();
LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
"couldn't create EGLContext");
// initialize our non-virtual displays 初始化显示设备
for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);
// set-up the displays that are already connected
if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) {
// All non-virtual displays are currently considered secure.
bool isSecure = true;
createBuiltinDisplayLocked(type);
wp<IBinder> token = mBuiltinDisplays[i];
sp<IGraphicBufferProducer> producer;
sp<IGraphicBufferConsumer> consumer;
BufferQueue::createBufferQueue(&producer, &consumer,
new GraphicBufferAlloc());
sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i,
consumer);
int32_t hwcId = allocateHwcDisplayId(type);
sp<DisplayDevice> hw = new DisplayDevice(this,
type, hwcId, mHwc->getFormat(hwcId), isSecure, token,
fbs, producer,
mRenderEngine->getEGLConfig());
if (i > DisplayDevice::DISPLAY_PRIMARY) {
// FIXME: currently we don't get blank/unblank requests
// for displays other than the main display, so we always
// assume a connected display is unblanked.
ALOGD("marking display %zu as acquired/unblanked", i);
hw->setPowerMode(HWC_POWER_MODE_NORMAL);
}
mDisplays.add(token, hw);
}
}
// make the GLContext current so that we can create textures when creating Layers
// (which may happens before we render something)
getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
mEventControlThread = new EventControlThread(this);
mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
// set a fake vsync period if there is no HWComposer
if (mHwc->initCheck() != NO_ERROR) {
mPrimaryDispSync.setPeriod(16666667);
}
// initialize our drawing state
mDrawingState = mCurrentState;
// set initial conditions (e.g. unblank default device)
initializeDisplays();//初始化显示设备
// start boot animation
startBootAnim();//启动开机动画
}
init函数主要工作:
1.初始化OpenGL ES图形库。
2. 创建显示设备的抽象代表,负责和显示设备打交道。
3. 创建显示设备对象。
4. 启动EventThread。监听和处理SurfaceFlinger中的事件。
5.设置软件VSync信号周期。
6.初始化显示设备,调用initializeDisplays完成。
7.启动开机动画,调用了startBootAnim函数,只是设置了两个属性,其中一个ctl.start是启动了bootanim进程。
- void SurfaceFlinger::startBootAnim() {
- // start boot animation
- property_set("service.bootanim.exit", "0");
- property_set("ctl.start", "bootanim");
- }
void SurfaceFlinger::startBootAnim() {
// start boot animation
property_set("service.bootanim.exit", "0");
property_set("ctl.start", "bootanim");
}
二、消息和事件分发 MessageQueue和EventThread
MessageQueue和用于消息和事件的分发,这个和之前博客分析过得消息机制原理差不多。
我们先来看看MessageQueue的主要成员变量
- class MessageQueue {
- ......
- sp<SurfaceFlinger> mFlinger;//指向SurfaceFlinger
- sp<Looper> mLooper;//消息机制Looper对象
- sp<EventThread> mEventThread;//关联的EventThread
- sp<IDisplayEventConnection> mEvents;
- sp<BitTube> mEventTube;
- sp<Handler> mHandler;//消息处理器
class MessageQueue {
......
sp<SurfaceFlinger> mFlinger;//指向SurfaceFlinger
sp<Looper> mLooper;//消息机制Looper对象
sp<EventThread> mEventThread;//关联的EventThread
sp<IDisplayEventConnection> mEvents;
sp<BitTube> mEventTube;
sp<Handler> mHandler;//消息处理器
其中mEventThread主要是用来分析VSync信号的。
在SurfaceFlinger中有一个类型为MessageQueue的成员变量mEventQueue,在SurfaceFlinger的onFirstRef函数中会调用其init函数
- void SurfaceFlinger::onFirstRef()
- {
- mEventQueue.init(this);
- }
void SurfaceFlinger::onFirstRef()
{
mEventQueue.init(this);
}
在这个函数中创建了Looper和Handler对象,并且把flinger保存在mFlinger中。
- void MessageQueue::init(const sp<SurfaceFlinger>& flinger)
- {
- mFlinger = flinger;
- mLooper = new Looper(true);
- mHandler = new Handler(*this);
- }
void MessageQueue::init(const sp<SurfaceFlinger>& flinger)
{
mFlinger = flinger;
mLooper = new Looper(true);
mHandler = new Handler(*this);
}
我们来看下Handler这个类,它是MessageQueue类的一个内部类,这个类主要处理3个消息。
- class Handler : public MessageHandler {
- enum {
- eventMaskInvalidate = 0x1,//invalidate消息
- eventMaskRefresh = 0x2,//刷新消息
- eventMaskTransaction = 0x4
- };
- MessageQueue& mQueue;
- int32_t mEventMask;
- public:
- Handler(MessageQueue& queue) : mQueue(queue), mEventMask(0) { }
- virtual void handleMessage(const Message& message);
- void dispatchRefresh();
- void dispatchInvalidate();
- void dispatchTransaction();
- };
class Handler : public MessageHandler {
enum {
eventMaskInvalidate = 0x1,//invalidate消息
eventMaskRefresh = 0x2,//刷新消息
eventMaskTransaction = 0x4
};
MessageQueue& mQueue;
int32_t mEventMask;
public:
Handler(MessageQueue& queue) : mQueue(queue), mEventMask(0) { }
virtual void handleMessage(const Message& message);
void dispatchRefresh();
void dispatchInvalidate();
void dispatchTransaction();
};
我们再来看在SurfaceFlinger主函数最后调用了下面方法。
- flinger->run();
flinger->run();
SurfaceFlinger::run代码如下
- void SurfaceFlinger::run() {
- do {
- waitForEvent();
- } while (true);
- }
void SurfaceFlinger::run() {
do {
waitForEvent();
} while (true);
}
waitForEvent函数如下:
- void SurfaceFlinger::waitForEvent() {
- mEventQueue.waitMessage();
- }
void SurfaceFlinger::waitForEvent() {
mEventQueue.waitMessage();
}
然后又调用了EventQueue的waitMessage方法,记住这里是在主线程中循环调用的。
下面我们来看下waitMessage方法,flushCommands之前在分析Binder的博客中有提到,主要是清理工作的,和Binder驱动的交互关了。而pollOnce是消息机制,主要调用了epoll_wait函数,会阻塞,阻塞完了会分发消息队列中的消息。这里的消息只有自己在Handler中发的消息,还有在setEventThread中自己添加的fd。
- 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);
- }
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);
}
下面是Handler中发送消息,这个会在pollOnce中处理。
- 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::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));
}
}
在SurfaceFlinger的init函数还调用了如下函数
- mSFEventThread = new EventThread(sfVsyncSrc);
- mEventQueue.setEventThread(mSFEventThread);
mSFEventThread = new EventThread(sfVsyncSrc);
mEventQueue.setEventThread(mSFEventThread);
我们来看setEventThread函数会调用Looper的addFd,这个最终也会在pollOnce中执行。mEventThread是一个EventThread对象,调用createEventConnection来创建一个连接。EventThread是一个线程类用来分发VSync消息。这个我们后面讲解VSync信号的时候还会详细分析。
- 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::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);
}
三、显示设备 DisplayDevice类
DisplayDevice是显示设备的抽象,定义了3中类型的显示设备。
1.DISPLAY_PRIMARY:主显示设备,通常是LCD屏
2.DISPLAY_EXTERNAL:扩展显示设备。通过HDMI输出的显示信号
3.DISPLAY_VIRTUAL:虚拟显示设备,通过WIFI输出信号
这3钟设备,第一种是基本配置,另外两种需要硬件支持。这里我们主要讲解第一种。
SurfaceFlinger中需要显示的图层(layer)将通过DisplayDevice对象传递到OpenGLES中进行合成,合成之后的图像再通过HWComposer对象传递到Framebuffer中显示。DisplayDevice对象中的成员变量mVisibleLayersSortedByZ保存了所有需要显示在本显示设备中显示的Layer对象,同时DisplayDevice对象也保存了和显示设备相关的显示方向、显示区域坐标等信息。
上节在SurfaceFlinger的init函数中有一段代码来创建DisplayDevice对象
- for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
- DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);
- // set-up the displays that are already connected
- if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) {
- // All non-virtual displays are currently considered secure.
- bool isSecure = true;
- createBuiltinDisplayLocked(type);//给显示设备分配一个token
- wp<IBinder> token = mBuiltinDisplays[i];
- sp<IGraphicBufferProducer> producer;
- sp<IGraphicBufferConsumer> consumer;
- BufferQueue::createBufferQueue(&producer, &consumer,
- new GraphicBufferAlloc());
- sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i,
- consumer);
- int32_t hwcId = allocateHwcDisplayId(type);
- sp<DisplayDevice> hw = new DisplayDevice(this,
- type, hwcId, mHwc->getFormat(hwcId), isSecure, token,
- fbs, producer,
- mRenderEngine->getEGLConfig());
- if (i > DisplayDevice::DISPLAY_PRIMARY) {
- // FIXME: currently we don't get blank/unblank requests
- // for displays other than the main display, so we always
- // assume a connected display is unblanked.
- ALOGD("marking display %zu as acquired/unblanked", i);
- hw->setPowerMode(HWC_POWER_MODE_NORMAL);
- }
- mDisplays.add(token, hw);//把显示设备对象保存在mDisplays列表中
- }
- }
for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);
// set-up the displays that are already connected
if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) {
// All non-virtual displays are currently considered secure.
bool isSecure = true;
createBuiltinDisplayLocked(type);//给显示设备分配一个token
wp<IBinder> token = mBuiltinDisplays[i];
sp<IGraphicBufferProducer> producer;
sp<IGraphicBufferConsumer> consumer;
BufferQueue::createBufferQueue(&producer, &consumer,
new GraphicBufferAlloc());
sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i,
consumer);
int32_t hwcId = allocateHwcDisplayId(type);
sp<DisplayDevice> hw = new DisplayDevice(this,
type, hwcId, mHwc->getFormat(hwcId), isSecure, token,
fbs, producer,
mRenderEngine->getEGLConfig());
if (i > DisplayDevice::DISPLAY_PRIMARY) {
// FIXME: currently we don't get blank/unblank requests
// for displays other than the main display, so we always
// assume a connected display is unblanked.
ALOGD("marking display %zu as acquired/unblanked", i);
hw->setPowerMode(HWC_POWER_MODE_NORMAL);
}
mDisplays.add(token, hw);//把显示设备对象保存在mDisplays列表中
}
}
所有显示设备的输出都要通过HWComposer对象完成,因此上面这段代码先调用了HWComposer的isConnected来检查显示设备是否已连接,只有和显示设备连接的DisplayDevice对象才会被创建出来。即使没有任何物理显示设备被检测到,SurfaceFlinger都需要一个DisplayDevice对象才能正常工作,因此,DISPLAY_PRIMARY类型的DisplayDevice对象总是会被创建出来。
createBuiltinDisplayLocked函数就是为显示设备对象创建一个BBinder类型的Token而已。
- void SurfaceFlinger::createBuiltinDisplayLocked(DisplayDevice::DisplayType type) {
- ALOGW_IF(mBuiltinDisplays[type],
- "Overwriting display token for display type %d", type);
- mBuiltinDisplays[type] = new BBinder();
- DisplayDeviceState info(type);
- // All non-virtual displays are currently considered secure.
- info.isSecure = true;
- mCurrentState.displays.add(mBuiltinDisplays[type], info);
- }
void SurfaceFlinger::createBuiltinDisplayLocked(DisplayDevice::DisplayType type) {
ALOGW_IF(mBuiltinDisplays[type],
"Overwriting display token for display type %d", type);
mBuiltinDisplays[type] = new BBinder();
DisplayDeviceState info(type);
// All non-virtual displays are currently considered secure.
info.isSecure = true;
mCurrentState.displays.add(mBuiltinDisplays[type], info);
}
然后会调用createBufferQueue函数创建一个producer和consumer,这个之前分析过。然后又创建了一个FramebufferSurface对象。这里我们看到在新建FramebufferSurface对象时把consumer参数传入了代表是一个消费者。而在DisplayDevice的构造函数中,会创建一个Surface对象传递给底层的OpenGL ES使用,而这个Surface是一个生产者。在OpenGl ES中合成好了图像之后会将图像数据写到Surface对象中,这将触发consumer对象的onFrameAvailable函数被调用:
这就是Surface数据好了就通知消费者来拿数据做显示用,在onFrameAvailable函数汇总,通过nextBuffer获得图像数据,然后调用HWComposer对象mHwc的fbPost函数输出。
- void FramebufferSurface::onFrameAvailable(const BufferItem& /* item */) {
- sp<GraphicBuffer> buf;
- sp<Fence> acquireFence;
- status_t err = nextBuffer(buf, acquireFence);
- if (err != NO_ERROR) {
- ALOGE("error latching nnext FramebufferSurface buffer: %s (%d)",
- strerror(-err), err);
- return;
- }
- err = mHwc.fbPost(mDisplayType, acquireFence, buf);
- if (err != NO_ERROR) {
- ALOGE("error posting framebuffer: %d", err);
- }
- }
void FramebufferSurface::onFrameAvailable(const BufferItem& /* item */) {
sp<GraphicBuffer> buf;
sp<Fence> acquireFence;
status_t err = nextBuffer(buf, acquireFence);
if (err != NO_ERROR) {
ALOGE("error latching nnext FramebufferSurface buffer: %s (%d)",
strerror(-err), err);
return;
}
err = mHwc.fbPost(mDisplayType, acquireFence, buf);
if (err != NO_ERROR) {
ALOGE("error posting framebuffer: %d", err);
}
}
fbPost函数最后通过调用Gralloc模块的post函数来输出图像。
我们再来看看DisplayDevice的构造函数
- DisplayDevice::DisplayDevice(
- const sp<SurfaceFlinger>& flinger,
- DisplayType type,
- int32_t hwcId,
- int format,
- bool isSecure,
- const wp<IBinder>& displayToken,
- const sp<DisplaySurface>& displaySurface,
- const sp<IGraphicBufferProducer>& producer,
- EGLConfig config)
- : lastCompositionHadVisibleLayers(false),
- mFlinger(flinger),
- mType(type), mHwcDisplayId(hwcId),
- mDisplayToken(displayToken),
- mDisplaySurface(displaySurface),
- mDisplay(EGL_NO_DISPLAY),
- mSurface(EGL_NO_SURFACE),
- mDisplayWidth(), mDisplayHeight(), mFormat(),
- mFlags(),
- mPageFlipCount(),
- mIsSecure(isSecure),
- mSecureLayerVisible(false),
- mLayerStack(NO_LAYER_STACK),
- mOrientation(),
- mPowerMode(HWC_POWER_MODE_OFF),
- mActiveConfig(0)
- {
- mNativeWindow = new Surface(producer, false);//创建Surface对象
- ANativeWindow* const window = mNativeWindow.get();
- /*
- * Create our display's surface
- */
- EGLSurface surface;
- EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- if (config == EGL_NO_CONFIG) {
- config = RenderEngine::chooseEglConfig(display, format);
- }
- surface = eglCreateWindowSurface(display, config, window, NULL);
- eglQuerySurface(display, surface, EGL_WIDTH, &mDisplayWidth);
- eglQuerySurface(display, surface, EGL_HEIGHT, &mDisplayHeight);
- // Make sure that composition can never be stalled by a virtual display
- // consumer that isn't processing buffers fast enough. We have to do this
- // in two places:
- // * Here, in case the display is composed entirely by HWC.
- // * In makeCurrent(), using eglSwapInterval. Some EGL drivers set the
- // window's swap interval in eglMakeCurrent, so they'll override the
- // interval we set here.
- if (mType >= DisplayDevice::DISPLAY_VIRTUAL)//虚拟设备不支持图像合成
- window->setSwapInterval(window, 0);
- mConfig = config;
- mDisplay = display;
- mSurface = surface;
- mFormat = format;
- mPageFlipCount = 0;
- mViewport.makeInvalid();
- mFrame.makeInvalid();
- // virtual displays are always considered enabled 虚拟设备屏幕认为是不关闭的
- mPowerMode = (mType >= DisplayDevice::DISPLAY_VIRTUAL) ?
- HWC_POWER_MODE_NORMAL : HWC_POWER_MODE_OFF;
- // Name the display. The name will be replaced shortly if the display
- // was created with createDisplay().
- switch (mType) {//显示设备名称
- case DISPLAY_PRIMARY:
- mDisplayName = "Built-in Screen";
- break;
- case DISPLAY_EXTERNAL:
- mDisplayName = "HDMI Screen";
- break;
- default:
- mDisplayName = "Virtual Screen"; // e.g. Overlay #n
- break;
- }
- // initialize the display orientation transform.
- setProjection(DisplayState::eOrientationDefault, mViewport, mFrame);
- }
DisplayDevice::DisplayDevice(
const sp<SurfaceFlinger>& flinger,
DisplayType type,
int32_t hwcId,
int format,
bool isSecure,
const wp<IBinder>& displayToken,
const sp<DisplaySurface>& displaySurface,
const sp<IGraphicBufferProducer>& producer,
EGLConfig config)
: lastCompositionHadVisibleLayers(false),
mFlinger(flinger),
mType(type), mHwcDisplayId(hwcId),
mDisplayToken(displayToken),
mDisplaySurface(displaySurface),
mDisplay(EGL_NO_DISPLAY),
mSurface(EGL_NO_SURFACE),
mDisplayWidth(), mDisplayHeight(), mFormat(),
mFlags(),
mPageFlipCount(),
mIsSecure(isSecure),
mSecureLayerVisible(false),
mLayerStack(NO_LAYER_STACK),
mOrientation(),
mPowerMode(HWC_POWER_MODE_OFF),
mActiveConfig(0)
{
mNativeWindow = new Surface(producer, false);//创建Surface对象
ANativeWindow* const window = mNativeWindow.get();
/*
* Create our display's surface
*/
EGLSurface surface;
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (config == EGL_NO_CONFIG) {
config = RenderEngine::chooseEglConfig(display, format);
}
surface = eglCreateWindowSurface(display, config, window, NULL);
eglQuerySurface(display, surface, EGL_WIDTH, &mDisplayWidth);
eglQuerySurface(display, surface, EGL_HEIGHT, &mDisplayHeight);
// Make sure that composition can never be stalled by a virtual display
// consumer that isn't processing buffers fast enough. We have to do this
// in two places:
// * Here, in case the display is composed entirely by HWC.
// * In makeCurrent(), using eglSwapInterval. Some EGL drivers set the
// window's swap interval in eglMakeCurrent, so they'll override the
// interval we set here.
if (mType >= DisplayDevice::DISPLAY_VIRTUAL)//虚拟设备不支持图像合成
window->setSwapInterval(window, 0);
mConfig = config;
mDisplay = display;
mSurface = surface;
mFormat = format;
mPageFlipCount = 0;
mViewport.makeInvalid();
mFrame.makeInvalid();
// virtual displays are always considered enabled 虚拟设备屏幕认为是不关闭的
mPowerMode = (mType >= DisplayDevice::DISPLAY_VIRTUAL) ?
HWC_POWER_MODE_NORMAL : HWC_POWER_MODE_OFF;
// Name the display. The name will be replaced shortly if the display
// was created with createDisplay().
switch (mType) {//显示设备名称
case DISPLAY_PRIMARY:
mDisplayName = "Built-in Screen";
break;
case DISPLAY_EXTERNAL:
mDisplayName = "HDMI Screen";
break;
default:
mDisplayName = "Virtual Screen"; // e.g. Overlay #n
break;
}
// initialize the display orientation transform.
setProjection(DisplayState::eOrientationDefault, mViewport, mFrame);
}
上面构造函数主要功能是创建了一个Surface对象mNativeWindow,同时用它作为参数创建EGLSurface对象,这个EGLSurface对象是OpenGL ES中绘图需要的。
这样,在DisplayDevice中就建立了一个通向Framebuffer的通道,只要向DisplayDevice的mSurface写入数据。就会到消费者FrameBufferSurface的onFrameAvailable函数,然后到HWComposer在到Gralloc模块,最后输出到显示设备。
swapBuffers函数将内部缓冲区的图像数据刷新到显示设备的Framebuffer中,它通过调用eglSwapBuffers函数来完成缓冲区刷新工作。但是注意调用swapBuffers输出图像是在显示设备不支持硬件composer的情况下。
- void DisplayDevice::swapBuffers(HWComposer& hwc) const {
- // We need to call eglSwapBuffers() if:
- // (1) we don't have a hardware composer, or
- // (2) we did GLES composition this frame, and either
- // (a) we have framebuffer target support (not present on legacy
- // devices, where HWComposer::commit() handles things); or
- // (b) this is a virtual display
- if (hwc.initCheck() != NO_ERROR ||
- (hwc.hasGlesComposition(mHwcDisplayId) &&
- (hwc.supportsFramebufferTarget() || mType >= DISPLAY_VIRTUAL))) {
- EGLBoolean success = eglSwapBuffers(mDisplay, mSurface);
- if (!success) {
- EGLint error = eglGetError();
- if (error == EGL_CONTEXT_LOST ||
- mType == DisplayDevice::DISPLAY_PRIMARY) {
- LOG_ALWAYS_FATAL("eglSwapBuffers(%p, %p) failed with 0x%08x",
- mDisplay, mSurface, error);
- } else {
- ALOGE("eglSwapBuffers(%p, %p) failed with 0x%08x",
- mDisplay, mSurface, error);
- }
- }
- }
- else if(hwc.supportsFramebufferTarget() || mType >= DISPLAY_VIRTUAL)
- {
- EGLBoolean success = eglSwapBuffersVIV(mDisplay, mSurface);
- if (!success) {
- EGLint error = eglGetError();
- ALOGE("eglSwapBuffersVIV(%p, %p) failed with 0x%08x",
- mDisplay, mSurface, error);
- }
- }
- status_t result = mDisplaySurface->advanceFrame();
- if (result != NO_ERROR) {
- ALOGE("[%s] failed pushing new frame to HWC: %d",
- mDisplayName.string(), result);
- }
- }
void DisplayDevice::swapBuffers(HWComposer& hwc) const {
// We need to call eglSwapBuffers() if:
// (1) we don't have a hardware composer, or
// (2) we did GLES composition this frame, and either
// (a) we have framebuffer target support (not present on legacy
// devices, where HWComposer::commit() handles things); or
// (b) this is a virtual display
if (hwc.initCheck() != NO_ERROR ||
(hwc.hasGlesComposition(mHwcDisplayId) &&
(hwc.supportsFramebufferTarget() || mType >= DISPLAY_VIRTUAL))) {
EGLBoolean success = eglSwapBuffers(mDisplay, mSurface);
if (!success) {
EGLint error = eglGetError();
if (error == EGL_CONTEXT_LOST ||
mType == DisplayDevice::DISPLAY_PRIMARY) {
LOG_ALWAYS_FATAL("eglSwapBuffers(%p, %p) failed with 0x%08x",
mDisplay, mSurface, error);
} else {
ALOGE("eglSwapBuffers(%p, %p) failed with 0x%08x",
mDisplay, mSurface, error);
}
}
}
else if(hwc.supportsFramebufferTarget() || mType >= DISPLAY_VIRTUAL)
{
EGLBoolean success = eglSwapBuffersVIV(mDisplay, mSurface);
if (!success) {
EGLint error = eglGetError();
ALOGE("eglSwapBuffersVIV(%p, %p) failed with 0x%08x",
mDisplay, mSurface, error);
}
}
status_t result = mDisplaySurface->advanceFrame();
if (result != NO_ERROR) {
ALOGE("[%s] failed pushing new frame to HWC: %d",
mDisplayName.string(), result);
}
}
四、VSync信号的分发过程
在之前的博客分析过,当VSync信号到来时会调用HWComposer类中的vsync函数
- void HWComposer::vsync(int disp, int64_t timestamp) {
- if (uint32_t(disp) < HWC_NUM_PHYSICAL_DISPLAY_TYPES) {
- {
- Mutex::Autolock _l(mLock);
- // There have been reports of HWCs that signal several vsync events
- // with the same timestamp when turning the display off and on. This
- // is a bug in the HWC implementation, but filter the extra events
- // out here so they don't cause havoc downstream.
- if (timestamp == mLastHwVSync[disp]) {
- ALOGW("Ignoring duplicate VSYNC event from HWC (t=%" PRId64 ")",
- timestamp);
- return;
- }
- mLastHwVSync[disp] = timestamp;
- }
- char tag[16];
- snprintf(tag, sizeof(tag), "HW_VSYNC_%1u", disp);
- ATRACE_INT(tag, ++mVSyncCounts[disp] & 1);
- mEventHandler.onVSyncReceived(disp, timestamp);
- }
- }
void HWComposer::vsync(int disp, int64_t timestamp) {
if (uint32_t(disp) < HWC_NUM_PHYSICAL_DISPLAY_TYPES) {
{
Mutex::Autolock _l(mLock);
// There have been reports of HWCs that signal several vsync events
// with the same timestamp when turning the display off and on. This
// is a bug in the HWC implementation, but filter the extra events
// out here so they don't cause havoc downstream.
if (timestamp == mLastHwVSync[disp]) {
ALOGW("Ignoring duplicate VSYNC event from HWC (t=%" PRId64 ")",
timestamp);
return;
}
mLastHwVSync[disp] = timestamp;
}
char tag[16];
snprintf(tag, sizeof(tag), "HW_VSYNC_%1u", disp);
ATRACE_INT(tag, ++mVSyncCounts[disp] & 1);
mEventHandler.onVSyncReceived(disp, timestamp);
}
}
这个函数主要是调用了mEventHandler.onVSyncReceived函数,让我们先来看下mEventHandler的构造,看HWComposer的构造函数,mEventHandler是传入的参数handler。
- HWComposer::HWComposer(
- const sp<SurfaceFlinger>& flinger,
- EventHandler& handler)
- : mFlinger(flinger),
- mFbDev(0), mHwc(0), mNumDisplays(1),
- mCBContext(new cb_context),
- mEventHandler(handler),
- mDebugForceFakeVSync(false)
HWComposer::HWComposer(
const sp<SurfaceFlinger>& flinger,
EventHandler& handler)
: mFlinger(flinger),
mFbDev(0), mHwc(0), mNumDisplays(1),
mCBContext(new cb_context),
mEventHandler(handler),
mDebugForceFakeVSync(false)
那么我们就要看新建HWComposer的地方了,是在SurfaceFlinger的init函数中新建的,这handler就是SurfaceFlinger对象。
- mHwc = new HWComposer(this,
- *static_cast<HWComposer::EventHandler *>(this));
mHwc = new HWComposer(this,
*static_cast<HWComposer::EventHandler *>(this));
因此上面的mEventHandler.onVSyncReceived函数,就是调用了SurfaceFlinger的onVSyncReceived函数
- void SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) {
- bool needsHwVsync = false;
- { // Scope for the lock
- Mutex::Autolock _l(mHWVsyncLock);
- if (type == 0 && mPrimaryHWVsyncEnabled) {
- needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp);
- }
- }
- if (needsHwVsync) {
- enableHardwareVsync();
- } else {
- disableHardwareVsync(false);
- }
- }
void SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) {
bool needsHwVsync = false;
{ // Scope for the lock
Mutex::Autolock _l(mHWVsyncLock);
if (type == 0 && mPrimaryHWVsyncEnabled) {
needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp);
}
}
if (needsHwVsync) {
enableHardwareVsync();
} else {
disableHardwareVsync(false);
}
}
4.1 DispSync类
上面函数我们主要看下DispSync的addResyncSample函数,看这个函数之前先看下DispSync的构造函数,在构造函数中启动了DispSyncThread线程
- DispSync::DispSync() :
- mRefreshSkipCount(0),
- mThread(new DispSyncThread()) {
- mThread->run("DispSync", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
DispSync::DispSync() :
mRefreshSkipCount(0),
mThread(new DispSyncThread()) {
mThread->run("DispSync", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
我们再来看addResyncSample函数,将VSync信号的时间戳保存大搜了数组mResyncSamples中。然后调用了updateModelLocked函数继续分发VSync信号。
- bool DispSync::addResyncSample(nsecs_t timestamp) {
- Mutex::Autolock lock(mMutex);
- size_t idx = (mFirstResyncSample + mNumResyncSamples) % MAX_RESYNC_SAMPLES;
- mResyncSamples[idx] = timestamp;
- if (mNumResyncSamples < MAX_RESYNC_SAMPLES) {
- mNumResyncSamples++;
- } else {
- mFirstResyncSample = (mFirstResyncSample + 1) % MAX_RESYNC_SAMPLES;
- }
- updateModelLocked();
- if (mNumResyncSamplesSincePresent++ > MAX_RESYNC_SAMPLES_WITHOUT_PRESENT) {
- resetErrorLocked();
- }
- if (kIgnorePresentFences) {
- // If we don't have the sync framework we will never have
- // addPresentFence called. This means we have no way to know whether
- // or not we're synchronized with the HW vsyncs, so we just request
- // that the HW vsync events be turned on whenever we need to generate
- // SW vsync events.
- return mThread->hasAnyEventListeners();
- }
- return mPeriod == 0 || mError > kErrorThreshold;
- }
bool DispSync::addResyncSample(nsecs_t timestamp) {
Mutex::Autolock lock(mMutex);
size_t idx = (mFirstResyncSample + mNumResyncSamples) % MAX_RESYNC_SAMPLES;
mResyncSamples[idx] = timestamp;
if (mNumResyncSamples < MAX_RESYNC_SAMPLES) {
mNumResyncSamples++;
} else {
mFirstResyncSample = (mFirstResyncSample + 1) % MAX_RESYNC_SAMPLES;
}
updateModelLocked();
if (mNumResyncSamplesSincePresent++ > MAX_RESYNC_SAMPLES_WITHOUT_PRESENT) {
resetErrorLocked();
}
if (kIgnorePresentFences) {
// If we don't have the sync framework we will never have
// addPresentFence called. This means we have no way to know whether
// or not we're synchronized with the HW vsyncs, so we just request
// that the HW vsync events be turned on whenever we need to generate
// SW vsync events.
return mThread->hasAnyEventListeners();
}
return mPeriod == 0 || mError > kErrorThreshold;
}
updateModelLocked主要显示利用数组mResyncSamples中的值计算mPeriod和mPhase这两个时间值。然后最后调用了mThread的updateModel函数。mThread是DispSyncThread类。
- void DispSync::updateModelLocked() {
- if (mNumResyncSamples >= MIN_RESYNC_SAMPLES_FOR_UPDATE) {
- ......
- //计算mPeriod和mPhase
- mThread->updateModel(mPeriod, mPhase);
- }
- }
void DispSync::updateModelLocked() {
if (mNumResyncSamples >= MIN_RESYNC_SAMPLES_FOR_UPDATE) {
......
//计算mPeriod和mPhase
mThread->updateModel(mPeriod, mPhase);
}
}
我们来看下DispSyncThread的updateModel函数,这个函数只是保存了参数,然后调用了Condition的signal唤醒线程。
- void updateModel(nsecs_t period, nsecs_t phase) {
- Mutex::Autolock lock(mMutex);
- mPeriod = period;
- mPhase = phase;
- mCond.signal();
- }
void updateModel(nsecs_t period, nsecs_t phase) {
Mutex::Autolock lock(mMutex);
mPeriod = period;
mPhase = phase;
mCond.signal();
}
我们再来看DispSyncThread的threadLoop函数,主要这个函数比较计算时间来决定是否要发送信号。如果没有信号发送就会在mCond等待,有信号发送前面会在updateModel中调用mCond的singal函数,这里线程就唤醒了。gatherCallbackInvocationsLocked函数获取本次VSync信号的回调函数列表,这些回调函数是通过DispSync类的addEventListener函数加入的。接着就调用fireCallbackInvocations来依次调用列表中所有对象的onDispSyncEvent函数。
- virtual bool threadLoop() {
- ......
- while (true) {
- Vector<CallbackInvocation> callbackInvocations;
- nsecs_t targetTime = 0;
- { // Scope for lock
- ......
- if (now < targetTime) {
- err = mCond.waitRelative(mMutex, targetTime - now);
- ......
- }
- now = systemTime(SYSTEM_TIME_MONOTONIC);
- ......
- callbackInvocations = gatherCallbackInvocationsLocked(now);
- }
- if (callbackInvocations.size() > 0) {
- fireCallbackInvocations(callbackInvocations);
- }
- }
- return false;
- }
virtual bool threadLoop() {
......
while (true) {
Vector<CallbackInvocation> callbackInvocations;
nsecs_t targetTime = 0;
{ // Scope for lock
......
if (now < targetTime) {
err = mCond.waitRelative(mMutex, targetTime - now);
......
}
now = systemTime(SYSTEM_TIME_MONOTONIC);
......
callbackInvocations = gatherCallbackInvocationsLocked(now);
}
if (callbackInvocations.size() > 0) {
fireCallbackInvocations(callbackInvocations);
}
}
return false;
}
fireCallbackInvocations函数就是遍历回调列表调用其onDispSyncEvent函数。
- void fireCallbackInvocations(const Vector<CallbackInvocation>& callbacks) {
- for (size_t i = 0; i < callbacks.size(); i++) {
- callbacks[i].mCallback->onDispSyncEvent(callbacks[i].mEventTime);
- }
- }
void fireCallbackInvocations(const Vector<CallbackInvocation>& callbacks) {
for (size_t i = 0; i < callbacks.size(); i++) {
callbacks[i].mCallback->onDispSyncEvent(callbacks[i].mEventTime);
}
}
4.2 EventThread和DispSync的关系
这里我们先不往下分析DispSync遍历调用回调,我们先来看看EventThread的threadLoop函数,这个函数逻辑很简单。调用waitForEvent来获取事件,然后调用每个连接的postEvent来发送Event。
- bool EventThread::threadLoop() {
- DisplayEventReceiver::Event event;
- Vector< sp<EventThread::Connection> > signalConnections;
- signalConnections = waitForEvent(&event);//获取Event
- // dispatch events to listeners...
- const size_t count = signalConnections.size();
- for (size_t i=0 ; i<count ; i++) {
- const sp<Connection>& conn(signalConnections[i]);
- // now see if we still need to report this event
- status_t err = conn->postEvent(event);//发送Event
- if (err == -EAGAIN || err == -EWOULDBLOCK) {
- // The destination doesn't accept events anymore, it's probably
- // full. For now, we just drop the events on the floor.
- // FIXME: Note that some events cannot be dropped and would have
- // to be re-sent later.
- // Right-now we don't have the ability to do this.
- ALOGW("EventThread: dropping event (%08x) for connection %p",
- event.header.type, conn.get());
- } else if (err < 0) {
- // handle any other error on the pipe as fatal. the only
- // reasonable thing to do is to clean-up this connection.
- // The most common error we'll get here is -EPIPE.
- removeDisplayEventConnection(signalConnections[i]);
- }
- }
- return true;
- }
bool EventThread::threadLoop() {
DisplayEventReceiver::Event event;
Vector< sp<EventThread::Connection> > signalConnections;
signalConnections = waitForEvent(&event);//获取Event
// dispatch events to listeners...
const size_t count = signalConnections.size();
for (size_t i=0 ; i<count ; i++) {
const sp<Connection>& conn(signalConnections[i]);
// now see if we still need to report this event
status_t err = conn->postEvent(event);//发送Event
if (err == -EAGAIN || err == -EWOULDBLOCK) {
// The destination doesn't accept events anymore, it's probably
// full. For now, we just drop the events on the floor.
// FIXME: Note that some events cannot be dropped and would have
// to be re-sent later.
// Right-now we don't have the ability to do this.
ALOGW("EventThread: dropping event (%08x) for connection %p",
event.header.type, conn.get());
} else if (err < 0) {
// handle any other error on the pipe as fatal. the only
// reasonable thing to do is to clean-up this connection.
// The most common error we'll get here is -EPIPE.
removeDisplayEventConnection(signalConnections[i]);
}
}
return true;
}
我们再来看下waitForEvent函数中下面代码段,timestamp为0表示没有时间,waitForSync为true表示至少有一个客户和EventThread建立了连接。这段代码一旦有客户连接,就调用enableVSyncLocked接收DispSyncSource的VSync信号。如果在接受信号中,所有客户都断开了连接,则调用disableVSyncLocked函数停止接受DispSyncSource对象的信号。
- // Here we figure out if we need to enable or disable vsyncs
- if (timestamp && !waitForVSync) {
- // we received a VSYNC but we have no clients
- // don't report it, and disable VSYNC events
- disableVSyncLocked();
- } else if (!timestamp && waitForVSync) {
- // we have at least one client, so we want vsync enabled
- // (TODO: this function is called right after we finish
- // notifying clients of a vsync, so this call will be made
- // at the vsync rate, e.g. 60fps. If we can accurately
- // track the current state we could avoid making this call
- // so often.)
- enableVSyncLocked();
- }
// Here we figure out if we need to enable or disable vsyncs
if (timestamp && !waitForVSync) {
// we received a VSYNC but we have no clients
// don't report it, and disable VSYNC events
disableVSyncLocked();
} else if (!timestamp && waitForVSync) {
// we have at least one client, so we want vsync enabled
// (TODO: this function is called right after we finish
// notifying clients of a vsync, so this call will be made
// at the vsync rate, e.g. 60fps. If we can accurately
// track the current state we could avoid making this call
// so often.)
enableVSyncLocked();
}
我们先来看下enableVSyncLocked函数
- void EventThread::enableVSyncLocked() {
- if (!mUseSoftwareVSync) {
- // never enable h/w VSYNC when screen is off
- if (!mVsyncEnabled) {
- mVsyncEnabled = true;
- mVSyncSource->setCallback(static_cast<VSyncSource::Callback*>(this));
- mVSyncSource->setVSyncEnabled(true);
- }
- }
- mDebugVsyncEnabled = true;
- sendVsyncHintOnLocked();
- }
void EventThread::enableVSyncLocked() {
if (!mUseSoftwareVSync) {
// never enable h/w VSYNC when screen is off
if (!mVsyncEnabled) {
mVsyncEnabled = true;
mVSyncSource->setCallback(static_cast<VSyncSource::Callback*>(this));
mVSyncSource->setVSyncEnabled(true);
}
}
mDebugVsyncEnabled = true;
sendVsyncHintOnLocked();
}
我们先来看看mVSyncSource->setCallback函数。先要知道这个mVSyncSource是在SurfaceFlinger的init函数中。
- 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);
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);
看到上面这段代码,我们知道这个mVsyncSource是DispSyncSource类,我们先来看起setCallback函数,就是把callback保存起来
- virtual void setCallback(const sp<VSyncSource::Callback>& callback) {
- Mutex::Autolock lock(mCallbackMutex);
- mCallback = callback;
- }
virtual void setCallback(const sp<VSyncSource::Callback>& callback) {
Mutex::Autolock lock(mCallbackMutex);
mCallback = callback;
}
再来看setVSyncEnabled函数,这里参数enable是true,就是调用了DispSync的addEventListenter。这里就回到了上一小节了,这里我们就在DispSync中注册了回调了
- virtual void setVSyncEnabled(bool enable) {
- Mutex::Autolock lock(mVsyncMutex);
- if (enable) {
- status_t err = mDispSync->addEventListener(mPhaseOffset,
- static_cast<DispSync::Callback*>(this));
- if (err != NO_ERROR) {
- ALOGE("error registering vsync callback: %s (%d)",
- strerror(-err), err);
- }
- //ATRACE_INT(mVsyncOnLabel.string(), 1);
- } else {
- status_t err = mDispSync->removeEventListener(
- static_cast<DispSync::Callback*>(this));
- if (err != NO_ERROR) {
- ALOGE("error unregistering vsync callback: %s (%d)",
- strerror(-err), err);
- }
- //ATRACE_INT(mVsyncOnLabel.string(), 0);
- }
- mEnabled = enable;
- }
virtual void setVSyncEnabled(bool enable) {
Mutex::Autolock lock(mVsyncMutex);
if (enable) {
status_t err = mDispSync->addEventListener(mPhaseOffset,
static_cast<DispSync::Callback*>(this));
if (err != NO_ERROR) {
ALOGE("error registering vsync callback: %s (%d)",
strerror(-err), err);
}
//ATRACE_INT(mVsyncOnLabel.string(), 1);
} else {
status_t err = mDispSync->removeEventListener(
static_cast<DispSync::Callback*>(this));
if (err != NO_ERROR) {
ALOGE("error unregistering vsync callback: %s (%d)",
strerror(-err), err);
}
//ATRACE_INT(mVsyncOnLabel.string(), 0);
}
mEnabled = enable;
}
这样回想上一节在fireCallbackInvocations中遍历所有的回调时,就调用了DispSyncSource类的onDispSyncEvent函数,而这个函数主要是调用了其成员变量mCallback的onVSyncEvent,这个mCallback就是之前在EventThread中的waitForEvent注册的,就是EventThread自己。
- virtual void onDispSyncEvent(nsecs_t when) {
- sp<VSyncSource::Callback> callback;
- {
- Mutex::Autolock lock(mCallbackMutex);
- callback = mCallback;
- if (mTraceVsync) {
- mValue = (mValue + 1) % 2;
- ATRACE_INT(mVsyncEventLabel.string(), mValue);
- }
- }
- if (callback != NULL) {
- callback->onVSyncEvent(when);
- }
- }
virtual void onDispSyncEvent(nsecs_t when) {
sp<VSyncSource::Callback> callback;
{
Mutex::Autolock lock(mCallbackMutex);
callback = mCallback;
if (mTraceVsync) {
mValue = (mValue + 1) % 2;
ATRACE_INT(mVsyncEventLabel.string(), mValue);
}
}
if (callback != NULL) {
callback->onVSyncEvent(when);
}
}
因此最后到了EventThread的onVsyncEvent函数,这个函数把数据放在mVSyncEvent数组第一个,然后调用了Condition的broadcast函数。
- void EventThread::onVSyncEvent(nsecs_t timestamp) {
- Mutex::Autolock _l(mLock);
- mVSyncEvent[0].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
- mVSyncEvent[0].header.id = 0;
- mVSyncEvent[0].header.timestamp = timestamp;
- mVSyncEvent[0].vsync.count++;
- mCondition.broadcast();
- }
void EventThread::onVSyncEvent(nsecs_t timestamp) {
Mutex::Autolock _l(mLock);
mVSyncEvent[0].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
mVSyncEvent[0].header.id = 0;
mVSyncEvent[0].header.timestamp = timestamp;
mVSyncEvent[0].vsync.count++;
mCondition.broadcast();
}
最后之前在EventThread的threadLoop函数中调用waitForEvent会阻塞,当这里调用Condition的broadcast之后,waitForEvent就唤醒,并且得到了mVsynEvent中的数据。紧接着就是在EventThread中的threadLoop调用conn->postEvent来发送Event。这里是通过BitTube对象中的socket发送到MessageQueue中。这个我们在第二节中分析过了。
4.3 MessageQueue分发VSync信号
我们来回顾下,在MessageQueue中有下面这个函数。这样当EventThread通过BitTube传送数据的话,pollOnce会唤醒epoll_wait然后就到这个cb_eventReceiver这个回调函数
- 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::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);
}
cb_eventReceiver就是调用了eventReceiver函数。
- 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;
- }
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;
}
这里我们支持VSync信号就会调用mHandler的dispatchRefresh函数。
- void MessageQueue::Handler::dispatchRefresh() {
- if ((android_atomic_or(eventMaskRefresh, &mEventMask) & eventMaskRefresh) == 0) {
- mQueue.mLooper->sendMessage(this, Message(MessageQueue::REFRESH));
- }
- }
void MessageQueue::Handler::dispatchRefresh() {
if ((android_atomic_or(eventMaskRefresh, &mEventMask) & eventMaskRefresh) == 0) {
mQueue.mLooper->sendMessage(this, Message(MessageQueue::REFRESH));
}
}
而在Hander的处理中,最终是调用了SurfaceFlinger的onMessageReceived函数
- case REFRESH:
- android_atomic_and(~eventMaskRefresh, &mEventMask);
- mQueue.mFlinger->onMessageReceived(message.what);
- break;
case REFRESH:
android_atomic_and(~eventMaskRefresh, &mEventMask);
mQueue.mFlinger->onMessageReceived(message.what);
break;
而在SurfaceFlinger的onMessageReceived函数最终会调用了handleMessageRefresh函数。
- void SurfaceFlinger::onMessageReceived(int32_t what) {
- ATRACE_CALL();
- switch (what) {
- ......
- case MessageQueue::REFRESH: {
- handleMessageRefresh();
- break;
- }
- }
- }
void SurfaceFlinger::onMessageReceived(int32_t what) {
ATRACE_CALL();
switch (what) {
......
case MessageQueue::REFRESH: {
handleMessageRefresh();
break;
}
}
}
handleMessageRefresh函数负责刷新系统的显示。这样我们就分析了从底层发送VSync信号最终到达SurfaceFlinger的handleMessageRefresh函数。
4.4 VSync信号分发总结
我们回顾下整个流程,VSync信号从底层产生后,经过几个函数,保存到了SurfaceFlinger的mPrimaryDispSync变量(DisySync类)的数组中,这样设计的目的让底层的调用尽快结束,否则会耽搁下次VSync信号的发送。然后在mPrimaryDispSync变量关联的线程开始分发数组中的VSync信号,分发的过程也调用了几个回调函数,最终结果是放在EventThread对象的数组中。EventThread是转发VSync信号的中心。不但会把VSync信号发给SurfaceFlinger,还会把信号发送到用户进程中去。EventThread的工作比较重,因此SurfaceFlinger中使用了两个EventThread对象来转发VSync信号。确保能及时转发。SurfaceFlinger中的MessageQueue收到Event后,会将Event转化成消息发送,这样最终就能在主线程调用SurfaceFlinger的函数处理VSync信号了。