本文均属自己阅读源码的点滴总结,转账请注明出处谢谢。
欢迎和大家交流。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(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 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 fbs = new FramebufferSurface(*mHwc, i);
sp stc = new SurfaceTextureClient(
static_cast< sp >(fbs->getBufferQueue()));
sp 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 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& 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> 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 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 fbs = new FramebufferSurface(*mHwc, i);
sp stc = new SurfaceTextureClient(
static_cast< sp >(fbs->getBufferQueue()));
sp 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& allocator)
{
if (allocator == NULL) {
sp 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) :
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 listener;
sp proxy;
listener = static_cast(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) {
...
mConsumerListener = consumerListener;
return OK;
}
step4,最终集成新建一个DisplayDevice
sp hw = new DisplayDevice(this,
type, isSecure, token, stc, fbs, mEGLConfig);//新的显示设备
step5.在SurfaceFlinger内接下去的内容将会在后续进行进一步分析。