SlideShare a Scribd company logo
1 of 23
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.cpp
void RefBase::incStrong(const void* id) const{

const_cast<RefBase*>(this)->onFirstRef();
}


SurfaceFlinger..cpp
void 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.cpp
status_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 buffer
Android                                                                       mapping


kernel

                                                   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.cpp
void EventThread::onFirstRef() {
  mHw.setVSyncHandler(this);
  DisplayHardware class에 EventThread를 Vsync event 핸들러로 등록 한다.
  run("EventThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
}

Ex)HWComposer에서 Vsync 발생 시 flow
HWCompser.cpp
void 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.cpp
int 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

More Related Content

What's hot

안드로이드 스터디 Jni 발표 자료 Rev05 송형주
안드로이드 스터디 Jni 발표 자료 Rev05 송형주안드로이드 스터디 Jni 발표 자료 Rev05 송형주
안드로이드 스터디 Jni 발표 자료 Rev05 송형주iamhjoo (송형주)
 
[143] Modern C++ 무조건 써야 해?
[143] Modern C++ 무조건 써야 해?[143] Modern C++ 무조건 써야 해?
[143] Modern C++ 무조건 써야 해?NAVER D2
 
[NDC2015] C++11 고급 기능 - Crow에 사용된 기법 중심으로
[NDC2015] C++11 고급 기능 - Crow에 사용된 기법 중심으로[NDC2015] C++11 고급 기능 - Crow에 사용된 기법 중심으로
[NDC2015] C++11 고급 기능 - Crow에 사용된 기법 중심으로Jaeseung Ha
 
Effective c++(chapter 5,6)
Effective c++(chapter 5,6)Effective c++(chapter 5,6)
Effective c++(chapter 5,6)문익 장
 
20150212 c++11 features used in crow
20150212 c++11 features used in crow20150212 c++11 features used in crow
20150212 c++11 features used in crowJaeseung Ha
 
객체 지향 발담그기 JCO 컨퍼런스 14회
객체 지향 발담그기 JCO 컨퍼런스 14회객체 지향 발담그기 JCO 컨퍼런스 14회
객체 지향 발담그기 JCO 컨퍼런스 14회beom kyun choi
 
GCGC- CGCII 서버 엔진에 적용된 기술 (2) - Perfornance
GCGC- CGCII 서버 엔진에 적용된 기술 (2) - PerfornanceGCGC- CGCII 서버 엔진에 적용된 기술 (2) - Perfornance
GCGC- CGCII 서버 엔진에 적용된 기술 (2) - Perfornance상현 조
 
Android ndk jni 설치및 연동
Android ndk jni 설치및 연동Android ndk jni 설치및 연동
Android ndk jni 설치및 연동Sangon Lee
 
[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍
[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍
[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍흥배 최
 
GCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing System
GCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing SystemGCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing System
GCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing System상현 조
 
Angular2 가기전 Type script소개
 Angular2 가기전 Type script소개 Angular2 가기전 Type script소개
Angular2 가기전 Type script소개Dong Jun Kwon
 
GCGC- CGCII 서버 엔진에 적용된 기술 (1)
GCGC- CGCII 서버 엔진에 적용된 기술 (1)GCGC- CGCII 서버 엔진에 적용된 기술 (1)
GCGC- CGCII 서버 엔진에 적용된 기술 (1)상현 조
 
NDC11_슈퍼클래스
NDC11_슈퍼클래스NDC11_슈퍼클래스
NDC11_슈퍼클래스noerror
 
[KGC 2011]Boost 라이브러리와 C++11
[KGC 2011]Boost 라이브러리와 C++11[KGC 2011]Boost 라이브러리와 C++11
[KGC 2011]Boost 라이브러리와 C++11흥배 최
 
Blockchain 4th dapp programming
Blockchain 4th dapp programmingBlockchain 4th dapp programming
Blockchain 4th dapp programmingihpark92
 
GCGC- CGCII 서버 엔진에 적용된 기술 (5) - Executor with Exception
GCGC- CGCII 서버 엔진에 적용된 기술 (5) - Executor with ExceptionGCGC- CGCII 서버 엔진에 적용된 기술 (5) - Executor with Exception
GCGC- CGCII 서버 엔진에 적용된 기술 (5) - Executor with Exception상현 조
 
GCGC- CGCII 서버 엔진에 적용된 기술 (8) - Group System
GCGC- CGCII 서버 엔진에 적용된 기술 (8) - Group SystemGCGC- CGCII 서버 엔진에 적용된 기술 (8) - Group System
GCGC- CGCII 서버 엔진에 적용된 기술 (8) - Group System상현 조
 

What's hot (20)

안드로이드 스터디 Jni 발표 자료 Rev05 송형주
안드로이드 스터디 Jni 발표 자료 Rev05 송형주안드로이드 스터디 Jni 발표 자료 Rev05 송형주
안드로이드 스터디 Jni 발표 자료 Rev05 송형주
 
[143] Modern C++ 무조건 써야 해?
[143] Modern C++ 무조건 써야 해?[143] Modern C++ 무조건 써야 해?
[143] Modern C++ 무조건 써야 해?
 
[NDC2015] C++11 고급 기능 - Crow에 사용된 기법 중심으로
[NDC2015] C++11 고급 기능 - Crow에 사용된 기법 중심으로[NDC2015] C++11 고급 기능 - Crow에 사용된 기법 중심으로
[NDC2015] C++11 고급 기능 - Crow에 사용된 기법 중심으로
 
Effective c++(chapter 5,6)
Effective c++(chapter 5,6)Effective c++(chapter 5,6)
Effective c++(chapter 5,6)
 
20150212 c++11 features used in crow
20150212 c++11 features used in crow20150212 c++11 features used in crow
20150212 c++11 features used in crow
 
객체 지향 발담그기 JCO 컨퍼런스 14회
객체 지향 발담그기 JCO 컨퍼런스 14회객체 지향 발담그기 JCO 컨퍼런스 14회
객체 지향 발담그기 JCO 컨퍼런스 14회
 
GCGC- CGCII 서버 엔진에 적용된 기술 (2) - Perfornance
GCGC- CGCII 서버 엔진에 적용된 기술 (2) - PerfornanceGCGC- CGCII 서버 엔진에 적용된 기술 (2) - Perfornance
GCGC- CGCII 서버 엔진에 적용된 기술 (2) - Perfornance
 
Android ndk jni 설치및 연동
Android ndk jni 설치및 연동Android ndk jni 설치및 연동
Android ndk jni 설치및 연동
 
[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍
[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍
[KGC 2012]Boost.asio를 이용한 네트웍 프로그래밍
 
GCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing System
GCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing SystemGCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing System
GCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing System
 
Angular2 가기전 Type script소개
 Angular2 가기전 Type script소개 Angular2 가기전 Type script소개
Angular2 가기전 Type script소개
 
GCGC- CGCII 서버 엔진에 적용된 기술 (1)
GCGC- CGCII 서버 엔진에 적용된 기술 (1)GCGC- CGCII 서버 엔진에 적용된 기술 (1)
GCGC- CGCII 서버 엔진에 적용된 기술 (1)
 
Clean code appendix 1
Clean code appendix 1Clean code appendix 1
Clean code appendix 1
 
NDC11_슈퍼클래스
NDC11_슈퍼클래스NDC11_슈퍼클래스
NDC11_슈퍼클래스
 
[KGC 2011]Boost 라이브러리와 C++11
[KGC 2011]Boost 라이브러리와 C++11[KGC 2011]Boost 라이브러리와 C++11
[KGC 2011]Boost 라이브러리와 C++11
 
Redux
ReduxRedux
Redux
 
Blockchain 4th dapp programming
Blockchain 4th dapp programmingBlockchain 4th dapp programming
Blockchain 4th dapp programming
 
GCGC- CGCII 서버 엔진에 적용된 기술 (5) - Executor with Exception
GCGC- CGCII 서버 엔진에 적용된 기술 (5) - Executor with ExceptionGCGC- CGCII 서버 엔진에 적용된 기술 (5) - Executor with Exception
GCGC- CGCII 서버 엔진에 적용된 기술 (5) - Executor with Exception
 
GCGC- CGCII 서버 엔진에 적용된 기술 (8) - Group System
GCGC- CGCII 서버 엔진에 적용된 기술 (8) - Group SystemGCGC- CGCII 서버 엔진에 적용된 기술 (8) - Group System
GCGC- CGCII 서버 엔진에 적용된 기술 (8) - Group System
 
6 function
6 function6 function
6 function
 

Viewers also liked

20分で理解するdisplaysystem
20分で理解するdisplaysystem20分で理解するdisplaysystem
20分で理解するdisplaysystemmagoroku Yamamoto
 
Surface flingerservice(서피스플링거서비스초기화)
Surface flingerservice(서피스플링거서비스초기화)Surface flingerservice(서피스플링거서비스초기화)
Surface flingerservice(서피스플링거서비스초기화)fefe7270
 
Android audio system(audioflinger)
Android audio system(audioflinger)Android audio system(audioflinger)
Android audio system(audioflinger)fefe7270
 
Android audio system(오디오 플링거 서비스 초기화)
Android audio system(오디오 플링거 서비스 초기화)Android audio system(오디오 플링거 서비스 초기화)
Android audio system(오디오 플링거 서비스 초기화)fefe7270
 
Android audio system(audiopolicy_manager)
Android audio system(audiopolicy_manager)Android audio system(audiopolicy_manager)
Android audio system(audiopolicy_manager)fefe7270
 
OpenMAX Overview
OpenMAX OverviewOpenMAX Overview
OpenMAX OverviewYoss Cohen
 
Stagefright recorder part1
Stagefright recorder part1Stagefright recorder part1
Stagefright recorder part1fefe7270
 
Stagefright入門
Stagefright入門Stagefright入門
Stagefright入門l_b__
 
Android audio system(오디오 출력-트랙생성)
Android audio system(오디오 출력-트랙생성)Android audio system(오디오 출력-트랙생성)
Android audio system(오디오 출력-트랙생성)fefe7270
 
A slightly deeper dive into Stagefright
A slightly deeper dive into StagefrightA slightly deeper dive into Stagefright
A slightly deeper dive into StagefrightAlexy Joseph
 
Android media framework overview
Android media framework overviewAndroid media framework overview
Android media framework overviewJerrin George
 
Android Multimedia Framework
Android Multimedia FrameworkAndroid Multimedia Framework
Android Multimedia FrameworkPicker Weng
 

Viewers also liked (15)

20分で理解するdisplaysystem
20分で理解するdisplaysystem20分で理解するdisplaysystem
20分で理解するdisplaysystem
 
Surface flingerservice(서피스플링거서비스초기화)
Surface flingerservice(서피스플링거서비스초기화)Surface flingerservice(서피스플링거서비스초기화)
Surface flingerservice(서피스플링거서비스초기화)
 
Android audio system(audioflinger)
Android audio system(audioflinger)Android audio system(audioflinger)
Android audio system(audioflinger)
 
Android audio system(오디오 플링거 서비스 초기화)
Android audio system(오디오 플링거 서비스 초기화)Android audio system(오디오 플링거 서비스 초기화)
Android audio system(오디오 플링거 서비스 초기화)
 
Android audio system(audiopolicy_manager)
Android audio system(audiopolicy_manager)Android audio system(audiopolicy_manager)
Android audio system(audiopolicy_manager)
 
OpenMAX Overview
OpenMAX OverviewOpenMAX Overview
OpenMAX Overview
 
Understanding open max il
Understanding open max ilUnderstanding open max il
Understanding open max il
 
Stagefright recorder part1
Stagefright recorder part1Stagefright recorder part1
Stagefright recorder part1
 
Stagefright入門
Stagefright入門Stagefright入門
Stagefright入門
 
Android audio system(오디오 출력-트랙생성)
Android audio system(오디오 출력-트랙생성)Android audio system(오디오 출력-트랙생성)
Android audio system(오디오 출력-트랙생성)
 
A slightly deeper dive into Stagefright
A slightly deeper dive into StagefrightA slightly deeper dive into Stagefright
A slightly deeper dive into Stagefright
 
IOMX in Android
IOMX in AndroidIOMX in Android
IOMX in Android
 
Android media framework overview
Android media framework overviewAndroid media framework overview
Android media framework overview
 
Design and Concepts of Android Graphics
Design and Concepts of Android GraphicsDesign and Concepts of Android Graphics
Design and Concepts of Android Graphics
 
Android Multimedia Framework
Android Multimedia FrameworkAndroid Multimedia Framework
Android Multimedia Framework
 

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

Hoons 닷넷 정기세미나
Hoons 닷넷 정기세미나Hoons 닷넷 정기세미나
Hoons 닷넷 정기세미나병걸 윤
 
Half sync/Half Async
Half sync/Half AsyncHalf sync/Half Async
Half sync/Half Asyncscor7910
 
[H3 2012] Bridge over troubled water : make plug-in for Appspresso
[H3 2012] Bridge over troubled water : make plug-in for Appspresso[H3 2012] Bridge over troubled water : make plug-in for Appspresso
[H3 2012] Bridge over troubled water : make plug-in for AppspressoKTH, 케이티하이텔
 
Open source apm scouter를 통한 관제 관리 jadecross 정환열 수석
Open source apm scouter를 통한 관제  관리 jadecross 정환열 수석Open source apm scouter를 통한 관제  관리 jadecross 정환열 수석
Open source apm scouter를 통한 관제 관리 jadecross 정환열 수석uEngine Solutions
 
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019min woog kim
 
Startup JavaScript 8 - NPM, Express.JS
Startup JavaScript 8 - NPM, Express.JSStartup JavaScript 8 - NPM, Express.JS
Startup JavaScript 8 - NPM, Express.JSCirculus
 
Linux Kernel 101 for Beginner
Linux Kernel 101 for BeginnerLinux Kernel 101 for Beginner
Linux Kernel 101 for BeginnerInfraEngineer
 
[오픈소스컨설팅] 스카우터 사용자 가이드 2020
[오픈소스컨설팅] 스카우터 사용자 가이드 2020[오픈소스컨설팅] 스카우터 사용자 가이드 2020
[오픈소스컨설팅] 스카우터 사용자 가이드 2020Ji-Woong Choi
 
7가지 동시성 모델 - 3장. 함수형 프로그래밍
7가지 동시성 모델 - 3장. 함수형 프로그래밍7가지 동시성 모델 - 3장. 함수형 프로그래밍
7가지 동시성 모델 - 3장. 함수형 프로그래밍Hyunsoo Jung
 
안드로이드 오픈소스 패턴 - 0.1
안드로이드 오픈소스 패턴 - 0.1안드로이드 오픈소스 패턴 - 0.1
안드로이드 오픈소스 패턴 - 0.1YoungSu Son
 
2. windows system과 file format
2. windows system과 file format2. windows system과 file format
2. windows system과 file formatYoungjun Chang
 
Concurrent Programming (Java thread 다루기)
Concurrent Programming (Java thread 다루기)Concurrent Programming (Java thread 다루기)
Concurrent Programming (Java thread 다루기)JungGeun Lee
 
리얼리눅스 제 1 회 세미나: "리눅스, 제대로 알고 코딩하자!"
리얼리눅스 제 1 회 세미나: "리눅스, 제대로 알고 코딩하자!"리얼리눅스 제 1 회 세미나: "리눅스, 제대로 알고 코딩하자!"
리얼리눅스 제 1 회 세미나: "리눅스, 제대로 알고 코딩하자!"리얼리눅스
 

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

Hoons 닷넷 정기세미나
Hoons 닷넷 정기세미나Hoons 닷넷 정기세미나
Hoons 닷넷 정기세미나
 
3 Professional MFC
3 Professional MFC3 Professional MFC
3 Professional MFC
 
Half sync/Half Async
Half sync/Half AsyncHalf sync/Half Async
Half sync/Half Async
 
[H3 2012] Bridge over troubled water : make plug-in for Appspresso
[H3 2012] Bridge over troubled water : make plug-in for Appspresso[H3 2012] Bridge over troubled water : make plug-in for Appspresso
[H3 2012] Bridge over troubled water : make plug-in for Appspresso
 
Open source apm scouter를 통한 관제 관리 jadecross 정환열 수석
Open source apm scouter를 통한 관제  관리 jadecross 정환열 수석Open source apm scouter를 통한 관제  관리 jadecross 정환열 수석
Open source apm scouter를 통한 관제 관리 jadecross 정환열 수석
 
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019
김민욱, (달빛조각사) 엘릭서를 이용한 mmorpg 서버 개발, NDC2019
 
04 프로세스
04 프로세스04 프로세스
04 프로세스
 
Startup JavaScript 8 - NPM, Express.JS
Startup JavaScript 8 - NPM, Express.JSStartup JavaScript 8 - NPM, Express.JS
Startup JavaScript 8 - NPM, Express.JS
 
Linux Kernel 101 for Beginner
Linux Kernel 101 for BeginnerLinux Kernel 101 for Beginner
Linux Kernel 101 for Beginner
 
2015 oce specification
2015 oce specification2015 oce specification
2015 oce specification
 
[오픈소스컨설팅] 스카우터 사용자 가이드 2020
[오픈소스컨설팅] 스카우터 사용자 가이드 2020[오픈소스컨설팅] 스카우터 사용자 가이드 2020
[오픈소스컨설팅] 스카우터 사용자 가이드 2020
 
Clojure Chapter.6
Clojure Chapter.6Clojure Chapter.6
Clojure Chapter.6
 
7가지 동시성 모델 - 3장. 함수형 프로그래밍
7가지 동시성 모델 - 3장. 함수형 프로그래밍7가지 동시성 모델 - 3장. 함수형 프로그래밍
7가지 동시성 모델 - 3장. 함수형 프로그래밍
 
안드로이드 오픈소스 패턴 - 0.1
안드로이드 오픈소스 패턴 - 0.1안드로이드 오픈소스 패턴 - 0.1
안드로이드 오픈소스 패턴 - 0.1
 
2. windows system과 file format
2. windows system과 file format2. windows system과 file format
2. windows system과 file format
 
Concurrent Programming (Java thread 다루기)
Concurrent Programming (Java thread 다루기)Concurrent Programming (Java thread 다루기)
Concurrent Programming (Java thread 다루기)
 
Manage book project
Manage book projectManage book project
Manage book project
 
Manage book project
Manage book projectManage book project
Manage book project
 
리얼리눅스 제 1 회 세미나: "리눅스, 제대로 알고 코딩하자!"
리얼리눅스 제 1 회 세미나: "리눅스, 제대로 알고 코딩하자!"리얼리눅스 제 1 회 세미나: "리눅스, 제대로 알고 코딩하자!"
리얼리눅스 제 1 회 세미나: "리눅스, 제대로 알고 코딩하자!"
 
ice_grad
ice_gradice_grad
ice_grad
 

More from fefe7270

Camera camcorder framework overview(ginger bread)
Camera camcorder framework overview(ginger bread)Camera camcorder framework overview(ginger bread)
Camera camcorder framework overview(ginger bread)fefe7270
 
C++정리 스마트포인터
C++정리 스마트포인터C++정리 스마트포인터
C++정리 스마트포인터fefe7270
 
Android audio system(audioplicy_service)
Android audio system(audioplicy_service)Android audio system(audioplicy_service)
Android audio system(audioplicy_service)fefe7270
 
Android audio system(audio_hardwareinterace)
Android audio system(audio_hardwareinterace)Android audio system(audio_hardwareinterace)
Android audio system(audio_hardwareinterace)fefe7270
 
Android audio system(pcm데이터출력준비-서비스서버)
Android audio system(pcm데이터출력준비-서비스서버)Android audio system(pcm데이터출력준비-서비스서버)
Android audio system(pcm데이터출력준비-서비스서버)fefe7270
 
Android audio system(pcm데이터출력요청-서비스클라이언트)
Android audio system(pcm데이터출력요청-서비스클라이언트)Android audio system(pcm데이터출력요청-서비스클라이언트)
Android audio system(pcm데이터출력요청-서비스클라이언트)fefe7270
 
Android audio system(오디오 출력-트랙활성화)
Android audio system(오디오 출력-트랙활성화)Android audio system(오디오 출력-트랙활성화)
Android audio system(오디오 출력-트랙활성화)fefe7270
 

More from fefe7270 (7)

Camera camcorder framework overview(ginger bread)
Camera camcorder framework overview(ginger bread)Camera camcorder framework overview(ginger bread)
Camera camcorder framework overview(ginger bread)
 
C++정리 스마트포인터
C++정리 스마트포인터C++정리 스마트포인터
C++정리 스마트포인터
 
Android audio system(audioplicy_service)
Android audio system(audioplicy_service)Android audio system(audioplicy_service)
Android audio system(audioplicy_service)
 
Android audio system(audio_hardwareinterace)
Android audio system(audio_hardwareinterace)Android audio system(audio_hardwareinterace)
Android audio system(audio_hardwareinterace)
 
Android audio system(pcm데이터출력준비-서비스서버)
Android audio system(pcm데이터출력준비-서비스서버)Android audio system(pcm데이터출력준비-서비스서버)
Android audio system(pcm데이터출력준비-서비스서버)
 
Android audio system(pcm데이터출력요청-서비스클라이언트)
Android audio system(pcm데이터출력요청-서비스클라이언트)Android audio system(pcm데이터출력요청-서비스클라이언트)
Android audio system(pcm데이터출력요청-서비스클라이언트)
 
Android audio system(오디오 출력-트랙활성화)
Android audio system(오디오 출력-트랙활성화)Android audio system(오디오 출력-트랙활성화)
Android audio system(오디오 출력-트랙활성화)
 

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

  • 2. 1.Surfaceflinger 서비스 구조 서비스 클라이언트 서비스 프록시 시스템 서비스 SurfaceComposer ISurfaceComposer SurfaceFlinger Client ISurfaceComposer SurfaceControl Client 리모트 서비스 ComposerService IGraphicAlloc Client Compser ISurface Surface GraphicBufferAlloc ISurfaceTexture SurfaceTextureClient BufferQueue 2
  • 3. 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
  • 4. 1.Surfaceflinger 서비스 구조-시스템/리모트 서비스  시스템 서비스 /리모트 서비스 구성요소 서비스 프록시 설명 SurfaceFlinger ISurfaceComposer 1.서피스 생성,삭제 2.레이어 합성 Client ISurfaceComposerClient 1.생성된 레이어를 Client 별로 관리 BufferQueue ISurfaceTexture 1.그래픽 버퍼 생성 2.레이어 하나 당 하나의 버퍼 큐 리모트 서비스가 생성 됨. GraphicBufferAlloc IGraphicBufferAlloc 1. 그래픽 버퍼 생성 후 메모리 할당 요청이 발생하면 graphic HAL에게 메모리 할당 요청 4
  • 5. 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
  • 6. 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
  • 7. 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
  • 8. 3.SurfaceFlinger 클래스의 인스턴스 생성 Pthread_create 2 3 Thread Run() _threadLoop() Refbase 4 1회호출 5 반복호출 1 SurfaceFlinger onFirstRef() ReadyToRun() ThreadLoop() RefBase.cpp void RefBase::incStrong(const void* id) const{ const_cast<RefBase*>(this)->onFirstRef(); } SurfaceFlinger..cpp void 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
  • 9. 3.SurfaceFlinger 클래스의 인스턴스 생성 Threads.cpp status_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
  • 10. 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
  • 11. 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
  • 12. 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
  • 13. 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
  • 14. 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
  • 15. 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
  • 16. 3.메인 디스플레이 초기화 SurfaceFlinger *EGL ANativeWindow OpenGL ES FramebufferNativeWindow API NativeBuffer Front buffer NativeBuffer back buffer Android mapping kernel FrameBuffer Front buffer back buffer 16
  • 17. 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
  • 18. 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
  • 19. 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
  • 20. 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
  • 21. 5.이벤트 쓰레드 생성 역할: HWComposer로 부터발생된 Vsync 이벤트를 서피스 플링거 서비스에게 전달해서 ,합성, 출력 할 수 있게 함. status_t SurfaceFlinger::readyToRun() { … mEventThread = new EventThread(this); } EventThread.cpp void EventThread::onFirstRef() { mHw.setVSyncHandler(this); DisplayHardware class에 EventThread를 Vsync event 핸들러로 등록 한다. run("EventThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE); } Ex)HWComposer에서 Vsync 발생 시 flow HWCompser.cpp void 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
  • 22. 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.cpp int 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
  • 23. 참고자료  안드로이드 미디어 프레임워크 –”개발자가 행복한 세상”  Goolge Jelly bean Source 23