The SurfaceFlinger service starts in init.rc. The last class_start command in boot Action starts all services classified as core, including SurfaceFlinger.
system/core/rootdir/init.rc
on boot
......
class_start core
......
service surfaceflinger /system/bin/surfaceflinger
class core
user system
group graphics drmrpc
onrestart restart zygote
writepid /dev/cpuset/system-background/tasks
Copy the code
Now determine the source location of the SurfaceFlinger service. In the following Android.mk, we find that the starting point is main_surfaceflinger.cpp.
frameworks/native/services/surfaceflinger/Android.mk
############################################################### # build surfaceflinger's executable include $(CLEAR_VARS) LOCAL_CLANG := true LOCAL_LDFLAGS := -Wl,--version-script,art/sigchainlib/version-script.txt -Wl,--export-dynamic LOCAL_CFLAGS := -DLOG_TAG=\"SurfaceFlinger\" LOCAL_CPPFLAGS := -std=c++11 LOCAL_SRC_FILES := \ main_surfaceflinger.cpp LOCAL_SHARED_LIBRARIES := \ libsurfaceflinger \ libcutils \ liblog \ libbinder \ libutils \ libdl LOCAL_WHOLE_STATIC_LIBRARIES := libsigchain LOCAL_MODULE := surfaceflinger ifdef TARGET_32_BIT_SURFACEFLINGER LOCAL_32_BIT_ONLY := true endif LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code include $(BUILD_EXECUTABLE) # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #Copy the code
Focus on SurfaceFlinger instantiation, and the init() method, whose run() method was introduced in the Android Source Graphics System relayoutWindow section.
frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp
using namespace android;
int main(int.char* *) {
// Limit the number of binder threads to 4 when starting SF with your own process.
ProcessState::self() - >setThreadPoolMaxThreadCount(4);
// Start the thread pool
sp<ProcessState> ps(ProcessState::self());
ps->startThreadPool(a);// instantiate SurfaceFlinger
sp<SurfaceFlinger> flinger = new SurfaceFlinger(a);setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);
set_sched_policy(0, SP_FOREGROUND);
// Initialize before the client connects
flinger->init(a);// Release surface Flinger
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);
// Run in this thread
flinger->run(a);return 0;
}
Copy the code
The SurfaceFlinger class has a set of parameters initialized in the no-argument constructor. The onFirstRef() method initializes mEventQueue (MessageQueue).
frameworks/native/services/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),
mForceFullDamage(false),
mPrimaryHWVsyncEnabled(false),
mHWVsyncAvailable(false),
mDaltonize(false),
mHasColorMatrix(false),
mHasPoweredOff(false),
mFrameBuckets(),
mTotalTime(0),
mLastSwapTime(0)
{
ALOGI("SurfaceFlinger is starting");
// Debug things...
char value[PROPERTY_VALUE_MAX];
property_get("ro.bq.gpu_to_cpu_unsupported", value, "0");
mGpuToCpuSupported = !atoi(value);
property_get("debug.sf.drop_missed_frames", value, "0");
mDropMissedFrames = 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()) {
// Failed to start DDMS debugging is not enabled
mDebugDDMS = 0; }}ALOGI_IF(mDebugRegion, "showupdates enabled");
ALOGI_IF(mDebugDDMS, "DDMS debugging enabled");
}
void SurfaceFlinger::onFirstRef(a)
{
mEventQueue.init(this);
}
Copy the code
MessageQueue: : init (…). Method initializes mFlinger, mLooper, and mHandler.
frameworks/native/services/surfaceflinger/MessageQueue.cpp
void MessageQueue::init(const sp<SurfaceFlinger>& flinger)
{
mFlinger = flinger;
mLooper = new Looper(true);
mHandler = new Handler(*this);
}
Copy the code
SurfaceFlinger initialization is commented in detail in the code.
frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::init(a) {
ALOGI( "SurfaceFlinger's main thread ready to run. "
"Initializing graphics H/W...");
Mutex::Autolock _l(mStateLock);
// Initialize EGL for default display
mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(mEGLDisplay, NULL.NULL);
/ / start 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);
// Initialize the H/W Composer object. There may or may not be actual hardware Composer below.
mHwc = new HWComposer(this,
*static_cast<HWComposer::EventHandler *>(this));
// Get a RenderEngine for a given display/configuration (without failure)
mRenderEngine = RenderEngine::create(mEGLDisplay, mHwc->getVisualID());
// Retrieves the selected/created EGL context
mEGLContext = mRenderEngine->getEGLContext(a);LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
"couldn't create EGLContext");
// Initialize the non-virtual display
for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);
// Set the monitor that is already connected
if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) {
// Currently, all non-virtual displays are considered secure.
bool isSecure = true;
createBuiltinDisplayLocked(type);
wp<IBinder> token = mBuiltinDisplays[i];
sp<IGraphicBufferProducer> producer;
sp<IGraphicBufferConsumer> consumer;
/ / create BufferQueue
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); }}// Keep GLContext up to date so that we can create textures when we create layers (this can happen before rendering something)
getDefaultDisplayDevice() - >makeCurrent(mEGLDisplay, mEGLContext);
mEventControlThread = new EventControlThread(this);
mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
// If there is no HWComposer, set a false vSYNC cycle
if (mHwc->initCheck() != NO_ERROR) {
mPrimaryDispSync.setPeriod(16666667);
}
// Initialize our drawing state
mDrawingState = mCurrentState;
// Set initial conditions (such as canceling the default device)
initializeDisplays(a);// Start the animation
startBootAnim(a); }Copy the code