surfaceFlingerはinit.rcにサービスとして存在し、次のように宣言されています。
service surfaceflinger /system/bin/surfaceflinger
class main
user system
group graphics drmrpc
onrestart restart zygote
上記からわかるように、surfaceflingerはzygoteと同じクラスmainに属しています。しかし、パラメータをつけて起動する必要はありません。同時に、surfaceflingerはサービスであるため、別の実行ファイルであり、プログラムパスは/system/bin/surfaceflingerで、別のプロセスで実行されます。
int main(int argc, char** argv) {
// When SF is launched in its own process, limit the number of
// binder threads to 4.
ProcessState::self()->setThreadPoolMaxThreadCount(4);//バインダースレッドの数を4
// start the thread pool
sp<ProcessState> ps(ProcessState::self());
ps->startThreadPool();//バインダースレッドを起動する
// instantiate surfaceflinger
sp<SurfaceFlinger> flinger = new SurfaceFlinger();//SFオブジェクトを作る
#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();//SFレイヤーの初期化は
// publish surface flinger
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);//SMに追加する
// run in this thread
flinger->run();//sf実行する。
return 0;
}
1.バインダーの実行環境の初期化 2.Sfオブジェクトの生成と初期化 3.他のプロセスにサービスを提供するために、ServiceMangerにSfサービスを追加 4.Sfは自身のスレッドで実行開始 5.
サービスプロセスであるSurfaceFlingerは、必然的にBinderを介したIPC通信を必要とするため、最初にBinder環境を初期化する必要があります。次にSurfaceFlingerオブジェクトが生成されます。
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),
mPrimaryHWVsyncEnabled(false),
mHWVsyncAvailable(false),
mDaltonize(false)
{
// debugging stuff...
char value[PROPERTY_VALUE_MAX];
property_get("ro.bq.gpu_to_cpu_unsupported", value, "0");
mGpuToCpuSupported = !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()) {
// start failed, and DDMS debugging not enabled
mDebugDDMS = 0;
}
}
}
コンストラクタのメソッドはシンプルで、メンバを初期化し、DDMS デバッグが有効かどうかなどの設定情報を読み込むだけです。次に init メソッドでオブジェクトを初期化します。この初期化処理は多くの重要な仕事をします。
frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
//sfの初期化メソッドは
void SurfaceFlinger::init() {
status_t err;
Mutex::Autolock _l(mStateLock);
// 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));//複合オブジェクトを作る
// First try to get an ES2 config
err = selectEGLConfig(mEGLDisplay, mHwc->getVisualID(), EGL_OPENGL_ES2_BIT,
&mEGLConfig);
if (err != NO_ERROR) {
// If ES2 fails, try ES1
err = selectEGLConfig(mEGLDisplay, mHwc->getVisualID(),
EGL_OPENGL_ES_BIT, &mEGLConfig);
}
EGLint r,g,b,a;
eglGetConfigAttrib(mEGLDisplay, mEGLConfig, EGL_RED_SIZE, &r);
eglGetConfigAttrib(mEGLDisplay, mEGLConfig, EGL_GREEN_SIZE, &g);
eglGetConfigAttrib(mEGLDisplay, mEGLConfig, EGL_BLUE_SIZE, &b);
eglGetConfigAttrib(mEGLDisplay, mEGLConfig, EGL_ALPHA_SIZE, &a);
// get a RenderEngine for the given display / config (can't fail)
mRenderEngine = RenderEngine::create(mEGLDisplay, mEGLConfig);//与えられたデバイスからレンダリング・エンジンを作る
// retrieve the EGL context that was selected/created
mEGLContext = mRenderEngine->getEGLContext();// EGL context
// figure out which format we got
eglGetConfigAttrib(mEGLDisplay, mEGLConfig,
EGL_NATIVE_VISUAL_ID, &mEGLNativeVisualId);
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;
createBuiltinDisplayLocked(type);
wp<IBinder> token = mBuiltinDisplays[i];
//ディスプレイ・デバイスのフレーム・バッファを管理するためにBufferQueueを作り、FramebufferSurfaceを通して管理する。
sp<BufferQueue> bq = new BufferQueue(new GraphicBufferAlloc());
sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i, bq);
sp<DisplayDevice> hw = new DisplayDevice(this,
type, allocateHwcDisplayId(type), isSecure, token,
fbs, bq,
mEGLConfig);//物理デバイスごとにディスプレイ・デバイス・オブジェクトを作る
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 %d as acquired/unblanked", i);
hw->acquireScreen();
}
mDisplays.add(token, hw);
}
}
// make the GLContext current so that we can create textures when creating Layers
// (which may happens before we render something)
getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);//EGLコンテキストをデフォルト・ディスプレイ・デバイスに関連付ける
// start the EventThread
sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
vsyncPhaseOffsetNs, true);//描画遅延オブジェクトを作る
mEventThread = new EventThread(vsyncSrc);//描画遅延Vsyncシグナルの管理を担当する。
sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
sfVsyncPhaseOffsetNs, false);//合成遅延オブジェクトを作る
mSFEventThread = new EventThread(sfVsyncSrc);//合成遅延Vsyncシグナルの管理を担当する。
mEventQueue.setEventThread(mSFEventThread);
mEventControlThread = new EventControlThread(this);
mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
}
init メソッドで sf は次のことを行います: 1. デフォルトのディスプレイデバイスの EGL 環境を初期化します 2. 合成オブジェクトを作成します 3. すべての非仮想ディスプレイデバイスを初期化します 4. 描画遅延 Vysnc ソースと合成遅延 Vysnc ソースを作成します。
void MessageQueue::setEventThread(const sp<EventThread>& eventThread)
{
mEventThread = eventThread;
mEvents = eventThread->createEventConnection();
mEventTube = mEvents->getDataChannel();
mLooper->addFd(mEventTube->getFd(), 0, ALOOPER_EVENT_INPUT,
MessageQueue::cb_eventReceiver, this);//sfのvsyncシグナル用のイベントコールバックを登録する。
}
mainメソッドで生成されたSurfaceFlingerは強い参照オブジェクトなので、最初の呼び出しはonFirstRefメソッドもトリガーし、SFのmEventQueueメンバを初期化することに注意してください。これはSFのメッセージ管理を担うMessageQueueオブジェクトです。
void SurfaceFlinger::onFirstRef()
{
mEventQueue.init(this);
}
void MessageQueue::init(const sp<SurfaceFlinger>& flinger)
{
mFlinger = flinger;//への参照を保持する。
mLooper = new Looper(true);//Looperオブジェクトを作る。
mHandler = new Handler(*this);// Handler
}
最後に、sfのrunメソッドが呼び出され、メッセージが到着するのを常に待ち、それらを処理するループに入ります。
void SurfaceFlinger::run() {
do {
waitForEvent();
} while (true);
}
void SurfaceFlinger::waitForEvent() {
mEventQueue.waitMessage();
}
frameworks/native/services/surfaceflinger/MessageQueue.cpp
void MessageQueue::waitMessage() {
do {
IPCThreadState::self()->flushCommands();
int32_t ret = mLooper->pollOnce(-1);//メッセージはMessageQueueのhandleMessageメソッドを呼び出すことで内部的に処理される。
switch (ret) {
case ALOOPER_POLL_WAKE:
case ALOOPER_POLL_CALLBACK:
continue;
case ALOOPER_POLL_ERROR:
ALOGE("ALOOPER_POLL_ERROR");
case ALOOPER_POLL_TIMEOUT:
// timeout (should not happen)
continue;
default:
// should not happen
ALOGE("Looper::pollOnce() returned unknown status %d", ret);
continue;
}
} while (true);
}
//メッセージはメッセージハンドラ
void MessageBase::handleMessage(const Message&) {
this->handler();
barrier.open();
};
一つはVsyncシグナルで、これは登録されたcb_eventReceiverイベント・コールバックを通して処理されます。もう一つはアプリケーション・プロセスやクライアントからのメッセージで、例えばレイヤーの作成要求などです。
frameworks/native/services/surfaceflinger/Client.cpp
status_t Client::createSurface(
const String8& name,
uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
sp<IBinder>* handle,
sp<IGraphicBufferProducer>* gbp)
{
class MessageCreateLayer : public MessageBase {// messagbase
SurfaceFlinger* flinger;
Client* client;
sp<IBinder>* handle;
sp<IGraphicBufferProducer>* gbp;
status_t result;
const String8& name;
uint32_t w, h;
PixelFormat format;
uint32_t flags;
public:
MessageCreateLayer(SurfaceFlinger* flinger,
const String8& name, Client* client,
uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
sp<IBinder>* handle,
sp<IGraphicBufferProducer>* gbp)
: flinger(flinger), client(client),
handle(handle), gbp(gbp),
name(name), w(w), h(h), format(format), flags(flags) {
}
status_t getResult() const { return result; }
virtual bool handler() {//ハンドラーメソッドはレシーバーがメッセージを処理するために実装される。
result = flinger->createLayer(name, client, w, h, format, flags,
handle, gbp);
return true;
}
};
sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(),
name, this, w, h, format, flags, handle, gbp);
mFlinger->postMessageSync(msg);
return static_cast<MessageCreateLayer*>( msg.get() )->getResult();
}