概述
SurfaceFlinger在Android中负责绘制应用程序的UI,是一个系统service,本文将从源码来描述SurfaceFlinger的启动过程,看看它是怎么启动,并做了什么。
首先,SurfaceFlinger的源码位于frameworks/native/services/surfaceflinger下面,编译出来是一个Android的可执行程序,在手机的文件系统中位于system/bin下面。
启动它的代码是在init.rc中,也就是说它是init进程通过解析init.rc来启动的。init.rc(位于system/core/rootdir下面)中代码如下:
service surfaceflinger /system/bin/surfaceflinger
class core
user system
group graphics drmrpc
onrestart restart zygote
被init进程启动后就会进入它的入口main()函数开始执行。他的入口main()函数定义在frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp中,main()函数源码如下:
int main(int, char**) {
// When SF is launched in its own process, limit the number of
// binder threads to 4.
ProcessState::self()->setThreadPoolMaxThreadCount(4);
// start the thread pool
sp<ProcessState> ps(ProcessState::self());
ps->startThreadPool();
// instantiate 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
flinger->init();
// publish surface flinger
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);
// run in this thread
flinger->run();
return 0;
}
这里首先设置SurfaceFlinger的线程池的最大线程数为4,然后启动线程池。
接着通过sp<SurfaceFlinger> flinger = new SurfaceFlinger();创建一个强指针的SurfaceFlinger对象。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),
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的类成员变量赋初值。
然后setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);就是设置线程调度的优先级;
接着调用SurfaceFlinger的init函数进行一些初始化工作,具体初始化内容下面分析。由于SurfaceFlinger继承自BnSurfaceComposer,而BnSurfaceComposer向上最终继承自RefBase,SurfaceFlinger实现了RefBase的onFirstRef()方法,所以当第一次引用SurfaceFlinger对象的时候onFirstRef()方法会自动被调用。onFirstRef()方法内容如下:
void SurfaceFlinger::onFirstRef()
{
mEventQueue.init(this);
}
它里面初始化一个消息队列MessageQueue来接收消息,这个init的实现在 frameworks/native/services/surfaceflinger/MessageQueue.cpp,代码如下:
void MessageQueue::init(const sp<SurfaceFlinger>& flinger)
{
mFlinger = flinger;
mLooper = new Looper(true);
mHandler = new Handler(*this);
}
这里主要是将创建的SurfaceFlinger对象的引用传给mEventQueue的指针变量 sp<SurfaceFlinger> mFlinger,然后创建Handler接收消息。在这个文件中实现了handleMessage()的接口,如下:
void MessageQueue::Handler::handleMessage(const Message& message) {
switch (message.what) {
case INVALIDATE:
android_atomic_and(~eventMaskInvalidate, &mEventMask);
mQueue.mFlinger->onMessageReceived(message.what);
break;
case REFRESH:
android_atomic_and(~eventMaskRefresh, &mEventMask);
mQueue.mFlinger->onMessageReceived(message.what);
break;
case TRANSACTION:
android_atomic_and(~eventMaskTransaction, &mEventMask);
mQueue.mFlinger->onMessageReceived(message.what);
break;
}
}
可以看出,接收到消息后会把消息通过SurfaceFlinger对象的引用进一步发送给SurfaceFlinger服务。然后在SurfaceFlinger中的onMessageReceived()方法就会接受这些消息并正真的进行处理,如下:
void SurfaceFlinger::onMessageReceived(int32_t what) {
ATRACE_CALL();
switch (what) {
case MessageQueue::TRANSACTION: {
handleMessageTransaction();
break;
}
case MessageQueue::INVALIDATE: {
bool refreshNeeded = handleMessageTransaction();
refreshNeeded |= handleMessageInvalidate();
refreshNeeded |= mRepaintEverything;
if (refreshNeeded) {
// Signal a refresh if a transaction modified the window state,
// a new buffer was latched, or if HWC has requested a full
// repaint
signalRefresh();
}
break;
}
case MessageQueue::REFRESH: {
handleMessageRefresh();
break;
}
}
}
现在说到了main_surfaceflinger.cpp中flinger->init();这里,具体init的实现下面细说,接着说main_surfaceflinger.cpp中的剩下几行代码。
由于SurfaceFlinger也是一个系统服务,所以需要ServiceManager进行统一管理,所以这里(sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);)SurfaceFlinger会把自己加到ServiceManager的管理列表中,让ServiceManager对自己进行管理。
最后SurfaceFlinger其实就是一个线程,所以直接调用它的run接口跑起来。
现在来看SurfaceFlinger.cpp中init函数的具体实现:
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);
// 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
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);
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函数里就是SurfaceFlinger初始化的地方,接下来一步步分析具体过程。
1、为默认的显示设备初始化EGL
代码如下:
<pre name="code" class="cpp">mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(mEGLDisplay, NULL, NULL);
首先调用 eglGetDisplay(EGL_DEFAULT_DISPLAY);获得默认的display设备。我们看下这个方法的实现:
EGLDisplay eglGetDisplay(EGLNativeDisplayType display)
{
clearError();
uintptr_t index = reinterpret_cast<uintptr_t>(display);
if (index >= NUM_DISPLAYS) {
return setError(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);
}
if (egl_init_drivers() == EGL_FALSE) {
return setError(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);
}
EGLDisplay dpy = egl_display_t::getFromNativeDisplay(display);
return dpy;
}
这个方法的实现位于 frameworksnativeopengllibsegleglApi.cpp中,首先会调用 egl_init_drivers()方法初始化egl动态库,具体实现如下:
EGLBoolean egl_init_drivers() {
EGLBoolean res;
pthread_mutex_lock(&sInitDriverMutex);
res = egl_init_drivers_locked();
pthread_mutex_unlock(&sInitDriverMutex);
return res;
}
这里使用线程锁保证访问的安全性,实际的实现在
egl_init_drivers_locked();这个方法中。这个方法实现如下:
tatic EGLBoolean egl_init_drivers_locked() {
if (sEarlyInitState) {
// initialized by static ctor. should be set here.
return EGL_FALSE;
}
// get our driver loader
Loader& loader(Loader::getInstance());
// dynamically load our EGL implementation
egl_connection_t* cnx = &gEGLImpl;
if (cnx->dso == 0) {
cnx->hooks[egl_connection_t::GLESv1_INDEX] =
&gHooks[egl_connection_t::GLESv1_INDEX];
cnx->hooks[egl_connection_t::GLESv2_INDEX] =
&gHooks[egl_connection_t::GLESv2_INDEX];
cnx->dso = loader.open(cnx);
}
return cnx->dso ? EGL_TRUE : EGL_FALSE;
}
首先通过调用pthread_once,也就是sEarlyInitState保证只初始化一次。接下来拿到Loader的实例,这个类主要是用来加载我们的EGL的库。这里定义一个egl_connection_t的指针cnx指向全局变量gEGLImpl,并且将cnx的hooks指向gHooks,最后通过loader实例对象的open函数打开EGL动态库,因此最后从EGL库中加载的接口函数指针都保存到了变量gEGLImpl和gHooks中了。这里的open函数的具体实现如下:
void* Loader::open(egl_connection_t* cnx)
{
void* dso;
driver_t* hnd = 0;
//首先加载GLES库
dso = load_driver("GLES", cnx, EGL | GLESv1_CM | GLESv2);
if (dso) {
hnd = new driver_t(dso);
} else {
// Always load EGL first
dso = load_driver("EGL", cnx, EGL);
if (dso) {
hnd = new driver_t(dso);
hnd->set( load_driver("GLESv1_CM", cnx, GLESv1_CM), GLESv1_CM );
hnd->set( load_driver("GLESv2", cnx, GLESv2), GLESv2 );
}
}
LOG_ALWAYS_FATAL_IF(!hnd, "couldn't find an OpenGL ES implementation");
#if defined(__LP64__)
cnx->libEgl = load_wrapper("/system/lib64/libEGL.so");
cnx->libGles2 = load_wrapper("/system/lib64/libGLESv2.so");
cnx->libGles1 = load_wrapper("/system/lib64/libGLESv1_CM.so");
#else
cnx->libEgl = load_wrapper("/system/lib/libEGL.so");
cnx->libGles2 = load_wrapper("/system/lib/libGLESv2.so");
cnx->libGles1 = load_wrapper("/system/lib/libGLESv1_CM.so");
#endif
LOG_ALWAYS_FATAL_IF(!cnx->libEgl,
"couldn't load system EGL wrapper libraries");
LOG_ALWAYS_FATAL_IF(!cnx->libGles2 || !cnx->libGles1,
"couldn't load system OpenGL ES wrapper libraries");
return (void*)hnd;
}
这里就是通过load_driver的接口去加载EGL的实现,首先通过dso = load_driver("GLES", cnx, EGL | GLESv1_CM | GLESv2);去拿GLES的库,通常的实现也就是这个相关的库,位于/system/lib/egl/下面。
void *Loader::load_driver(const char* kind,
egl_connection_t* cnx, uint32_t mask)
{
class MatchFile {
public:
static String8 find(const char* kind) {
String8 result;
String8 pattern;
pattern.appendFormat("lib%s", kind);
const char* const searchPaths[] = {
#if defined(__LP64__)
"/vendor/lib64/egl",
"/system/lib64/egl"
#else
"/vendor/lib/egl",
"/system/lib/egl"
#endif
};
// first, we search for the exact name of the GLES userspace
// driver in both locations.
// i.e.:
// libGLES.so, or:
// libEGL.so, libGLESv1_CM.so, libGLESv2.so
for (size_t i=0 ; i<NELEM(searchPaths) ; i++) {
if (find(result, pattern, searchPaths[i], true)) {
return result;
}
}
// for compatibility with the old "egl.cfg" naming convention
// we look for files that match:
// libGLES_*.so, or:
// libEGL_*.so, libGLESv1_CM_*.so, libGLESv2_*.so
pattern.append("_");
for (size_t i=0 ; i<NELEM(searchPaths) ; i++) {
if (find(result, pattern, searchPaths[i], false)) {
return result;
}
}
// we didn't find the driver. gah.
result.clear();
return result;
}
private:
static bool find(String8& result,
const String8& pattern, const char* const search, bool exact) {
// in the emulator case, we just return the hardcoded name
// of the software renderer.
if (checkGlesEmulationStatus() == 0) {
ALOGD("Emulator without GPU support detected. "
"Fallback to software renderer.");
#if defined(__LP64__)
result.setTo("/system/lib64/egl/libGLES_android.so");
#else
result.setTo("/system/lib/egl/libGLES_android.so");
#endif
return true;
}
if (exact) {
String8 absolutePath;
absolutePath.appendFormat("%s/%s.so", search, pattern.string());
if (!access(absolutePath.string(), R_OK)) {
result = absolutePath;
return true;
}
return false;
}
DIR* d = opendir(search);
if (d != NULL) {
struct dirent cur;
struct dirent* e;
while (readdir_r(d, &cur, &e) == 0 && e) {
if (e->d_type == DT_DIR) {
continue;
}
if (!strcmp(e->d_name, "libGLES_android.so")) {
// always skip the software renderer
continue;
}
if (strstr(e->d_name, pattern.string()) == e->d_name) {
if (!strcmp(e->d_name + strlen(e->d_name) - 3, ".so")) {
result.clear();
result.appendFormat("%s/%s", search, e->d_name);
closedir(d);
return true;
}
}
}
closedir(d);
}
return false;
}
};
//这里的到刚才加载的动态库的绝对路径
String8 absolutePath = MatchFile::find(kind);
if (absolutePath.isEmpty()) {
// this happens often, we don't want to log an error
return 0;
}
const char* const driver_absolute_path = absolutePath.string();
//根据获得动态库的绝对路径通过dlopen函数打开刚才的库,将地址指针赋给dso
void* dso = dlopen(driver_absolute_path, RTLD_NOW | RTLD_LOCAL);
if (dso == 0) {
const char* err = dlerror();
ALOGE("load_driver(%s): %s", driver_absolute_path, err?err:"unknown");
return 0;
}
ALOGD("loaded %s", driver_absolute_path);
//下面通过刚才打开的库的指针获得getProcAddress,然后在通过getProcAddress拿到定义的EGL的接口函数的入口地址,并保存在全局变量传递过来的cnx中,这个cnx指向的就是全局变量gEGLImpl
if (mask & EGL) {
getProcAddress = (getProcAddressType)dlsym(dso, "eglGetProcAddress");
ALOGE_IF(!getProcAddress,
"can't find eglGetProcAddress() in %s", driver_absolute_path);
egl_t* egl = &cnx->egl;
__eglMustCastToProperFunctionPointerType* curr =
(__eglMustCastToProperFunctionPointerType*)egl;
char const * const * api = egl_names;
while (*api) {
char const * name = *api;
__eglMustCastToProperFunctionPointerType f =
(__eglMustCastToProperFunctionPointerType)dlsym(dso, name);
if (f == NULL) {
// couldn't find the entry-point, use eglGetProcAddress()
f = getProcAddress(name);
if (f == NULL) {
f = (__eglMustCastToProperFunctionPointerType)0;
}
}
*curr++ = f;
api++;
}
}
if (mask & GLESv1_CM) {
init_api(dso, gl_names,
(__eglMustCastToProperFunctionPointerType*)
&cnx->hooks[egl_connection_t::GLESv1_INDEX]->gl,
getProcAddress);
}
if (mask & GLESv2) {
init_api(dso, gl_names,
(__eglMustCastToProperFunctionPointerType*)
&cnx->hooks[egl_connection_t::GLESv2_INDEX]->gl,
getProcAddress);
}
return dso;
}
根据不同的设备不同的实现会加载不同的库,本文所用的设备实现为libGLES_mali.so,位于/system/lib/egl/下。如上面的代码注释中的所描述的,拿到libGLES_mali.so并通过dlopen打开然后拿到EGL接口函数的入口地址,保存在全局变量gEGLImpl中供后面调用。这里EGL接口函数的定义就是代码中egl_names这个数组中,这个数组的定义如下:
<pre name="code" class="cpp">char const * const gl_names[] = {
#include "../entries.in"
NULL
};
而这个entries.in就在frameworks/native/opengl/libs下面,其内容如下:
GL_ENTRY(void, glActiveShaderProgram, GLuint pipeline, GLuint program)
GL_ENTRY(void, glActiveShaderProgramEXT, GLuint pipeline, GLuint program)
GL_ENTRY(void, glActiveTexture, GLenum texture)
GL_ENTRY(void, glAlphaFunc, GLenum func, GLfloat ref)
GL_ENTRY(void, glAlphaFuncQCOM, GLenum func, GLclampf ref)
GL_ENTRY(void, glAlphaFuncx, GLenum func, GLfixed ref)
GL_ENTRY(void, glAlphaFuncxOES, GLenum func, GLfixed ref)
GL_ENTRY(void, glAttachShader, GLuint program, GLuint shader)
GL_ENTRY(void, glBeginPerfMonitorAMD, GLuint monitor)
GL_ENTRY(void, glBeginPerfQueryINTEL, GLuint queryHandle)
GL_ENTRY(void, glBeginQuery, GLenum target, GLuint id)
GL_ENTRY(void, glBeginQueryEXT, GLenum target, GLuint id)
GL_ENTRY(void, glBeginTransformFeedback, GLenum primitiveMode)
GL_ENTRY(void, glBindAttribLocation, GLuint program, GLuint index, const GLchar * name)
GL_ENTRY(void, glBindBuffer, GLenum target, GLuint buffer)
GL_ENTRY(void, glBindBufferBase, GLenum target, GLuint index, GLuint buffer)
GL_ENTRY(void, glBindBufferRange, GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size)
GL_ENTRY(void, glBindFramebuffer, GLenum target, GLuint framebuffer)
GL_ENTRY(void, glBindFramebufferOES, GLenum target, GLuint framebuffer)
GL_ENTRY(void, glBindImageTexture, GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format)
GL_ENTRY(void, glBindProgramPipeline, GLuint pipeline)
GL_ENTRY(void, glBindProgramPipelineEXT, GLuint pipeline)
GL_ENTRY(void, glBindRenderbuffer, GLenum target, GLuint renderbuffer)
GL_ENTRY(void, glBindRenderbufferOES, GLenum target, GLuint renderbuffer)
GL_ENTRY(void, glBindSampler, GLuint unit, GLuint sampler)
GL_ENTRY(void, glBindTexture, GLenum target, GLuint texture)
GL_ENTRY(void, glBindTransformFeedback, GLenum target, GLuint id)
GL_ENTRY(void, glBindVertexArray, GLuint array)
GL_ENTRY(void, glBindVertexArrayOES, GLuint array)
GL_ENTRY(void, glBindVertexBuffer, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride)
GL_ENTRY(void, glBlendBarrierKHR, void)
GL_ENTRY(void, glBlendBarrierNV, void)
GL_ENTRY(void, glBlendColor, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
GL_ENTRY(void, glBlendEquation, GLenum mode)
GL_ENTRY(void, glBlendEquationOES, GLenum mode)
GL_ENTRY(void, glBlendEquationSeparate, GLenum modeRGB, GLenum modeAlpha)
GL_ENTRY(void, glBlendEquationSeparateOES, GLenum modeRGB, GLenum modeAlpha)
GL_ENTRY(void, glBlendEquationSeparateiEXT, GLuint buf, GLenum modeRGB, GLenum modeAlpha)
GL_ENTRY(void, glBlendEquationiEXT, GLuint buf, GLenum mode)
GL_ENTRY(void, glBlendFunc, GLenum sfactor, GLenum dfactor)
GL_ENTRY(void, glBlendFuncSeparate, GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha)
GL_ENTRY(void, glBlendFuncSeparateOES, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
GL_ENTRY(void, glBlendFuncSeparateiEXT, GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
里面就是EGL接口的定义。
到这里我们其实只是将我们EGL库加载起来,也就是我们回到上面已经提到的eglGetDisplay函数的egl_init_drivers这里:
EGLDisplay eglGetDisplay(EGLNativeDisplayType display)
{
clearError();
uintptr_t index = reinterpret_cast<uintptr_t>(display);
if (index >= NUM_DISPLAYS) {
return setError(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);
}
if (<strong>egl_init_drivers()</strong> == EGL_FALSE) {
return setError(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);
}
EGLDisplay dpy = egl_display_t::getFromNativeDisplay(display);
return dpy;
}
EGLDisplay egl_display_t::getFromNativeDisplay(EGLNativeDisplayType disp) {
if (uintptr_t(disp) >= NUM_DISPLAYS)
return NULL;
return sDisplay[uintptr_t(disp)].getDisplay(disp);
}
接着调用getDisplay方法:
EGLDisplay egl_display_t::getDisplay(EGLNativeDisplayType display) {
Mutex::Autolock _l(lock);
// get our driver loader
Loader& loader(Loader::getInstance());
egl_connection_t* const cnx = &gEGLImpl;
if (cnx->dso && disp.dpy == EGL_NO_DISPLAY) {
EGLDisplay dpy = cnx->egl.eglGetDisplay(display);
disp.dpy = dpy;
if (dpy == EGL_NO_DISPLAY) {
loader.close(cnx->dso);
cnx->dso = NULL;
}
}
return EGLDisplay(uintptr_t(display) + 1U);
}
这里最终返回EGLDisplay一样display设备类型的变量,值为1;
这样我们再回到SurfaceFlinger.cpp中的init方法中,就走完了mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);这一步,拿到了EGLDisplay实现。接下来调用eglInitialize(mEGLDisplay, NULL, NULL);这里主要设置一下已经拿到的设备的一些状态信息,并保存在全局变量gEGLImpl中。这样我们就为默认的display设备初始化完成了EGL实现。
先到这里,下篇接着分析。
最后
以上就是潇洒心锁为你收集整理的Android 5.1 源码学习之SurfaceFlinger的启动(一)的全部内容,希望文章能够帮你解决Android 5.1 源码学习之SurfaceFlinger的启动(一)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复