SurfaceFlinger是Android的一个native进程,负责将图层进行合成,图层叠加起来就构成了我们看到的界面。合成的方式分为在线合成和离线合成。在线合成是指现在一块buffer画好所有的内容,然后直接交给linux图像驱动framebuffer显示出来;离线合成是指将一些图层的buffer直接递交HWComposer,HWComposer指的是能够处理图像数据并组合的现实硬件模块(有些设备上可能没有),当需要显示某一行的数据时,再将这些图层的数据进行处理组合后再交给framebuffer显示出来,合成方式有MDP,DYN,C2D等,反正不是GPU,因而减轻了GPU负担。
SurfaceFlinger启动的main函数在main_surfaceflinger.cpp中。最后的run函数使SurfaceFlinger进程陷入do…while循环中,不会退出。我们重点关注SurfaceFlinger的init函数。
/frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp
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;
}
下面介绍的情况均以只有一个主屏幕(id为0)为前提,实际上Android支持三种屏幕:主屏幕,外接屏幕(HDMI等),虚拟屏幕(投屏)。init函数的主要工作有:1.初始化EGL的一些环境以及设置;2.启动hwc;3.搜寻可用的屏幕,初始化屏幕的一些信息,新建DisplayDevice和FramebufferSurface,并分别作为生产者和消费者;4.分别为app端和SurfaceFlinger建立一个EventThread以响应vysnc信号;5.启动bootanimation。
/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
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
//初始化EGL环境
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.
//初始化hwc
mHwc = new HWComposer(this,
*static_cast<HWComposer::EventHandler *>(this));
// get a RenderEngine for the given display / config (can't fail)
//创建RenderEngine,RenderEngine封装了一些OpenGL的操作
mRenderEngine = RenderEngine::create(mEGLDisplay, mHwc->getVisualID());
// retrieve the EGL context that was selected/created
//获取EGL上下文
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;
//创建内置屏幕,每个屏幕id对应一个binder对象
createBuiltinDisplayLocked(type);
wp<IBinder> token = mBuiltinDisplays[i];
//创建生产者和消费者
sp<IGraphicBufferProducer> producer;
sp<IGraphicBufferConsumer> consumer;
BufferQueue::createBufferQueue(&producer, &consumer,
new GraphicBufferAlloc());
//新建FramebufferSurface作为消费者,向framebuffer传递数据就靠它了
sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i,
consumer);
//为屏幕创建hwc层的id
int32_t hwcId = allocateHwcDisplayId(type);
//新建DisplayDevice生产者,与显示画面有关
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);
}
//屏幕id的对应的binder对象和DisplayDevice组成键值对,保存在mDisplays
mDisplays.add(token, hw);
}
}
// make the GLContext current so that we can create textures when creating Layers
// (which may happens before we render something)
//DisplayDevice::makeCurrent会调用到eglMakeCurrent,libagl.so的实现里eglMakeCurrent会dequeue一块buffer
getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
// start the EventThread
//基于不同的vsync信号模型创建的EventThread,mEventThread是app端对vsync信号的处理线程,mSFEventThread是SurfaceFlinger端对vysnc信号的处理线程
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线程用来开关vsync
mEventControlThread = new EventControlThread(this);
mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
// set a fake vsync period if there is no HWComposer
//hwc层初始化失败后,使用1/16666667的屏幕刷新周期
if (mHwc->initCheck() != NO_ERROR) {
mPrimaryDispSync.setPeriod(16666667);
}
// initialize our drawing state
//初始化mDrawingState
mDrawingState = mCurrentState;
// set initial conditions (e.g. unblank default device)
//初始化主屏幕的一些flag和信息
initializeDisplays();
// start boot animation
//启动bootanimation
startBootAnim();
}
先看看hwc的初始化。vsync信号分为两种:1.硬件产生的vsync;2.软件模拟的vsync。这份源码对应的是Android 5.1,使用的hwc HAL版本是1.4,所以不会打开framebuffer设备,在有hwc设备的情况下不会开启软件模拟vysnc。
而且硬件vsync一开始是出于关闭状态的。
/frameworks/native/services/surfaceflinger/DisplayHardware/HWComposer.cpp
HWComposer::HWComposer(
const sp<SurfaceFlinger>& flinger,
EventHandler& handler)
: mFlinger(flinger),
mFbDev(0), mHwc(0), mNumDisplays(1),
mCBContext(new cb_context),
mEventHandler(handler),
mDebugForceFakeVSync(false)
{
for (size_t i =0 ; i<MAX_HWC_DISPLAYS ; i++) {
mLists[i] = 0;
}
for (size_t i=0 ; i<HWC_NUM_PHYSICAL_DISPLAY_TYPES ; i++) {
mLastHwVSync[i] = 0;
mVSyncCounts[i] = 0;
}
char value[PROPERTY_VALUE_MAX];
property_get("debug.sf.no_hw_vsync", value, "0");
//mDebugForceFakeVSync决定我们是否启用硬件vsync,为true时永久关闭硬件vsync
mDebugForceFakeVSync = atoi(value);
//表示是否需要软件模拟vsync
bool needVSyncThread = true;
// Note: some devices may insist that the FB HAL be opened before HWC.
//加载framebuffer和hwc的HAL模块
int fberr = loadFbHalModule();
loadHwcModule();
if (mFbDev && mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
// close FB HAL if we don't needed it.
// FIXME: this is temporary until we're not forced to open FB HAL
// before HWC.
//如果framebuffer和hwc的硬件设备都被成功加载,且hwc HAL版本大于等于1.1,关闭framebuffer硬件设备
framebuffer_close(mFbDev);
mFbDev = NULL;
}
// If we have no HWC, or a pre-1.1 HWC, an FB dev is mandatory.
if ((!mHwc || !hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1))
&& !mFbDev) {
ALOGE("ERROR: failed to open framebuffer (%s), aborting",
strerror(-fberr));
abort();
}
// these display IDs are always reserved
//NUM_BUILTIN_DISPLAYS(2)以内的id已被占用,申请hwc id需要从NUM_BUILTIN_DISPLAYS开始申请
for (size_t i=0 ; i<NUM_BUILTIN_DISPLAYS ; i++) {
mAllocatedDisplayIDs.markBit(i);
}
if (mHwc) {
ALOGI("Using %s version %u.%u", HWC_HARDWARE_COMPOSER,
(hwcApiVersion(mHwc) >> 24) & 0xff,
(hwcApiVersion(mHwc) >> 16) & 0xff);
if (mHwc->registerProcs) {
//注册hwc HAL层回调事件
mCBContext->hwc = this;
mCBContext->procs.invalidate = &hook_invalidate;
mCBContext->procs.vsync = &hook_vsync;
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);
}
// don't need a vsync thread if we have a hardware composer
//有hwc模块就不需要软件模拟vysnc了
needVSyncThread = false;
// always turn vsync off when we start
//hwc初始化时先关闭硬件vysnc
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_3)) {
// 1.3 adds support for virtual displays
mNumDisplays = MAX_HWC_DISPLAYS;
} else if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
// 1.1 adds support for multiple displays
mNumDisplays = NUM_BUILTIN_DISPLAYS;
} else {
mNumDisplays = 1;
}
}
if (mFbDev) {
//hwc HAL1.1以上的版本mFbDev为null,不会走到该分支
ALOG_ASSERT(!(mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)),
"should only have fbdev if no hwc or hwc is 1.0");
DisplayData& disp(mDisplayData[HWC_DISPLAY_PRIMARY]);
disp.connected = true;
disp.format = mFbDev->format;
DisplayConfig config = DisplayConfig();
config.width = mFbDev->width;
config.height = mFbDev->height;
config.xdpi = mFbDev->xdpi;
config.ydpi = mFbDev->ydpi;
config.refresh = nsecs_t(1e9 / mFbDev->fps);
disp.configs.push_back(config);
disp.currentConfig = 0;
} else if (mHwc) {
// here we're guaranteed to have at least HWC 1.1
//执行到这里说明是hwc HAL1.1以上的版本,这里从HAL层获取屏幕信息填充mDisplayData成员变量
for (size_t i =0 ; i<NUM_BUILTIN_DISPLAYS ; i++) {
queryDisplayProperties(i);
}
}
if (needVSyncThread) {
// we don't have VSYNC support, we need to fake it
//不支持硬件vsyn,就开启软件模拟vysnc线程
mVSyncThread = new VSyncThread(*this);
}
}
再看看DisplayDevice的初始化。
/frameworks/native/services/surfaceflinger/DisplayDevice.cpp
DisplayDevice::DisplayDevice(
const sp<SurfaceFlinger>& flinger,
DisplayType type,
int32_t hwcId,
int format,
bool isSecure,
const wp<IBinder>& displayToken,
const sp<DisplaySurface>& displaySurface,
const sp<IGraphicBufferProducer>& 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)
{
//DisplayDevice新建一个Surface作为生产者
mNativeWindow = new Surface(producer, false);
ANativeWindow* const window = mNativeWindow.get();
/*
* Create our display's surface
*/
EGLSurface surface;
EGLint w, h;
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (config == EGL_NO_CONFIG) {
config = RenderEngine::chooseEglConfig(display, format);
}
//创建EGLSurface
surface = eglCreateWindowSurface(display, config, window, NULL);
//获取Surface的宽高,保存在mDisplayWidth和mDisplayHeight中,这两个值在消费者FrameBufferSurfcae创建时从hwc HAL层获得,就是屏幕的宽高值
eglQuerySurface(display, surface, EGL_WIDTH, &mDisplayWidth);
eglQuerySurface(display, surface, 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 = surface;
mFormat = format;
mPageFlipCount = 0;
mViewport.makeInvalid();
mFrame.makeInvalid();
// virtual displays are always considered enabled
//主屏幕的电源模式初始化为关闭状态,在SurfaceFlinger::onInitializeDisplays中,会将主屏幕的电源模式设为HWC_POWER_MODE_NORMAL
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;
}
// initialize the display orientation transform.
//调整显示设备视角的大小、位移、旋转等参数,eOrientationDefault指的是默认的旋转方向,mViewport指的是逻辑显示区域,mFrame指的是物理显示区域
setProjection(DisplayState::eOrientationDefault, mViewport, mFrame);
}
再看看双EventThread的初始化。我们可以在基于物理vsync的基础上添加相移,作为独立的vsync起始位置mPhase,再根据vsync的周期mPeriod,可以独立就算出一个独立的vsync模型,供app和SurfaceFlinger两个EventThread使用。而且还可以在后续的过程中动态更新这个vsync模型,这样做可以使物理vsync,app绘制下一帧,SurfaceFlinger合成图层错开工作,避免同一时间同时执行这三个操作,提高效率。
vsyncPhaseOffsetNs是app端的DispSyncSource使用的相移mPhase由VSYNC_EVENT_PHASE_OFFSET_NS宏指定,可以在在mk文件加入LOCAL_CFLAGS := -DVSYNC_EVENT_PHASE_OFFSET_NS=xxx指定;而SurfaceFlinger端使用的相移SF_VSYNC_EVENT_PHASE_OFFSET_NS则由SF_VSYNC_EVENT_PHASE_OFFSET_NS指定,也可以在mk文件中指定。而mPeriod在两个DispSyncSource构建时为0。
/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
// 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);
mPrimaryDispSync是一个DispSync对象,其在构造时会执行一个DispSyncThread线程。该线程负责在使能vync的时候执行一些回调操作,从而触发更新图层或者app绘制下一帧的动作。这个在以后篇幅再介绍。
/frameworks/native/services/surfaceflinger/DispSync.cpp
DispSync::DispSync() :
mRefreshSkipCount(0),
mThread(new DispSyncThread()) {
mThread->run("DispSync", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
reset();
beginResync();
if (kTraceDetailedInfo) {
// If we're not getting present fences then the ZeroPhaseTracer
// would prevent HW vsync event from ever being turned off.
// Even if we're just ignoring the fences, the zero-phase tracing is
// not needed because any time there is an event registered we will
// turn on the HW vsync events.
if (!kIgnorePresentFences) {
addEventListener(0, new ZeroPhaseTracer());
}
}
}
SurfaceFlinger::initializeDisplays用来初始化一些状态。
/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::initializeDisplays() {
class MessageScreenInitialized : public MessageBase {
SurfaceFlinger* flinger;
public:
MessageScreenInitialized(SurfaceFlinger* flinger) : flinger(flinger) { }
virtual bool handler() {
flinger->onInitializeDisplays();
return true;
}
};
sp<MessageBase> msg = new MessageScreenInitialized(this);
postMessageAsync(msg); // we may be called from main thread, use async message
}
DisplayState用来记录一个屏幕设备的状态信息。这里将主屏幕的变化flag设为eDisplayProjectionChanged |eLayerStackChanged;将layerStack 设为0(通常一个屏幕对应一个layerstack);将orientation设为默认旋转方向等等。这些信息都会被封装到DisplayState中,这个DisplayState会被添加到装载DisplayState的vector displays中,通过setTransactionState–>setDisplayStateLocked传递给mCurrentState的displays成员。SurfaceFlinger维持了两个成员变量mCurrentState和mDrawingState,mCurrentState记录了SurfaceFlinger当前屏幕的相关信息,mDrawingState记录了上一次更新图层时屏幕的相关信息。通过对比mCurrentState和mDrawingState,可以知道屏幕的哪些参数发生了改变,并更新这些信息到mCurrentState中。如果发生了变化,还会触发一次signalTransaction以更新图层。
/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::onInitializeDisplays() {
// reset screen orientation and use primary layer stack
Vector<ComposerState> state;
Vector<DisplayState> displays;
DisplayState d;
d.what = DisplayState::eDisplayProjectionChanged |
DisplayState::eLayerStackChanged;
d.token = mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY];
d.layerStack = 0;
d.orientation = DisplayState::eOrientationDefault;
d.frame.makeInvalid();
d.viewport.makeInvalid();
d.width = 0;
d.height = 0;
displays.add(d);
setTransactionState(state, displays, 0);
setPowerModeInternal(getDisplayDevice(d.token), HWC_POWER_MODE_NORMAL);
const nsecs_t period =
getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
mAnimFrameTracker.setDisplayRefreshPeriod(period);
}
/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::setTransactionState(
const Vector<ComposerState>& state,
const Vector<DisplayState>& displays,
uint32_t flags)
{
ATRACE_CALL();
Mutex::Autolock _l(mStateLock);
uint32_t transactionFlags = 0;
if (flags & eAnimation) {
// For window updates that are part of an animation we must wait for
// previous animation "frames" to be handled.
while (mAnimTransactionPending) {
status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
if (CC_UNLIKELY(err != NO_ERROR)) {
// just in case something goes wrong in SF, return to the
// caller after a few seconds.
ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out "
"waiting for previous animation frame");
mAnimTransactionPending = false;
break;
}
}
}
size_t count = displays.size();
for (size_t i=0 ; i<count ; i++) {
const DisplayState& s(displays[i]);
//更新屏幕信息到mCurrentState
transactionFlags |= setDisplayStateLocked(s);
}
count = state.size();
for (size_t i=0 ; i<count ; i++) {
const ComposerState& s(state[i]);
// Here we need to check that the interface we're given is indeed
// one of our own. A malicious client could give us a NULL
// IInterface, or one of its own or even one of our own but a
// different type. All these situations would cause us to crash.
//
// NOTE: it would be better to use RTTI as we could directly check
// that we have a Client*. however, RTTI is disabled in Android.
if (s.client != NULL) {
sp<IBinder> binder = s.client->asBinder();
if (binder != NULL) {
String16 desc(binder->getInterfaceDescriptor());
if (desc == ISurfaceComposerClient::descriptor) {
sp<Client> client( static_cast<Client *>(s.client.get()) );
transactionFlags |= setClientStateLocked(client, s.state);
}
}
}
}
if (transactionFlags) {
// this triggers the transaction
//屏幕信息发生了变化,触发更新图层
setTransactionFlags(transactionFlags);
// if this is a synchronous transaction, wait for it to take effect
// before returning.
if (flags & eSynchronous) {
mTransactionPending = true;
}
if (flags & eAnimation) {
mAnimTransactionPending = true;
}
while (mTransactionPending) {
status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
if (CC_UNLIKELY(err != NO_ERROR)) {
// just in case something goes wrong in SF, return to the
// called after a few seconds.
ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!");
mTransactionPending = false;
break;
}
}
}
}
/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
uint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s)
{
ssize_t dpyIdx = mCurrentState.displays.indexOfKey(s.token);
if (dpyIdx < 0)
return 0;
uint32_t flags = 0;
DisplayDeviceState& disp(mCurrentState.displays.editValueAt(dpyIdx));
if (disp.isValid()) {
const uint32_t what = s.what;
if (what & DisplayState::eSurfaceChanged) {
if (disp.surface->asBinder() != s.surface->asBinder()) {
disp.surface = s.surface;
flags |= eDisplayTransactionNeeded;
}
}
if (what & DisplayState::eLayerStackChanged) {
if (disp.layerStack != s.layerStack) {
disp.layerStack = s.layerStack;
flags |= eDisplayTransactionNeeded;
}
}
if (what & DisplayState::eDisplayProjectionChanged) {
if (disp.orientation != s.orientation) {
disp.orientation = s.orientation;
flags |= eDisplayTransactionNeeded;
}
if (disp.frame != s.frame) {
disp.frame = s.frame;
flags |= eDisplayTransactionNeeded;
}
if (disp.viewport != s.viewport) {
disp.viewport = s.viewport;
flags |= eDisplayTransactionNeeded;
}
}
if (what & DisplayState::eDisplaySizeChanged) {
if (disp.width != s.width) {
disp.width = s.width;
flags |= eDisplayTransactionNeeded;
}
if (disp.height != s.height) {
disp.height = s.height;
flags |= eDisplayTransactionNeeded;
}
}
}
return flags;
}
/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& hw,
int mode) {
ALOGD("Set power mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
this);
int32_t type = hw->getDisplayType();
int currentMode = hw->getPowerMode();
if (mode == currentMode) {
ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode);
return;
}
hw->setPowerMode(mode);
if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
ALOGW("Trying to set power mode for virtual display");
return;
}
if (currentMode == HWC_POWER_MODE_OFF) {
getHwComposer().setPowerMode(type, mode);
if (type == DisplayDevice::DISPLAY_PRIMARY) {
// FIXME: eventthread only knows about the main display right now
mEventThread->onScreenAcquired();
resyncToHardwareVsync(true);
}
mVisibleRegionsDirty = true;
repaintEverything();
} else if (mode == HWC_POWER_MODE_OFF) {
if (type == DisplayDevice::DISPLAY_PRIMARY) {
disableHardwareVsync(true); // also cancels any in-progress resync
// FIXME: eventthread only knows about the main display right now
mEventThread->onScreenReleased();
}
getHwComposer().setPowerMode(type, mode);
mVisibleRegionsDirty = true;
// from this point on, SF will stop drawing on this display
} else {
getHwComposer().setPowerMode(type, mode);
}
}
:initializeDisplays还有一步操作是设置DisplayDevice的PowerMode。主屏幕初始化时的PowerMode为HWC_POWER_MODE_OFF,现在要更新为HWC_POWER_MODE_NORMAL。
/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& hw,
int mode) {
ALOGD("Set power mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
this);
int32_t type = hw->getDisplayType();
int currentMode = hw->getPowerMode();
if (mode == currentMode) {
ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode);
return;
}
//更新DisplayDevice的PowerMode
hw->setPowerMode(mode);
if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
ALOGW("Trying to set power mode for virtual display");
return;
}
if (currentMode == HWC_POWER_MODE_OFF) {
//设置hwc的PowerMode
getHwComposer().setPowerMode(type, mode);
if (type == DisplayDevice::DISPLAY_PRIMARY) {
// FIXME: eventthread only knows about the main display right now
mEventThread->onScreenAcquired();
//需要打开硬件vsync同步
resyncToHardwareVsync(true);
}
mVisibleRegionsDirty = true;
//触发重绘操作
repaintEverything();
} else if (mode == HWC_POWER_MODE_OFF) {
if (type == DisplayDevice::DISPLAY_PRIMARY) {
disableHardwareVsync(true); // also cancels any in-progress resync
// FIXME: eventthread only knows about the main display right now
mEventThread->onScreenReleased();
}
getHwComposer().setPowerMode(type, mode);
mVisibleRegionsDirty = true;
// from this point on, SF will stop drawing on this display
} else {
getHwComposer().setPowerMode(type, mode);
}
}
这里会更新vysnc周期mPeriod为hwc层的硬件Vysnc周期,一般为1/60s,因为从灭屏状态进入到点亮屏幕状态需要重建vsync模型。mPrimaryHWVsyncEnabled被初始化为false,所以通过EventControlThread::setVsyncEnabled就可以打开硬件Vsync了,从此开始进入Vsync的世界。
/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::resyncToHardwareVsync(bool makeAvailable) {
Mutex::Autolock _l(mHWVsyncLock);
if (makeAvailable) {
mHWVsyncAvailable = true;
} else if (!mHWVsyncAvailable) {
ALOGE("resyncToHardwareVsync called when HW vsync unavailable");
return;
}
const nsecs_t period =
getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
mPrimaryDispSync.reset();
mPrimaryDispSync.setPeriod(period);
if (!mPrimaryHWVsyncEnabled) {
mPrimaryDispSync.beginResync();
//eventControl(HWC_DISPLAY_PRIMARY, SurfaceFlinger::EVENT_VSYNC, true);
mEventControlThread->setVsyncEnabled(true);
mPrimaryHWVsyncEnabled = true;
}
}
SurfaceFlinger初始化的最后一步是启动bootanimation,由于跟原理无关,先略去。