Android系统的SurfaceFlinger服务有两种启动方式:1)在SystemServer进程中以服务线程的方式提供服务;2)启动SurfaceFlinger独立的进程通过服务。第一种方式是在SystemServer进程启动过程中启动SurfaceFlinger服务的,而第二中方式是在Android启动脚本init.rc中配置SurfaceFlinger服务,通过init进程来启动的。下面就分别介绍SurfaceFlinger的两种启动方式。
extern "C" status_t system_init()
{
ALOGI("Entered system_init()");
sp proc(ProcessState::self());
sp sm = defaultServiceManager();
ALOGI("ServiceManager: %p\n", sm.get());
sp grim = new GrimReaper();
sm->asBinder()->linkToDeath(grim, grim.get(), 0);
char propBuf[PROPERTY_VALUE_MAX];
property_get("system_init.startsurfaceflinger", propBuf, "1");
if (strcmp(propBuf, "1") == 0) {
// Start the SurfaceFlinger
SurfaceFlinger::instantiate();
}
....
}
static void instantiate() { publish(); }
static status_t publish(bool allowIsolated = false) {
sp sm(defaultServiceManager());
return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated);
}
函数首先得到ServiceManager的Binder代理对象,然后构造一个SurfaceFlinger对象,并注册到ServiceManager进程中。
int main(int argc, char** argv) {
SurfaceFlinger::publishAndJoinThreadPool(true);
// When SF is launched in its own process, limit the number of
// binder threads to 4.
ProcessState::self()->setThreadPoolMaxThreadCount(4);
return 0;
}
函数调用SurfaceFlinger类的publishAndJoinThreadPool方法启动构造SurfaceFlinger对象并注册到ServiceManager进程中,然后调用setThreadPoolMaxThreadCount函数来设置SurfaceFlinger进程的最大Binder线程数。
static void publishAndJoinThreadPool(bool allowIsolated = false) {
sp sm(defaultServiceManager());
sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated);
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
和前面的publish函数一样,首先得到ServiceManager的Binder代理对象,然后构造一个SurfaceFlinger对象,并注册到ServiceManager进程中,只不过这里额外调用了ProcessState::self()->startThreadPool()来启动Binder线程池,并且将当前进程的主线程注册到Binder线程池中,对于SurfaceFlinger服务进程来说,为了接收客户端的请求,SurfaceFlinger服务进程必现启动Binder线程池。如果SurfaceFlinger以服务线程的方式在SystemServer进程中启动的话,就无需启动Binder线程,因为SurfaceFlinger服务驻留在SystemServer进程中,而SysteServer进程自己维护了一个Binder线程池。
SurfaceFlinger::SurfaceFlinger()
: BnSurfaceComposer(), Thread(false),
mTransactionFlags(0),
mTransationPending(false),
mLayersRemoved(false),
mBootTime(systemTime()),
mVisibleRegionsDirty(false),
mHwWorkListDirty(false),
mElectronBeamAnimationMode(0),
mDebugRegion(0),
mDebugDDMS(0),
mDebugDisableHWC(0),
mDebugDisableTransformHint(0),
mDebugInSwapBuffers(0),
mLastSwapBufferTime(0),
mDebugInTransaction(0),
mLastTransactionTime(0),
mBootFinished(false),
mSecureFrameBuffer(0)
{
init();
}
构造过程仅仅初始化了SurfaceFlinger的成员变量,同时调用了父类BnSurfaceComposer的构造函数。最后使用init方法来作一些初始化工作。
void SurfaceFlinger::init()
{
ALOGI("SurfaceFlinger is starting");
char value[PROPERTY_VALUE_MAX];
property_get("debug.sf.showupdates", value, "0");
mDebugRegion = atoi(value);
property_get("ro.bootmode", value, "mode");
if (!(strcmp(value, "engtest")
&& strcmp(value, "special")
&& strcmp(value, "wdgreboot")
&& strcmp(value, "unknowreboot")
&& strcmp(value, "panic"))) {
SurfaceFlinger::sBootanimEnable = false;
}
}
读取开机模式属性ro.bootmode来决定是否要显示开机动画,关于开机动画在 Android 开关机动画显示源码分析中介绍了。由于SurfaceFlinger继承于RefBase类,同时实现了RefBase的onFirstRef()方法,因此在第一次引用SurfaceFlinger对象时,onFirstRef()函数自动被调用:
void SurfaceFlinger::onFirstRef()
{
mEventQueue.init(this);
run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
// Wait for the main thread to be done with its initialization
mReadyToRunBarrier.wait();
}
mEventQueue是MessageQueue类型变量,定义在frameworks\native\services\surfaceflinger\MessageQueue.h这里调用init函数初始化mEventQueue消息队列
void MessageQueue::init(const sp& flinger)
{
mFlinger = flinger;
mLooper = new Looper(true);
mHandler = new Handler(*this);
}
mReadyToRunBarrier为Barrier类型的变量,用于阻塞,启动线程运行,对象构造时,状态初始化为CLOSED,因此在调用它的wait方法时,当前SurfaceFlinger线程睡眠等待SystemServer主线程调用readyToRun()函数完成SurfaceFlinger运行前的初始化工作。
inline Barrier() : state(CLOSED) { }
void wait() const {
Mutex::Autolock _l(lock);
while (state == CLOSED) {
cv.wait(lock);
}
}
SurfaceFlinger继承于Thread类,因此构造一个SurfaceFlinger对象,其实就是创建一个线程,当调用其run方法时,就是启动该线程的运行,在SurfaceFlinger线程运行前,需要主线程初始化OpenGL库,因此在主线程完成初始化工作前,需要让SurfaceFlinger线程睡眠等待,主线程初始化工作:
status_t SurfaceFlinger::readyToRun()
{
ALOGI( "SurfaceFlinger's main thread ready to run. ""Initializing graphics H/W...");
// we only support one display currently
int dpy = 0;
{
//初始化主显示屏,即从SurfaceFlinger中取出第0号GraphicPlane
GraphicPlane& plane(graphicPlane(dpy));
//创建DisplayHardware,并和显示屏绑定
DisplayHardware* const hw = new DisplayHardware(this, dpy);
plane.setDisplayHardware(hw);
}
//创建一块大小为4k的匿名共享内存,用于共享显示屏幕信息
mServerHeap = new MemoryHeapBase(4096,MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap");
ALOGE_IF(mServerHeap==0, "can't create shared memory dealer");
//将该匿名共享内存的首地址转换为surface_flinger_cblk_t类型的指针,表明该共享内存存储surface_flinger_cblk_t结构体数据
mServerCblk = static_cast(mServerHeap->getBase());
ALOGE_IF(mServerCblk==0, "can't get to shared control block's address");
new(mServerCblk) surface_flinger_cblk_t;
//从显示屏的DisplayHardware中得到屏幕的宽高,并设置为当前主显示屏
const GraphicPlane& plane(graphicPlane(dpy));
const DisplayHardware& hw = plane.displayHardware();
const uint32_t w = hw.getWidth();
const uint32_t h = hw.getHeight();
const uint32_t f = hw.getFormat();
hw.makeCurrent();
//将屏幕信息保存到匿名共享内存中,从而共享给所有进程
mServerCblk->connected |= 1<displays + dpy;
memset(dcblk, 0, sizeof(display_cblk_t));
dcblk->w = plane.getWidth();
dcblk->h = plane.getHeight();
dcblk->format = f;
dcblk->orientation = ISurfaceComposer::eOrientationDefault;
dcblk->xdpi = hw.getDpiX();
dcblk->ydpi = hw.getDpiY();
dcblk->fps = hw.getRefreshRate();
dcblk->density = hw.getDensity();
//初始化OpenGL|ES
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glPixelStorei(GL_PACK_ALIGNMENT, 4);
glEnableClientState(GL_VERTEX_ARRAY);
glShadeModel(GL_FLAT);
glDisable(GL_DITHER);
glDisable(GL_CULL_FACE);
const uint16_t g0 = pack565(0x0F,0x1F,0x0F);
const uint16_t g1 = pack565(0x17,0x2f,0x17);
const uint16_t wormholeTexData[4] = { g0, g1, g1, g0 };
glGenTextures(1, &mWormholeTexName);
glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0,GL_RGB, GL_UNSIGNED_SHORT_5_6_5, wormholeTexData);
const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) };
glGenTextures(1, &mProtectedTexName);
glBindTexture(GL_TEXTURE_2D, mProtectedTexName);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0,GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData);
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// put the origin in the left-bottom corner
glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h
// 启动EventThread线程
mEventThread = new EventThread(this);
mEventQueue.setEventThread(mEventThread);
hw.startSleepManagement();
//主线程已经完成初始化工作,唤醒睡眠等待中的SurfaceFlinger线程接收客户端的请求
mReadyToRunBarrier.open();
//启动开机动画
startBootAnim();
return NO_ERROR;
}
函数首先初始化主显示屏,为该GraphicPlane创建DisplayHardware对象,然后创建一块匿名共享内存,用于保存显示屏幕信息,同时共享给系统的其他进程访问,接着初始化OpenGL库,同时启动EventThread线程,唤醒SurfaceFlinger线程,并启动开机动画。
GraphicPlane& SurfaceFlinger::graphicPlane(int dpy)
{
return const_cast(const_cast(this)->graphicPlane(dpy));
}
//Android4.1只支持1个屏幕显示,#define DISPLAY_COUNT 1
const GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const
{
ALOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy);
const GraphicPlane& plane(mGraphicPlanes[dpy]);
return plane;
}
DisplayHardware::DisplayHardware(const sp& flinger,uint32_t dpy): DisplayHardwareBase(flinger, dpy),
mFlinger(flinger), mFlags(0), mHwc(0)
{
init(dpy);
}
构造DisplayHardware对象前,首先会构造其父类DisplayHardwareBase对象。
DisplayHardwareBase::DisplayHardwareBase(const sp& flinger,
uint32_t displayIndex)
{
mScreenAcquired = true;
mDisplayEventThread = new DisplayEventThread(flinger);
}
在DisplayHardwareBase对象内部创建一个DisplayEventThread线程
DisplayHardwareBase::DisplayEventThread::DisplayEventThread(const sp& flinger)
: Thread(false), mFlinger(flinger) {
}
然后初始化DisplayHardware
void DisplayHardware::init(uint32_t dpy)
{
//创建FramebufferNativeWindow对象
mNativeWindow = new FramebufferNativeWindow();
//在构造FramebufferNativeWindow对象时,通过打开Gralloc硬件抽象层模块,得到framebuffer_device_t
framebuffer_device_t const * fbDev = mNativeWindow->getDevice();
if (!fbDev) {
ALOGE("Display subsystem failed to initialize. check logs. exiting...");
exit(0);
}
int format;
ANativeWindow const * const window = mNativeWindow.get();
//查询指定window的format信息
window->query(window, NATIVE_WINDOW_FORMAT, &format);
mDpiX = mNativeWindow->xdpi;
mDpiY = mNativeWindow->ydpi;
mRefreshRate = fbDev->fps;
if (mDpiX == 0 || mDpiY == 0) {
ALOGE("invalid screen resolution from fb HAL (xdpi=%f, ydpi=%f), ""defaulting to 160 dpi", mDpiX, mDpiY);
mDpiX = mDpiY = 160;
}
class Density {
//通过读取属性得到屏幕像素密度
static int getDensityFromProperty(char const* propName) {
char property[PROPERTY_VALUE_MAX];
int density = 0;
if (property_get(propName, property, NULL) > 0) {
density = atoi(property);
}
return density;
}
public:
//提供两个得到屏幕像素密度的接口,getEmuDensity用于得到模拟器的像素密度;getBuildDensity用于得到编译指定的屏幕像素密度
static int getEmuDensity() {
return getDensityFromProperty("qemu.sf.lcd_density"); }
static int getBuildDensity() {
return getDensityFromProperty("ro.sf.lcd_density"); }
};
// The density of the device is provided by a build property
mDensity = Density::getBuildDensity() / 160.0f;
if (mDensity == 0) {
// the build doesn't provide a density -- this is wrong! use xdpi instead
ALOGE("ro.sf.lcd_density must be defined as a build property");
mDensity = mDpiX / 160.0f;
}
if (Density::getEmuDensity()) {
// if "qemu.sf.lcd_density" is specified, it overrides everything
mDpiX = mDpiY = mDensity = Density::getEmuDensity();
mDensity /= 160.0f;
}
/* FIXME: this is a temporary HACK until we are able to report the refresh rate
* properly from the HAL. The WindowManagerService now relies on this value.
*/
#ifndef REFRESH_RATE
mRefreshRate = fbDev->fps;
#else
mRefreshRate = REFRESH_RATE;
#warning "refresh rate set via makefile to REFRESH_RATE"
#endif
mRefreshPeriod = nsecs_t(1e9 / mRefreshRate);
EGLint w, h, dummy;
EGLint numConfigs=0;
EGLSurface surface;
EGLContext context;
EGLBoolean result;
status_t err;
// initialize EGL
EGLint attribs[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_NONE, 0,
EGL_NONE
};
// debug: disable h/w rendering
char property[PROPERTY_VALUE_MAX];
if (property_get("debug.sf.hw", property, NULL) > 0) {
if (atoi(property) == 0) {
ALOGW("H/W composition disabled");
attribs[2] = EGL_CONFIG_CAVEAT;
attribs[3] = EGL_SLOW_CONFIG;
}
}
// TODO: all the extensions below should be queried through
// eglGetProcAddress().
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(display, NULL, NULL);
eglGetConfigs(display, NULL, 0, &numConfigs);
EGLConfig config = NULL;
err = selectConfigForPixelFormat(display, attribs, format, &config);
ALOGE_IF(err, "couldn't find an EGLConfig matching the screen format");
EGLint r,g,b,a;
eglGetConfigAttrib(display, config, EGL_RED_SIZE, &r);
eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &g);
eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &b);
eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &a);
if (mNativeWindow->isUpdateOnDemand()) {
mFlags |= PARTIAL_UPDATES;
}
if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) == EGL_TRUE) {
if (dummy == EGL_SLOW_CONFIG)
mFlags |= SLOW_CONFIG;
}
//Create our main surface
surface = eglCreateWindowSurface(display, config, mNativeWindow.get(), NULL);
eglQuerySurface(display, surface, EGL_WIDTH, &mWidth);
eglQuerySurface(display, surface, EGL_HEIGHT, &mHeight);
if (mFlags & PARTIAL_UPDATES) {
// if we have partial updates, we definitely don't need to
// preserve the backbuffer, which may be costly.
eglSurfaceAttrib(display, surface,EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED);
}
//Create our OpenGL ES context
EGLint contextAttributes[] = {
#ifdef EGL_IMG_context_priority
#ifdef HAS_CONTEXT_PRIORITY
#warning "using EGL_IMG_context_priority"
EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG,
#endif
#endif
EGL_NONE, EGL_NONE
};
context = eglCreateContext(display, config, NULL, contextAttributes);
mDisplay = display;
mConfig = config;
mSurface = surface;
mContext = context;
mFormat = fbDev->format;
mPageFlipCount = 0;
// Gather OpenGL ES extensions
result = eglMakeCurrent(display, surface, surface, context);
if (!result) {
ALOGE("Couldn't create a working GLES context. check logs. exiting...");
exit(0);
}
GLExtensions& extensions(GLExtensions::getInstance());
extensions.initWithGLStrings(
glGetString(GL_VENDOR),
glGetString(GL_RENDERER),
glGetString(GL_VERSION),
glGetString(GL_EXTENSIONS),
eglQueryString(display, EGL_VENDOR),
eglQueryString(display, EGL_VERSION),
eglQueryString(display, EGL_EXTENSIONS));
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims);
// Unbind the context from this thread
eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
// initialize the H/W composer
mHwc = new HWComposer(mFlinger, *this, mRefreshPeriod);
if (mHwc->initCheck() == NO_ERROR) {
mHwc->setFrameBuffer(mDisplay, mSurface);
}
}
//创建一块大小为4k的匿名共享内存,用于共享显示屏幕信息
mServerHeap = new MemoryHeapBase(4096,MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap");
ALOGE_IF(mServerHeap==0, "can't create shared memory dealer");
//将该匿名共享内存的首地址转换为surface_flinger_cblk_t类型的指针,表明该共享内存存储surface_flinger_cblk_t结构体数据
mServerCblk = static_cast(mServerHeap->getBase());
ALOGE_IF(mServerCblk==0, "can't get to shared control block's address");
new(mServerCblk) surface_flinger_cblk_t;
//从显示屏的DisplayHardware中得到屏幕的宽高,并设置为当前主显示屏
const GraphicPlane& plane(graphicPlane(dpy));
const DisplayHardware& hw = plane.displayHardware();
const uint32_t w = hw.getWidth();
const uint32_t h = hw.getHeight();
const uint32_t f = hw.getFormat();
hw.makeCurrent();
//将屏幕信息保存到匿名共享内存中,从而共享给所有进程
mServerCblk->connected |= 1<displays + dpy;
memset(dcblk, 0, sizeof(display_cblk_t));
dcblk->w = plane.getWidth();
dcblk->h = plane.getHeight();
dcblk->format = f;
dcblk->orientation = ISurfaceComposer::eOrientationDefault;
dcblk->xdpi = hw.getDpiX();
dcblk->ydpi = hw.getDpiY();
dcblk->fps = hw.getRefreshRate();
dcblk->density = hw.getDensity();
EventThread::EventThread(const sp& flinger)
: mFlinger(flinger),
mHw(flinger->graphicPlane(0).editDisplayHardware()),
mLastVSyncTimestamp(0),
mVSyncTimestamp(0),
mUseSoftwareVSync(false),
mDeliveredEvents(0),
mDebugVsyncEnabled(false)
{
}
void EventThread::onFirstRef() {
mHw.setVSyncHandler(this);
run("EventThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
}
DisplayEventThread线程启动过程:
void DisplayHardwareBase::startSleepManagement() const {
if (mDisplayEventThread->initCheck() == NO_ERROR) {
mDisplayEventThread->run("DisplayEventThread", PRIORITY_URGENT_DISPLAY);
} else {
ALOGW("/sys/power/wait_for_fb_{wake|sleep} don't exist");
}
}