SurfaceFlinger 原理分析
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SurfaceFlinger 原理分析相关的知识,希望对你有一定的参考价值。
参考技术ASurfaceFlinger是android multimedia的一个部分,在Android 的实现中它是一个service,提供系统范围内的surface composer功能,它能够将各种应用程序的2D、3D surface进行组合。
每个应用程序可能对应着一个或者多个图形界面,而每个界面我们就称之为一个surface ,或者说是window ,在上面的图中我们能看到4 个surface ,一个是home 界面,还有就是红、绿、蓝分别代表的3个surface ,而两个button 实际是home surface 里面的内容。我们需要考虑一下情况:
在实际中对这些Surface 进行merge 可以采用两种方式,一种就是采用软件的形式来merge ,还一种就是采用硬件的方式,软件的方式就是我们的 SurfaceFlinger ,而硬件的方式就是 Overlay 。
因为硬件merge 内容相对简单,我们首先来看overlay 。以IMX51 为例子,当IPU 向内核申请FB 的时候它会申请3 个FB ,一个是主屏的,还一个是副屏的,还一个就是Overlay 的。 简单地来说,Overlay就是我们将硬件所能接受的格式数据和控制信息送到这个Overlay FrameBuffer,由硬件驱动来负责merge Overlay buffer和主屏buffer中的内容。
一般来说现在的硬件都只支持一个Overlay,主要用在视频播放以及camera preview上,因为视频内容的不断变化用硬件Merge比用软件Merge要有效率得多,下面就是使用Overlay和不使用Overlay的过程:
surfaceFlinger 只是负责 merge Surface 的控制,比如说计算出两个 Surface 重叠的区域,至于 Surface 需要显示的内容,则通过 skia,opengl 和 pixflinger 来计算。
创建过程
SurfaceFlinger 是一个线程类,它继承了 Thread 类。当创建 SurfaceFlinger 这个服务的时候会启动一个 SurfaceFlinger 监听线程,这个线程会一直等待事件的发生,比如说需要进行 sruface flip ,或者说窗口位置大小发生了变化等,一旦产生这些事件,SurfaceComposerClient 就会通过 IBinder 发出信号,这个线程就会结束等待处理这些事件,处理完成以后会继续等待,如此循环。
SurfaceComposerClient 和 SurfaceFlinger 是通过 SurfaceFlingerSynchro 这个类来同步信号的,其实说穿了就是一个条件变量。监听线程等待条件的值一旦变成 OPEN 就结束等待并将条件置成 CLOSE 然后进行事件处理,处理完成以后再继续等待条件的值变成 OPEN ,而 Client 的Surface 一旦改变就通过 IBinder 通知 SurfaceFlinger 将条件变量的值变成 OPEN ,并唤醒等待的线程,这样就通过线程类和条件变量实现了一个动态处理机制。
窗口状态变化的处理是一个很复杂的过程,SurfaceFlinger 只是执行 Windows Manager 的指令,由 Windows manager 来决定什么是偶改变大小、位置、透明度、以及如何调整layer 之间的顺序, SurfaceFlinger 仅仅只是执行它的指令。
普通的Android控件,例如TextView、Button和CheckBox等,它们都是将自己的UI绘制在宿主窗口的绘图表面之上,这意味着它们的UI是在应用程序的主线程中进行绘制的。由于应用程序的主线程除了要绘制UI之外,还需要及时地响应用户输入,否则系统就会认为应用程序没有响应了。而对于一些游戏画面,或者摄像头预览、视频播放来说,它们的UI都比较复杂,而且要求能够进行高效的绘制。这时候就必须要给那些需要复杂而高效UI的视图生成一个独立的绘图表面,以及使用一个独立的线程来绘制这些视图的UI。
SurfaceFlinger服务运行在Android系统的System进程中,它负责管理Android系统的帧缓冲区(Frame Buffer)。Android应用程序为了能够将自己的UI绘制在系统的帧缓冲区上,它们就必须要与SurfaceFlinger服务进行通信。
在APP端执行draw的时候,数据很明显是要绘制到APP的进程空间,但是视图窗口要经过SurfaceFlinger图层混排才会生成最终的帧,而SurfaceFlinger又运行在另一个独立的服务进程,那么View视图的数据是如何在两个进程间传递的呢,普通的Binder通信肯定不行,因为Binder不太适合这种数据量较大的通信,那么View数据的通信采用的是什么IPC手段呢?答案就是共享内存,更精确的说是匿名共享内存。共享内存是Linux自带的一种IPC机制,Android直接使用了该模型,不过做出了自己的改进,进而形成了Android的匿名共享内存(Anonymous Shared Memory-Ashmem)。通过Ashmem,APP进程同SurfaceFlinger共用一块内存,如此,就不需要进行数据拷贝,APP端绘制完毕,通知SurfaceFlinger端合成,再输出到硬件进行显示即可。
在每一个Android应用程序与SurfaceFlinger服务之间的连接上加上一块用来传递UI元数据的匿名共享内存,这个共享内存就是 SharedClient
在每一个SharedClient里面,有至多31个SharedBufferStack。SharedBufferStack就是Android应用程序和SurfaceFlinger 的缓冲区堆栈。用来缓冲 UI 元数据。
一般我们就绘制UI的时候,都会采用一种称为“双缓冲”的技术。双缓冲意味着要使用两个缓冲区,其中一个称为Front Buffer,另外一个称为Back Buffer。UI总是先在Back Buffer中绘制,然后再和Front Buffer交换,渲染到显示设备中。这下就可以理解SharedBufferStack的含义了吧?SurfaceFlinger服务只不过是将传统的“双缓冲”技术升华和抽象为了一个SharedBufferStack。可别小看了这个升华和抽象,有了SharedBufferStack之后,SurfaceFlinger 服务就可以使用N个缓冲区技术来绘制UI了。N值的取值范围为2到16。例如,在Android 2.3中,N的值等于2,而在Android 4.1中,据说就等于3了。
在SurfaceFlinger服务中,每一个SharedBufferStack都对应一个Surface,即一个窗口。这样,我们就可以知道为什么每一个SharedClient里面包含的是一系列SharedBufferStack而不是单个SharedBufferStack: 一个SharedClient对应一个Android应用程序,而一个Android应用程序可能包含有多个窗口 ,即Surface。从这里也可以看出,一个Android应用程序至多可以包含31个Surface。
SharedBufferStack中的 缓冲区只是用来描述UI元数据的 ,这意味着它们不包含真正的UI数据。 真正的UI数据保存在GraphicBuffer中 ,后面我们再描述GaphicBuffer。因此,为了完整地描述一个UI,SharedBufferStack中的每一个已经使用了的缓冲区都对应有一个GraphicBuffer,用来描述真正的UI数据。当SurfaceFlinger服务缓制Buffer-1和Buffer-2的时候,就会找到与它们所对应的GraphicBuffer,这样就可以将对应的UI绘制出来了。
当Android应用程序需要 更新一个Surface 的时候,它就会找到与它所对应的SharedBufferStack,并且从它的空闲缓冲区列表的尾部取出一个空闲的Buffer。我们假设这个取出来的空闲Buffer的编号为index。接下来Android应用程序就请求SurfaceFlinger服务为这个编号为index的 Buffer分配一个图形缓冲区GraphicBuffer 。
SurfaceFlinger 服务分配好图形缓冲区 GraphicBuffer 之后,会将它的编号设置为 index,然后再将这个图形缓冲区 GraphicBuffer 返回给 Android 应用程序访问。Android应用程序得到了 SurfaceFlinger 服务返回的图形缓冲区 GraphicBuffer 之后,就在里面 写入UI数据 。写完之后,就将与它所对应的缓冲区,即编号为 index 的 Buffer,插入到对应的 SharedBufferStack 的已经使用了的 缓冲区列表的头部 去。这一步完成了之后,Android 应用程序就通知 SurfaceFlinger 服务去绘制那些保存在已经使用了的缓冲区所描述的图形缓冲区GraphicBuffer了。用上面例子来说,SurfaceFlinger服务需要绘制的是编号为1和2的Buffer所对应的图形缓冲区GraphicBuffer。由于SurfaceFlinger服务知道编号为1和2的 Buffer 所对应的图形缓冲区 GraphicBuffer 在哪里,因此,Android 应用程序只需要告诉 SurfaceFlinger 服务要绘制的 Buffer 的编号就OK了。 当一个已经被使用了的Buffer被绘制了之后,它就重新变成一个空闲的 Buffer 了 。
SharedBufferStack 是在 Android 应用程序和 SurfaceFlinger 服务之间共享的,但是,Android 应用程序和 SurfaceFlinger 服务使用 SharedBufferStack 的方式是不一样的,具体来说,就是 Android 应用程序关心的是它里面的空闲缓冲区列表,而 SurfaceFlinger 服务关心的是它里面的已经使用了的缓冲区列表。从SurfaceFlinger服务的角度来看,保存在 SharedBufferStack中 的已经使用了的缓冲区其实就是在排队等待渲染。
为了方便 SharedBufferStack 在 Android 应用程序和 SurfaceFlinger 服务中的访问,Android 系统分别使用 SharedBufferClient 和 SharedBufferServer 来描述 SharedBufferStack ,其中,SharedBufferClient 用来在Android 应用程序这一侧访问 SharedBufferStack 的空闲缓冲区列表,而 SharedBufferServer 用来在SurfaceFlinger 服务这一侧访问 SharedBufferStack 的排队缓冲区列表。
只要 SharedBufferStack 中的 available 的 buffer 的数量大于0, SharedBufferClient 就会将指针 tail 往前移一步,并且减少 available 的值,以便可以获得一个空闲的 Buffer。当 Android 应用程序往这个空闲的 Buffer 写入好数据之后,它就会通过 SharedBufferClient 来将它添加到 SharedBufferStack 中的排队缓冲区列表的尾部去,即指针 queue_head 的下一个位置上。
当 Android 应用程序通知 SurfaceFlinger 服务更新UI的时候,只要对应的 SharedBufferStack 中的 queued 的缓冲区的数量大于0,SharedBufferServer 就会将指针 head 的下一个Buffer绘制出来,并且将指针 head 向前移一步,以及将 queued 的值减1。
参考:
https://blog.csdn.net/luoshengyang/article/details/7846923
Android 图形架构 之二—— SurfaceFlinger 启动和连接
前言
Android 图形架构 之一 ——概述
Android 图形架构 之二—— SurfaceFlinger 启动和连接
Android 图形架构 之三—— 创建Layer、Surface、SurfaceControl
Android 图形架构 之四——图形缓冲区的申请和消费流程及核心类
Android 图形架构 之五——深入分析addView所发生的的一切
Android 图形架构 之六——深入分析draw()是如何工作的
Android 图形架构 之七——Choreographer 源码分析
Android图形架构 之八——硬件VSync、VSync-app、Vsync-sf
上一篇文章从全局来分析了Android 图形架构,本篇文章来分析SurfaceFlinger,surface的创建、图像的处理,管理设备的帧缓冲区等等,它是图像流的消费者,是本系列文章的核心
一、SurfaceFlinger的启动过程
启动概述
SurfaceFlinger服务是一个独立进程。
关于硬件方面的服务都在 frameworks/native/services/ 文件夹下,例如:audiomanager、powermanager、inputflinger、sensorservice、surfaceflinger等。我们接下来
SurfaceFlinger服务配置,位于frameworks/native/services/surfaceflinger/surfaceflinger.rc中:
service surfaceflinger /system/bin/surfaceflinger
class core animation
user system
group graphics drmrpc readproc
onrestart restart zygote
writepid /dev/stune/foreground/tasks
socket pdx/system/vr/display/client stream 0666 system graphics u:object_r:pdx_display_client_endpoint_socket:s0
socket pdx/system/vr/display/manager stream 0666 system graphics u:object_r:pdx_display_manager_endpoint_socket:s0
socket pdx/system/vr/display/vsync stream 0666 system graphics u:object_r:pdx_display_vsync_endpoint_socket:s0
SurfaceFlinger服务配置,位于frameworks/native/services/surfaceflinger/Android.mk 中:
###############################################################
# build surfaceflinger's executable
include $(CLEAR_VARS)
LOCAL_CFLAGS:= -DLOG_TAG=\\"SurfaceFlinger\\"
# SurfaceFlinger启动文件
LOCAL_SRC_FILES:= \\
main_surfaceflinger.cpp
LOCAL_SHARED_LIBRARIES := \\
libsurfaceflinger \\
libcutils \\
liblog \\
libbinder \\
libutils
# SurfaceFlinger是个动态库
LOCAL_MODULE:= surfaceflinger
ifdef TARGET_32_BIT_SURFACEFLINGER
LOCAL_32_BIT_ONLY := true
endif
include $(BUILD_EXECUTABLE)
从Makefile文件可以看出,相关依赖和主文件会被编译成libsurfaceflinger.so,然后SurfaceFlinger是对库的一个“封装调用”,里面有个main_surfaceflinger.cpp,我们可以沿着它的main函数往下分析
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.
//在该进程设置了binder线程池最大数为4
ProcessState::self()->setThreadPoolMaxThreadCount(4);
// start the thread pool
//将当前线程加入到这个Binder线程池中去。例如:app进程通过binder通信,通知SurfaceFlinger进行渲染
sp<ProcessState> ps(ProcessState::self());
ps->startThreadPool();
// instantiate surfaceflinger
//创建一个SurfaceFlinger强引用对象
sp<SurfaceFlinger> flinger = new SurfaceFlinger();
#if defined(HAVE_PTHREADS)
setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);
#endif
set_sched_policy(0, SP_FOREGROUND);
// initialize before clients can connect
//SurfaceFlinger 初始化
flinger->init();
// publish surface flinger
//把SurfaceFlinger服务注册到ServiceManager中
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);
// run in this thread
//运行线程,无限循环等待数据到来
flinger->run();
return 0;
接下来重点分析 创建SurfaceFlinger对象,执行init函数,和运行UI渲染流程。
创建SurfaceFlinger对象
new一个SurfaceFlinger对象,并赋给强引用指针。我们先看看它的构造函数,位于frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp中:
代码二:
SurfaceFlinger::SurfaceFlinger()
: BnSurfaceComposer(),
mTransactionFlags(0),
mTransactionPending(false),
mAnimTransactionPending(false),
mLayersRemoved(false),
mRepaintEverything(0),
mRenderEngine(NULL),
mBootTime(systemTime()),
mVisibleRegionsDirty(false),
mHwWorkListDirty(false),
mAnimCompositionPending(false),
mDebugRegion(0),
mDebugDDMS(0),
mDebugDisableHWC(0),
mDebugDisableTransformHint(0),
mDebugInSwapBuffers(0),
mLastSwapBufferTime(0),
mDebugInTransaction(0),
mLastTransactionTime(0),
mBootFinished(false),
mPrimaryHWVsyncEnabled(false),//主显屏硬件VSync信号关闭
mHWVsyncAvailable(false),
mDaltonize(false),
mHasColorMatrix(false)
ALOGI("SurfaceFlinger is starting");
//一些调试变量,忽略一下内容
// debugging stuff...
char value[PROPERTY_VALUE_MAX];
property_get("ro.bq.gpu_to_cpu_unsupported", value, "0");
mGpuToCpuSupported = !atoi(value);
property_get("debug.sf.showupdates", value, "0");
mDebugRegion = atoi(value);
property_get("debug.sf.ddms", value, "0");
mDebugDDMS = atoi(value);
if (mDebugDDMS)
if (!startDdmConnection())
// start failed, and DDMS debugging not enabled
mDebugDDMS = 0;
ALOGI_IF(mDebugRegion, "showupdates enabled");
ALOGI_IF(mDebugDDMS, "DDMS debugging enabled");
SurfaceFlinger类继承了BnSurfaceComposer类,而后者是一个实现了ISurfaceComposer接口的Binder本地对象类。 该对象被赋值给一个强指针引用flinger
当一个对象第一次被一个强指针引用时,该对象的成员函数onFirstRef就会被调用。下面来看SurfaceFlinger的成员函数onFirstRef
代码三:
// mEventQueue在SurfaceFlinger.h中声明
// these are thread safe
mutable MessageQueue mEventQueue;
// SurfaceFlinger.cpp中定义
void SurfaceFlinger::onFirstRef()
mEventQueue.init(this);
MessageQueue 类在frameworks/native/services/surfaceflinger/MessageQueue.h中定义,init函数如下:
代码四:
void MessageQueue::init(const sp<SurfaceFlinger>& flinger)
mFlinger = flinger;
mLooper = new Looper(true);
mHandler = new Handler(*this);
调用MessageQueue的init,在MessageQueue中建了一个Looper和Handler,注意不是Java中的,native实现的。SurfaceFlinger的核心就是接收消息,处理消息。
执行init函数
回到代码一,继续往下执行init函数
void SurfaceFlinger::init()
ALOGI( "SurfaceFlinger's main thread ready to run. "
"Initializing graphics H/W...");
status_t err;
Mutex::Autolock _l(mStateLock);
//初始化OpenGL 图形库相关配置
// initialize EGL for the default display 将EGL初始化成默认的显示,默认是主屏幕,编号为0
mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(mEGLDisplay, NULL, NULL);
//创建显示设备的抽象代表,负责和显示设备打交道
// 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);
// start the EventThread
//创建两个软件VSync,它们会根据硬件的VSync 来设置频率,稳定后,硬件VSync就会停止,使用软件生成的VSync
//app的VSync信号,也就是Systrace中的VSync-app,它最终是发往到choreographer,主要处理三件事情INPUT、ANIMATION、TRAVERSAL
sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
vsyncPhaseOffsetNs, true, "app");
mEventThread = new EventThread(vsyncSrc);
//SF的VSync信号,也就是Systrace中的VSync-sf,,它最终是发往到SurfaceFlinger,读取GraphicBuffer,最后通过Gralloc 把数据写入FrameBuffer
sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
sfVsyncPhaseOffsetNs, true, "sf");
mSFEventThread = new EventThread(sfVsyncSrc);
//SF的VSync信号控制逻辑也要放入mEventQueue消息队列
mEventQueue.setEventThread(mSFEventThread);
//VSync信号闸刀控制线程
mEventControlThread = new EventControlThread(this);
mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
// set a fake vsync period if there is no HWComposer
//如果硬件设备检测有问题,或者没有硬件设备驱动提供Vsync信号,则设置软件VSync信号
if (mHwc->initCheck() != NO_ERROR)
mPrimaryDispSync.setPeriod(16666667);
// initialize our drawing state
mDrawingState = mCurrentState;
// set initial conditions (e.g. unblank default device)
//初始化显示设备,调用initializeDisplays完成
initializeDisplays();
// start boot animation
//启动开机动画,调用了startBootAnim函数,只是设置了两个属性,其中一个ctl.start是启动了bootanim进程
startBootAnim();
关于VSync 信号,后面会详细讲解
SurfaceFlinger 的run函数
再次回到代码一,执行了flinger->run()
,运行线程,等待数据。下面就来看看SurfaceFlinger 的run函数
void SurfaceFlinger::run()
do
waitForEvent();
while (true);
void SurfaceFlinger::waitForEvent()
mEventQueue.waitMessage();
调用了EventQueue的waitMessage方法,记住这里是在主线程中循环调用的。
void MessageQueue::waitMessage()
do
//flushCommands主要是清理工作的
IPCThreadState::self()->flushCommands();
//pollOnce是消息机制,主要调用了epoll_wait函数,会阻塞,阻塞完了会分发消息队列中的消息
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);
发送消息
调用SurfaceFlinger 的postMessageSync(msg); 来发送消息
status_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
nsecs_t reltime, uint32_t /* flags */)
//向mEventQueue,即MessageQueue中发送消息
status_t res = mEventQueue.postMessage(msg, reltime);
//这里等着,同步就在同步函数中等着
if (res == NO_ERROR)
msg->wait();
return res;
处理消息
从上面waitMessage得知,消息处理都位于里面无限循环处的的int32_t ret = mLooper->pollOnce(-1);我们追寻到Looper中的pollOnce函数,位于system/core/libutils/Looper.cpp中:
int Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData)
int result = 0;
for (;;)
...
result = pollInner(timeoutMillis);
调用Looper 的函数 pollInner
int Looper::pollInner(int timeoutMillis)
// Invoke pending message callbacks.
mNextMessageUptime = LLONG_MAX;
while (mMessageEnvelopes.size() != 0)
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(0);
if (messageEnvelope.uptime <= now)
// Remove the envelope from the list.
// We keep a strong reference to the handler until the call to handleMessage
// finishes. Then we drop it so that the handler can be deleted *before*
// we reacquire our lock.
// obtain handler
sp<MessageHandler> handler = messageEnvelope.handler;
Message message = messageEnvelope.message;
//把头删除啊
mMessageEnvelopes.removeAt(0);
mSendingMessage = true;
mLock.unlock();
#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS
ALOGD("%p ~ pollOnce - sending message: handler=%p, what=%d",
this, handler.get(), message.what);
#endif
//处理消息啊
handler->handleMessage(message);
// release handler
mLock.lock();
mSendingMessage = false;
result = ALOOPER_POLL_CALLBACK;
else
// The last message left at the head of the queue determines the next wakeup time.
mNextMessageUptime = messageEnvelope.uptime;
break;
发给SF的消息被封装在MessageEnvelope结构中,SF一直在mMessageEnvelopes队列中从头部取出消息,然后执行,即handler->handleMessage(message),这个即是我们上面提到的framework/native/services/surfaceflinger/MessageQueue.cpp中:
void MessageBase::handleMessage(const Message&)
this->handler();
//打开栅栏
barrier.open();
;
二、SurfaceFlinger的连接过程
每一个有UI的Android应用程序都需要与SurfaceFlinger服务建立一个连接,以便可以通过这个连接来请求SurfaceFlinger服务为它创建和渲染Surface。
应用程序和SurfaceFlinger服务 是运行在不同的进程中,所以在连接的过程中,涉及到很多进程间通信,主要联系可参考下图:
在下面介绍的很多类,会使用类继承的接口来表示,下图是主要类关系,蓝色表示在客户端,紫色表示服务端
当应用程序需要请求SurfaceFlinger服务时,首先需要构造SurfaceComposerClient对象,通过SurfaceComposerClient对象就可以访问SurfaceFlinger服务了。基本的服务流程都是这么走的,我们看一下SurfaceComposerClient的构造函数:
代码一:
SurfaceComposerClient::SurfaceComposerClient()
: mStatus(NO_INIT), mComposer(Composer::getInstance())
SurfaceComposerClient 继承于RefBase类,在创建SurfaceComposerClient对象,系统第一次引用SurfaceComposerClient对象时,onFirstRef函数自动调用,我们看一下它的onFirstRef
代码二:
void SurfaceComposerClient::onFirstRef()
//1、获得SurfaceFlinger服务,从上图可知SurfaceFlinger 继承了ISurfaceComposer
sp<ISurfaceComposer> sm(ComposerService::getComposerService());
if (sm != 0)
//2、与SurfaceFlinger建立连接
sp<ISurfaceComposerClient> conn = sm->createConnection();
if (conn != 0)
//之后就可以通过这个连接,进行通信
mClient = conn;
mStatus = NO_ERROR;
来看一下获取SurfaceFlinger服务的过程
代码三:
sp<ISurfaceComposer> ComposerService::getComposerService()
//ComposerService 是单例模式
ComposerService& instance = ComposerService::getInstance();
Mutex::Autolock _l(instance.mLock);
if (instance.mComposerService == NULL)
//获取SurfaceFlinger服务的代理对象
ComposerService::getInstance().connectLocked();
assert(instance.mComposerService != NULL);
ALOGD("ComposerService reconnected"以上是关于SurfaceFlinger 原理分析的主要内容,如果未能解决你的问题,请参考以下文章
SurfaceFlinger的渲染客户端Surface初始化
SurfaceFlinger的渲染客户端Surface初始化
SurfaceFlinger的渲染客户端Surface初始化