本文均属自己阅读源码的点滴总结,转账请注明出处谢谢。
欢迎和大家交流。qq:1037701636 email:[email protected]
Android源码版本Version:4.2.2; 硬件平台 全志A31
接着上文的SF启动流程,这里单独拎出来分析SurfaceFlinger::readyToRun()函数。里面的知识点比较多,只能和大家分享自己所知道的,共同交流学习。
status_t SurfaceFlinger::readyToRun() { ALOGI( "SurfaceFlinger's main thread ready to run. " "Initializing graphics H/W..."); // initialize EGL for the default display mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); eglInitialize(mEGLDisplay, NULL, NULL);//EGL的初始化 // 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 // initialize the config and context EGLint format = mHwc->getVisualID(); mEGLConfig = selectEGLConfig(mEGLDisplay, format);//配置EGL的参数 mEGLContext = createGLContext(mEGLDisplay, mEGLConfig);//初始化上下文内容 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_DISPLAY_TYPES ; i++) {//DisplayDevice::NUM_DISPLAY_TYPES = 2 DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);//0:HWC_DISPLAY_PRIMARY,1:HWC_DISPLAY_EXTERNAL mDefaultDisplays[i] = new BBinder(); wp<IBinder> token = mDefaultDisplays[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 = mHwc->isSecure(i); mCurrentState.displays.add(token, DisplayDeviceState(type)); sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i); sp<SurfaceTextureClient> stc = new SurfaceTextureClient( static_cast< sp<ISurfaceTexture> >(fbs->getBufferQueue())); sp<DisplayDevice> hw = new DisplayDevice(this, type, isSecure, token, stc, fbs, mEGLConfig);//新的显示设备 if (i > DisplayDevice::DISPLAY_PRIMARY) {//HDMI,i= 1 // 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);//将准备好的显示硬件维护在mDefaultDisplays[i]中 } } // we need a GL context current in a few places, when initializing // OpenGL ES (see below), or creating a layer, // or when a texture is (asynchronously) destroyed, and for that // we need a valid surface, so it's convenient to use the main display // for that. sp<const DisplayDevice> hw(getDefaultDisplayDevice()); // initialize OpenGL ES DisplayDevice::makeCurrent(mEGLDisplay, hw, mEGLContext); initializeGL(mEGLDisplay); // start the EventThread mEventThread = new EventThread(this);//新建一个事件线程用于创建event的消息,处理VSYC同步事件 mEventQueue.setEventThread(mEventThread); // initialize our drawing state mDrawingState = mCurrentState; // We're now ready to accept clients... mReadyToRunBarrier.open(); // set initial conditions (e.g. unblank default device) initializeDisplays(); // start boot animation startBootAnim();//开启动画属性 return NO_ERROR; } int32_t SurfaceFlinger::allocateHwcDisplayId(DisplayDevice::DisplayType type) { return (uint32_t(type) < DisplayDevice::NUM_DISPLAY_TYPES) ? type : mHwc->allocateDisplayId(); }
在进入线程循环前,之所以执行他,因为SF正在运行前还有许多的工作要做,从下面几个点开始分析:
step1: new HWComposer()
在这里冒昧的称其为硬件合成器,从他的实现来看,可以看出他是和底层驱动走的最近的地方,因为涉及到了Gralloc模块(即所谓的Framebffer,主要用于图形的最终显示。
构造函数如下:
HWComposer::HWComposer( const sp<SurfaceFlinger>& flinger, EventHandler& handler) : mFlinger(flinger), mFbDev(0), mHwc(0), mNumDisplays(1), mCBContext(new cb_context), mEventHandler(handler), mVSyncCount(0), mDebugForceFakeVSync(false) { for (size_t i =0 ; i<MAX_DISPLAYS ; i++) { mLists[i] = 0; mFrame[i].left = 0; mFrame[i].top = 0; mFrame[i].right = -1; mFrame[i].bottom = -1; } char value[PROPERTY_VALUE_MAX]; property_get("debug.sf.no_hw_vsync", value, "0"); mDebugForceFakeVSync = atoi(value); bool needVSyncThread = true; // Note: some devices may insist that the FB HAL be opened before HWC. loadFbHalModule();//加载framerbuffer模块gralloc loadHwcModule();//加载HWComposer模块 ...... {//如果支持硬件hw ALOGI("Using %s version %u.%u", HWC_HARDWARE_COMPOSER, (hwcApiVersion(mHwc) >> 24) & 0xff, (hwcApiVersion(mHwc) >> 16) & 0xff);//1.1版本 if (mHwc->registerProcs) { mCBContext->hwc = this; mCBContext->procs.invalidate = &hook_invalidate; mCBContext->procs.vsync = &hook_vsync;//相关hwc的回调函数初始化 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);//向HAL注册回调函数 } // don't need a vsync thread if we have a hardware composer needVSyncThread = false;//有硬件合成器就不需要软件的Vsync同步 // 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 if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_2)) { // 1.2 adds support for virtual displays mNumDisplays = MAX_DISPLAYS;//1.2支持虚拟屏 } else if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) { // 1.1 adds support for multiple displays mNumDisplays = HWC_NUM_DISPLAY_TYPES;//1.1支持2个屏 } else { mNumDisplays = 1; } } }
两个重要的成员函数loadFbHalModule和loadHwcModule
void HWComposer::loadFbHalModule() { hw_module_t const* module; if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) != 0) {//GRALLOC_HARDWARE_MODULE_ID = "Gralloc" ALOGE("%s module not found", GRALLOC_HARDWARE_MODULE_ID); return; } int err = framebuffer_open(module, &mFbDev);//gralloc内部的fb0模块 if (err) { ALOGE("framebuffer_open failed (%s)", strerror(-err)); return; } }
根据博文Android中的HAL相关库搜索机制和原理学习可知最终会获取对应的framebuffer和hardware composer模块。
另外通过mHwc->registerProcs(mHwc, &mCBContext->procs);//向HAL注册对应的回调函数,供底层事件的回调调用。
step2: 对显示屏的初始化
mDisplayData[HWC_DISPLAY_PRIMARY]维护主要的显示屏,由下面的枚举类型来负责
enum { HWC_DISPLAY_PRIMARY = 0, HWC_DISPLAY_EXTERNAL = 1, // HDMI, DP, etc. HWC_NUM_DISPLAY_TYPES };
显示屏的相关信息提取与维护有函数HWComposer::queryDisplayProperties来完成:
status_t HWComposer::queryDisplayProperties(int disp) { LOG_ALWAYS_FATAL_IF(!mHwc || !hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)); // use zero as default value for unspecified attributes int32_t values[NUM_DISPLAY_ATTRIBUTES - 1]; memset(values, 0, sizeof(values)); uint32_t config; size_t numConfigs = 1; status_t err = mHwc->getDisplayConfigs(mHwc, disp, &config, &numConfigs);//得到显示器的配置 if (err != NO_ERROR) { // this can happen if an unpluggable display is not connected mDisplayData[disp].connected = false; return err; } err = mHwc->getDisplayAttributes(mHwc, disp, config, DISPLAY_ATTRIBUTES, values);//获取显示属性 ...... }
step3:进一步初始化SF端需要的surface信息
// initialize our non-virtual displays for (size_t i=0 ; i<DisplayDevice::NUM_DISPLAY_TYPES ; i++) {//DisplayDevice::NUM_DISPLAY_TYPES = 2 DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);//0:HWC_DISPLAY_PRIMARY,1:HWC_DISPLAY_EXTERNAL mDefaultDisplays[i] = new BBinder(); wp<IBinder> token = mDefaultDisplays[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 = mHwc->isSecure(i); mCurrentState.displays.add(token, DisplayDeviceState(type)); sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i); sp<SurfaceTextureClient> stc = new SurfaceTextureClient( static_cast< sp<ISurfaceTexture> >(fbs->getBufferQueue())); sp<DisplayDevice> hw = new DisplayDevice(this, type, isSecure, token, stc, fbs, mEGLConfig);//新的显示设备 if (i > DisplayDevice::DISPLAY_PRIMARY) {//HDMI,i= 1 // 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);//将准备好的显示硬件维护在mDefaultDisplays[i]中 } }
这里分别new了FramebufferSurface和SurfaceTextureClient,下面对其进行分析
FramebufferSurface::FramebufferSurface(HWComposer& hwc, int disp) : ConsumerBase(new BufferQueue(true, new GraphicBufferAlloc())), mDisplayType(disp), mCurrentBufferSlot(-1), mCurrentBuffer(0), mHwc(hwc) { mName = "FramebufferSurface"; mBufferQueue->setConsumerName(mName); mBufferQueue->setConsumerUsageBits(GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER); mBufferQueue->setDefaultBufferFormat(mHwc.getFormat(disp)); mBufferQueue->setDefaultBufferSize(mHwc.getWidth(disp), mHwc.getHeight(disp)); mBufferQueue->setSynchronousMode(true); mBufferQueue->setDefaultMaxBufferCount(NUM_FRAMEBUFFER_SURFACE_BUFFERS); }
OK,这里又进入了FramebufferSurface的构造函数,该类继承ConsumerBase类,对该构造函数分为以下几个部分来分析。
a. new GraphicBufferAlloc(),新建一个图形缓存分配器类
b. new BufferQueue() 新建缓存队列类, 如下:
BufferQueue::BufferQueue(bool allowSynchronousMode, const sp<IGraphicBufferAlloc>& allocator) { if (allocator == NULL) { sp<ISurfaceComposer> composer(ComposerService::getComposerService()); mGraphicBufferAlloc = composer->createGraphicBufferAlloc();//创建GraphicBuffer if (mGraphicBufferAlloc == 0) { ST_LOGE("createGraphicBufferAlloc() failed in BufferQueue()"); } } else { mGraphicBufferAlloc = allocator; } }
新建的图像缓存分配器保存在BufferQueue队列当中。
c. new ConsumerBase类
ConsumerBase::ConsumerBase(const sp<BufferQueue>& bufferQueue) : mAbandoned(false), mBufferQueue(bufferQueue) { // Choose a name using the PID and a process-unique ID. mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId()); // Note that we can't create an sp<...>(this) in a ctor that will not keep a // reference once the ctor ends, as that would cause the refcount of 'this' // dropping to 0 at the end of the ctor. Since all we need is a wp<...> // that's what we create. wp<BufferQueue::ConsumerListener> listener; sp<BufferQueue::ConsumerListener> proxy; listener = static_cast<BufferQueue::ConsumerListener*>(this); proxy = new BufferQueue::ProxyConsumerListener(listener);//新建一个监听代理 status_t err = mBufferQueue->consumerConnect(proxy);//创建一个ConsumerListener代理 if (err != NO_ERROR) { CB_LOGE("SurfaceTexture: error connecting to BufferQueue: %s (%d)", strerror(-err), err); } else { mBufferQueue->setConsumerName(mName); } }
新建的ConsumerBase类,内部主要完成了创建一个BufferQueue的代理监听,同时将当前的mBufferQueue与监听连接在一起,具体如何使用后续会分析到。
status_t BufferQueue::consumerConnect(const sp<ConsumerListener>& consumerListener) { ... mConsumerListener = consumerListener; return OK; }
step4,最终集成新建一个DisplayDevice
sp<DisplayDevice> hw = new DisplayDevice(this, type, isSecure, token, stc, fbs, mEGLConfig);//新的显示设备
step5.在SurfaceFlinger内接下去的内容将会在后续进行进一步分析。