SurfaceFlinger 线程启动是由kenerl加载init.rc文件后, 执行system/bin文件夹下的可执行文件: surfaceflinger, 启动main函数:
先见时序图:
启动main函数后创建自己的线程, 并限定binder线程最大为4个, 初始话后加入线程池:
ProcessState::self()->setThreadPoolMaxThreadCount(4); // 设置最大线程数
sp ps(ProcessState::self());
ps->startThreadPool();
Main函数调用surface flinger的init函数, 对EGL, RenderEngine 等初始化:
mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(mEGLDisplay, NULL, NULL); // EGL 的初始化动作
sp vsyncSrc = new DispSyncSource(&mPrimaryDispSync, vsyncPhaseOffsetNs, true, "app"); // 虚拟化Vsync App UI部分
mEventThread = new EventThread(vsyncSrc);
sp sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync, sfVsyncPhaseOffsetNs, true, "sf"); // 虚拟化Vsync SF合成部分
mSFEventThread = new EventThread(sfVsyncSrc);
mEventQueue.setEventThread(mSFEventThread);
// Initialize the H/W composer object. There may or may not be an
// actual hardware composer underneath.
mHwc = DisplayUtils::getInstance()->getHWCInstance(this, *static_cast(this)); // 初始化hardwarecomposer
// 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");
(1) . EGL的初始就不说了, 有意思的是 google 实例了两个不同的VsyncSource : vsyncSrc 与 sfvsyncSrc 一个是app ui的vsync另一个是surfaceflinger合成的vsync, 他们只是将hardware层传过来的vsync虚拟化了.
他们根据sfVsyncPhaseOffsetNs 与 vsyncPhaseOffsetNs 两个相对偏移量将
app UI绘制 与 SF合成区分
其中Phase Offset 1, 2 的值可以改变, 这样做的目的是避免了因同时唤醒app UI 渲染和SF合成是造成对CPU资源的抢占.
(2) . 接下来启动上述EventThread.
EventThread的构造函数只是初始化一些数据, 重要的是它的onFirstRef函数(使用强指针时, 就会触发onFirstRef函数 )
void EventThread::onFirstRef() {
run("EventThread", PRIORITY_URGENT_DISPLAY+PRIORITY_MORE_FAVORABLE);
}
Run 启动threadloop: 其中一个重要的函数: waitForEvent,
( 3 ) . HWcomposer初始化:
HWComposer::HWComposer(
const sp& flinger, EventHandler& handler)
: mFlinger(flinger),mFbDev(0), mHwc(0), mNumDisplays(1),
mCBContext(new cb_context), mEventHandler(handler), mDebugForceFakeVSync(false)
{
... ...
// Note: some devices may insist that the FB HAL be opened before HWC.
int fberr = loadFbHalModule(); // 加载准备framebuffer hal模块, 最终加载gralloc.XX.so动态库
loadHwcModule(); // 加载准备硬件加速模块 最终会加载各平台对应的hwcomposer.XX.so动态库
... ...
if (needVSyncThread) {
// we don't have VSYNC support, we need to fake it
mVSyncThread = new VSyncThread(*this); // Vsync周期控制
}
}
HWcomposer 的初始化其中两个很重要的工作就是加载FB HAL与 Hwc 模块, 它们为数据在硬件合成方面做准备工作
( 4 ) . 根据EGL display与 像素格式创建RenderEngine, 并获取当前EGLContext
// initialize our non-virtual displays
for (size_t i=0 ; iisConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) {
// All non-virtual displays are currently considered secure.
bool isSecure = true;
createBuiltinDisplayLocked(type);
wp token = mBuiltinDisplays[i];
sp producer;
sp consumer;
BufferQueue::createBufferQueue(&producer, &consumer,
new GraphicBufferAlloc());
sp fbs = new FramebufferSurface(*mHwc, i,
consumer);
int32_t hwcId = allocateHwcDisplayId(type);
sp 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);
}
// When a non-virtual display device is added at boot time,
// update the active config by querying HWC otherwise the
// default config (config 0) will be used.
int activeConfig = mHwc->getActiveConfig(hwcId);
if (activeConfig >= 0) {
hw->setActiveConfig(activeConfig);
}
mDisplays.add(token, hw);
}
}
( 1 ) . 初始化BufferQueue, 这个Queue是生产者IGraphicBufferProducer 与 消费者IGraphicBufferConsumer 的关键桥梁,
( 2 ) . 创建一个FramebufferSurface
( 3 ) . 初始化各个DisplayDevice, 每个显示设备都会封装为一个DisplayDevice, 如HDMI等
DisplayDevice::DisplayDevice(
const sp& flinger,
DisplayType type,
int32_t hwcId,
int format,
bool isSecure,
const wp& displayToken,
const sp& displaySurface,
const sp& producer,
EGLConfig config)
: lastCompositionHadVisibleLayers(false),
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),
mLayerStack(NO_LAYER_STACK),
mOrientation(),
mPowerMode(HWC_POWER_MODE_OFF),
mActiveConfig(0)
{
Surface* surface;
mNativeWindow = surface = new Surface(producer, false); // 创建一个surface
ANativeWindow* const window = mNativeWindow.get(); // 获取一个本地窗口
char property[PROPERTY_VALUE_MAX];
/*
* Create our display's surface
*/
EGLSurface eglSurface;
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (config == EGL_NO_CONFIG) {
config = RenderEngine::chooseEglConfig(display, format);
}
eglSurface = eglCreateWindowSurface(display, config, window, NULL);
eglQuerySurface(display, eglSurface, EGL_WIDTH, &mDisplayWidth);
eglQuerySurface(display, eglSurface, EGL_HEIGHT, &mDisplayHeight);
// Make sure that composition can never be stalled by a virtual display
// consumer that isn't processing buffers fast enough. We have to do this
// in two places:
// * Here, in case the display is composed entirely by HWC.
// * In makeCurrent(), using eglSwapInterval. Some EGL drivers set the
// window's swap interval in eglMakeCurrent, so they'll override the
// interval we set here.
if (mType >= DisplayDevice::DISPLAY_VIRTUAL)
window->setSwapInterval(window, 0);
mConfig = config;
mDisplay = display;
mSurface = eglSurface;
mFormat = format;
mPageFlipCount = 0;
mViewport.makeInvalid();
mFrame.makeInvalid();
// virtual displays are always considered enabled
mPowerMode = (mType >= DisplayDevice::DISPLAY_VIRTUAL) ?
HWC_POWER_MODE_NORMAL : HWC_POWER_MODE_OFF;
// 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;
}
mPanelInverseMounted = false;
// Check if panel is inverse mounted (contents show up HV flipped)
property_get("persist.panel.inversemounted", property, "0");
mPanelInverseMounted = !!atoi(property);
// initialize the display orientation transform.
setProjection(DisplayState::eOrientationDefault, mViewport, mFrame);
#ifdef NUM_FRAMEBUFFER_SURFACE_BUFFERS
surface->allocateBuffers();
#endif
}
// make the GLContext current so that we can create textures when creating Layers
// (which may happens before we render something)
getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
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(); // 设置初始的layer数据
// start boot animation
startBootAnim(); // 开机动画设置
在SurfaceFlinger init完成之后, 会执行它的run函数, 使之进入死循环,去等待vsync信号: waitForEvent()
至此SurfaceFlinger的初始话工作完成, 但这才是开始, android的surface系统值得我们去深究, 去探索.