• Save
Surface flingerservice(서피스플링거서비스초기화 jb)
Upcoming SlideShare
Loading in...5
×
 

Surface flingerservice(서피스플링거서비스초기화 jb)

on

  • 2,414 views

 

Statistics

Views

Total Views
2,414
Views on SlideShare
2,314
Embed Views
100

Actions

Likes
1
Downloads
0
Comments
0

4 Embeds 100

http://fefe7270.blogspot.kr 94
http://translate.googleusercontent.com 3
http://fefe7270.blogspot.com 2
http://fefe7270.blogspot.in 1

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Surface flingerservice(서피스플링거서비스초기화 jb) Surface flingerservice(서피스플링거서비스초기화 jb) Presentation Transcript

    • SurfaceFlingerService(서피스플링거서비스초기화 JB) 박철희 1
    • 1.Surfaceflinger 서비스 구조 서비스 클라이언트 서비스 프록시 시스템 서비스 SurfaceComposer ISurfaceComposer SurfaceFlinger Client ISurfaceComposer SurfaceControl Client 리모트 서비스 ComposerService IGraphicAlloc Client Compser ISurface Surface GraphicBufferAlloc ISurfaceTexture SurfaceTextureClient BufferQueue 2
    • 1.Surfaceflinger 서비스 구조-서비스 클라이언트  서비스 클라이언트 구성요소 설명 SurfaceComposeClient 1.서피스 플링거 서비스와 연결 2. 서피스 생성,삭제, 상태변경 요청 SurfaceControl 1.레이어마다 하나의 SurfaceControl 객체가 생성 됨. 2. SurfaceComposeClient 의 상태 변경 함수를 매핑하여 사용 함. ComposerService 1.애플리케이션이 서피스 플링거와 연결 시 서피스 플링거 서비스의 서비스 프록시 (ISurfaceComposer)를 획득 함. 2.디스플레이 공유 메모리의 서비스 프록시 획득 Composer 1. SurfaceComposeClient에서 레이어의 상태 변경 요청 시 Composer 클래스의 함수 사용 Surface(c++) 1.SurfaceTextureClient를 상속 받음. 2. 서피스의 네이티브 윈도우를 사용 할 수 있도록 도와줌. SurfaceTextureClient 1.안드로이드 네이티브 윈도우의 그래픽 버퍼를 사용하기 위한 멤버 함수를 가짐. 3
    • 1.Surfaceflinger 서비스 구조-시스템/리모트 서비스  시스템 서비스 /리모트 서비스 구성요소 서비스 프록시 설명 SurfaceFlinger ISurfaceComposer 1.서피스 생성,삭제 2.레이어 합성 Client ISurfaceComposerClient 1.생성된 레이어를 Client 별로 관리 BufferQueue ISurfaceTexture 1.그래픽 버퍼 생성 2.레이어 하나 당 하나의 버퍼 큐 리모트 서비스가 생성 됨. GraphicBufferAlloc IGraphicBufferAlloc 1. 그래픽 버퍼 생성 후 메모리 할당 요청이 발생하면 graphic HAL에게 메모리 할당 요청 4
    • 2.Surfaceflinger 서비스 아키텍처 서비스 클라이언트 SurfaceFlinger Client 1 2 ANativeWindow Refbas 3 dequeue surfacetexture e SurfaceControl BufferQueue 4 그래픽버퍼 queue layer1 2 5 surfacetextureclient layer2 합성 OpenGL surface layer3 ES API 1 서피스 플링거와 연결이 되면 서피스를 관리하는 Client 리모트 서비스가 생성된다. 2 서피스 (layer)생성이 되면 서버측에는 surfacetexture가 생성되고, 클라이언트에는 surfacetextureclient가 생성된다. 3 어플리케이션은 surfacetextureclient를 이용하여 그래픽 버퍼의 요청(dequeue), 출력요청(queue) 할 수 있다. 4 애플리케이션 측에서 그래픽 버퍼 요청이 발생하면 SurfaceTexture는 GraphicBufferAlloc 리모트 서비스에게 그래픽 메모리를 요청하여 할당 받는다. (그래픽 버퍼 할당) 5 서피스 출력 요청이 발생 되면 Surfaceflinger는 각 그래픽 버퍼를 OpenGL ES API를 사용하여 합성한다. 서피스 출력 모드:동기,비동기 -동기:출력 요청이 발생한 버퍼의 인덱스를 mQueue 변수에 차례로 저장하고, 서피스 플링거 서비스의 합성을 요청 함. -비동기:mQueue 변수의 첫번째 인덱스에 저장하고, 서피스 플링거 서비스의 합성을 요청 함. 5
    • 3.SurfaceFlinger 클래스의 인스턴스 생성-ICS 이전 Systemserver.java public class SystemServer { public static void main(String[] args) { System.loadLibrary("android_servers"); init1(args); } native public static void init1(String[] args); } Com_android_server_systemserser.cpp static JNINativeMethod gMethods[] = { /* name, signature, funcPtr */ { "init1", "([Ljava/lang/String;)V", (void*) android_server_SystemServer_init1 }, }; static void android_server_SystemServer_init1(JNIEnv* env, jobject clazz) { system_init(); } System_init.cpp extern "C" status_t system_init() { SurfaceFlinger::instantiate(); SensorService::instantiate(); jclass clazz = env->FindClass("com/android/server/SystemServer"); jmethodID methodId = env->GetStaticMethodID(clazz, "init2", "()V"); env->CallStaticVoidMethod(clazz, methodId); } 6
    • 3.SurfaceFlinger 클래스의 인스턴스 생성-ICS 이후 System_init.cpp extern "C" status_t system_init() { if (strcmp(propBuf, "1") == 0) {  init.rc에 다음과 같이 정의 되어서 system init에서 surfaceflinger를 실행하지 않음 // Start the SurfaceFlinger SurfaceFlinger::instantiate(); # Set this property so surfaceflinger is not started by system_init }} setprop system_init.startsurfaceflinger 0 Init.rc(systemcorerootdir) service servicemanager /system/bin/servicemanager class core user system group system critical onrestart restart zygote onrestart restart media onrestart restart surfaceflinger zygote를 실행하면서 surfaceflinger를 독립 프로세스로 실행 시킴. onrestart restart drm Main_surfaceFlinger.cpp int main(int argc, char** argv) { SurfaceFlinger::publishAndJoinThreadPool(true); return 0; } 7
    • 3.SurfaceFlinger 클래스의 인스턴스 생성 Pthread_create 2 3 Thread Run() _threadLoop() Refbase 4 1회호출 5 반복호출 1 SurfaceFlinger onFirstRef() ReadyToRun() ThreadLoop()RefBase.cppvoid RefBase::incStrong(const void* id) const{const_cast<RefBase*>(this)->onFirstRef();}SurfaceFlinger..cppvoid SurfaceFlinger::onFirstRef(){ mEventQueue.init(this);  서피스 플링거 서비스가 사용할 네이티브 루퍼와 핸들러를 생성한다. run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);1 // Wait for the main thread to be done with its initialization mReadyToRunBarrier.wait();  ReadyToRun 함수에서 mReadyToRunBarrier.open()가 불릴때 까지 기다린다.} 8
    • 3.SurfaceFlinger 클래스의 인스턴스 생성Threads.cppstatus_t Thread::run(const char* name, int32_t priority, size_t stack){res = androidCreateRawThreadEtc (_threadLoop,this, name, priority, stack, &mThread);} 2 int androidCreateRawThreadEtc(){ int result = pthread_create(&thread, &attr, (android_pthread_entry)entryFunction, userData); } 3 int Thread::_threadLoop(void* user) { do { bool result; if (first) { first = false; self->mStatus = self->readyToRun(); 4 } else{ result = self->threadLoop(); 5 } } } 9
    • 3.SurfaceFlinger 클래스의 인스턴스 생성-readyToRun() SurfacefFlinger.cpp status_t SurfaceFlinger::readyToRun() ( 1.메인 디스 플레이 초기화 // initialize the main display GraphicPlane& plane(graphicPlane(dpy)); DisplayHardware* const hw = new DisplayHardware(this, dpy); plane.setDisplayHardware(hw); 2. 디스 플레이 공유 메모리 생성 // create the shared control-block mServerHeap = new MemoryHeapBase(4096, MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap"); mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase()); new(mServerCblk) surface_flinger_cblk_t; 3. initialize the shared control block mServerCblk->connected |= 1<<dpy; display_cblk_t* dcblk = mServerCblk->displays + dpy; memset(dcblk, 0, sizeof(display_cblk_t)); 4.open GL ES 초기화 // Initialize OpenGL|ES glPixelStorei(GL_UNPACK_ALIGNMENT, 4); glPixelStorei(GL_PACK_ALIGNMENT, 4); glEnableClientState(GL_VERTEX_ARRAY); 5.이벤트 쓰레드 생성:이벤트 쓰레드를 생성하여 하드웨어 컴포저에서 발생한 Vsync 이벤트를 전파한다. mEventThread = new EventThread(this); mEventQueue.setEventThread(mEventThread); hw.startSleepManagement(); 6.onfirstref()에서 기다리고 있는 thread에 signal 보냄. mReadyToRunBarrier.open(); 7.부트 애니메이션 시작 startBootAnim(); } 10
    • 3.메인 디스플레이 초기화 1.GraphicPlane& plane(graphicPlane(dpy)); 디스플레이의 정보를 가지는 GraphicPlane 객체를 생성한다. GraphicPlane& plane(graphicPlane(dpy)); //dpy=0; GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) { return const_cast<GraphicPlane&>(const_cast<SurfaceFlinger const *>(this)->graphicPlane(dpy)); } const GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const { const GraphicPlane& plane(mGraphicPlanes[dpy]);  GraphicPlane class의 생성자 호출 return plane; } 11
    • 3.메인 디스플레이 초기화 2. DisplayHardware* const hw = new DisplayHardware(this, dpy); DisplayHardware를 생성 (전원 on/off 이벤트 처리 쓰레드 생성, EGL Native 윈도우 생성, EGL 초기화 수행) 1.전원 버튼 이벤트 처리 쓰레드 생성 :서피스 플링거 서비스는 디스플레이가 켜져 있을 시에만 합성을 수행 함. 디스 플레이의 전원 상태를 감시하고 통지해 주는 displayEventThread를 생성하고 처리 함. DisplayHardwareBase::DisplayHardwareBase(const sp<SurfaceFlinger>& flinger, uint32_t displayIndex) { mScreenAcquired = true; mDisplayEventThread = new DisplayEventThread(flinger); } Thread DisplayHardwarebase DisplayEventThread New DisplayHardware Init() 12
    • 3.메인 디스플레이 초기화2. EGL Native 윈도우 생성:안드로이드는 프레임 버퍼를 추상화한 FramebufferNativeWindow class를 제공 함.DisplayHardware::DisplayHardware(..): DisplayHardwareBase(flinger, dpy),mFlinger(flinger), mFlags(0), mHwc(0){ init(dpy);} void DisplayHardware::init(uint32_t dpy) { 1. 프레임 버퍼 HAL 생성 mNativeWindow = new FramebufferNativeWindow(); }FramebufferNativeWindow::FramebufferNativeWindow(){ if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) { gralloc.xxx.so 를 load해서, gralloc_module_t(module) 구조체를 획득한다. -gralloc_module_t 구조체의 주요 함수 함수명 역활 사용자 registerbuffer 그래픽 버퍼를 gralloc HAL에 등록 GraphicBufferMapper사용자 unregisterbuffer 버퍼 등록 해지 lock 그래픽 버퍼에 할당된 메모리의 가상주소 획득 unlock 가상주소에 렌더링이 완료됨을 알림 13
    • 3.메인 디스플레이 초기화 err = framebuffer_open(module, &fbDev); framebuffer device를 open하고 반환된 framebuffer_device_t 구조체의 포인터를 fbDev에 저장한다. (fbDev는 이제 벤더에서 제공하는 라이브러리 함수를 사용할 수 있다.) Hardware/libhardware/include/hardware/fb.h static inline int framebuffer_open(const struct hw_module_t* module, struct framebuffer_device_t** device) { return module->methods->open(module, GRALLOC_HARDWARE_FB0, (struct hw_device_t**)device); } "fb0" err = gralloc_open(module, &grDev); 그래픽 버퍼 할당 device를 open하고 반환된 alloc_device_t 구조체의 포인터를 grDev에 저장한다. Hardware/libhardware/include/hardware/gralloc.h static inline int gralloc_open(const struct hw_module_t* module, struct alloc_device_t** device) { return module->methods->open(module, GRALLOC_HARDWARE_GPU0, (struct hw_device_t**)device); } “gpu0” 14
    • 3.메인 디스플레이 초기화 프레임 버퍼 생성for (i = 0; i < mNumBuffers; i++) { buffers[i] = new NativeBuffer( fbDev->width, fbDev->height, fbDev->format, GRALLOC_USAGE_HW_FB); }EGL에서 렌더링에 사용할 프런트 버퍼와 백 버퍼를 NativeBuffer 타입의 버퍼로 생성 한다. GRALLOC_USAGE_HW_FB 는 NativeBuffer 타입의 버퍼가 프레임 버퍼에 매핑되어 있다는 것을 의미함.for (i = 0; i < mNumBuffers; i++){ err = grDev->alloc(grDev, fbDev->width, fbDev->height, fbDev->format, GRALLOC_USAGE_HW_FB, &buffers[i]->handle, &buffers[i]->stride);} Nativebuffer 와 mapping된 framebuffer에 메모리를 할당한다. (buffer의 handle이 할당된 메모리를 가리키게 된다(&buffers[i]->handle))const_cast<uint32_t&>(ANativeWindow::flags) = fbDev->flags;const_cast<float&>(ANativeWindow::xdpi) = fbDev->xdpi;const_cast<float&>(ANativeWindow::ydpi) = fbDev->ydpi;프레임 버퍼 정보를 FramebufferANativeWindow 클래스의 부모인 ANativeWindow 구조체에 저당한다. 이후, 디스플레이 공유 메모리에는 ANativeWindow 에 저장된 프레임 버퍼 정보들이 저장된다.ANativeWindow::setSwapInterval = setSwapInterval; int FramebufferNativeWindow::lockBuffer(..){ANativeWindow::dequeueBuffer = dequeueBuffer; framebuffer_device_t* fb = self->fbDev;ANativeWindow::lockBuffer = lockBuffer; fb-> lockBuffer(fb, index);ANativeWindow::queueBuffer = queueBuffer; } …ANativeWindow method와 framebuffer method를 mapping한다. (ANativeWindow Type의 surface에서 lockbuffer를 호출하면, FramebufferNativeWindow 의 lockbuffer가 호출된다.) 15
    • 3.메인 디스플레이 초기화 SurfaceFlinger *EGL ANativeWindow OpenGL ES FramebufferNativeWindow API NativeBuffer Front buffer NativeBuffer back bufferAndroid mappingkernel FrameBuffer Front buffer back buffer 16
    • 3.메인 디스플레이 초기화3. EGL 초기 화 :Open GL ES와 Native system 사이의 interface를 제공 함.void DisplayHardware::init(uint32_t dpy){ … 1)EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); 기본 디스플레이 정보를 획득 한다. 2)eglInitialize(display, NULL, NULL); EGL 내부 적으로 사용하는 구조체를 초기화 한다. 3)eglGetConfigs(display, NULL, 0, &numConfigs); eglGetDisplay에서 전달 받은 display의 사용 가능한 config 개수를 획득한다. 4) eglChooseConfig(dpy, attrs, configs, numConfigs, &n); 사용자가 지정하는 속성에 부합하는 surface를 생성하기 위한 config정보를 설정한다. 5) eglCreateWindowSurface(display, config, mNativeWindow.get(), NULL); 화면에 표시될 네이티브 윈도우를 생성한다. 이때 framebufferNativeWindow의 객체를 넘겨 준다. 6) eglCreateContext(display, config, NULL, contextAttributes); 렌더링에 필요한 상태를 저장할 컨텍스트를 생성한다. 7) eglMakeCurrent(display, surface, surface, context); 현재 렌더링 쓰레드에 사용할 컨텍스트와 display,config 정보 등을 바인드 한다. …} 17
    • 3.메인 디스플레이 초기화 4.HW Compser를 초기화 한다. mHwc = new HWComposer(mFlinger, *this, mRefreshPeriod); if (mHwc->initCheck() == NO_ERROR) { mHwc->setFrameBuffer(mDisplay, mSurface); hwc_module_t HAL_MODULE_INFO_SYM = { EGL Surfae를 hwcomposer의 buffer로 설정 함. common: { } tag: HARDWARE_MODULE_TAG, } version_major: 1, version_minor: 0, id: HWC_HARDWARE_MODULE_ID, name: "Sample hwcomposer module",HWComposer::HWComposer(const sp<SurfaceFlinger>& flinger) author: "The Android Open Source Project", : mFlinger(flinger), methods: &hwc_module_methods, mModule(0), mHwc(0), mList(0), mCapacity(0), } mNumOVLayers(0), mNumFBLayers(0), }; mDpy(EGL_NO_DISPLAY), mSur(EGL_NO_SURFACE){ int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule); if (err == 0) { err = hwc_open(mModule, &mHwc); if (err == 0) { static inline int hwc_open(const struct hw_module_t* module, if (mHwc->registerProcs) { hwc_composer_device_t** device) mCBContext.hwc = this; { mCBContext.procs.invalidate = &hook_invalidate; return module->methods->open(module, mHwc->registerProcs(mHwc, &mCBContext.procs); HWC_HARDWARE_COMPOSER, } (struct hw_device_t**)device); } } }} static struct hw_module_methods_t hwc_module_methods = { open: hwc_device_open }; 18
    • 3.메인 디스플레이 초기화static int hwc_device_open(const struct hw_module_t* module, const char* name,struct hw_device_t** device){ dev->mOverlayLibObject = new overlay::Overlay(); overlay 생성 dev->previousOverlayHandle = NULL; dev->hwcOverlayStatus = HWC_OVERLAY_CLOSED; dev->device.common.tag = HARDWARE_DEVICE_TAG; dev->device.common.version = 0; dev->device.common.module = const_cast<hw_module_t*>(module); dev->device.common.close = hwc_device_close; dev->device.prepare = hwc_prepare; dev->device.set = hwc_set; dev->device.registerProcs = hwc_registerProcs; dev->device.enableHDMIOutput = hwc_enableHDMIOutput; *device = &dev->device.common;} hwc_module_t hwc_device_t hw_module_t hw_device_t module id HWC_HARDWARE_MODULE_ close hwc_device_close ID methods hwc_module_methods 생성 prepare hwc_prepare set hwc_set registerProcs hwc_registerProcs hwc_module_methods mOverlayLibObject new overlay open hwc_device_open 19
    • 4.디스플레이 공유 메모리 생성 및 초기화1. mServerHeap = new MemoryHeapBase(4096, MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap"); 디스플레이의 정보를 공유할 디스플레이 공유 메모리 생성2. mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase()); 생성된 공유 메모리의 시작점을 얻어 옴.3. new(mServerCblk) surface_flinger_cblk_t; 시작점에 surface_flinger_cblk_t를 생성하고, mServerCblk 멤버 변수가 가리킴.4. mServerCblk->connected |= 1<<dpy; connected 변수에 연결된 display의 식별번호를 저장(1개인 경우 0x00000001, 두개인 경우 0x00000011)5. display_cblk_t* dcblk = mServerCblk->displays + dpy; memset(dcblk, 0, sizeof(display_cblk_t)); dcblk->w = plane.getWidth(); dcblk->h = plane.getHeight(); dcblk->format = f; dcblk->orientation = ISurfaceComposer::eOrientationDefault; display_cblk_t 를 생성하고 displayhardware 구조체 value로 초기화 함. 디스플레이 공유 메모리 surface_flinger_cblk_t surfaceflinger connected mServerCblk Dislay_cblk_t dcblk w,h:프레임 버퍼 너비,높이 Density,fps Format,orientation Xdpi,ydpi 20
    • 5.이벤트 쓰레드 생성역할: HWComposer로 부터발생된 Vsync 이벤트를 서피스 플링거 서비스에게 전달해서 ,합성, 출력 할 수 있게 함.status_t SurfaceFlinger::readyToRun(){ … mEventThread = new EventThread(this);}EventThread.cppvoid EventThread::onFirstRef() { mHw.setVSyncHandler(this); DisplayHardware class에 EventThread를 Vsync event 핸들러로 등록 한다. run("EventThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);}Ex)HWComposer에서 Vsync 발생 시 flowHWCompser.cppvoid HWComposer::vsync(int dpy, int64_t timestamp) { ATRACE_INT("VSYNC", ++mVSyncCount&1); mEventHandler.onVSyncReceived(dpy, timestamp);} mEventHandler는 EventThread 로 등록되어 있음.void EventThread::onVSyncReceived(int, nsecs_t timestamp) { Mutex::Autolock _l(mLock); mVSyncTimestamp = timestamp; mCondition.broadcast();} Threadloop의 wait 상태를 깨움(mCondition.broadcast();) 21
    • 5.이벤트 쓰레드 생성bool EventThread::threadLoop(){ void SurfaceFlinger::onMessageReceived(int32_t what) … { vsync.header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC; switch (what) { vsync.header.timestamp = timestamp; case MessageQueue::INVALIDATE: vsync.vsync.count = mDeliveredEvents; case MessageQueue::REFRESH: { conn->postEvent(vsync); 화면 합성 및 출력 … }} DISPLAY_EVENT_VSYNC type의 event 전 } 달MessageQueue.cppint MessageQueue::eventReceiver(int fd, int events) { ssize_t n; DisplayEventReceiver::Event buffer[8]; while ((n = DisplayEventReceiver::getEvents(mEventTube, buffer, 8)) > 0) { for (int i=0 ; i<n ; i++) { if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) { mHandler->signalRefresh(); break; Surfaceflinger의 onMessageReceived 호출 }}void MessageQueue::Handler::signalRefresh(){ if ((android_atomic_or(eventMaskRefresh, &mEventMask) & eventMaskRefresh) == 0) { mQueue.mLooper->sendMessage(this, Message(MessageQueue::REFRESH)); }} 22
    • 참고자료 안드로이드 미디어 프레임워크 –”개발자가 행복한 세상” Goolge Jelly bean Source 23