您的位置:首页 > 移动开发 > Android开发

Android 4.4 Graphic系统详解(1) SurfaceFlinger的启动过程

2017-08-01 10:00 941 查看


init启动SurfaceFlinger

SurfaceFlinger目前的启动方式是做为init进程中的一个Service来启动。

在init中添加如下配置代码:
[cpp] view plaincopy



# Set this property so surfaceflinger is not started by system_init
setprop system_init.startsurfaceflinger 0

service surfaceflinger /system/bin/surfaceflinger
class main
user system
group graphics drmrpc
onrestart restart zygote


系统将启动/system/bin/目录下的surfaceflinger bin文件来运行SurfaceFlinger。

关于init.rc的语法问题,我们将有专门的文章展开讨论(TODO)。


SurfaceFlinger启动过程

我们继续来看下对应的bin文件中的代码,位置在Android\frameworks\native\services\surfaceflinger下。
[cpp] view plaincopy



int main(int argc, char** argv) {
// 1.创建surfaceflinger对象
sp<SurfaceFlinger> flinger = new SurfaceFlinger();
// initialize before clients can connect
// 2.初始化
flinger->init();
// 3.注册SF服务
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);
// 4.运行程序
flinger->run();
return 0;
}


从上面代码中我们看到SF的创建过程主要有四个步骤,我们来逐一分析一下。


1. 创建SF对象

[cpp] view plaincopy



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),
mDebugFps(0),
mDebugDDMS(0),
mDebugDisableHWC(0),
mDebugDisableTransformHint(0),
mDebugInSwapBuffers(0),
mLastSwapBufferTime(0),
mDebugInTransaction(0),
mLastTransactionTime(0),
mBootFinished(false),
mPrimaryHWVsyncEnabled(false),
mHWVsyncAvailable(false),
mDaltonize(false),
/* Activity-Activity: */
mProjectionType(ORTHOGRAPHIC_PROJECTION)
/* Activity-Activity: Change End*/
// End
{
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.showfps", value, "0");
mDebugFps = 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(mDebugFps,          "showfps enabled");
ALOGI_IF(mDebugDDMS, "DDMS debugging enabled");
}


其实这个创建过程很简单,无非就是初始化了一些值。从配置中读取了一些值。

需要注意的一点是,SurfaceFlinger实现了三个接口:
[cpp] view plaincopy



class SurfaceFlinger : public BnSurfaceComposer,
private IBinder::DeathRecipient,
private HWComposer::EventHandler


BnSurfaceComposer意思是指这个Surface混合的native端,这显然也符合我们对SF功能的认识—-用于Layer的混合处理。

另外,我们会在后面消息的处理一节中单独讲解HWComposer::EventHandler接口的作用。


2.初始化

其实相比SurfaceFlinger的创建,初始化做了更多的工作。

这一过程比较复杂,我们分为几部分来分析:

2.1 EGL初始化

[cpp] view plaincopy



void SurfaceFlinger::init() {
ALOGI(  "SurfaceFlinger's main thread ready to run. "
"Initializing graphics H/W...");
status_t err;
Mutex::Autolock _l(mStateLock);
// initialize EGL for the default display
mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(mEGLDisplay, NULL, NULL);
...
}


首先SF初始化时,会进行一些EGL的初始化工作。

我们知道EGL是用来管理绘图表面(Drawing surfaces),并且提供了如下的机制

1) 与本地窗口系统进行通信(本地窗口在X-Window下是XDisplay ID,在MS Windows下是Window DC,而在Android平台上EGL是NativeDisplayType)

2) 查找绘图表面可用的类型和配置信息

3) 创建绘图表面

4) 同步OpenGL ES 2.0和其他的渲染API(Open VG、本地窗口系统的绘图命令等)

5) 管理渲染资源,比如材质

eglGetDisplay调用egl_display_t::get_display(dpy)获取(连接)显示设备的句柄。

egl_display_t结构用来存储get_display函数获取的物理显示设备。

这里的EGL_DEFAULT_DISPLAY类型是NativeDisplayType,是一个关联系统物理屏幕的通用数据类型。

每个 EGLDisplay 在使用前都需要通过eglInitialize函数来初始化。初始化 EGLDisplay 的同时,你可以得到系统中 EGL 的实现版本号。

这个整个过程是由平台实现的,我们看不到具体实现代码(libagl里面有一套谷歌的实现,但是非常简单)。

2.2 创建HWComposer

[cpp] view plaincopy



{
...
// 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));
...
}


接下来是创建了一个HWComposer,也就是一个负责硬件合成的模块。但是我们也看到上面的注释明确写着,下面可能并没有一个真正的硬件支持。我们来研究下这个HWComposer的创建过程:
[cpp] view plaincopy



HWComposer::HWComposer(
const sp<SurfaceFlinger>& flinger,
EventHandler& handler)
: mFlinger(flinger),
mFbDev(0), mHwc(0), mNumDisplays(1),
mCBContext(new cb_context),
mEventHandler(handler),
mDebugForceFakeVSync(false)
{
for (size_t i =0 ; i<MAX_HWC_DISPLAYS ; i++) {
mLists[i] = 0;
}
//首先是一些和VSYNC有关的信息的初始化
//因为在硬件支持的情况下,VSYNC的功能就是由HWC提供的
for (size_t i=0 ; i<HWC_NUM_PHYSICAL_DISPLAY_TYPES ; i++) {
mLastHwVSync[i] = 0;
mVSyncCounts[i] = 0;
}
//根据配置来看是否需要模拟VSYNC消息
char value[PROPERTY_VALUE_MAX];
property_get("debug.sf.no_hw_vsync", value, "0");
mDebugForceFakeVSync = atoi(value);

bool needVSyncThread = true;
//加载Gralloc中的GRALLOC_HARDWARE_FB0设备,和HWC设备
// Note: some devices may insist that the FB HAL be opened before HWC.
int fberr = loadFbHalModule();
loadHwcModule();

if (mFbDev && mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
// close FB HAL if we don't needed it.
// FIXME: this is temporary until we're not forced to open FB HAL
// before HWC.
framebuffer_close(mFbDev);
mFbDev = NULL;
}

// If we have no HWC, or a pre-1.1 HWC, an FB dev is mandatory.
if ((!mHwc || !hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1))
&& !mFbDev) {
ALOGE("ERROR: failed to open framebuffer (%s), aborting",
strerror(-fberr));
abort();
}

// these display IDs are always reserved
for (size_t i=0 ; i<NUM_BUILTIN_DISPLAYS ; i++) {
mAllocatedDisplayIDs.markBit(i);
}
//如果我们有HWC这个硬件设备,那么我们就注册一些HWC的函数
//另外,就不需要使用vsync的进程,因为我们有了硬件支持的VSYNC中断
if (mHwc) {
ALOGI("Using %s version %u.%u", HWC_HARDWARE_COMPOSER,
(hwcApiVersion(mHwc) >> 24) & 0xff,
(hwcApiVersion(mHwc) >> 16) & 0xff);
if (mHwc->registerProcs) {
mCBContext->hwc = this;
mCBContext->procs.invalidate = &hook_invalidate;
mCBContext->procs.vsync = &hook_vsync;
if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1))
mCBContext->procs.hotplug = &hook_hotplug;
else
mCBContext->procs.hotplug = NULL;
memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero));
mHwc->registerProcs(mHwc, &mCBContext->procs);
}

// don't need a vsync thread if we have a hardware composer
needVSyncThread = false;
// always turn vsync off when we start
eventControl(HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0);

// the number of displays we actually have depends on the
// hw composer version
//根据HWC硬件的支持情况,来设置显示屏幕的数量
if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_3)) {
// 1.3 adds support for virtual displays
mNumDisplays = MAX_HWC_DISPLAYS;
} else if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
// 1.1 adds support for multiple displays
mNumDisplays = NUM_BUILTIN_DISPLAYS;
} else {
mNumDisplays = 1;
}
}
//如果我们能获取到FB设置,那么我们就从FB设备里面读取一些屏幕相关的I型难洗
if (mFbDev) {
ALOG_ASSERT(!(mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)),
"should only have fbdev if no hwc or hwc is 1.0");

DisplayData& disp(mDisplayData[HWC_DISPLAY_PRIMARY]);
disp.connected = true;
disp.width = mFbDev->width;
disp.height = mFbDev->height;
disp.format = mFbDev->format;
disp.xdpi = mFbDev->xdpi;
disp.ydpi = mFbDev->ydpi;
if (disp.refresh == 0) {
disp.refresh = nsecs_t(1e9 / mFbDev->fps);
ALOGW("getting VSYNC period from fb HAL: %lld", disp.refresh);
}
if (disp.refresh == 0) {
disp.refresh = nsecs_t(1e9 / 60.0);
ALOGW("getting VSYNC period from thin air: %lld",
mDisplayData[HWC_DISPLAY_PRIMARY].refresh);
}
} else if (mHwc) {//否则我们将会从HWC中读取相关配置,打log确认下走哪个分支
// here we're guaranteed to have at least HWC 1.1
for (size_t i =0 ; i<NUM_BUILTIN_DISPLAYS ; i++) {
queryDisplayProperties(i);
}
}

// End
//显然,如果需要模拟VSync信号的话,我们需要线程来做这个工作
if (needVSyncThread) {
// we don't have VSYNC support, we need to fake it
//VSyncThread类的实现很简单,无非就是一个计时器而已,定时发送消息而已
//TODO VSYNC专题
mVSyncThread = new VSyncThread(*this);
}
}


2.3 EGL配置


HWC模块创建完成之后,我们继续回到SurfaceFlinger的初始化过程,后面将继续是一些EGL相关的配置:
[cpp] view plaincopy



{
...
//首先获取OpenGL ES2.0的配置,在另外一篇文档中,我们提到过从KK之后,SF开始使用ES 2.0
// First try to get an ES2 config
err = selectEGLConfig(mEGLDisplay, mHwc->getVisualID(), EGL_OPENGL_ES2_BIT,
&mEGLConfig);
//当然如果获取失败,还是会继续使用1.0,TODO 我们会新开一个专题讲OpengGL
if (err != NO_ERROR) {
// If ES2 fails, try ES1
err = selectEGLConfig(mEGLDisplay, mHwc->getVisualID(),
EGL_OPENGL_ES_BIT, &mEGLConfig);
}

if (err != NO_ERROR) {
// still didn't work, probably because we're on the emulator...
// try a simplified query
ALOGW("no suitable EGLConfig found, trying a simpler query");
err = selectEGLConfig(mEGLDisplay, mHwc->getVisualID(), 0, &mEGLConfig);
}

if (err != NO_ERROR) {
// this EGL is too lame for android
LOG_ALWAYS_FATAL("no suitable EGLConfig found, giving up");
}

// 打印一些配置信息
EGLint r,g,b,a;
eglGetConfigAttrib(mEGLDisplay, mEGLConfig, EGL_RED_SIZE,   &r);
eglGetConfigAttrib(mEGLDisplay, mEGLConfig, EGL_GREEN_SIZE, &g);
eglGetConfigAttrib(mEGLDisplay, mEGLConfig, EGL_BLUE_SIZE,  &b);
eglGetConfigAttrib(mEGLDisplay, mEGLConfig, EGL_ALPHA_SIZE, &a);
ALOGI("EGL informations:");
ALOGI("vendor    : %s", eglQueryString(mEGLDisplay, EGL_VENDOR));
ALOGI("version   : %s", eglQueryString(mEGLDisplay, EGL_VERSION));
ALOGI("extensions: %s", eglQueryString(mEGLDisplay, EGL_EXTENSIONS));
ALOGI("Client API: %s", eglQueryString(mEGLDisplay, EGL_CLIENT_APIS)?:"Not Supported");
ALOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, mEGLConfig);

// get a RenderEngine for the given display / config (can't fail)
// KK升级一章中我们讲过SF通过RenderEngine来实现了使用不同版本的OpenGL
mRenderEngine = RenderEngine::create(mEGLDisplay, mEGLConfig);

// retrieve the EGL context that was selected/created
//获取ES的上下文,这个是用于SF的上下文
mEGLContext = mRenderEngine->getEGLContext();

// figure out which format we got
eglGetConfigAttrib(mEGLDisplay, mEGLConfig,
EGL_NATIVE_VISUAL_ID, &mEGLNativeVisualId);

LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
"couldn't create EGLContext");
...
}


2.4 display设置


EGL和OpenGL ES的配置设置完毕之后,我们将对display进行设置。
[cpp] view plaincopy



{
...
// 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];

//对于每个display,SF都会创建一个新的BufferQueue
sp<BufferQueue> bq = new BufferQueue(new GraphicBufferAlloc());
sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i, bq);
//最后,用我们创建的这些内容,来创建一个DisplayDevice
//它有两个重要的变量,一个是mFrameBufferSurface和mNativeWindow。
//mFrameBufferSurace是FrameBufferSurface类型,
//当显示设备不属于VIRTUAL类型的话,则该变量不为空
sp<DisplayDevice> hw = new DisplayDevice(this,
type, allocateHwcDisplayId(type), isSecure, token,
fbs, bq,
mEGLConfig);
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 %d as acquired/unblanked", i);
//这里应该是指非主屏幕的屏幕一旦注册,就长期处于开启状态
hw->acquireScreen();
}
mDisplays.add(token, hw);
}
}
...
}


上面这段代码其实涉及到了三个重要的概念,BufferQueue、FrameBufferSurface以及DisplayDevice。

BufferQueue做为Graphic的核心组件,我们在讲解Graphic总体结构时已经有说明,后面会另开专题说明。我们先来看下FrameBufferSurface的实现:
[cpp] view plaincopy



FramebufferSurface::FramebufferSurface(HWComposer& hwc, int disp,
const sp<IGraphicBufferConsumer>& consumer) :
ConsumerBase(consumer),
mDisplayType(disp),
mCurrentBufferSlot(-1),
mCurrentBuffer(0),
mHwc(hwc)
{
mName = "FramebufferSurface";
mConsumer->setConsumerName(mName);
mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_FB |
GRALLOC_USAGE_HW_RENDER |
GRALLOC_USAGE_HW_COMPOSER);
mConsumer->setDefaultBufferFormat(mHwc.getFormat(disp));
mConsumer->setDefaultBufferSize(mHwc.getWidth(disp),  mHwc.getHeight(disp));
mConsumer->setDefaultMaxBufferCount(NUM_FRAMEBUFFER_SURFACE_BUFFERS);
mConsumer->setMaxAcquiredBufferCount(NUM_FRAMEBUFFER_SURFACE_BUFFERS - 1);
}


我们使用了BufferQueue来创建了一个FramebufferSurface,显然这个FramebufferSurface是一个消费者。在创建过程我们使用了屏幕的编号和HWC,我们可以猜测这个FBS是和一个屏幕绑定的,而且最终应该也是要通过HWC进行渲染。我们可以理解为这是SF在这个屏幕上使用的帧缓冲区,那么也就是一旦使用SF合成,最后数据应该是合成在了这里面(待验证),然后这里面的数据通过HWC显示在了屏幕上。猜测一下,这个是不是就是抓dump时抓到的那个HWC_FRAMEBUFFER_TARGET?

FBS的创建并没有特别之处,需要留意的是这里设置了MaxBufferCount和MaxAcquiredBufferCount,我们在Graphic总体架构一文中已经提到了设置这两个属性的作用。

DisplayDevice其实是抽象了显示设备,封装了用于渲染的Surface和HWComposer模块等,从而尽可能使得SurfaceFlinger只要和它打交道。来看下他的创建过程:
[cpp] view plaincopy



DisplayDevice::DisplayDevice(
const sp<SurfaceFlinger>& flinger,
DisplayType type,
int32_t hwcId,
bool isSecure,
const wp<IBinder>& displayToken,
const sp<DisplaySurface>& displaySurface,
const sp<IGraphicBufferProducer>& producer,
EGLConfig config)
: 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),
mScreenAcquired(false),
mLayerStack(NO_LAYER_STACK),
mOrientation()
{
mNativeWindow = new Surface(producer, false);
ANativeWindow* const window = mNativeWindow.get();

int format;
window->query(window, NATIVE_WINDOW_FORMAT, &format);

/*
* Create our display's surface
*/
EGLSurface surface;
EGLint w, h;
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
surface = eglCreateWindowSurface(display, config, window, NULL);
eglQuerySurface(display, surface, EGL_WIDTH,  &mDisplayWidth);
eglQuerySurface(display, surface, EGL_HEIGHT, &mDisplayHeight);

mDisplay = display;
mSurface = surface;
mFormat  = format;
mPageFlipCount = 0;
mViewport.makeInvalid();
mFrame.makeInvalid();
float mFOV = 30.0f;
float tangent = tan(PI / 180.0f * mFOV / 2.0f);
mDefaultX = -((float) mDisplayWidth / 2.0f);
mDefaultY = -((float) mDisplayHeight / 2.0f);
mDefaultZ = -(((float) mDisplayHeight / 2.0f) / tangent);
/* Activity-Activity: Change End*/

// virtual displays are always considered enabled
mScreenAcquired = (mType >= DisplayDevice::DISPLAY_VIRTUAL);

// 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;
}
char property[PROPERTY_VALUE_MAX];
int panelOrientation = DisplayState::eOrientationDefault;
// Set the panel orientation from the property.
property_get("persist.panel.orientation", property, "0");
panelOrientation = atoi(property) / 90;

// initialize the display orientation transform.
setProjection(panelOrientation, mViewport, mFrame);
}


这段创建同样相当之长,我们目前只关注这里面创建了一个EGLSurface。我们在前面的文章中曾经提到过这个类,这个实际上就是一个供GLES使用的窗口缓冲区,为GLES提供了一个绘制的地方。

在这个EGLSurface里面是一个Surface,本质上下面还是一个BufferQueue。

渲染这个EGLSurface将导致一个buffer出队渲染入队的过程,lock和unlock过程是通过eglSwapBuffers函数来提供的。

2.5 makeCurrent


看完了上面几个重要概念的讲解,我们继续回到SF的init过程中来。

下面是对主屏幕对应的display进行makeCurrent操作:
[cpp] view plaincopy



{
...
//  initialize OpenGL ES
/* Activity-Activity: */
setProjectionType(ORTHOGRAPHIC_PROJECTION);
/* Activity-Activity: Change End*/

// make the GLContext current so that we can create textures when creating Layers
// (which may happens before we render something)
getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
...
}


注意到这里调用的实际上是DisplayDevice类提供的函数,这也某种程度上说明了我们前面提到的DisplayDevice的作用是:封装了用于渲染的Surface和HWComposer模块等,从而尽可能使得SurfaceFlinger只要和它打交道。看下这个makeCurrent函数:
[cpp] view plaincopy



EGLBoolean DisplayDevice::makeCurrent(EGLDisplay dpy, EGLContext ctx) const {
EGLBoolean result = EGL_TRUE;
EGLSurface sur = eglGetCurrentSurface(EGL_DRAW);
if (sur != mSurface) {
result = eglMakeCurrent(dpy, mSurface, mSurface, ctx);
if (result == EGL_TRUE) {
if (mType >= DisplayDevice::DISPLAY_VIRTUAL)
eglSwapInterval(dpy, 0);
}
}
setViewportAndProjection();
return result;
}


这里获取了当前使用的EGLSurface,一旦发现这个Surface发生了改变,就要重新调用eglMakeCurrent函数来设置,这是因为一个线程同时只能有一个EGLSurface作为current。而关于eglMakeCurrent函数的更详尽的说明,我们将在EGL和GLES的章节中给予说明。

2.6 EventThread的创建


再次回到SF的init过程中来:
[cpp] view plaincopy



{
...
// start the EventThread
sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
vsyncPhaseOffsetNs, true);
mEventThread = new EventThread(vsyncSrc);
sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
sfVsyncPhaseOffsetNs, true);
mSFEventThread = new EventThread(sfVsyncSrc);
mEventQueue.setEventThread(mSFEventThread);

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);
}
...
}


这段讲了EventThread的创建和使用。EventThread主要用于VSYNC消息的处理,我们同样会单开一个章节来讲解VSYNC的逻辑。

EventControlThread是用来向真实的VSync硬件发命令的,我们这里暂时不展开。

而一旦硬件不能正常发送VSYNC命令时,我们则通过软件方式模拟,我们可以看到这里把模拟的间隔时间设置为16.6ms左右。

2.7 初始化显示设备


终于到了init函数的最后几句话,首先是初始化显示设备。
[cpp] view plaincopy



{
...
// initialize our drawing state
mDrawingState = mCurrentState;

// set initial conditions (e.g. unblank default device)
initializeDisplays();

...
}


我们来看初始化显示设备的逻辑:
[cpp] view plaincopy



void SurfaceFlinger::onInitializeDisplays() {
// reset screen orientation and use primary layer stack
Vector<ComposerState> state;
Vector<DisplayState> displays;
DisplayState d;
d.what = DisplayState::eDisplayProjectionChanged |
DisplayState::eLayerStackChanged;
d.token = mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY];
d.layerStack = 0;
d.orientation = DisplayState::eOrientationDefault;
d.frame.makeInvalid();
d.viewport.makeInvalid();
displays.add(d);
setTransactionState(state, displays, 0);
onScreenAcquired(getDefaultDisplayDevice());

const nsecs_t period =
getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
mAnimFrameTracker.setDisplayRefreshPeriod(period);
property_set("debug.sf.layerdump", "0");
}


其中setTransactionState函数在很多地方都会有调用,作用主要是处理上层的各个命令,并根据flag设置event通知Threadloop进行处理,TODO

而onScreenAcquired同样是一个重要的函数,不仅在这里,在屏幕会唤醒时同样会调用。
[cpp] view plaincopy



void SurfaceFlinger::onScreenAcquired(const sp<const DisplayDevice>& hw) {
ALOGD("Screen acquired, type=%d flinger=%p", hw->getDisplayType(), this);
if (hw->isScreenAcquired()) {
// this is expected, e.g. when power manager wakes up during boot
ALOGD(" screen was previously acquired");
return;
}

hw->acquireScreen();
int32_t type = hw->getDisplayType();
if (type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
// built-in display, tell the HWC
getHwComposer().acquire(type);

if (type == DisplayDevice::DISPLAY_PRIMARY) {
// FIXME: eventthread only knows about the main display right now
mEventThread->onScreenAcquired();

resyncToHardwareVsync(true);
}
}
mVisibleRegionsDirty = true;
repaintEverything();
}


这里有几个点比较重要,首先是通知HWC,调用了HWC的acquire函数:
[cpp] view plaincopy



status_t HWComposer::acquire(int disp) {
LOG_FATAL_IF(disp >= VIRTUAL_DISPLAY_ID_BASE);
if (mHwc) {
return (status_t)mHwc->blank(mHwc, disp, 0);
}
return NO_ERROR;
}


接下来,调用了EventThread的onScreenAcquired函数。
[cpp] view plaincopy



void EventThread::onScreenAcquired() {
if (mUseSoftwareVSync) {
// resume use of h/w vsync
mUseSoftwareVSync = false;
mCondition.broadcast();
}
}


这个函数首先判断如果在之前mUseSoftwareVSync被设置为了true,这里需要改回来。而mUseSoftwareVSync这个值其实是在onScreenReleased被设置为true的(也就是说,在屏幕被灭掉之后,就变为软件的VSync,TODO,在屏幕黑掉之后,还有没有绘制或者显示方面的工作?)。

后面这个广播发送的主要作用是唤醒EventThread线程,并打开VSync事件发送器(可以看下waitForEvent函数)。

接下来的resyncToHardwareVsync函数逻辑比较简单,应该就是开启硬件的VSYNC。
[cpp] view plaincopy



void SurfaceFlinger::resyncToHardwareVsync(bool makeAvailable) {
Mutex::Autolock _l(mHWVsyncLock);

if (makeAvailable) {
mHWVsyncAvailable = true;
} else if (!mHWVsyncAvailable) {
ALOGE("resyncToHardwareVsync called when HW vsync unavailable");
return;
}

const nsecs_t period =
getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);

mPrimaryDispSync.reset();
mPrimaryDispSync.setPeriod(period);

if (!mPrimaryHWVsyncEnabled) {
mPrimaryDispSync.beginResync();
//eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
mEventControlThread->setVsyncEnabled(true);
mPrimaryHWVsyncEnabled = true;
}
}


最后是调用了repaintEverything函数,这个函数就是发送invalidate消息,请求屏幕刷新。

2.8 开机动画


回到init的过程上来。
[cpp] view plaincopy



{
...
// start boot animation
startBootAnim();

}


播放开机动画我们会专门讲解,这里不再展开。


3.注册SF服务

向Android的ServiceManager进程注册服务是系统的通用逻辑,不再展开,这里就是注册了一个名叫的SurfaceFlinger的服务而已。


4.运行程序

在一系列的准备工作之后,终于到了启动SurfaceFlinger的时候。
[cpp] view plaincopy



void SurfaceFlinger::run() {
do {
waitForEvent();
} while (true);
}
void SurfaceFlinger::waitForEvent() {
mEventQueue.waitMessage();
}


而这个过程其实异常简单,SF进入死循环中,一直在等待消息的传来。


总结

这样,我们就完整的分析了SF的启动过程,我们将在下一节继续分析SF对消息的处理过程。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息