Android 图形架构 之二—— SurfaceFlinger 启动和连接
Posted 薛瑄
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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"以上是关于Android 图形架构 之二—— SurfaceFlinger 启动和连接的主要内容,如果未能解决你的问题,请参考以下文章
Android 图形架构 之七——Choreographer 源码分析
Android 图形架构 之七——Choreographer 源码分析
Android 图形架构 之三—— 创建LayerSurfaceSurfaceControl
Android 图形架构 之三—— 创建LayerSurfaceSurfaceControl