Your SlideShare is downloading. ×
Surface flingerservice(서피스플링거서비스초기화)
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Introducing the official SlideShare app

Stunning, full-screen experience for iPhone and Android

Text the download link to your phone

Standard text messaging rates apply

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

1,821
views

Published on

Published in: Technology

0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,821
On Slideshare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
0
Comments
0
Likes
2
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. SurfaceFlingerService(서피스플링거서비스초기화) 박철희 1
  • 2. 1.Surfaceflinger 전체 구조 SurfaceFlinger Client NaitveWindow App SurfacecomposerClient layer1 OpenGL ES Graphic buffer API NativeBuffer Front buffer *EGL layer2 NativeBuffer layer3 back bufferAndroid mmap으로 mapping mappingkernel FrameBuffer Graphic buffer 공유 메모리 Front buffer Lcd Pannel …… back buffer *EGL:Embedded Graphic Library 2
  • 3. 2.SurfaceFlinger 클래스의 인스턴스 생성 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); } 3
  • 4. 2.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(){ run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);1 // Wait for the main thread to be done with its initialization mReadyToRunBarrier.wait();  ReadyToRun 함수에서 mReadyToRunBarrier.open()가 불릴때 까지 기다린다.} 4
  • 5. 2.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 } } } 5
  • 6. 2.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.onfirstref()에서 기다리고 있는 thread에 signal 보냄. mReadyToRunBarrier.open(); 6.부트 애니메이션 시작 // start boot animation property_set("ctl.start", "bootanim");  /system/bin/bootanimation 프로세스 실행. } 6
  • 7. 3.메인 디스플레이 초기화 1.GraphicPlane& plane(graphicPlane(dpy)); 디스플레이의 정보를 가지는 graphicplane calss를 생성하고 , 0번째 요소를 메인 디스플레이로 설정한다. 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]); return plane; } 2. DisplayHardware* const hw = new DisplayHardware(this, dpy); DisplayHardware를 생성하고, EGL 네이티브 윈도우를 생성하고 초기화 한다. DisplayHardware::DisplayHardware(..): DisplayHardwareBase(flinger, dpy),mFlinger(flinger), mFlags(0), mHwc(0) { init(dpy); } void DisplayHardware::init(uint32_t dpy) { mNativeWindow = new FramebufferNativeWindow(); Native window 생성 //EGL 초기화 수행 } 7
  • 8. 3.메인 디스플레이 초기화FramebufferNativeWindow::FramebufferNativeWindow(){ if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) { gralloc.msm8960.so 를 load해서 err = framebuffer_open(module, &fbDev); framebuffer device를 open하고 framebuffer에 접근할 수 있는 변수를 fbDev에 저장한다. 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하고 ,device에 접근 할 수 있는 변수를 grDev에 저장한다. tatic 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” for (i = 0; i < mNumBuffers; i++) { buffers[i] = new NativeBuffer( fbDev->width, fbDev->height, fbDev->format, GRALLOC_USAGE_HW_FB); } framebuffer를 가리키는 Nativebuffer 구조체를 생성한다. Nativebuffer의 그래픽 버퍼가 프레임 버퍼에 매핑되어 있다는 의미 8
  • 9. 3.메인 디스플레이 초기화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에 메모리를 할당한다.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; } …NativeWindow method와 framebuffer method를 mapping한다.} 3. plane.setDisplayHardware(hw); 생성한 displayHardware의 정보들을 GraphicPlane class에 설정해 준다.(withd,height,orientation) void GraphicPlane::setDisplayHardware(DisplayHardware *hw) { mHw = hw; const float w = hw->getWidth(); const float h = hw->getHeight(); GraphicPlane::orientationToTransfrom(displayOrientation, w, h,&mDisplayTransform); } 9
  • 10. 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 10
  • 11. 참고. Android HAL 구조 분석(Framebuffer_open 분석)1.Android HAL의 일반적인 구조 xxx_module_t Xxx_device_t hw_module_t hw_device_t Module id Xxx_HARDWARE_MODULE_I D close methods 생성 Xxx_close Xxx_module_methods open Xxx_device_open Struct xxx_module_t HAL_MODULE_INFO_SYM={ Static int xxx_device_open(…){ common:{ tag:HARDWARE_MODULE_TAG, xxx_device_t *dev; version_major:1, dev=(xxx_device_t *)malloc(sizeof(xxx_device_t)); version_minor:0, id:xxx_HARDWARE_MODULD_ID, dev->common.module=<hw_module_t>(module); name:”xxx module” Dev->close=xxx_close author:”xxx” methods :&xxx_module_medthods *device=&dev->device.common; } } } Static struct hw_module_methods_t xxx_module_methods={ open:xxx_device_open }; 11
  • 12. 참고. Android HAL 구조 분석(Framebuffer_open 분석)2.framebuffer_open 분석 if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) { err = framebuffer_open(module, &fbDev); struct private_module_t HAL_MODULE_INFO_SYM = { } base: { common: { tag: HARDWARE_MODULE_TAG, version_major: 1,static inline int framebuffer_open(const struct hw_module_t* version_minor: 0,module, id: GRALLOC_HARDWARE_MODULE_ID, struct framebuffer_device_t** device) { name: "Graphics Memory Allocator Module", return module->methods->open(module, author: "The Android Open Source Project", GRALLOC_HARDWARE_FB0, (struct methods: &gralloc_module_methods,hw_device_t**)device); dso: 0,} reserved: {0}, }, static struct hw_module_methods_t gralloc_module_methods = { open: gralloc_device_open };int gralloc_device_open(const hw_module_t* module, const char* name,hw_device_t** device){ status = fb_device_open(module, name, device);}int fb_device_open(hw_module_t const* module, const char* name,hw_device_t** device){fb_context_t *dev = (fb_context_t*)malloc(sizeof(*dev));dev->device.common.module = const_cast<hw_module_t*>(module); dev->device.setSwapInterval = fb_setSwapInterval;dev->device.common.close = fb_close; dev->device.post = fb_post; 12
  • 13. 참고. Android HAL 구조 분석(Framebuffer_open 분석) private_module_t fb_context_t hw_module_t hw_device_t Module id GRALLOC_HARDWARE_MODULE_ ID close methods 생성 fb_close setSwapInterval fb_setSwapInterval post fb_post gralloc_module_methods open gralloc_device_open dev->device.width; dev->device.height; dev->device.format 13