SlideShare a Scribd company logo
1 of 21
SurfaceFlingerService
(서피스 플링거 연결-ICS)




                             박철희

                         1
화면 출력 요청 전 과정




                    x


                    x   x

                x


                            2
1.서피스 플링거 연결 요청

 1.Surfaceflinger 검색 및 proxy 획득




                  ISurfaceComposer

  Android_view_Surface.cpp
  static void SurfaceSession_init(JNIEnv* env, jobject clazz)
  {
     sp<SurfaceComposerClient> client = new SurfaceComposerClient;
  }


 SurfaceComposerClient.cpp
 SurfaceComposerClient::SurfaceComposerClient(): mStatus(NO_INIT), mComposer(Composer::getInstance())
 {
 }
 SurfaceComposerClient는 Refbase를 상속받았기 때문에, onFirstRef 가 불린다.



  void SurfaceComposerClient::onFirstRef()
  {
    sp<ISurfaceComposer> sm(getComposerService());
     ..
                                                                                                  3
static inline sp<ISurfaceComposer> getComposerService() {
    return ComposerService::getComposerService();
 }


 sp<ISurfaceComposer> ComposerService::getComposerService() {
   return ComposerService::getInstance().mComposerService;
 }
                             ComposerService 는 singleton class를 상속받았음으로,
                             이미 ComposerService 객체가 있으면 그 객체를 return하고,
                             없으면, ComposerService 의 생성자를 호출해서 객체를 생성한다.

  ComposerService::ComposerService()
  : Singleton<ComposerService>() {
     const String16 name("SurfaceFlinger");
     while (getService(name, &mComposerService) != NO_ERROR) {
       usleep(250000);
     }
      SurfaceFlinger service의 proxy(ISurfaceCompser)를 mComposerService 에 저장한다.

  }

2.디스플레이 공유 메모리 서비스의 프록시 획득




                                                                                  4
1.서피스 플링거 연결 요청


  SurfaceComposerClient.cpp
  ComposerService::ComposerService(): Singleton<ComposerService>() {
    const String16 name("SurfaceFlinger");
    while (getService(name, &mComposerService) != NO_ERROR) {
       usleep(250000);
    }
     SurfaceFlinger service의 proxy(ISurfaceCompser)를 mComposerService 에 저장한다.
    mServerCblkMemory = mComposerService->getCblk();
    Surface flinger의 getCblk를 이용하여 디스플레이 공유 메모리의 서비스 프락시(IMemoryHep)을 획득한다.
    mServerCblk = static_cast<surface_flinger_cblk_t volatile *>(mServerCblkMemory->getBase());
    획득한 proxy로 공유메모리의 surface_flinger_cblk_t 구조체의 주소를 획득한다.
  }




                                        surface_flinger_cblk_t                  surfaceflinger
    SurfaceComposerClient

                                              connected                         mServerCblk
       ComposerService
                                     Dislay_cblk_t dcblk

          mServerCblk                  w,h:프레임 버퍼 너비,높이
                                              Density,fps
                                           Format,orientation
                                              Xdpi,ydpi




                                                                                                 5
1.서피스 플링거 연결 요청

3.서피스 플링거 연결 요청 및 서비스 클라이언트 프락시 획득




                 ISurfaceComposerClient

  void SurfaceComposerClient::onFirstRef()
  {
      sp<ISurfaceComposer> sm(getComposerService());
   if (sm != 0) {                                                   ISurfaceComposerClient
        sp<ISurfaceComposerClient> conn = sm->createConnection();
        Surfaceflinger에 있는 createConnection 가 호출 됨.
  }                                                                 BnSurfaceComposerClient
  SurfaceFlinger.cpp
  sp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
  {                                                                             Client
    sp<ISurfaceComposerClient> bclient;
    sp<Client> client(new Client(this));                            ~Client();
    status_t err = client->initCheck();                             createSurface;
    if (err == NO_ERROR) {                                          destroySurface
        bclient = client;                                           DefaultKeyedVector< size_t,
    }                                                               wp<LayerBaseClient> >
    return bclient;Client class의 proxy인 ISurfaceComposerClient가    mLayers;
                     return됨.
  }                                                                                  6
1.서피스 플링거 연결 요청

-서피스 클라이언트 리모트 서비스의 역할

1.서피스 플링거 서비스의 래퍼:
 서피스 플링거 서비스 기능 중 일부를 사용할 수 있도록 제공함
 (서피스 생성,삭제,서피스 상태 변경)

2.애플리케이션별 레이어 관리:
 서피스 클라이언트 별로 서피스에 대한 지역 식별자를 할당하고, DefaultKeyedVector에
 지역식별자와 layer를 함께 추가함.

3. 레이어 상태 변경:애플리케이션이 서피스의 상태 변경(가로,세로 전환)을 서피스 클라이언트 리모트
           서비스에게 요청한다.

4.애플리케이션 레이어의 생명 주기 관리:
 서피스 생성을 요청한 애플리케이션이 비정상적으로 동작을 종료하더라도 관리하고 있는 서피스와
 관련 자원을 서피스 클라이언트의 소멸자에서 자동으로 해제해 준다.
 (why? Client class는 Refbase class를 상속 받는데 이 Refbase class는 참조하는 곳이 없어질때
      자동으로 소멸자를 불러주게 된다.)




                                                                    7
2.서피스 생성 요청 (서비스 클라이언트)
Surface.java
public Surface()
{
  init(s,pid,name,display,w,h,format,flags);
}

Android_view_surface.cpp
                                                                          struct surface_data_t {
static void Surface_init
                                                                                int32_t        token;
{
                                                                                int32_t        identity;
  surface = client->createSurface(pid, name, dpy, w, h, format, flags);
                                                                                status_t readFromParcel(const Parcel& parcel);
}
                                                                                status_t writeToParcel(Parcel* parcel) const;
sp<SurfaceControl> SurfaceComposerClient::createSurface(…)                   };
{
  ISurfaceComposerClient::surface_data_t data;
  p<ISurface> surface = mClient->createSurface(&data, pid, name,display, w, h, format, flags);
  서피스 클라이언트의 createSurface를 호출하여 SurfaceTextureLayer 핸들을 생성한다.
    이때 data 구조체에 생성된 서피스에 대한 정보를 채워준다.
    SurfaceTextureLayer 핸들에 접근할 수 있는 BSurface Class의 proxy가 surface 변수에 저장된다.
    if (surface != 0) {
        result = new SurfaceControl(this, surface, data, w, h, format, flags);
        return된 Isurface proxy를 이용해서 SurfaceControl class를 생성한다.
          이 class는 SurfaceTextureLayer proxy를 획득하거나, 서피스의 상태 변경을 할 수 있게 해 준다.
    }
  setSurfaceControl(env, clazz, surface);
}

static void setSurfaceControl(JNIEnv* env, jobject clazz, const sp<SurfaceControl>& surface)
{
   env->SetIntField(clazz, so.surfaceControl, (int)surface.get()); SurfaceControl를 so.surfaceControl 에 저장한다.
}

                                                                                                             8
2.서피스 생성 요청 (서비스 클라이언트)
sp<ISurface> Client::createSurface(ISurfaceComposerClient::surface_data_t* params, const String8& name,
    DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
    uint32_t flags)
{

    class MessageCreateSurface : public MessageBase {

    public:
       MessageCreateSurface(SurfaceFlinger* flinger,
              ISurfaceComposerClient::surface_data_t* params,
              const String8& name, Client* client,
              DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
              uint32_t flags)
          : flinger(flinger), params(params), client(client), name(name),
            display(display), w(w), h(h), format(format), flags(flags)
       {
       }
       sp<ISurface> getResult() const { return result; }
       virtual bool handler() {
          result = flinger->createSurface(params, name, client,
                 display, w, h, format, flags);
          return true;
       }
    };

    sp<MessageBase> msg = new MessageCreateSurface(mFlinger.get(),params, name, this, display, w, h, format, flags);

    mFlinger->postMessageSync(msg);  MessageCreateSurface의 handler가 호출 됨.
    return static_cast<MessageCreateSurface*>( msg.get() )->getResult();
     Bsurface Class의 proxy를 return 함.
}

                                                                                                          9
3.서피스 생성 요청 (서비스 서버)
sp<ISurface> SurfaceFlinger::createSurface(…)
{
  sp<LayerBaseClient> layer;
   sp<Layer> normalLayer;
   switch (flags & eFXSurfaceMask) {
      case eFXSurfaceNormal:
         normalLayer = createNormalSurface(client, d, w, h, flags, format); 1.Layer class 생성.
        layer = normalLayer;
        break;
    }

    if (layer != 0) {
       layer->initStates(w, h, flags); 2.생성된 layer 상태 초기화
       ssize_t token = addClientLayer(client, layer);  3.전역 레이어 목록과 지역 레이어 목록에 추가
       surfaceHandle = layer->getSurface();  4. Bsurface의 proxy(Isurface)를 가져옴.
       if (surfaceHandle != 0) {  mClient->createSurface 호출시 넘겨준 surface_data_t 구조체에 값을 채움.
           params->token = token;  서피스 지역 식별자
           params->identity = surfaceHandle->getIdentity();  서피스 전역 식별자
     }
       setTransactionFlags(eTransactionNeeded); 서피스 플링거가 합성 시 참조하는 상태 플래그에 설정.

    return surfaceHandle;  . Bsurface의 proxy(Isurface)를 return함.
}




                                                                                                10
3.서피스 생성 요청 (서비스 서버)

  1. Layer class 생성
  normalLayer = createNormalSurface(client, d, w, h, flags, format);


sp<Layer> SurfaceFlinger::createNormalSurface(..)                                                LayerBase
{
  sp<Layer> layer = new Layer(this, display, client);
  Layer class 생성 시 LayerBase의 생성자 부터 호출된다.                                                  LayerBaseClient
   return layer;
}

                                                                                                   Layer          Layer
                                                                                     Layer
                                                                                                 Screenshot        Dim
Layerbase.cpp
LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display)
  : dpy(display), contentDirty(false),
    sequence(uint32_t(android_atomic_inc(&sSequence))),                                       SurfaceFlinger
     sSequence 값을 sequence에 저장하고 sSequence를 1증가 시킨다.                                                    지역 레이어 목록
     sequence 변수는 동일 Z-order 값을 가지는 레이어를 정렬할때 사용 함.
                                                                               전역 레이어 목록                     Client 1
{
  …                                                                            zorder                         Token=1
                                                                                        mIdentity
}                                                                                                             Token=2
                                                                                 4           4
LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,     3           1
                                                                                                         지역 레이어 목록
     const sp<Client>& client)                                                   2           2
  : LayerBase(flinger, display), mClientRef(client),                             1           3               Client 2
    mIdentity(uint32_t(android_atomic_inc(&sIdentity)))
    서피스 전역 식별자인 mIdentity의 값을 설정한다.                                                                           Token=1
{                                                                                                              Token=2
}



                                                                                                             11
3.서피스 생성 요청 (서비스 서버)
Layer::Layer(SurfaceFlinger* flinger,
    DisplayID display, const sp<Client>& client)
  : LayerBaseClient(flinger, display, client),
{
  …
}
Layer생성자에서는 특별한 동작을 수행하지 않음. RefBase class를 상속했음으로, onFirstRef()가 불림.


 void Layer::onFirstRef()
 {
   struct FrameQueuedListener : public SurfaceTexture::FrameAvailableListener {
      FrameQueuedListener(Layer* layer) : mLayer(layer) { }
   private:
      wp<Layer> mLayer;
      virtual void onFrameAvailable() {
         sp<Layer> that(mLayer.promote());
         if (that != 0) {                                        void Layer::onFrameQueued() {
             that->onFrameQueued();                                 android_atomic_inc(&mQueuedFrames);
         }                                                          mFlinger->signalEvent();
      }                                                          }
   };
   mSurfaceTexture = new SurfaceTextureLayer(mTextureName, this);
   mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this));
   SurfaceTextureLayer의 listener를 FrameAvailableListener 로 등록 한다.
   onFrameAvailable 메소드는 surfacetexture.cpp의 queuebuffer에서 불린다.
   mSurfaceTexture->setSynchronousMode(true);
   mSurfaceTexture->setBufferCountServer(BUFFER_COUNT_SERVER);
 }
                                      SurfaceTextureLayer는 Surfacetexture를 상속 받으므로 SurfaceTextureLayer
                                      생성자 호출 시 SurfaceTexture의 생성자가 먼저 불린다.

                                                                                                     12
3.서피스 생성 요청 (서비스 서버)
SurfaceTexture::SurfaceTexture(…)
{
  sp<ISurfaceComposer> composer(ComposerService::getComposerService());
   mGraphicBufferAlloc = composer->createGraphicBufferAlloc();
   Surfaceflinger의 createGraphicBufferAlloc을 호출한다.
}

Surfaceflinger.cpp
sp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
{
  sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
  return gba;
}

GraphicBufferAlloc::GraphicBufferAlloc() {
  mFreedIndex = -1;
  mSize = 0;
}

mGraphicBufferAlloc는 SurfaceTexture::dequeueBuffer에서 사용된다.
status_t SurfaceTexture::dequeueBuffer(…)
{
       usage |= GraphicBuffer::USAGE_HW_TEXTURE;
       status_t error;
       sp<GraphicBuffer> graphicBuffer(mGraphicBufferAlloc->createGraphicBuffer( w, h, format, usage, &error));
        mSlots[buf].mGraphicBuffer = graphicBuffer;
         graphicBuffer 에 메모리를 할당 하고 graphicBuffer 를 가리키는 mSlots[buf] 를 return한다.
}

sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(…)
{
  sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
  return graphicBuffer;
}

                                                                                                                  13
3.서피스 생성 요청 (서비스 서버)
GraphicBuffer::GraphicBuffer(…)
{
  mInitCheck = initSize(w, h, reqFormat, reqUsage);
}

status_t GraphicBuffer::initSize(uint32_t w, uint32_t h, PixelFormat format,
      uint32_t reqUsage)
{
   GraphicBufferAllocator& allocator = GraphicBufferAllocator::get();
   status_t err = allocator.alloc(w, h, format, reqUsage, &handle, &stride);
    할당된 메모리의 handle을 &handle에 저장한다.
   return err;
}                                                  virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) = 0;
                                                     virtual status_t setBufferCount(int bufferCount) = 0;
                  IsurfaceTexture                    virtual status_t dequeueBuffer, virtual status_t queueBuffer, virtual void cancelBuffer(int slot) = 0;
                                                     virtual status_t setCrop(const Rect& reg) = 0;
                                                     virtual status_t setTransform(uint32_t transform) = 0;
                                                     virtual status_t setScalingMode(int mode) = 0;
                                                     virtual int query(int what, int* value) = 0;
                 BnSurfaceTexture                    virtual status_t setSynchronousMode(bool enabled) = 0;
                                                     virtual status_t connect, virtual status_t disconnect




                  SurfaceTexture


                                                       virtual status_t setBufferCount(int bufferCount);
                  SurfaceTextureLayer                  virtual status_t queueBuffer, dequeueBuffer,connet


                                                      virtual void onDraw(const Region& clip) const;
                       Layer
                                                      virtual uint32_t doTransaction(uint32_t transactionFlags);
                                                       virtual void lockPageFlip(bool& recomputeVisibleRegions);
                                                      virtual void unlockPageFlip()

                                                                                                                                          14
3.서피스 생성 요청 (서비스 서버)
SurfaceTexture class에 접근하기 위해서 SurfacetexturelClient를 생성한다.

static void Surface_readFromParcel( JNIEnv* env, jobject clazz, jobject argParcel)
{
   sp<Surface> sur(Surface::readFromParcel(*parcel));
   setSurface(env, clazz, sur);
}

static void setSurface(JNIEnv* env, jobject clazz, const sp<Surface>& surface)
{
   env->SetIntField(clazz, so.surface, (int)surface.get());
   Surface::readFromParcel 에 의해 생성된 Surface(SurfacetexturelClient를 상속받음)를 so.surface에 저장한다.
}


sp<Surface> Surface::readFromParcel(const Parcel& data)
{
  surface = new Surface(data, binder);
}
                                                                                     SurfaceTextureClient::SurfaceTextureClient() {
                                                                                        SurfaceTextureClient::init();
Surface::Surface(const Parcel& parcel, const sp<IBinder>& ref)                       }
  : SurfaceTextureClient()  SurfaceTextureClient의 생성자가 먼저 불린다.
{                                                                                    void SurfaceTextureClient::init() {
                                                                                     ANativeWindow::dequeueBuffer =
    st = interface_cast<ISurfaceTexture>(st_binder);
    surfacetexturelayer의 ISurfaceTexture를 가져온다.                                     hook_dequeueBuffer;
     init(st);                                                                         ANativeWindow::cancelBuffer =
}                                                                                    hook_cancelBuffer;
                                                                                       ANativeWindow::lockBuffer         =
                                                                                     hook_lockBuffer;
                                                                                       ANativeWindow::queueBuffer          =
                                                                                     hook_queueBuffer;
                                                                                     }
                                                                                                                   15
3.서피스 생성 요청 (서비스 서버)
void Surface::init(const sp<ISurfaceTexture>& surfaceTexture)
{

    if (mSurface != NULL || surfaceTexture != NULL) {
      if (surfaceTexture != NULL)
       {
           setISurfaceTexture(surfaceTexture);
        }
}


void SurfaceTextureClient::setISurfaceTexture(
     const sp<ISurfaceTexture>& surfaceTexture)
{
  mSurfaceTexture = surfaceTexture;
}


이렇게 생성된 SurfaceControl, Surface class는 getSurfaceControl()와 getSurface()에 의해서 불려 진다.


android_view_Surface.cpp
static sp<SurfaceControl> getSurfaceControl(JNIEnv* env, jobject clazz)
{
    SurfaceControl* const p = (SurfaceControl*)env->GetIntField(clazz, so.surfaceControl);
   return sp<SurfaceControl>(p);
}

static sp<Surface> getSurface(JNIEnv* env, jobject clazz)
{
   sp<Surface> result(Surface_getSurface(env, clazz));  sp<Surface> surface((Surface*)env->GetIntField(clazz, so.surface));
   return result;
}


                                                                                                                    16
3.서피스 생성 요청 (서비스 서버)




       Client                             SurfaceFlinger
                                                 Client

     surfacecomposerclient
                                                    surfacetexture
         surfacecontrol        BSurface
                                                  SurfaceTextureLaye
                                                  r
                                                        layer
             surface
        surfacetextureclient




                                                              17
3.서피스 생성 전체 그림


                             Android_view_surface.cpp


                                                  SurfaceFlingerClient                SurfaceFlinger

                                                                                             Client

SurfaceView   Surface.java
                                                        surfacecomposerclient
                              Get                                                               surfacetexture
         H                    SurfaceControl
                              {                             surfacecontrol      BSurface
         O
                               Surfacecontrol                                                 SurfaceTextureLayer
         L
         D                    }
         E                                                                                            layer
         R                                                     surface
                               getSurface
                               {                        surfacetextureclient
                               Surface
                               }




                                                                                                18
3.푸시 버퍼 서피스 생성 요청 (서비스 서버)

2.생성된 layer 상태 초기화
layer->initStates(w, h, flags);
Layerbase class의 initStates 가 호출됨.


void LayerBase::initStates(uint32_t w, uint32_t h, uint32_t flags)
{

     mCurrentState.z       = 0; mCurrentState.w      = w; mCurrentState.h = h;
     mCurrentState.requested_w = w; mCurrentState.requested_h = h;
     mCurrentState.sequence    = 0;
     sequence 값은 드로잉 프레임에서의 레이어와 현재 프레임의 레이어 상태가 변경될 때 1씩 증가
     mDrawingState = mCurrentState;
      mDrawingState (화면에 출력중인 레이어의 상태 저장)과
       mCurrentState(화면 출력을 위해 합성중인 레이어의 상태 저장)를 동일하게 설정
}
    3.전역 레이어 목록과 지역 레이어 목록에 추가
    ssize_t token = addClientLayer(client, layer);


                               SurfaceFlinger                        1.전역 레이어 목록
                                                                     -서피스 플링거 서비스에서 생성된 전체 레이어 목록
                                                지역 레이어 목록            -정렬 순서:zorder 순서
         전역 레이어 목록                                                   - mCurrentState.layersSortedByZ 변수로 관리
                                                Client 1
          layersSortedByZ                                            2.지역 레이어 목록
                                                 mLayers
          zorder   mIdentity                                         -특정 Client에서 생성된 레이어 목록
                                                 Token=1
            4          4                                             -지역 레이어 목록의 레이어는 전역 레이어 목록에
            3          1
                                                 Token=2              추가됨.
                                                                     -Client class의 mLayers 변수로 관리

                                                                                                19
3.푸시 버퍼 서피스 생성 요청 (서비스 서버)

ssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
     const sp<LayerBaseClient>& lbc)
{
  // 지역 레이어 목록에 추가
  size_t name = client->attachLayer(lbc);

    // 전역 레이어 목록에 추가
    addLayer_l(lbc);

    return ssize_t(name);
}


size_t Client::attachLayer(const sp<LayerBaseClient>& layer)
{
   size_t name = mNameGenerator++;
   mLayers.add(name, layer);
   return name;
}


status_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer)
{
   ssize_t i = mCurrentState.layersSortedByZ.add(layer);
   return (i < 0) ? status_t(i) : status_t(NO_ERROR);
}




                                                                   20
3.푸시 버퍼 서피스 생성 요청 (서비스 서버)

 4. SurfaceTexturelayer 핸들을 가져옴
 surfaceHandle = layer->getSurface();


Layerbase.cpp의 getSurface가 호출 됨.
sp<LayerBaseClient::Surface> LayerBaseClient::getSurface()
{
  sp<Surface> s;
  Mutex::Autolock _l(mLock);
  s = mClientSurface.promote();
  if (s == 0) {
      s = createSurface();
      mClientSurface = s;
  }
  return s;
}                    Layer.cpp의 오버라이딩 된 createSurface를 부른다.

                                                    class BSurface : public BnSurface, public LayerCleaner {
Layer.cpp                                                wp<const Layer> mOwner;
sp<ISurface> Layer::createSurface()                      virtual sp<ISurfaceTexture> getSurfaceTexture() const {
{                                                           sp<ISurfaceTexture> res;
  sp<ISurface> sur(new BSurface(mFlinger, this));           sp<const Layer> that( mOwner.promote() );
   return sur;                                              if (that != NULL) {
  SurfaceTextureLayer에 접근 할 수 있는                               res = that->mSurfaceTexture;
                                                            }
    Bsurface class를 생성하고 proxy인 Isurface를
                                                            return res;
    return한다.
                                                         }
}                                                     public:
                                                         BSurface(const sp<SurfaceFlinger>& flinger,
                                                                const sp<Layer>& layer)
                                                            : LayerCleaner(flinger, layer), mOwner(layer) { }
                                                      };

More Related Content

What's hot

Startup JavaScript 6 - 함수, 스코프, 클로저
Startup JavaScript 6 - 함수, 스코프, 클로저Startup JavaScript 6 - 함수, 스코프, 클로저
Startup JavaScript 6 - 함수, 스코프, 클로저Circulus
 
객체 지향 발담그기 JCO 컨퍼런스 14회
객체 지향 발담그기 JCO 컨퍼런스 14회객체 지향 발담그기 JCO 컨퍼런스 14회
객체 지향 발담그기 JCO 컨퍼런스 14회beom kyun choi
 
Blockchain 4th dapp programming
Blockchain 4th dapp programmingBlockchain 4th dapp programming
Blockchain 4th dapp programmingihpark92
 
세션5. web3.js와 Node.js 를 사용한 dApp 개발
세션5. web3.js와 Node.js 를 사용한 dApp 개발세션5. web3.js와 Node.js 를 사용한 dApp 개발
세션5. web3.js와 Node.js 를 사용한 dApp 개발Jay JH Park
 
Startup JavaScript 4 - 객체
Startup JavaScript 4 - 객체Startup JavaScript 4 - 객체
Startup JavaScript 4 - 객체Circulus
 
[스프링 스터디 2일차] 서비스 추상화
[스프링 스터디 2일차] 서비스 추상화[스프링 스터디 2일차] 서비스 추상화
[스프링 스터디 2일차] 서비스 추상화AnselmKim
 
Blockchain 3rd smart contract programming
Blockchain 3rd smart contract programmingBlockchain 3rd smart contract programming
Blockchain 3rd smart contract programmingihpark92
 
Es2015 Simple Overview
Es2015 Simple OverviewEs2015 Simple Overview
Es2015 Simple OverviewKim Hunmin
 
GCGC- CGCII 서버 엔진에 적용된 기술 (2) - Perfornance
GCGC- CGCII 서버 엔진에 적용된 기술 (2) - PerfornanceGCGC- CGCII 서버 엔진에 적용된 기술 (2) - Perfornance
GCGC- CGCII 서버 엔진에 적용된 기술 (2) - Perfornance상현 조
 
GCGC- CGCII 서버 엔진에 적용된 기술 (1)
GCGC- CGCII 서버 엔진에 적용된 기술 (1)GCGC- CGCII 서버 엔진에 적용된 기술 (1)
GCGC- CGCII 서버 엔진에 적용된 기술 (1)상현 조
 
세션3. geth 클라이언트 실습 및 모니터링과 시각화
세션3. geth 클라이언트 실습 및 모니터링과 시각화세션3. geth 클라이언트 실습 및 모니터링과 시각화
세션3. geth 클라이언트 실습 및 모니터링과 시각화Jay JH Park
 
세션1. block chain as a platform
세션1. block chain as a platform세션1. block chain as a platform
세션1. block chain as a platformJay JH Park
 
세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍
세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍
세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍Jay JH Park
 
NDC11_슈퍼클래스
NDC11_슈퍼클래스NDC11_슈퍼클래스
NDC11_슈퍼클래스noerror
 
GCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing System
GCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing SystemGCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing System
GCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing System상현 조
 
React로 TDD 쵸큼 맛보기
React로 TDD 쵸큼 맛보기React로 TDD 쵸큼 맛보기
React로 TDD 쵸큼 맛보기Kim Hunmin
 
이더리움의 현황, 한계점 및 개선노력
이더리움의 현황, 한계점 및 개선노력 이더리움의 현황, 한계점 및 개선노력
이더리움의 현황, 한계점 및 개선노력 Younghoon Moon
 
Blockchain 1st bitcoin_core
Blockchain 1st bitcoin_coreBlockchain 1st bitcoin_core
Blockchain 1st bitcoin_coreihpark92
 
GCGC- CGCII 서버 엔진에 적용된 기술 (5) - Executor with Exception
GCGC- CGCII 서버 엔진에 적용된 기술 (5) - Executor with ExceptionGCGC- CGCII 서버 엔진에 적용된 기술 (5) - Executor with Exception
GCGC- CGCII 서버 엔진에 적용된 기술 (5) - Executor with Exception상현 조
 

What's hot (20)

Startup JavaScript 6 - 함수, 스코프, 클로저
Startup JavaScript 6 - 함수, 스코프, 클로저Startup JavaScript 6 - 함수, 스코프, 클로저
Startup JavaScript 6 - 함수, 스코프, 클로저
 
객체 지향 발담그기 JCO 컨퍼런스 14회
객체 지향 발담그기 JCO 컨퍼런스 14회객체 지향 발담그기 JCO 컨퍼런스 14회
객체 지향 발담그기 JCO 컨퍼런스 14회
 
Blockchain 4th dapp programming
Blockchain 4th dapp programmingBlockchain 4th dapp programming
Blockchain 4th dapp programming
 
세션5. web3.js와 Node.js 를 사용한 dApp 개발
세션5. web3.js와 Node.js 를 사용한 dApp 개발세션5. web3.js와 Node.js 를 사용한 dApp 개발
세션5. web3.js와 Node.js 를 사용한 dApp 개발
 
Startup JavaScript 4 - 객체
Startup JavaScript 4 - 객체Startup JavaScript 4 - 객체
Startup JavaScript 4 - 객체
 
[스프링 스터디 2일차] 서비스 추상화
[스프링 스터디 2일차] 서비스 추상화[스프링 스터디 2일차] 서비스 추상화
[스프링 스터디 2일차] 서비스 추상화
 
Blockchain 3rd smart contract programming
Blockchain 3rd smart contract programmingBlockchain 3rd smart contract programming
Blockchain 3rd smart contract programming
 
Es2015 Simple Overview
Es2015 Simple OverviewEs2015 Simple Overview
Es2015 Simple Overview
 
GCGC- CGCII 서버 엔진에 적용된 기술 (2) - Perfornance
GCGC- CGCII 서버 엔진에 적용된 기술 (2) - PerfornanceGCGC- CGCII 서버 엔진에 적용된 기술 (2) - Perfornance
GCGC- CGCII 서버 엔진에 적용된 기술 (2) - Perfornance
 
GCGC- CGCII 서버 엔진에 적용된 기술 (1)
GCGC- CGCII 서버 엔진에 적용된 기술 (1)GCGC- CGCII 서버 엔진에 적용된 기술 (1)
GCGC- CGCII 서버 엔진에 적용된 기술 (1)
 
세션3. geth 클라이언트 실습 및 모니터링과 시각화
세션3. geth 클라이언트 실습 및 모니터링과 시각화세션3. geth 클라이언트 실습 및 모니터링과 시각화
세션3. geth 클라이언트 실습 및 모니터링과 시각화
 
세션1. block chain as a platform
세션1. block chain as a platform세션1. block chain as a platform
세션1. block chain as a platform
 
세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍
세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍
세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍
 
NDC11_슈퍼클래스
NDC11_슈퍼클래스NDC11_슈퍼클래스
NDC11_슈퍼클래스
 
Clean code appendix 1
Clean code appendix 1Clean code appendix 1
Clean code appendix 1
 
GCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing System
GCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing SystemGCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing System
GCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing System
 
React로 TDD 쵸큼 맛보기
React로 TDD 쵸큼 맛보기React로 TDD 쵸큼 맛보기
React로 TDD 쵸큼 맛보기
 
이더리움의 현황, 한계점 및 개선노력
이더리움의 현황, 한계점 및 개선노력 이더리움의 현황, 한계점 및 개선노력
이더리움의 현황, 한계점 및 개선노력
 
Blockchain 1st bitcoin_core
Blockchain 1st bitcoin_coreBlockchain 1st bitcoin_core
Blockchain 1st bitcoin_core
 
GCGC- CGCII 서버 엔진에 적용된 기술 (5) - Executor with Exception
GCGC- CGCII 서버 엔진에 적용된 기술 (5) - Executor with ExceptionGCGC- CGCII 서버 엔진에 적용된 기술 (5) - Executor with Exception
GCGC- CGCII 서버 엔진에 적용된 기술 (5) - Executor with Exception
 

Similar to Surface flingerservice(서피스 플링거 연결 ics)

Effective c++(chapter 5,6)
Effective c++(chapter 5,6)Effective c++(chapter 5,6)
Effective c++(chapter 5,6)문익 장
 
[Swift] Command
[Swift] Command[Swift] Command
[Swift] CommandBill Kim
 
모델링 연습 리뷰
모델링 연습 리뷰모델링 연습 리뷰
모델링 연습 리뷰beom kyun choi
 
Node.js and react
Node.js and reactNode.js and react
Node.js and reactHyungKuIm
 
Android 기초강좌 애플리캐이션 구조
Android 기초강좌 애플리캐이션 구조Android 기초강좌 애플리캐이션 구조
Android 기초강좌 애플리캐이션 구조Sangon Lee
 
Create-React-App으로 SSR을 구현하며 배운 점 (feat. TypeScript)
Create-React-App으로 SSR을 구현하며 배운 점 (feat. TypeScript)Create-React-App으로 SSR을 구현하며 배운 점 (feat. TypeScript)
Create-React-App으로 SSR을 구현하며 배운 점 (feat. TypeScript)LanarkSeung
 
TR 069 클라이언트 검토자료 3편
TR 069 클라이언트 검토자료 3편TR 069 클라이언트 검토자료 3편
TR 069 클라이언트 검토자료 3편ymtech
 
GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출
GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출
GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출GDG Korea
 
Startup JavaScript 8 - NPM, Express.JS
Startup JavaScript 8 - NPM, Express.JSStartup JavaScript 8 - NPM, Express.JS
Startup JavaScript 8 - NPM, Express.JSCirculus
 
12장 상속 (고급)
12장 상속 (고급)12장 상속 (고급)
12장 상속 (고급)유석 남
 
Hoons 닷넷 정기세미나
Hoons 닷넷 정기세미나Hoons 닷넷 정기세미나
Hoons 닷넷 정기세미나병걸 윤
 
안드로이드 오픈소스 그리고 패턴
안드로이드 오픈소스 그리고 패턴  안드로이드 오픈소스 그리고 패턴
안드로이드 오픈소스 그리고 패턴 YoungSu Son
 
Airflow를 이용한 데이터 Workflow 관리
Airflow를 이용한  데이터 Workflow 관리Airflow를 이용한  데이터 Workflow 관리
Airflow를 이용한 데이터 Workflow 관리YoungHeon (Roy) Kim
 
Reflow and repaint 성능 비용
Reflow and repaint 성능 비용Reflow and repaint 성능 비용
Reflow and repaint 성능 비용Doo Sung Eom
 
안드로이드 오픈소스 패턴 - 0.1
안드로이드 오픈소스 패턴 - 0.1안드로이드 오픈소스 패턴 - 0.1
안드로이드 오픈소스 패턴 - 0.1YoungSu Son
 
Kubernetes & helm 활용
Kubernetes & helm 활용Kubernetes & helm 활용
Kubernetes & helm 활용SK Telecom
 
Terraform을 이용한 Infrastructure as Code 실전 구성하기 :: 변정훈::AWS Summit Seoul 2018
 Terraform을 이용한 Infrastructure as Code 실전 구성하기 :: 변정훈::AWS Summit Seoul 2018 Terraform을 이용한 Infrastructure as Code 실전 구성하기 :: 변정훈::AWS Summit Seoul 2018
Terraform을 이용한 Infrastructure as Code 실전 구성하기 :: 변정훈::AWS Summit Seoul 2018Amazon Web Services Korea
 
Terraform을 이용한 Infrastructure as Code 실전 구성하기
Terraform을 이용한 Infrastructure as Code 실전 구성하기Terraform을 이용한 Infrastructure as Code 실전 구성하기
Terraform을 이용한 Infrastructure as Code 실전 구성하기JeongHun Byeon
 
웹 사이트 시각화 및 성능 관리
웹 사이트 시각화 및 성능 관리웹 사이트 시각화 및 성능 관리
웹 사이트 시각화 및 성능 관리mosaicnet
 
Ai C#세미나
Ai C#세미나Ai C#세미나
Ai C#세미나Astin Choi
 

Similar to Surface flingerservice(서피스 플링거 연결 ics) (20)

Effective c++(chapter 5,6)
Effective c++(chapter 5,6)Effective c++(chapter 5,6)
Effective c++(chapter 5,6)
 
[Swift] Command
[Swift] Command[Swift] Command
[Swift] Command
 
모델링 연습 리뷰
모델링 연습 리뷰모델링 연습 리뷰
모델링 연습 리뷰
 
Node.js and react
Node.js and reactNode.js and react
Node.js and react
 
Android 기초강좌 애플리캐이션 구조
Android 기초강좌 애플리캐이션 구조Android 기초강좌 애플리캐이션 구조
Android 기초강좌 애플리캐이션 구조
 
Create-React-App으로 SSR을 구현하며 배운 점 (feat. TypeScript)
Create-React-App으로 SSR을 구현하며 배운 점 (feat. TypeScript)Create-React-App으로 SSR을 구현하며 배운 점 (feat. TypeScript)
Create-React-App으로 SSR을 구현하며 배운 점 (feat. TypeScript)
 
TR 069 클라이언트 검토자료 3편
TR 069 클라이언트 검토자료 3편TR 069 클라이언트 검토자료 3편
TR 069 클라이언트 검토자료 3편
 
GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출
GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출
GKAC 2015 Apr. - Battery, 안드로이드를 위한 쉬운 웹 API 호출
 
Startup JavaScript 8 - NPM, Express.JS
Startup JavaScript 8 - NPM, Express.JSStartup JavaScript 8 - NPM, Express.JS
Startup JavaScript 8 - NPM, Express.JS
 
12장 상속 (고급)
12장 상속 (고급)12장 상속 (고급)
12장 상속 (고급)
 
Hoons 닷넷 정기세미나
Hoons 닷넷 정기세미나Hoons 닷넷 정기세미나
Hoons 닷넷 정기세미나
 
안드로이드 오픈소스 그리고 패턴
안드로이드 오픈소스 그리고 패턴  안드로이드 오픈소스 그리고 패턴
안드로이드 오픈소스 그리고 패턴
 
Airflow를 이용한 데이터 Workflow 관리
Airflow를 이용한  데이터 Workflow 관리Airflow를 이용한  데이터 Workflow 관리
Airflow를 이용한 데이터 Workflow 관리
 
Reflow and repaint 성능 비용
Reflow and repaint 성능 비용Reflow and repaint 성능 비용
Reflow and repaint 성능 비용
 
안드로이드 오픈소스 패턴 - 0.1
안드로이드 오픈소스 패턴 - 0.1안드로이드 오픈소스 패턴 - 0.1
안드로이드 오픈소스 패턴 - 0.1
 
Kubernetes & helm 활용
Kubernetes & helm 활용Kubernetes & helm 활용
Kubernetes & helm 활용
 
Terraform을 이용한 Infrastructure as Code 실전 구성하기 :: 변정훈::AWS Summit Seoul 2018
 Terraform을 이용한 Infrastructure as Code 실전 구성하기 :: 변정훈::AWS Summit Seoul 2018 Terraform을 이용한 Infrastructure as Code 실전 구성하기 :: 변정훈::AWS Summit Seoul 2018
Terraform을 이용한 Infrastructure as Code 실전 구성하기 :: 변정훈::AWS Summit Seoul 2018
 
Terraform을 이용한 Infrastructure as Code 실전 구성하기
Terraform을 이용한 Infrastructure as Code 실전 구성하기Terraform을 이용한 Infrastructure as Code 실전 구성하기
Terraform을 이용한 Infrastructure as Code 실전 구성하기
 
웹 사이트 시각화 및 성능 관리
웹 사이트 시각화 및 성능 관리웹 사이트 시각화 및 성능 관리
웹 사이트 시각화 및 성능 관리
 
Ai C#세미나
Ai C#세미나Ai C#세미나
Ai C#세미나
 

More from fefe7270

Surface flingerservice(서피스플링거서비스초기화)
Surface flingerservice(서피스플링거서비스초기화)Surface flingerservice(서피스플링거서비스초기화)
Surface flingerservice(서피스플링거서비스초기화)fefe7270
 
Stagefright recorder part1
Stagefright recorder part1Stagefright recorder part1
Stagefright recorder part1fefe7270
 
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
 
Android audio system(audioflinger)
Android audio system(audioflinger)Android audio system(audioflinger)
Android audio system(audioflinger)fefe7270
 
Android audio system(audiopolicy_manager)
Android audio system(audiopolicy_manager)Android audio system(audiopolicy_manager)
Android audio system(audiopolicy_manager)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
 
Android audio system(오디오 출력-트랙활성화)
Android audio system(오디오 출력-트랙활성화)Android audio system(오디오 출력-트랙활성화)
Android audio system(오디오 출력-트랙활성화)fefe7270
 
Android audio system(오디오 플링거 서비스 초기화)
Android audio system(오디오 플링거 서비스 초기화)Android audio system(오디오 플링거 서비스 초기화)
Android audio system(오디오 플링거 서비스 초기화)fefe7270
 

More from fefe7270 (13)

Surface flingerservice(서피스플링거서비스초기화)
Surface flingerservice(서피스플링거서비스초기화)Surface flingerservice(서피스플링거서비스초기화)
Surface flingerservice(서피스플링거서비스초기화)
 
Stagefright recorder part1
Stagefright recorder part1Stagefright recorder part1
Stagefright recorder part1
 
Camera camcorder framework overview(ginger bread)
Camera camcorder framework overview(ginger bread)Camera camcorder framework overview(ginger bread)
Camera camcorder framework overview(ginger bread)
 
Android audio system(audioflinger)
Android audio system(audioflinger)Android audio system(audioflinger)
Android audio system(audioflinger)
 
Android audio system(audiopolicy_manager)
Android audio system(audiopolicy_manager)Android audio system(audiopolicy_manager)
Android audio system(audiopolicy_manager)
 
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(오디오 출력-트랙생성)
 
Android audio system(오디오 출력-트랙활성화)
Android audio system(오디오 출력-트랙활성화)Android audio system(오디오 출력-트랙활성화)
Android audio system(오디오 출력-트랙활성화)
 
Android audio system(오디오 플링거 서비스 초기화)
Android audio system(오디오 플링거 서비스 초기화)Android audio system(오디오 플링거 서비스 초기화)
Android audio system(오디오 플링거 서비스 초기화)
 

Surface flingerservice(서피스 플링거 연결 ics)

  • 2. 화면 출력 요청 전 과정 x x x x 2
  • 3. 1.서피스 플링거 연결 요청 1.Surfaceflinger 검색 및 proxy 획득 ISurfaceComposer Android_view_Surface.cpp static void SurfaceSession_init(JNIEnv* env, jobject clazz) { sp<SurfaceComposerClient> client = new SurfaceComposerClient; } SurfaceComposerClient.cpp SurfaceComposerClient::SurfaceComposerClient(): mStatus(NO_INIT), mComposer(Composer::getInstance()) { } SurfaceComposerClient는 Refbase를 상속받았기 때문에, onFirstRef 가 불린다. void SurfaceComposerClient::onFirstRef() { sp<ISurfaceComposer> sm(getComposerService()); .. 3
  • 4. static inline sp<ISurfaceComposer> getComposerService() { return ComposerService::getComposerService(); } sp<ISurfaceComposer> ComposerService::getComposerService() { return ComposerService::getInstance().mComposerService; } ComposerService 는 singleton class를 상속받았음으로, 이미 ComposerService 객체가 있으면 그 객체를 return하고, 없으면, ComposerService 의 생성자를 호출해서 객체를 생성한다. ComposerService::ComposerService() : Singleton<ComposerService>() { const String16 name("SurfaceFlinger"); while (getService(name, &mComposerService) != NO_ERROR) { usleep(250000); }  SurfaceFlinger service의 proxy(ISurfaceCompser)를 mComposerService 에 저장한다. } 2.디스플레이 공유 메모리 서비스의 프록시 획득 4
  • 5. 1.서피스 플링거 연결 요청 SurfaceComposerClient.cpp ComposerService::ComposerService(): Singleton<ComposerService>() { const String16 name("SurfaceFlinger"); while (getService(name, &mComposerService) != NO_ERROR) { usleep(250000); }  SurfaceFlinger service의 proxy(ISurfaceCompser)를 mComposerService 에 저장한다. mServerCblkMemory = mComposerService->getCblk(); Surface flinger의 getCblk를 이용하여 디스플레이 공유 메모리의 서비스 프락시(IMemoryHep)을 획득한다. mServerCblk = static_cast<surface_flinger_cblk_t volatile *>(mServerCblkMemory->getBase()); 획득한 proxy로 공유메모리의 surface_flinger_cblk_t 구조체의 주소를 획득한다. } surface_flinger_cblk_t surfaceflinger SurfaceComposerClient connected mServerCblk ComposerService Dislay_cblk_t dcblk mServerCblk w,h:프레임 버퍼 너비,높이 Density,fps Format,orientation Xdpi,ydpi 5
  • 6. 1.서피스 플링거 연결 요청 3.서피스 플링거 연결 요청 및 서비스 클라이언트 프락시 획득 ISurfaceComposerClient void SurfaceComposerClient::onFirstRef() { sp<ISurfaceComposer> sm(getComposerService()); if (sm != 0) { ISurfaceComposerClient sp<ISurfaceComposerClient> conn = sm->createConnection(); Surfaceflinger에 있는 createConnection 가 호출 됨. } BnSurfaceComposerClient SurfaceFlinger.cpp sp<ISurfaceComposerClient> SurfaceFlinger::createConnection() { Client sp<ISurfaceComposerClient> bclient; sp<Client> client(new Client(this)); ~Client(); status_t err = client->initCheck(); createSurface; if (err == NO_ERROR) { destroySurface bclient = client; DefaultKeyedVector< size_t, } wp<LayerBaseClient> > return bclient;Client class의 proxy인 ISurfaceComposerClient가 mLayers; return됨. } 6
  • 7. 1.서피스 플링거 연결 요청 -서피스 클라이언트 리모트 서비스의 역할 1.서피스 플링거 서비스의 래퍼: 서피스 플링거 서비스 기능 중 일부를 사용할 수 있도록 제공함 (서피스 생성,삭제,서피스 상태 변경) 2.애플리케이션별 레이어 관리: 서피스 클라이언트 별로 서피스에 대한 지역 식별자를 할당하고, DefaultKeyedVector에 지역식별자와 layer를 함께 추가함. 3. 레이어 상태 변경:애플리케이션이 서피스의 상태 변경(가로,세로 전환)을 서피스 클라이언트 리모트 서비스에게 요청한다. 4.애플리케이션 레이어의 생명 주기 관리: 서피스 생성을 요청한 애플리케이션이 비정상적으로 동작을 종료하더라도 관리하고 있는 서피스와 관련 자원을 서피스 클라이언트의 소멸자에서 자동으로 해제해 준다. (why? Client class는 Refbase class를 상속 받는데 이 Refbase class는 참조하는 곳이 없어질때 자동으로 소멸자를 불러주게 된다.) 7
  • 8. 2.서피스 생성 요청 (서비스 클라이언트) Surface.java public Surface() { init(s,pid,name,display,w,h,format,flags); } Android_view_surface.cpp struct surface_data_t { static void Surface_init int32_t token; { int32_t identity; surface = client->createSurface(pid, name, dpy, w, h, format, flags); status_t readFromParcel(const Parcel& parcel); } status_t writeToParcel(Parcel* parcel) const; sp<SurfaceControl> SurfaceComposerClient::createSurface(…) }; { ISurfaceComposerClient::surface_data_t data; p<ISurface> surface = mClient->createSurface(&data, pid, name,display, w, h, format, flags); 서피스 클라이언트의 createSurface를 호출하여 SurfaceTextureLayer 핸들을 생성한다. 이때 data 구조체에 생성된 서피스에 대한 정보를 채워준다. SurfaceTextureLayer 핸들에 접근할 수 있는 BSurface Class의 proxy가 surface 변수에 저장된다. if (surface != 0) { result = new SurfaceControl(this, surface, data, w, h, format, flags); return된 Isurface proxy를 이용해서 SurfaceControl class를 생성한다. 이 class는 SurfaceTextureLayer proxy를 획득하거나, 서피스의 상태 변경을 할 수 있게 해 준다. } setSurfaceControl(env, clazz, surface); } static void setSurfaceControl(JNIEnv* env, jobject clazz, const sp<SurfaceControl>& surface) { env->SetIntField(clazz, so.surfaceControl, (int)surface.get()); SurfaceControl를 so.surfaceControl 에 저장한다. } 8
  • 9. 2.서피스 생성 요청 (서비스 클라이언트) sp<ISurface> Client::createSurface(ISurfaceComposerClient::surface_data_t* params, const String8& name, DisplayID display, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) { class MessageCreateSurface : public MessageBase { public: MessageCreateSurface(SurfaceFlinger* flinger, ISurfaceComposerClient::surface_data_t* params, const String8& name, Client* client, DisplayID display, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) : flinger(flinger), params(params), client(client), name(name), display(display), w(w), h(h), format(format), flags(flags) { } sp<ISurface> getResult() const { return result; } virtual bool handler() { result = flinger->createSurface(params, name, client, display, w, h, format, flags); return true; } }; sp<MessageBase> msg = new MessageCreateSurface(mFlinger.get(),params, name, this, display, w, h, format, flags); mFlinger->postMessageSync(msg);  MessageCreateSurface의 handler가 호출 됨. return static_cast<MessageCreateSurface*>( msg.get() )->getResult();  Bsurface Class의 proxy를 return 함. } 9
  • 10. 3.서피스 생성 요청 (서비스 서버) sp<ISurface> SurfaceFlinger::createSurface(…) { sp<LayerBaseClient> layer; sp<Layer> normalLayer; switch (flags & eFXSurfaceMask) { case eFXSurfaceNormal: normalLayer = createNormalSurface(client, d, w, h, flags, format); 1.Layer class 생성. layer = normalLayer; break; } if (layer != 0) { layer->initStates(w, h, flags); 2.생성된 layer 상태 초기화 ssize_t token = addClientLayer(client, layer);  3.전역 레이어 목록과 지역 레이어 목록에 추가 surfaceHandle = layer->getSurface();  4. Bsurface의 proxy(Isurface)를 가져옴. if (surfaceHandle != 0) {  mClient->createSurface 호출시 넘겨준 surface_data_t 구조체에 값을 채움. params->token = token;  서피스 지역 식별자 params->identity = surfaceHandle->getIdentity();  서피스 전역 식별자 } setTransactionFlags(eTransactionNeeded); 서피스 플링거가 합성 시 참조하는 상태 플래그에 설정. return surfaceHandle;  . Bsurface의 proxy(Isurface)를 return함. } 10
  • 11. 3.서피스 생성 요청 (서비스 서버) 1. Layer class 생성 normalLayer = createNormalSurface(client, d, w, h, flags, format); sp<Layer> SurfaceFlinger::createNormalSurface(..) LayerBase { sp<Layer> layer = new Layer(this, display, client); Layer class 생성 시 LayerBase의 생성자 부터 호출된다. LayerBaseClient return layer; } Layer Layer Layer Screenshot Dim Layerbase.cpp LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display) : dpy(display), contentDirty(false), sequence(uint32_t(android_atomic_inc(&sSequence))), SurfaceFlinger  sSequence 값을 sequence에 저장하고 sSequence를 1증가 시킨다. 지역 레이어 목록  sequence 변수는 동일 Z-order 값을 가지는 레이어를 정렬할때 사용 함. 전역 레이어 목록 Client 1 { … zorder Token=1 mIdentity } Token=2 4 4 LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display, 3 1 지역 레이어 목록 const sp<Client>& client) 2 2 : LayerBase(flinger, display), mClientRef(client), 1 3 Client 2 mIdentity(uint32_t(android_atomic_inc(&sIdentity))) 서피스 전역 식별자인 mIdentity의 값을 설정한다. Token=1 { Token=2 } 11
  • 12. 3.서피스 생성 요청 (서비스 서버) Layer::Layer(SurfaceFlinger* flinger, DisplayID display, const sp<Client>& client) : LayerBaseClient(flinger, display, client), { … } Layer생성자에서는 특별한 동작을 수행하지 않음. RefBase class를 상속했음으로, onFirstRef()가 불림. void Layer::onFirstRef() { struct FrameQueuedListener : public SurfaceTexture::FrameAvailableListener { FrameQueuedListener(Layer* layer) : mLayer(layer) { } private: wp<Layer> mLayer; virtual void onFrameAvailable() { sp<Layer> that(mLayer.promote()); if (that != 0) { void Layer::onFrameQueued() { that->onFrameQueued(); android_atomic_inc(&mQueuedFrames); } mFlinger->signalEvent(); } } }; mSurfaceTexture = new SurfaceTextureLayer(mTextureName, this); mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this)); SurfaceTextureLayer의 listener를 FrameAvailableListener 로 등록 한다. onFrameAvailable 메소드는 surfacetexture.cpp의 queuebuffer에서 불린다. mSurfaceTexture->setSynchronousMode(true); mSurfaceTexture->setBufferCountServer(BUFFER_COUNT_SERVER); } SurfaceTextureLayer는 Surfacetexture를 상속 받으므로 SurfaceTextureLayer 생성자 호출 시 SurfaceTexture의 생성자가 먼저 불린다. 12
  • 13. 3.서피스 생성 요청 (서비스 서버) SurfaceTexture::SurfaceTexture(…) { sp<ISurfaceComposer> composer(ComposerService::getComposerService()); mGraphicBufferAlloc = composer->createGraphicBufferAlloc(); Surfaceflinger의 createGraphicBufferAlloc을 호출한다. } Surfaceflinger.cpp sp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc() { sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc()); return gba; } GraphicBufferAlloc::GraphicBufferAlloc() { mFreedIndex = -1; mSize = 0; } mGraphicBufferAlloc는 SurfaceTexture::dequeueBuffer에서 사용된다. status_t SurfaceTexture::dequeueBuffer(…) { usage |= GraphicBuffer::USAGE_HW_TEXTURE; status_t error; sp<GraphicBuffer> graphicBuffer(mGraphicBufferAlloc->createGraphicBuffer( w, h, format, usage, &error)); mSlots[buf].mGraphicBuffer = graphicBuffer;  graphicBuffer 에 메모리를 할당 하고 graphicBuffer 를 가리키는 mSlots[buf] 를 return한다. } sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(…) { sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage)); return graphicBuffer; } 13
  • 14. 3.서피스 생성 요청 (서비스 서버) GraphicBuffer::GraphicBuffer(…) { mInitCheck = initSize(w, h, reqFormat, reqUsage); } status_t GraphicBuffer::initSize(uint32_t w, uint32_t h, PixelFormat format, uint32_t reqUsage) { GraphicBufferAllocator& allocator = GraphicBufferAllocator::get(); status_t err = allocator.alloc(w, h, format, reqUsage, &handle, &stride); 할당된 메모리의 handle을 &handle에 저장한다. return err; } virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) = 0; virtual status_t setBufferCount(int bufferCount) = 0; IsurfaceTexture virtual status_t dequeueBuffer, virtual status_t queueBuffer, virtual void cancelBuffer(int slot) = 0; virtual status_t setCrop(const Rect& reg) = 0; virtual status_t setTransform(uint32_t transform) = 0; virtual status_t setScalingMode(int mode) = 0; virtual int query(int what, int* value) = 0; BnSurfaceTexture virtual status_t setSynchronousMode(bool enabled) = 0; virtual status_t connect, virtual status_t disconnect SurfaceTexture virtual status_t setBufferCount(int bufferCount); SurfaceTextureLayer virtual status_t queueBuffer, dequeueBuffer,connet virtual void onDraw(const Region& clip) const; Layer virtual uint32_t doTransaction(uint32_t transactionFlags); virtual void lockPageFlip(bool& recomputeVisibleRegions); virtual void unlockPageFlip() 14
  • 15. 3.서피스 생성 요청 (서비스 서버) SurfaceTexture class에 접근하기 위해서 SurfacetexturelClient를 생성한다. static void Surface_readFromParcel( JNIEnv* env, jobject clazz, jobject argParcel) { sp<Surface> sur(Surface::readFromParcel(*parcel)); setSurface(env, clazz, sur); } static void setSurface(JNIEnv* env, jobject clazz, const sp<Surface>& surface) { env->SetIntField(clazz, so.surface, (int)surface.get()); Surface::readFromParcel 에 의해 생성된 Surface(SurfacetexturelClient를 상속받음)를 so.surface에 저장한다. } sp<Surface> Surface::readFromParcel(const Parcel& data) { surface = new Surface(data, binder); } SurfaceTextureClient::SurfaceTextureClient() { SurfaceTextureClient::init(); Surface::Surface(const Parcel& parcel, const sp<IBinder>& ref) } : SurfaceTextureClient()  SurfaceTextureClient의 생성자가 먼저 불린다. { void SurfaceTextureClient::init() { ANativeWindow::dequeueBuffer = st = interface_cast<ISurfaceTexture>(st_binder); surfacetexturelayer의 ISurfaceTexture를 가져온다. hook_dequeueBuffer; init(st); ANativeWindow::cancelBuffer = } hook_cancelBuffer; ANativeWindow::lockBuffer = hook_lockBuffer; ANativeWindow::queueBuffer = hook_queueBuffer; } 15
  • 16. 3.서피스 생성 요청 (서비스 서버) void Surface::init(const sp<ISurfaceTexture>& surfaceTexture) { if (mSurface != NULL || surfaceTexture != NULL) { if (surfaceTexture != NULL) { setISurfaceTexture(surfaceTexture); } } void SurfaceTextureClient::setISurfaceTexture( const sp<ISurfaceTexture>& surfaceTexture) { mSurfaceTexture = surfaceTexture; } 이렇게 생성된 SurfaceControl, Surface class는 getSurfaceControl()와 getSurface()에 의해서 불려 진다. android_view_Surface.cpp static sp<SurfaceControl> getSurfaceControl(JNIEnv* env, jobject clazz) { SurfaceControl* const p = (SurfaceControl*)env->GetIntField(clazz, so.surfaceControl); return sp<SurfaceControl>(p); } static sp<Surface> getSurface(JNIEnv* env, jobject clazz) { sp<Surface> result(Surface_getSurface(env, clazz));  sp<Surface> surface((Surface*)env->GetIntField(clazz, so.surface)); return result; } 16
  • 17. 3.서피스 생성 요청 (서비스 서버) Client SurfaceFlinger Client surfacecomposerclient surfacetexture surfacecontrol BSurface SurfaceTextureLaye r layer surface surfacetextureclient 17
  • 18. 3.서피스 생성 전체 그림 Android_view_surface.cpp SurfaceFlingerClient SurfaceFlinger Client SurfaceView Surface.java surfacecomposerclient Get surfacetexture H SurfaceControl { surfacecontrol BSurface O Surfacecontrol SurfaceTextureLayer L D } E layer R surface getSurface { surfacetextureclient Surface } 18
  • 19. 3.푸시 버퍼 서피스 생성 요청 (서비스 서버) 2.생성된 layer 상태 초기화 layer->initStates(w, h, flags); Layerbase class의 initStates 가 호출됨. void LayerBase::initStates(uint32_t w, uint32_t h, uint32_t flags) { mCurrentState.z = 0; mCurrentState.w = w; mCurrentState.h = h; mCurrentState.requested_w = w; mCurrentState.requested_h = h; mCurrentState.sequence = 0; sequence 값은 드로잉 프레임에서의 레이어와 현재 프레임의 레이어 상태가 변경될 때 1씩 증가 mDrawingState = mCurrentState;  mDrawingState (화면에 출력중인 레이어의 상태 저장)과 mCurrentState(화면 출력을 위해 합성중인 레이어의 상태 저장)를 동일하게 설정 } 3.전역 레이어 목록과 지역 레이어 목록에 추가 ssize_t token = addClientLayer(client, layer); SurfaceFlinger 1.전역 레이어 목록 -서피스 플링거 서비스에서 생성된 전체 레이어 목록 지역 레이어 목록 -정렬 순서:zorder 순서 전역 레이어 목록 - mCurrentState.layersSortedByZ 변수로 관리 Client 1 layersSortedByZ 2.지역 레이어 목록 mLayers zorder mIdentity -특정 Client에서 생성된 레이어 목록 Token=1 4 4 -지역 레이어 목록의 레이어는 전역 레이어 목록에 3 1 Token=2 추가됨. -Client class의 mLayers 변수로 관리 19
  • 20. 3.푸시 버퍼 서피스 생성 요청 (서비스 서버) ssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client, const sp<LayerBaseClient>& lbc) { // 지역 레이어 목록에 추가 size_t name = client->attachLayer(lbc); // 전역 레이어 목록에 추가 addLayer_l(lbc); return ssize_t(name); } size_t Client::attachLayer(const sp<LayerBaseClient>& layer) { size_t name = mNameGenerator++; mLayers.add(name, layer); return name; } status_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer) { ssize_t i = mCurrentState.layersSortedByZ.add(layer); return (i < 0) ? status_t(i) : status_t(NO_ERROR); } 20
  • 21. 3.푸시 버퍼 서피스 생성 요청 (서비스 서버) 4. SurfaceTexturelayer 핸들을 가져옴 surfaceHandle = layer->getSurface(); Layerbase.cpp의 getSurface가 호출 됨. sp<LayerBaseClient::Surface> LayerBaseClient::getSurface() { sp<Surface> s; Mutex::Autolock _l(mLock); s = mClientSurface.promote(); if (s == 0) { s = createSurface(); mClientSurface = s; } return s; } Layer.cpp의 오버라이딩 된 createSurface를 부른다. class BSurface : public BnSurface, public LayerCleaner { Layer.cpp wp<const Layer> mOwner; sp<ISurface> Layer::createSurface() virtual sp<ISurfaceTexture> getSurfaceTexture() const { { sp<ISurfaceTexture> res; sp<ISurface> sur(new BSurface(mFlinger, this)); sp<const Layer> that( mOwner.promote() ); return sur; if (that != NULL) { SurfaceTextureLayer에 접근 할 수 있는 res = that->mSurfaceTexture; } Bsurface class를 생성하고 proxy인 Isurface를 return res; return한다. } } public: BSurface(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer) : LayerCleaner(flinger, layer), mOwner(layer) { } };