SlideShare a Scribd company logo
1 of 24
SurfaceFlingerService
(서피스 상태 변경-JB )




                            박철희
                        1
1.서피스 상태 변경 요청(서비스 클라이언트)

1.서피스 추가/삭제
2.개별 레이어 상태 변경(크기,zorder)
3.프레임 상태 변경(orientation변경)

1.서피스 추가/삭제
 서피스가 추가 또는 삭제 되면 전역 레이어 목록이 변경되어야 한다.
   이를 위해서 추가 또는 삭제 시에 mTransactionFlags 에 eTransactionNeeded을 설정하고
   Vsync를 발생 시킨다.
sp<ISurface> SurfaceFlinger::createSurface(…)
{

    normalLayer = createNormalSurface(client, d, w, h, flags, format);

    setTransactionFlags(eTransactionNeeded);
                                                         uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
                                                         {
}
                                                            uint32_t old = android_atomic_or(flags, &mTransactionFlags);
                                                            if ((old & flags)==0) { // wake the server up
status_t SurfaceFlinger::removeSurface()
                                                                 signalTransaction();
{
                                                            }
   …
                                                            return old;
   setTransactionFlags(eTransactionNeeded);
                                                         }
}
                                                         void SurfaceFlinger::signalTransaction() {
                                                           mEventQueue.invalidate();
                                                           MessageQueue에서 Vsync 발생 시킴.
                                                         }
                                                                                                               2
1.서피스 상태 변경 요청(서비스 클라이언트)

2.개별 레이어 상태 변경(크기,zorder)
  -레이어(서피스) 상태 변경은 트랜잭션 시작과 종료 사이에만 가능하다.
  -다수의 상태 변경 함수를 동시에 중첩하여 설정 할 수 있다.
   ex)fade out 의 기능과 같이 메뉴가 투명해 지면서 축소가 되고 위치가 변경이 되는 경우
     “투명,축소,위치변경”이 동시에 실행 된다.
  레이어의 상태를 변경할 때 클라이언트와 서버의 동작




                                                    3
1.서피스 상태 변경 요청(서비스 클라이언트)

Bootanimation.cpp
status_t BootAnimation::readyToRun()
{
 sp<SurfaceControl> control = session()->createSurface(getpid(), 0, dinfo.w, dinfo.h, PIXEL_FORMAT_RGBA_8888);
    SurfaceComposerClient::openGlobalTransaction(); transaction 시작
   control->setLayer(0x40000000); 서피스의 zorder 변경
   SurfaceComposerClient::closeGlobalTransaction(); transaction 종료
}

1)Transaction 시작
status_t SurfaceComposerClient:: openGlobalTransaction()
{
   ICS 이후 부터 특별한 동작은 하지 않음.
}

2) 서피스의 zorder 변경
Surface.cpp
status_t SurfaceControl::setLayer(int32_t layer)
{
   status_t err = validate();
   if (err < 0) return err;
   const sp<SurfaceComposerClient>& client(mClient);
   return client->setLayer(mToken, layer);  상태 변경의 대상이 되는 레이어를 알려 주기 위해 mToken을 넘겨 준다.
}                                     (mToken은 SurfaceControl 생성자에서 생성된 layer를 가리키게 된다.)




                                                                                                        4
1.서피스 상태 변경 요청(서비스 클라이언트)
SurfaceComposerClient.cpp
status_t SurfaceComposerClient::setLayer(SurfaceID id, int32_t z)
{
  return getComposer().setLayer(this, id, z);
}

status_t Composer::setLayer(const sp<SurfaceComposerClient>& client, SurfaceID id, int32_t z) {
  layer_state_t* s = getLayerStateLocked(client, id); 서피스의 상태 변경 정보를 저장할 layer_state_t를 생성한다.
   s->what |= ISurfaceComposer::eLayerChanged;
   s->z = z;
   layer state 구조체에 what(상태 변경 이벤트),z(zoder값)을 저장한다.
   return NO_ERROR;
}

layer_state_t* Composer::getLayerStateLocked(const sp<SurfaceComposerClient>& client, SurfaceID id) {

    ComposerState s;
    s.client = client->mClient; 서피스 클라이언트 리코트 서비스에 대한 Proxy(ISurfaceComposerClient)를 저장한다.
    s.state.surface = id;       상태가 변경된 서피스의 지역 식별자를 저장한다.

    ssize_t index = mStates.indexOf(s);
    if (index < 0) {
        // we don't have it, add an initialized layer_state to our list
        index = mStates.add(s);  상태가 변경된 layer_state_t 구조체를 mStates 에 넣는다.
                                  이 mStates 는 서피스 플링거에게 전달되어 서피스 상태 변경에 사용된다.
    }

    ComposerState* const out = mStates.editArray();
    return &(out[index].state);
}


                                                                                                        5
1.서피스 상태 변경 요청(서비스 클라이언트)
3. transaction 종료

SurfaceComposerClient.cpp
static void closeGlobalTransaction(bool synchronous)
{
      Composer::getInstance().closeGlobalTransactionImpl(synchronous);
}




void Composer::closeGlobalTransactionImpl(bool synchronous)
{
  sp<ISurfaceComposer> sm(getComposerService());

    Vector<ComposerState> transaction;
     transaction = mStates;
      애플리케이션에서 발생한 상태 변경 이벤트를 mStates 변수에 발생한 순서대로 저장해 두고,
        서피스 플링거에게 전달 한다.
     mStates.clear();
     mStates 배열을 초기화 한다.
     orientation = mOrientation;
     mOrientation = ISurfaceComposer::eOrientationUnchanged;
    sm->setTransactionState(transaction, orientation, flags);
     서비스 플링거에게 서피스들의 상태 변경 정보를 저장한 transaction 과 출력 방향을 저장한 orientation을 전달 한다.
}




                                                                          6
2.서피스 상태 변경 (서비스 서버)

서피스 플링거 서비스는 레이어의 상태 변경이 발생하면 상태 변경 이벤트의 종류에 따라 처리한다.



      상태 변경                동작                        값이 설정되는 경우
       이벤트
  eTransactionNeeded   전역 레이어 목록에     1)   setOrientation: 회전 방향 변경
                       포함된            2)   Freeze: 디스플레이가 갱신되지 않도록 만듦.
                       모든 레이어의 무효화    3)   Unfreeze:freeze상태를 해지
                       영역을 재계산        4)   createSurface:레이어 생성
                                      5)   destroySurface:레이어 삭제
                                      6)   setLayer:레이어의 높이 값 변경



   eTraversalNeeded    상태가 변경된 레이어    1)   setPosition:위치 결정
                       의 무효화 영역을 재계   2)   setLayer:레이어의 높이 값 변경
                       산              3)   setSize: 크기 번경
                                      4)   setAlpha: 개별 레이어 전체의 투명도 변경
                                      5)   setMatrix: 레이어 메트릭스 변경
                                      6)   setTransparentRegionHint: 레이어 반투명 영역 변경
                                      7)   segFlags:레이어 가시성 변경(hide,show)




                                                                         7
2.서피스 상태 변경 (서비스 서버)
void SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state, int orientation, uint32_t flags)
{

    if (mCurrentState.orientation != orientation) {  이전 설정된 출력 방향과 다르면
         mCurrentState.orientation = orientation; 현재 출력 방향을 설정하고
         transactionFlags |= eTransactionNeeded; 전체 레이어의 무효화 영역을 설정하기 위해 eTransactionNeeded 설정함.
    }

    const size_t count = state.size();
    for (size_t i=0 ; i<count ; i++) {
       const ComposerState& s(state[i]);
       sp<Client> client( static_cast<Client *>(s.client.get()) ); 변경 요청이 발생한 서피스 클라이언트를 획득한다.
       transactionFlags |= setClientStateLocked(client, s.state);
    }

    if (transactionFlags) {
         setTransactionFlags(transactionFlags);  변경된 플래그 값을 mTransactionFlags 에 반영하고 signalTransaction 를
                                         호출해서 합성 이벤트를 발생시킨다.(mEventQueue.invalidate())

      if (flags & eSynchronous) {
          mTransationPending = true;
           모든 레이어의 가로,세로 값이 변경 될때 까지 기다리기 위한 변수
      }
      while (mTransationPending) {
          status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
          레이어의 크기가 재설정 될 동안 기다린다.
            mTransationPending = false;
             break;
          }
}


                                                                                                                8
2.서피스 상태 변경 (서비스 서버)

uint32_t SurfaceFlinger::setClientStateLocked(const sp<Client>& client, const layer_state_t& s)
{

    if (what & eLayerChanged) {
            ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
            if (layer->setLayer(s.z)) {
                mCurrentState.layersSortedByZ.removeAt(idx);
                전역 레이어 목록에서 해당 레이어 삭제
                mCurrentState.layersSortedByZ.add(layer);
                다시 추가.
                flags |= eTransactionNeeded|eTraversalNeeded;
                zorder 변경은 개별 레이어의 상태 변경 (eTraversalNeeded) 및 전역 레이어 목록 변경(eTransactionNeeded)
                  이 필요함.
     }

    if (what & eVisibilityChanged) {
          if (layer->setFlags(s.flags, s.mask))
           flags |= eTraversalNeeded; 가시성 변경은 “개별 레이어 상태 변경”에 해당함으로 서피스 플링거의
                                           mTransactionFlags 변수에 eTraversalNeeded 값 설정.
     }

}

Layerbase.cpp
bool LayerBase::setFlags(uint8_t flags, uint8_t mask) {
  const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
   Layerbase의 mCurrentState. 변수에 변경할 속성을 set한다.
   mCurrentState.sequence++; 서피스의 상태가 변경되었다는 사실을 mCurrentState.의 sequence를 하나 증가 시켜 표시.
  mCurrentState.flags = newFlags;
  return true;
}
                                                                                9
3.윈도우 속성 변경(서비스 클라이언트)

 서피스 텍스쳐에 설정된 안드로이드 네이티브 윈도우의 속성값을 변경.

 윈도우 속성 변경 예 ex)setBufferCount()




  native_window_set_usage               그래픽 버퍼의 속성을 설정

  native_window_set_crop                최종적으로 디스플레이에 출력 될 화면의 크기를 결정 함.

  native_window_set_buffer_count        그래픽 버퍼의 개수 지정

  native_window_set_buffers_transform   윈도우의 출력 방향 결정

  native_window_set_buffers_timestamp   윈도우의 화면 출력을 요청하면 서버에서는 출력 요청이 발생한 시간 값을 저장

  native_window_api_connect             윈도우의 사용을 위해 윈도우와 어플리케이션을 연결함.

                                                                          10
3.윈도우 속성 변경(서비스 클라이언트)
Ex)Cameraservice의 setPreviewWindow

status_t CameraService::Client::setPreviewWindow(const sp<IBinder>& binder, const sp<ANativeWindow>& window)
{

    if (window != 0) {
        result = native_window_api_connect(window.get(), NATIVE_WINDOW_API_CAMERA);
}

Window.h
static inline int native_window_api_connect(struct ANativeWindow* window, int api)
{
   return window->perform(window, NATIVE_WINDOW_API_CONNECT, api);
}

Surfacetextureclient.cpp
int SurfaceTextureClient::perform(int operation, va_list args)
{
      case NATIVE_WINDOW_API_CONNECT:
       res = dispatchConnect(args);
       break;
}
int SurfaceTextureClient::dispatchConnect(va_list args) {
    int api = va_arg(args, int);
   return connect(api);
}

int SurfaceTextureClient::connect(int api)
{
    int err = mSurfaceTexture->connect(api, &output);
    output.deflate(&mDefaultWidth, &mDefaultHeight, &mTransformHint, &numPendingBuffers);
}
                                                                                                      11
3.윈도우 속성 변경(서비스 서버)
BufferQueue.cpp

status_t BufferQueue::connect(int api, QueueBufferOutput* output)
{
   switch (api) {
     case NATIVE_WINDOW_API_EGL:
     case NATIVE_WINDOW_API_CPU:
     case NATIVE_WINDOW_API_MEDIA:
     case NATIVE_WINDOW_API_CAMERA:
            mConnectedApi = api;
           output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint,mQueue.size());
           인자로 넘어온 output에 mDefaultWidth, mDefaultHeight 값 들을 넣는다.
             이 값들은 SurfaceTextureclient의 connect함수에서 deflate로 다시 값들을 가져 간다.
        }
        break;
     default:
        err = -EINVAL;
        break;
   }

    mBufferHasBeenQueued = false;

    return err;
}




                                                                                           12
4.그래픽 버퍼 요청(서비스 클라이언트)
 그래픽 버퍼 획득 과정




                         13
4.그래픽 버퍼 요청(서비스 클라이언트)
Ex)그래픽 버퍼 요청
OmxCodec.cpp
status_t OMXCodec::pushBlankBuffersToNativeWindow()
{
  …
   for (int i = 0; i < numBufs + 1; i++) {
      err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &anb);       -----(1)
      sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));                       -----(2)
      err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));                 -----(3)
      *img = 0; 가상 주소의 내용을 0으로 채운다(blank buffer)
       err = buf->unlock();  그래픽 버퍼의 사용완료를 그래픽 HAL에게 알림.
       err = mNativeWindow->queueBuffer(mNativeWindow.get(),buf->getNativeBuffer());
       수정된 그래픽 버퍼를 출력 요청 한다.
}

1) mNativeWindow->dequeueBuffer(mNativeWindow.get(), &anb);
dequeueBuffe 는 ANativeWindow 를 상속 받은 SurfaceTextureClient 의 hook_dequeubuufer에 매핑되어 있다.

int SurfaceTextureClient::hook_dequeueBuffer(ANativeWindow* window, ANativeWindowBuffer** buffer) {
   SurfaceTextureClient* c = getSelf(window);
   return c->dequeueBuffer(buffer);  c는 SurfaceTextureClient 를 가리 킴.
}

int SurfaceTextureClient::dequeueBuffer(android_native_buffer_t** buffer)
 {
status_t result = mSurfaceTexture->dequeueBuffer(&buf, reqW, reqH, mReqFormat, mReqUsage); -----(1-1)
sp<GraphicBuffer>& gbuf(mSlots[buf].buffer);
 if ((result & ISurfaceTexture::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) {
       result = mSurfaceTexture->requestBuffer(buf, &gbuf);} -----(1-2)
  *buffer = gbuf.get();
   return OK;
}
                                                                                                        14
4.그래픽 버퍼 요청(서비스 클라이언트)
(1-1) mSurfaceTexture->dequeueBuffer(&buf, reqW, reqH, mReqFormat, mReqUsage);

- mSurfaceTexture 는 ISurfaceTexture를 가리킨다. 이를 통해 BufferQueue의 dequeueBuffer를 호출한다.
- Buf:호출 시 그래픽 버퍼의 번호를 저장할 정수형 변수,
  이 정수형 변수를 사용할 그래픽 버퍼의 index를 가리킨다.
- reqW, reqH: 생성할 그래픽 버퍼의 가로,세로 크기

   그래픽 버퍼 요청 시 클라이언트와 서버의 상호 동작




                                                                                     15
4.그래픽 버퍼 요청(서비스 클라이언트)
(1) 애플리케이션은 ISurfaceTexture 서비스 프록시의 dequeueBuffer()를 호출하여 그래픽 버펴를 요청한다.
(2) 서버 측에서는 BufferSlot 배열에서 FREE 상태의 슬롯을 찾는다. 그런 후 해당 배열의 상태를 DEQUEUED로 변경한다.
(3) Bufferslot 배열의 인덱스를 반환한다. 배열의 인덱스의 그래픽 버퍼가 없어면 requestbuffer로 할당된 그래픽 버퍼를 요청한다
(4) 애플리케이션이 렌더링이 완료된 그래픽 버퍼를 queuebuffer()를 이용하여 서버측에 전달한다.
(5) 서퍼에서는 버퍼 큐(mQueue)에 해당 그래픽 버퍼의 인덱스를 넣는다. 그런 후 해당 배열의 상태를 QUEUED로 변경한다.

(1-2) mSurfaceTexture->requestBuffer(buf, &gbuf);
 if ((result & ISurfaceTexture::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) {
     해당 그래픽 버퍼 번호에 처음으로 그래픽 번호를 요청하거나, 요청한 버퍼의 크기나 픽셀 포맷 등이 기존에 할당된
        버퍼와 다른 경우 서버측에게 새로 할당 된 그래픽 버퍼의 전달을 요청한다.
       (이 경우 dequeueBuffer함수는 BUFFER_NEEDS_REALLOCATION를 반환 함.)
       result = mSurfaceTexture->requestBuffer(buf, &gbuf);
  *buffer = gbuf.get();
  생성된 그래픽 버퍼를 애플리케이션으로 반환 함.
   return OK;
}
ISurfaceTexture.cpp
virtual status_t requestBuffer(int bufferIdx, sp<GraphicBuffer>* buf) {
       Parcel data, reply;
       data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
       data.writeInt32(bufferIdx); 요청할 버퍼의 index
       status_t result =remote()->transact(REQUEST_BUFFER, data, &reply);
       서버에 REQUEST_BUFFER 요청 보냄. 서버는 해당하는 인덱스의 BufferSlot 배열에 GraphicBuffer 객체를 생성한다.
       bool nonNull = reply.readInt32();
       if (nonNull) {
           *buf = new GraphicBuffer(); 서피스 텍스쳐 클라이언트에도 GraphicBuffer를 생성한다.
           reply.read(**buf); 서버영역에서 생성된 그래픽 버퍼의 정보를 방금 생성한 GraphicBuffer 에 채워 넣는다.
                          이렇게 함으로써 서버에서 생성된 그래픽 버퍼와 동일한 값을 클라이언트에서도 유지하게 된다.
       }
       result = reply.readInt32();
       return result;
    }
                                                                                  16
4.그래픽 버퍼 요청(서비스 클라이언트)
(2) sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));                      GraphicBuffer::GraphicBuffer(
   ANativeWindowBuffer(anb)를 가지는 GraphicBuffer를 생성한다.                         ANativeWindowBuffer* buffer,
                                                                                bool keepOwnership) {
(3) err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));                width = buffer->width;
   애플리케이션에서 버퍼의 사용을 위해서는 접근 가능한 그래픽 버퍼의 가상주소를                                    height = buffer->height;
    필요로 한다.                                                                       stride = buffer->stride;
    그래픽 버퍼의 가상주소를 획득하기 위해 GraphicBuffer class의 lock함수가                            format = buffer->format;
    불려진다.                                                                         usage = buffer->usage;
                                                                                  handle = buffer->handle;
status_t GraphicBuffer::lock(uint32_t usage, void** vaddr)                     }
{
   const Rect lockBounds(width, height);
   status_t res = lock(usage, lockBounds, vaddr);
   //vaddr: 가상주소를 저장할 포인터
   return res;
}


status_t GraphicBuffer::lock(uint32_t usage, const Rect& rect, void** vaddr)
{
   status_t res = getBufferMapper().lock(handle, usage, rect, vaddr);
    getBufferMapper 함수를 이용하여 전달된 그래픽 버퍼에 대한 가상 주소를 반환한다.
   return res;
}




                                                                                                  17
4.그래픽 버퍼 생성(서비스 서버)
서비스 서버 측에서 그래픽 버퍼를 할당하는 과정은
1)버퍼 슬롯의 개수 확인 2)버퍼 슬롯의 인덱스 획득 3)그래픽 버퍼 할당 으로 구분된다.
1)버퍼 슬롯의 개수 확인
status_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h, uint32_t format, uint32_t usage)
{
   while (tryAgain) {
      const int minBufferCountNeeded = mSynchronousMode ? mMinSyncBufferSlots : mMinAsyncBufferSlots;
      동기식, 비동기식에 따라 필요한 최소 버퍼수를 minBufferCountNeeded 에 넣는다.
     const bool numberOfBuffersNeedsToChange = !mClientBufferCount &&
                                             ((mServerBufferCount != mBufferCount) ||
                                                         (mServerBufferCount < minBufferCountNeeded));
       setBufferCount 함수로 버퍼 개수를 설정하거나(mClientBufferCount 변경),
          서버에서 설정한 버퍼의 수가 BufferQueue에 설정된 버퍼의 수와 다르거나 (mServerBufferCount != mBufferCount),
           서버에서 설정한 버퍼의 수가 설정 가능한 최소 버퍼 수보다 작을 경우
          (mServerBufferCount < minBufferCountNeeded
          numberOfBuffersNeedsToChange를 true로 setting한다.
          이 의미는 버퍼의 수를 수정하겠다는 의미 이다.
        if (!mQueue.isEmpty() && numberOfBuffersNeedsToChange) {
              버퍼의 수 변경이 필요하지만, 출력 대기 큐(mQueue)에 출력 요청한 인덱스가 남아 있다면,
               mDequeueCondition.wait(mMutex);
              출력 대기 큐가 모두 소비 될 때 까지 기다린다.
             continue;
         }
        if (numberOfBuffersNeedsToChange) {
             freeAllBuffersLocked();  mSlot의 모든 배열을 초기화 한다.(mSlot에 할당된 모든 그래픽 버퍼가 해지 된다.)
             mBufferCount = mServerBufferCount; 서버에서 요청한 버퍼 수를 mBufferCount 에 저장한다.
            if (mBufferCount < minBufferCountNeeded)
                 mBufferCount = minBufferCountNeeded; 버퍼 최소값보다 작으면 버퍼 최소 값으로 저장 한다.
                  returnFlags |= ISurfaceTexture::RELEASE_ALL_BUFFERS;
             SurfaceTextureClient의 dequeueBuffer함수는 서버에서 RELEASE_ALL_BUFFERS 가 반환되면
               freeAllBuffers를 불러 클라이언트에 매핑된 그래픽 버퍼를 모두 해지 한다.}
                                                                                               18
4.그래픽 버퍼 생성(서비스 서버)
2)사용 가능한 버퍼 슬롯의 인덱스 획득

status_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h, uint32_t format, uint32_t usage)
{
   while (tryAgain) {

       …
       found = INVALID_BUFFER_SLOT;
       foundSync = INVALID_BUFFER_SLOT;
        for (int i = 0; i < mBufferCount; i++) {
          const int state = mSlots[i].mBufferState;
           if (state == BufferSlot::FREE) 버퍼의 상태가 free인 값을 검색하여 인덱스를 획득한다.
           {
                foundSync = i;
                    found = i;
            }

       tryAgain = found == INVALID_BUFFER_SLOT;
        if (tryAgain) {
            mDequeueCondition.wait(mMutex);
            사용 가능한 버퍼가 없는 경우, FREE인 상태의 버퍼가 생길 때 까지 기다린다.
        }

       *outBuf = found;
       dequeueBuffer() 함수 호출 시 전달 된 인자에 검색에 성공한 BufferSlot 배열의 인덱스를 저장하여,
         클라이언트 측으로 전달한다.
       …




                                                                                                            19
4.그래픽 버퍼 생성(서비스 서버)
3)그래픽 버퍼 할당
status_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h, uint32_t format, uint32_t usage)
{
   while (tryAgain) {
         …
        const sp<GraphicBuffer>& buffer(mSlots[buf].mGraphicBuffer);
       검색된 인덱스의 GraphicBuffer 객체의 참조를 획득한다. 이전에 할당된 그래픽 버퍼가 있다면 재사용이 가능한다.
        mSlots[buf].mBufferState = BufferSlot::DEQUEUED;
        검색한 슬롯의 상태를 DEQUEUED 로 변경한다.

        if ((buffer == NULL) ||
          needNewBuffer(currentGeometry, requiredGeometry, updatedGeometry) ||
         ((uint32_t(buffer->usage) & usage) != usage)) 그래픽 버퍼를 새로 생성해야 하면(처음 생성 or size 변경)
    {
         sp<GraphicBuffer> graphicBuffer( mGraphicBufferAlloc->createGraphicBuffer( w, h, format, usage, &error));
         그래픽 버퍼를 생성한다. mGraphicBufferAlloc은 IGraphicBufferAlloc 서비스 프락시를 가리킨다.

        mSlots[buf].mGraphicBuffer = graphicBuffer;
        생성한 그래픽 버퍼를 해당 슬롯의 mGraphicBuffer 에 저장한다.
        returnFlags |= ISurfaceTexture::BUFFER_NEEDS_REALLOCATION;
        새롭게 할당된 버퍼가 있을 경우 설정하는 value이다.
          클라이언트 측에서는 BUFFER_NEEDS_REALLOCATION 이 전달되면 ISurfaceTexture의 requestBuffer()
          함수를 호출하여 생성된 그래픽 버퍼를 전달 받는다.

}
SurfaceFlinger.cpp
sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
           PixelFormat format, uint32_t usage, status_t* error) {
  sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage, mBufferSize));
  status_t err = graphicBuffer->initCheck();
  return graphicBuffer;
}
                                                                                                              20
4.그래픽 버퍼 생성(서비스 서버)
GraphicBuffer.cpp
GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h,
     PixelFormat reqFormat, uint32_t reqUsage, uint32_t bufferSize)
  : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()),
    mInitCheck(NO_ERROR), mIndex(-1)
{
  mInitCheck = initSize(w, h, reqFormat, reqUsage, bufferSize);
}

 mOwner: 그래픽 버퍼의 메모리에 대한 소유자
  -ownNone: 애플리케이션 영역에서 그래픽 버퍼가 생성될 때 할당 됨. 하지만 requestBuffer() 함수를 호출하여
           그래픽 버퍼를 전달 받을 때 이 값은 ownHandle 로 변경 됨.
  -ownHandle: 클라이언트에서 사용할 그래픽 버퍼의 경우.
  -ownData: 서버에서 사용할 그래픽 버퍼의 경우
 mBufferMapper: 그래픽 버퍼의 메모리 할당 후 애플리케이션에서 매핑 할 때 사용하는 GraphicBufferMapper 클래스
               객체 저장.

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);
    GraphicBufferAllocator 클래스의 alloc함수를 호출함.
  return err;                                                                   GraphicBufferAllocator::
}                                                                                 GraphicBufferAllocator(): mAllocDev(0)
                                                                                {
status_t GraphicBufferAllocator::alloc(…)                                           hw_get_module(
{                                                                                    GRALLOC_HARDWARE_MODULE_ID,
  err = mAllocDev->alloc(mAllocDev, w, h, format, usage, handle, stride);       &module);
  그래픽 할당 HAL의 alloc 함수를 호출 한다.                                                      if (err == 0) {
}                                                                                     gralloc_open(module, &mAllocDev);
                                                                                  }
                                                                                }
                                                                                                                  21
4.그래픽 버퍼 생성(서비스 서버)
dequeueBuffer 의 result가 BUFFER_NEEDS_REALLOCATION 일경우 mSurfaceTexture->requestBuffer를 호출하여
BufferQueue 의 requestBuffer를 부른다.

ISurfaceTexture.cpp
status_t BnSurfaceTexture::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
  switch(code) {
     case REQUEST_BUFFER: {
        CHECK_INTERFACE(ISurfaceTexture, data, reply);
        int bufferIdx = data.readInt32();
        sp<GraphicBuffer> buffer;
        int result = requestBuffer(bufferIdx, &buffer);
        reply->writeInt32(buffer != 0);
        if (buffer != 0) {
            reply->write(*buffer);
           반환된 그래픽 버퍼를 바인더에 쓴다.
            이렇게 함으로써 서피스 플링거 영역에 생성된 그래픽 버퍼와 같은 값을 가진 GraphicBuffer 객체를
              어플리케이션 영역에 생성 할 수 있게 된다.
        }
        reply->writeInt32(result);
        return NO_ERROR;
     } break;

}


BufferQueue.cpp
status_t BufferQueue::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
   *buf = mSlots[slot].mGraphicBuffer;
    클라이언트로 부터 전달받은 인덱스에 해당하는 그래픽 버퍼를 GraphicBuffer 에 저장하여 반환한다.
   return NO_ERROR;
}
                                                                                                          22
참고.그래픽 버퍼 요청 /생성 과정


  Application                            SurfaceTextureClient                                       BufferQueue
                        1                                                           2
                  SurfaceTextureClient
                                                                         BufferQueue에 요청
 버퍼 요청            에 요청                     버퍼 요청
 (dequeubuffer)                            (dequeubuffer)

                                             0       mSlot[0]                                  0       mSlot[0]   D
 9                                                                              4
 전달 받은                                       1       mSlot[1]           찾은 FREE Slost의         1       mSlot[1]   D
 GraphicBuffer를                                                         Index를 return함.
 사용하기 위해                                     2       mSlot[2]                                  2       mSlot[2]   F
 가상주소를
 Mapping 후                                  …                                                  …
 그래픽 버퍼를 사용한다.                                                  5 Requestbuffer를
                                                                  호출해서 할당된 그래픽
                                                                  버퍼를 전달 받음

                                                         Requestbuffer를                                3   Status가 FREE인 slot
                                                 6       호출시 클라이언트 측에                                      을 찾고 그래픽 버퍼
                                                         빈 GraphicBuffer 를 생성                              할당 함.

                                                 GraphicBuffer                                 GraphicBuffer
  GraphicBuffer
                        8                                                               7
                                                     그래픽 버퍼                                         그래픽 버퍼
     그래픽 버퍼
                   클라이언트 측의                                                서버에서 생성된
                   GraphicBuffer를                                          동일한 그래픽 버퍼를
                   Application에서 사용하기                                      클라이언트 측의 GraphicBuffer
                   위해서 전달 한다.                                              로 읽어 옴.




                                                                                                             23
참고자료


 안드로이드 미디어 프레임워크 –”개발자가 행복한 세상”

 Goolge Jelly bean Source




                                   24

More Related Content

What's hot

[스프링 스터디 2일차] 서비스 추상화
[스프링 스터디 2일차] 서비스 추상화[스프링 스터디 2일차] 서비스 추상화
[스프링 스터디 2일차] 서비스 추상화AnselmKim
 
Startup JavaScript 6 - 함수, 스코프, 클로저
Startup JavaScript 6 - 함수, 스코프, 클로저Startup JavaScript 6 - 함수, 스코프, 클로저
Startup JavaScript 6 - 함수, 스코프, 클로저Circulus
 
Startup JavaScript 4 - 객체
Startup JavaScript 4 - 객체Startup JavaScript 4 - 객체
Startup JavaScript 4 - 객체Circulus
 
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
 
Ji 개발 리뷰 (신림프로그래머)
Ji 개발 리뷰 (신림프로그래머)Ji 개발 리뷰 (신림프로그래머)
Ji 개발 리뷰 (신림프로그래머)beom kyun choi
 
07 스레드스케줄링,우선순위,그리고선호도
07 스레드스케줄링,우선순위,그리고선호도07 스레드스케줄링,우선순위,그리고선호도
07 스레드스케줄링,우선순위,그리고선호도ssuser3fb17c
 
Blockchain 3rd smart contract programming
Blockchain 3rd smart contract programmingBlockchain 3rd smart contract programming
Blockchain 3rd smart contract programmingihpark92
 
세션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
 
7가지 동시성 모델 - 데이터 병렬성
7가지 동시성 모델 - 데이터 병렬성7가지 동시성 모델 - 데이터 병렬성
7가지 동시성 모델 - 데이터 병렬성HyeonSeok Choi
 
세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍
세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍
세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍Jay JH Park
 
세션3. geth 클라이언트 실습 및 모니터링과 시각화
세션3. geth 클라이언트 실습 및 모니터링과 시각화세션3. geth 클라이언트 실습 및 모니터링과 시각화
세션3. geth 클라이언트 실습 및 모니터링과 시각화Jay JH Park
 
5-5. html5 connectivity
5-5. html5 connectivity5-5. html5 connectivity
5-5. html5 connectivityJinKyoungHeo
 
이더리움의 현황, 한계점 및 개선노력
이더리움의 현황, 한계점 및 개선노력 이더리움의 현황, 한계점 및 개선노력
이더리움의 현황, 한계점 및 개선노력 Younghoon Moon
 
GCGC- CGCII 서버 엔진에 적용된 기술 (2) - Perfornance
GCGC- CGCII 서버 엔진에 적용된 기술 (2) - PerfornanceGCGC- CGCII 서버 엔진에 적용된 기술 (2) - Perfornance
GCGC- CGCII 서버 엔진에 적용된 기술 (2) - Perfornance상현 조
 
Jupyter notebok tensorboard 실행하기_20160706
Jupyter notebok tensorboard 실행하기_20160706Jupyter notebok tensorboard 실행하기_20160706
Jupyter notebok tensorboard 실행하기_20160706Yong Joon Moon
 
UML distilled 1장 스터디 발표 자료
UML distilled 1장 스터디 발표 자료UML distilled 1장 스터디 발표 자료
UML distilled 1장 스터디 발표 자료beom kyun choi
 
GCGC- CGCII 서버 엔진에 적용된 기술 (1)
GCGC- CGCII 서버 엔진에 적용된 기술 (1)GCGC- CGCII 서버 엔진에 적용된 기술 (1)
GCGC- CGCII 서버 엔진에 적용된 기술 (1)상현 조
 

What's hot (20)

[스프링 스터디 2일차] 서비스 추상화
[스프링 스터디 2일차] 서비스 추상화[스프링 스터디 2일차] 서비스 추상화
[스프링 스터디 2일차] 서비스 추상화
 
Startup JavaScript 6 - 함수, 스코프, 클로저
Startup JavaScript 6 - 함수, 스코프, 클로저Startup JavaScript 6 - 함수, 스코프, 클로저
Startup JavaScript 6 - 함수, 스코프, 클로저
 
Clean code appendix 1
Clean code appendix 1Clean code appendix 1
Clean code appendix 1
 
Startup JavaScript 4 - 객체
Startup JavaScript 4 - 객체Startup JavaScript 4 - 객체
Startup JavaScript 4 - 객체
 
함수적 사고 2장
함수적 사고 2장함수적 사고 2장
함수적 사고 2장
 
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 개발
 
Ji 개발 리뷰 (신림프로그래머)
Ji 개발 리뷰 (신림프로그래머)Ji 개발 리뷰 (신림프로그래머)
Ji 개발 리뷰 (신림프로그래머)
 
07 스레드스케줄링,우선순위,그리고선호도
07 스레드스케줄링,우선순위,그리고선호도07 스레드스케줄링,우선순위,그리고선호도
07 스레드스케줄링,우선순위,그리고선호도
 
Blockchain 3rd smart contract programming
Blockchain 3rd smart contract programmingBlockchain 3rd smart contract programming
Blockchain 3rd smart contract programming
 
세션1. block chain as a platform
세션1. block chain as a platform세션1. block chain as a platform
세션1. block chain as a platform
 
7가지 동시성 모델 - 데이터 병렬성
7가지 동시성 모델 - 데이터 병렬성7가지 동시성 모델 - 데이터 병렬성
7가지 동시성 모델 - 데이터 병렬성
 
세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍
세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍
세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍
 
세션3. geth 클라이언트 실습 및 모니터링과 시각화
세션3. geth 클라이언트 실습 및 모니터링과 시각화세션3. geth 클라이언트 실습 및 모니터링과 시각화
세션3. geth 클라이언트 실습 및 모니터링과 시각화
 
5-5. html5 connectivity
5-5. html5 connectivity5-5. html5 connectivity
5-5. html5 connectivity
 
이더리움의 현황, 한계점 및 개선노력
이더리움의 현황, 한계점 및 개선노력 이더리움의 현황, 한계점 및 개선노력
이더리움의 현황, 한계점 및 개선노력
 
GCGC- CGCII 서버 엔진에 적용된 기술 (2) - Perfornance
GCGC- CGCII 서버 엔진에 적용된 기술 (2) - PerfornanceGCGC- CGCII 서버 엔진에 적용된 기술 (2) - Perfornance
GCGC- CGCII 서버 엔진에 적용된 기술 (2) - Perfornance
 
Jupyter notebok tensorboard 실행하기_20160706
Jupyter notebok tensorboard 실행하기_20160706Jupyter notebok tensorboard 실행하기_20160706
Jupyter notebok tensorboard 실행하기_20160706
 
UML distilled 1장 스터디 발표 자료
UML distilled 1장 스터디 발표 자료UML distilled 1장 스터디 발표 자료
UML distilled 1장 스터디 발표 자료
 
GCGC- CGCII 서버 엔진에 적용된 기술 (1)
GCGC- CGCII 서버 엔진에 적용된 기술 (1)GCGC- CGCII 서버 엔진에 적용된 기술 (1)
GCGC- CGCII 서버 엔진에 적용된 기술 (1)
 

Viewers also liked

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

Viewers also liked (11)

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(audiopolicy_manager)
Android audio system(audiopolicy_manager)Android audio system(audiopolicy_manager)
Android audio system(audiopolicy_manager)
 
Surface flingerservice(서피스플링거서비스초기화)
Surface flingerservice(서피스플링거서비스초기화)Surface flingerservice(서피스플링거서비스초기화)
Surface flingerservice(서피스플링거서비스초기화)
 
Stagefright recorder part1
Stagefright recorder part1Stagefright recorder part1
Stagefright recorder part1
 
Android audio system(오디오 출력-트랙생성)
Android audio system(오디오 출력-트랙생성)Android audio system(오디오 출력-트랙생성)
Android audio system(오디오 출력-트랙생성)
 
Android audio system(audioflinger)
Android audio system(audioflinger)Android audio system(audioflinger)
Android audio system(audioflinger)
 
Android Audio & OpenSL
Android Audio & OpenSLAndroid Audio & OpenSL
Android Audio & OpenSL
 
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
Android Audio SystemAndroid Audio System
Android Audio System
 
Android audio system(audio_hardwareinterace)
Android audio system(audio_hardwareinterace)Android audio system(audio_hardwareinterace)
Android audio system(audio_hardwareinterace)
 

Similar to Surface flingerservice(서피스 상태 변경 jb)

Smc–state machinecompiler
Smc–state machinecompilerSmc–state machinecompiler
Smc–state machinecompilerDong Hyeun Lee
 
Half sync/Half Async
Half sync/Half AsyncHalf sync/Half Async
Half sync/Half Asyncscor7910
 
[Swift] Command
[Swift] Command[Swift] Command
[Swift] CommandBill Kim
 
Node.js and react
Node.js and reactNode.js and react
Node.js and reactHyungKuIm
 
오픈소스GIS 개론 과정 - OpenLayers 기초
오픈소스GIS 개론 과정 - OpenLayers 기초오픈소스GIS 개론 과정 - OpenLayers 기초
오픈소스GIS 개론 과정 - OpenLayers 기초HaNJiN Lee
 
Side Effect in Compose (Android Jetpack)
Side Effect in Compose (Android Jetpack)Side Effect in Compose (Android Jetpack)
Side Effect in Compose (Android Jetpack)SSLEE14
 
React Hooks 마법. 그리고 깔끔한 사용기
React Hooks 마법. 그리고 깔끔한 사용기React Hooks 마법. 그리고 깔끔한 사용기
React Hooks 마법. 그리고 깔끔한 사용기NAVER SHOPPING
 
Startup JavaScript 8 - NPM, Express.JS
Startup JavaScript 8 - NPM, Express.JSStartup JavaScript 8 - NPM, Express.JS
Startup JavaScript 8 - NPM, Express.JSCirculus
 
05.실행환경 교육교재(업무처리,연계통합)
05.실행환경 교육교재(업무처리,연계통합)05.실행환경 교육교재(업무처리,연계통합)
05.실행환경 교육교재(업무처리,연계통합)Hankyo
 
[143] Modern C++ 무조건 써야 해?
[143] Modern C++ 무조건 써야 해?[143] Modern C++ 무조건 써야 해?
[143] Modern C++ 무조건 써야 해?NAVER D2
 
[Swift] State
[Swift] State[Swift] State
[Swift] StateBill Kim
 
NDC11_슈퍼클래스
NDC11_슈퍼클래스NDC11_슈퍼클래스
NDC11_슈퍼클래스noerror
 
7가지 동시성 모델 - 3장. 함수형 프로그래밍
7가지 동시성 모델 - 3장. 함수형 프로그래밍7가지 동시성 모델 - 3장. 함수형 프로그래밍
7가지 동시성 모델 - 3장. 함수형 프로그래밍Hyunsoo Jung
 
[0312 조진현] good bye dx9
[0312 조진현] good bye dx9[0312 조진현] good bye dx9
[0312 조진현] good bye dx9진현 조
 
Effective c++(chapter 5,6)
Effective c++(chapter 5,6)Effective c++(chapter 5,6)
Effective c++(chapter 5,6)문익 장
 
Nodejs, PhantomJS, casperJs, YSlow, expressjs
Nodejs, PhantomJS, casperJs, YSlow, expressjsNodejs, PhantomJS, casperJs, YSlow, expressjs
Nodejs, PhantomJS, casperJs, YSlow, expressjs기동 이
 
#19.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
#19.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...#19.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
#19.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...탑크리에듀(구로디지털단지역3번출구 2분거리)
 

Similar to Surface flingerservice(서피스 상태 변경 jb) (20)

Smc–state machinecompiler
Smc–state machinecompilerSmc–state machinecompiler
Smc–state machinecompiler
 
Half sync/Half Async
Half sync/Half AsyncHalf sync/Half Async
Half sync/Half Async
 
[Swift] Command
[Swift] Command[Swift] Command
[Swift] Command
 
D2 Rain (2/2)
D2 Rain (2/2)D2 Rain (2/2)
D2 Rain (2/2)
 
Node.js and react
Node.js and reactNode.js and react
Node.js and react
 
오픈소스GIS 개론 과정 - OpenLayers 기초
오픈소스GIS 개론 과정 - OpenLayers 기초오픈소스GIS 개론 과정 - OpenLayers 기초
오픈소스GIS 개론 과정 - OpenLayers 기초
 
Side Effect in Compose (Android Jetpack)
Side Effect in Compose (Android Jetpack)Side Effect in Compose (Android Jetpack)
Side Effect in Compose (Android Jetpack)
 
React Hooks 마법. 그리고 깔끔한 사용기
React Hooks 마법. 그리고 깔끔한 사용기React Hooks 마법. 그리고 깔끔한 사용기
React Hooks 마법. 그리고 깔끔한 사용기
 
Startup JavaScript 8 - NPM, Express.JS
Startup JavaScript 8 - NPM, Express.JSStartup JavaScript 8 - NPM, Express.JS
Startup JavaScript 8 - NPM, Express.JS
 
Redux
ReduxRedux
Redux
 
05.실행환경 교육교재(업무처리,연계통합)
05.실행환경 교육교재(업무처리,연계통합)05.실행환경 교육교재(업무처리,연계통합)
05.실행환경 교육교재(업무처리,연계통합)
 
스프링 마이바티스 무료강의 / 챕터5. 스프링 트랜잭션(Spring Transaction)
스프링 마이바티스 무료강의 / 챕터5. 스프링 트랜잭션(Spring Transaction)스프링 마이바티스 무료강의 / 챕터5. 스프링 트랜잭션(Spring Transaction)
스프링 마이바티스 무료강의 / 챕터5. 스프링 트랜잭션(Spring Transaction)
 
[143] Modern C++ 무조건 써야 해?
[143] Modern C++ 무조건 써야 해?[143] Modern C++ 무조건 써야 해?
[143] Modern C++ 무조건 써야 해?
 
[Swift] State
[Swift] State[Swift] State
[Swift] State
 
NDC11_슈퍼클래스
NDC11_슈퍼클래스NDC11_슈퍼클래스
NDC11_슈퍼클래스
 
7가지 동시성 모델 - 3장. 함수형 프로그래밍
7가지 동시성 모델 - 3장. 함수형 프로그래밍7가지 동시성 모델 - 3장. 함수형 프로그래밍
7가지 동시성 모델 - 3장. 함수형 프로그래밍
 
[0312 조진현] good bye dx9
[0312 조진현] good bye dx9[0312 조진현] good bye dx9
[0312 조진현] good bye dx9
 
Effective c++(chapter 5,6)
Effective c++(chapter 5,6)Effective c++(chapter 5,6)
Effective c++(chapter 5,6)
 
Nodejs, PhantomJS, casperJs, YSlow, expressjs
Nodejs, PhantomJS, casperJs, YSlow, expressjsNodejs, PhantomJS, casperJs, YSlow, expressjs
Nodejs, PhantomJS, casperJs, YSlow, expressjs
 
#19.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
#19.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...#19.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
#19.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_국비지원IT학원/실업자/재직자환급교육/자바/스프링/...
 

Surface flingerservice(서피스 상태 변경 jb)

  • 2. 1.서피스 상태 변경 요청(서비스 클라이언트) 1.서피스 추가/삭제 2.개별 레이어 상태 변경(크기,zorder) 3.프레임 상태 변경(orientation변경) 1.서피스 추가/삭제 서피스가 추가 또는 삭제 되면 전역 레이어 목록이 변경되어야 한다. 이를 위해서 추가 또는 삭제 시에 mTransactionFlags 에 eTransactionNeeded을 설정하고 Vsync를 발생 시킨다. sp<ISurface> SurfaceFlinger::createSurface(…) { normalLayer = createNormalSurface(client, d, w, h, flags, format); setTransactionFlags(eTransactionNeeded); uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) { } uint32_t old = android_atomic_or(flags, &mTransactionFlags); if ((old & flags)==0) { // wake the server up status_t SurfaceFlinger::removeSurface() signalTransaction(); { } … return old; setTransactionFlags(eTransactionNeeded); } } void SurfaceFlinger::signalTransaction() { mEventQueue.invalidate(); MessageQueue에서 Vsync 발생 시킴. } 2
  • 3. 1.서피스 상태 변경 요청(서비스 클라이언트) 2.개별 레이어 상태 변경(크기,zorder) -레이어(서피스) 상태 변경은 트랜잭션 시작과 종료 사이에만 가능하다. -다수의 상태 변경 함수를 동시에 중첩하여 설정 할 수 있다. ex)fade out 의 기능과 같이 메뉴가 투명해 지면서 축소가 되고 위치가 변경이 되는 경우 “투명,축소,위치변경”이 동시에 실행 된다.  레이어의 상태를 변경할 때 클라이언트와 서버의 동작 3
  • 4. 1.서피스 상태 변경 요청(서비스 클라이언트) Bootanimation.cpp status_t BootAnimation::readyToRun() { sp<SurfaceControl> control = session()->createSurface(getpid(), 0, dinfo.w, dinfo.h, PIXEL_FORMAT_RGBA_8888); SurfaceComposerClient::openGlobalTransaction(); transaction 시작 control->setLayer(0x40000000); 서피스의 zorder 변경 SurfaceComposerClient::closeGlobalTransaction(); transaction 종료 } 1)Transaction 시작 status_t SurfaceComposerClient:: openGlobalTransaction() {  ICS 이후 부터 특별한 동작은 하지 않음. } 2) 서피스의 zorder 변경 Surface.cpp status_t SurfaceControl::setLayer(int32_t layer) { status_t err = validate(); if (err < 0) return err; const sp<SurfaceComposerClient>& client(mClient); return client->setLayer(mToken, layer);  상태 변경의 대상이 되는 레이어를 알려 주기 위해 mToken을 넘겨 준다. } (mToken은 SurfaceControl 생성자에서 생성된 layer를 가리키게 된다.) 4
  • 5. 1.서피스 상태 변경 요청(서비스 클라이언트) SurfaceComposerClient.cpp status_t SurfaceComposerClient::setLayer(SurfaceID id, int32_t z) { return getComposer().setLayer(this, id, z); } status_t Composer::setLayer(const sp<SurfaceComposerClient>& client, SurfaceID id, int32_t z) { layer_state_t* s = getLayerStateLocked(client, id); 서피스의 상태 변경 정보를 저장할 layer_state_t를 생성한다. s->what |= ISurfaceComposer::eLayerChanged; s->z = z; layer state 구조체에 what(상태 변경 이벤트),z(zoder값)을 저장한다. return NO_ERROR; } layer_state_t* Composer::getLayerStateLocked(const sp<SurfaceComposerClient>& client, SurfaceID id) { ComposerState s; s.client = client->mClient; 서피스 클라이언트 리코트 서비스에 대한 Proxy(ISurfaceComposerClient)를 저장한다. s.state.surface = id; 상태가 변경된 서피스의 지역 식별자를 저장한다. ssize_t index = mStates.indexOf(s); if (index < 0) { // we don't have it, add an initialized layer_state to our list index = mStates.add(s);  상태가 변경된 layer_state_t 구조체를 mStates 에 넣는다. 이 mStates 는 서피스 플링거에게 전달되어 서피스 상태 변경에 사용된다. } ComposerState* const out = mStates.editArray(); return &(out[index].state); } 5
  • 6. 1.서피스 상태 변경 요청(서비스 클라이언트) 3. transaction 종료 SurfaceComposerClient.cpp static void closeGlobalTransaction(bool synchronous) { Composer::getInstance().closeGlobalTransactionImpl(synchronous); } void Composer::closeGlobalTransactionImpl(bool synchronous) { sp<ISurfaceComposer> sm(getComposerService()); Vector<ComposerState> transaction; transaction = mStates; 애플리케이션에서 발생한 상태 변경 이벤트를 mStates 변수에 발생한 순서대로 저장해 두고, 서피스 플링거에게 전달 한다. mStates.clear(); mStates 배열을 초기화 한다. orientation = mOrientation; mOrientation = ISurfaceComposer::eOrientationUnchanged; sm->setTransactionState(transaction, orientation, flags); 서비스 플링거에게 서피스들의 상태 변경 정보를 저장한 transaction 과 출력 방향을 저장한 orientation을 전달 한다. } 6
  • 7. 2.서피스 상태 변경 (서비스 서버) 서피스 플링거 서비스는 레이어의 상태 변경이 발생하면 상태 변경 이벤트의 종류에 따라 처리한다. 상태 변경 동작 값이 설정되는 경우 이벤트 eTransactionNeeded 전역 레이어 목록에 1) setOrientation: 회전 방향 변경 포함된 2) Freeze: 디스플레이가 갱신되지 않도록 만듦. 모든 레이어의 무효화 3) Unfreeze:freeze상태를 해지 영역을 재계산 4) createSurface:레이어 생성 5) destroySurface:레이어 삭제 6) setLayer:레이어의 높이 값 변경 eTraversalNeeded 상태가 변경된 레이어 1) setPosition:위치 결정 의 무효화 영역을 재계 2) setLayer:레이어의 높이 값 변경 산 3) setSize: 크기 번경 4) setAlpha: 개별 레이어 전체의 투명도 변경 5) setMatrix: 레이어 메트릭스 변경 6) setTransparentRegionHint: 레이어 반투명 영역 변경 7) segFlags:레이어 가시성 변경(hide,show) 7
  • 8. 2.서피스 상태 변경 (서비스 서버) void SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state, int orientation, uint32_t flags) { if (mCurrentState.orientation != orientation) {  이전 설정된 출력 방향과 다르면 mCurrentState.orientation = orientation; 현재 출력 방향을 설정하고 transactionFlags |= eTransactionNeeded; 전체 레이어의 무효화 영역을 설정하기 위해 eTransactionNeeded 설정함. } const size_t count = state.size(); for (size_t i=0 ; i<count ; i++) { const ComposerState& s(state[i]); sp<Client> client( static_cast<Client *>(s.client.get()) ); 변경 요청이 발생한 서피스 클라이언트를 획득한다. transactionFlags |= setClientStateLocked(client, s.state); } if (transactionFlags) { setTransactionFlags(transactionFlags);  변경된 플래그 값을 mTransactionFlags 에 반영하고 signalTransaction 를 호출해서 합성 이벤트를 발생시킨다.(mEventQueue.invalidate()) if (flags & eSynchronous) { mTransationPending = true;  모든 레이어의 가로,세로 값이 변경 될때 까지 기다리기 위한 변수 } while (mTransationPending) { status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 레이어의 크기가 재설정 될 동안 기다린다. mTransationPending = false; break; } } 8
  • 9. 2.서피스 상태 변경 (서비스 서버) uint32_t SurfaceFlinger::setClientStateLocked(const sp<Client>& client, const layer_state_t& s) { if (what & eLayerChanged) { ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); if (layer->setLayer(s.z)) { mCurrentState.layersSortedByZ.removeAt(idx); 전역 레이어 목록에서 해당 레이어 삭제 mCurrentState.layersSortedByZ.add(layer); 다시 추가. flags |= eTransactionNeeded|eTraversalNeeded; zorder 변경은 개별 레이어의 상태 변경 (eTraversalNeeded) 및 전역 레이어 목록 변경(eTransactionNeeded) 이 필요함. } if (what & eVisibilityChanged) { if (layer->setFlags(s.flags, s.mask)) flags |= eTraversalNeeded; 가시성 변경은 “개별 레이어 상태 변경”에 해당함으로 서피스 플링거의 mTransactionFlags 변수에 eTraversalNeeded 값 설정. } } Layerbase.cpp bool LayerBase::setFlags(uint8_t flags, uint8_t mask) { const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask); Layerbase의 mCurrentState. 변수에 변경할 속성을 set한다. mCurrentState.sequence++; 서피스의 상태가 변경되었다는 사실을 mCurrentState.의 sequence를 하나 증가 시켜 표시. mCurrentState.flags = newFlags; return true; } 9
  • 10. 3.윈도우 속성 변경(서비스 클라이언트) 서피스 텍스쳐에 설정된 안드로이드 네이티브 윈도우의 속성값을 변경.  윈도우 속성 변경 예 ex)setBufferCount() native_window_set_usage 그래픽 버퍼의 속성을 설정 native_window_set_crop 최종적으로 디스플레이에 출력 될 화면의 크기를 결정 함. native_window_set_buffer_count 그래픽 버퍼의 개수 지정 native_window_set_buffers_transform 윈도우의 출력 방향 결정 native_window_set_buffers_timestamp 윈도우의 화면 출력을 요청하면 서버에서는 출력 요청이 발생한 시간 값을 저장 native_window_api_connect 윈도우의 사용을 위해 윈도우와 어플리케이션을 연결함. 10
  • 11. 3.윈도우 속성 변경(서비스 클라이언트) Ex)Cameraservice의 setPreviewWindow status_t CameraService::Client::setPreviewWindow(const sp<IBinder>& binder, const sp<ANativeWindow>& window) { if (window != 0) { result = native_window_api_connect(window.get(), NATIVE_WINDOW_API_CAMERA); } Window.h static inline int native_window_api_connect(struct ANativeWindow* window, int api) { return window->perform(window, NATIVE_WINDOW_API_CONNECT, api); } Surfacetextureclient.cpp int SurfaceTextureClient::perform(int operation, va_list args) { case NATIVE_WINDOW_API_CONNECT: res = dispatchConnect(args); break; } int SurfaceTextureClient::dispatchConnect(va_list args) { int api = va_arg(args, int); return connect(api); } int SurfaceTextureClient::connect(int api) { int err = mSurfaceTexture->connect(api, &output); output.deflate(&mDefaultWidth, &mDefaultHeight, &mTransformHint, &numPendingBuffers); } 11
  • 12. 3.윈도우 속성 변경(서비스 서버) BufferQueue.cpp status_t BufferQueue::connect(int api, QueueBufferOutput* output) { switch (api) { case NATIVE_WINDOW_API_EGL: case NATIVE_WINDOW_API_CPU: case NATIVE_WINDOW_API_MEDIA: case NATIVE_WINDOW_API_CAMERA: mConnectedApi = api; output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint,mQueue.size()); 인자로 넘어온 output에 mDefaultWidth, mDefaultHeight 값 들을 넣는다. 이 값들은 SurfaceTextureclient의 connect함수에서 deflate로 다시 값들을 가져 간다. } break; default: err = -EINVAL; break; } mBufferHasBeenQueued = false; return err; } 12
  • 13. 4.그래픽 버퍼 요청(서비스 클라이언트)  그래픽 버퍼 획득 과정 13
  • 14. 4.그래픽 버퍼 요청(서비스 클라이언트) Ex)그래픽 버퍼 요청 OmxCodec.cpp status_t OMXCodec::pushBlankBuffersToNativeWindow() { … for (int i = 0; i < numBufs + 1; i++) { err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &anb); -----(1) sp<GraphicBuffer> buf(new GraphicBuffer(anb, false)); -----(2) err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); -----(3) *img = 0; 가상 주소의 내용을 0으로 채운다(blank buffer) err = buf->unlock();  그래픽 버퍼의 사용완료를 그래픽 HAL에게 알림. err = mNativeWindow->queueBuffer(mNativeWindow.get(),buf->getNativeBuffer()); 수정된 그래픽 버퍼를 출력 요청 한다. } 1) mNativeWindow->dequeueBuffer(mNativeWindow.get(), &anb); dequeueBuffe 는 ANativeWindow 를 상속 받은 SurfaceTextureClient 의 hook_dequeubuufer에 매핑되어 있다. int SurfaceTextureClient::hook_dequeueBuffer(ANativeWindow* window, ANativeWindowBuffer** buffer) { SurfaceTextureClient* c = getSelf(window); return c->dequeueBuffer(buffer);  c는 SurfaceTextureClient 를 가리 킴. } int SurfaceTextureClient::dequeueBuffer(android_native_buffer_t** buffer) { status_t result = mSurfaceTexture->dequeueBuffer(&buf, reqW, reqH, mReqFormat, mReqUsage); -----(1-1) sp<GraphicBuffer>& gbuf(mSlots[buf].buffer); if ((result & ISurfaceTexture::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) { result = mSurfaceTexture->requestBuffer(buf, &gbuf);} -----(1-2) *buffer = gbuf.get(); return OK; } 14
  • 15. 4.그래픽 버퍼 요청(서비스 클라이언트) (1-1) mSurfaceTexture->dequeueBuffer(&buf, reqW, reqH, mReqFormat, mReqUsage); - mSurfaceTexture 는 ISurfaceTexture를 가리킨다. 이를 통해 BufferQueue의 dequeueBuffer를 호출한다. - Buf:호출 시 그래픽 버퍼의 번호를 저장할 정수형 변수, 이 정수형 변수를 사용할 그래픽 버퍼의 index를 가리킨다. - reqW, reqH: 생성할 그래픽 버퍼의 가로,세로 크기  그래픽 버퍼 요청 시 클라이언트와 서버의 상호 동작 15
  • 16. 4.그래픽 버퍼 요청(서비스 클라이언트) (1) 애플리케이션은 ISurfaceTexture 서비스 프록시의 dequeueBuffer()를 호출하여 그래픽 버펴를 요청한다. (2) 서버 측에서는 BufferSlot 배열에서 FREE 상태의 슬롯을 찾는다. 그런 후 해당 배열의 상태를 DEQUEUED로 변경한다. (3) Bufferslot 배열의 인덱스를 반환한다. 배열의 인덱스의 그래픽 버퍼가 없어면 requestbuffer로 할당된 그래픽 버퍼를 요청한다 (4) 애플리케이션이 렌더링이 완료된 그래픽 버퍼를 queuebuffer()를 이용하여 서버측에 전달한다. (5) 서퍼에서는 버퍼 큐(mQueue)에 해당 그래픽 버퍼의 인덱스를 넣는다. 그런 후 해당 배열의 상태를 QUEUED로 변경한다. (1-2) mSurfaceTexture->requestBuffer(buf, &gbuf); if ((result & ISurfaceTexture::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) { 해당 그래픽 버퍼 번호에 처음으로 그래픽 번호를 요청하거나, 요청한 버퍼의 크기나 픽셀 포맷 등이 기존에 할당된 버퍼와 다른 경우 서버측에게 새로 할당 된 그래픽 버퍼의 전달을 요청한다. (이 경우 dequeueBuffer함수는 BUFFER_NEEDS_REALLOCATION를 반환 함.) result = mSurfaceTexture->requestBuffer(buf, &gbuf); *buffer = gbuf.get(); 생성된 그래픽 버퍼를 애플리케이션으로 반환 함. return OK; } ISurfaceTexture.cpp virtual status_t requestBuffer(int bufferIdx, sp<GraphicBuffer>* buf) { Parcel data, reply; data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor()); data.writeInt32(bufferIdx); 요청할 버퍼의 index status_t result =remote()->transact(REQUEST_BUFFER, data, &reply); 서버에 REQUEST_BUFFER 요청 보냄. 서버는 해당하는 인덱스의 BufferSlot 배열에 GraphicBuffer 객체를 생성한다. bool nonNull = reply.readInt32(); if (nonNull) { *buf = new GraphicBuffer(); 서피스 텍스쳐 클라이언트에도 GraphicBuffer를 생성한다. reply.read(**buf); 서버영역에서 생성된 그래픽 버퍼의 정보를 방금 생성한 GraphicBuffer 에 채워 넣는다. 이렇게 함으로써 서버에서 생성된 그래픽 버퍼와 동일한 값을 클라이언트에서도 유지하게 된다. } result = reply.readInt32(); return result; } 16
  • 17. 4.그래픽 버퍼 요청(서비스 클라이언트) (2) sp<GraphicBuffer> buf(new GraphicBuffer(anb, false)); GraphicBuffer::GraphicBuffer( ANativeWindowBuffer(anb)를 가지는 GraphicBuffer를 생성한다. ANativeWindowBuffer* buffer, bool keepOwnership) { (3) err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); width = buffer->width; 애플리케이션에서 버퍼의 사용을 위해서는 접근 가능한 그래픽 버퍼의 가상주소를 height = buffer->height; 필요로 한다. stride = buffer->stride; 그래픽 버퍼의 가상주소를 획득하기 위해 GraphicBuffer class의 lock함수가 format = buffer->format; 불려진다. usage = buffer->usage; handle = buffer->handle; status_t GraphicBuffer::lock(uint32_t usage, void** vaddr) } { const Rect lockBounds(width, height); status_t res = lock(usage, lockBounds, vaddr); //vaddr: 가상주소를 저장할 포인터 return res; } status_t GraphicBuffer::lock(uint32_t usage, const Rect& rect, void** vaddr) { status_t res = getBufferMapper().lock(handle, usage, rect, vaddr);  getBufferMapper 함수를 이용하여 전달된 그래픽 버퍼에 대한 가상 주소를 반환한다. return res; } 17
  • 18. 4.그래픽 버퍼 생성(서비스 서버) 서비스 서버 측에서 그래픽 버퍼를 할당하는 과정은 1)버퍼 슬롯의 개수 확인 2)버퍼 슬롯의 인덱스 획득 3)그래픽 버퍼 할당 으로 구분된다. 1)버퍼 슬롯의 개수 확인 status_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h, uint32_t format, uint32_t usage) { while (tryAgain) { const int minBufferCountNeeded = mSynchronousMode ? mMinSyncBufferSlots : mMinAsyncBufferSlots; 동기식, 비동기식에 따라 필요한 최소 버퍼수를 minBufferCountNeeded 에 넣는다. const bool numberOfBuffersNeedsToChange = !mClientBufferCount && ((mServerBufferCount != mBufferCount) || (mServerBufferCount < minBufferCountNeeded));  setBufferCount 함수로 버퍼 개수를 설정하거나(mClientBufferCount 변경), 서버에서 설정한 버퍼의 수가 BufferQueue에 설정된 버퍼의 수와 다르거나 (mServerBufferCount != mBufferCount), 서버에서 설정한 버퍼의 수가 설정 가능한 최소 버퍼 수보다 작을 경우 (mServerBufferCount < minBufferCountNeeded numberOfBuffersNeedsToChange를 true로 setting한다. 이 의미는 버퍼의 수를 수정하겠다는 의미 이다. if (!mQueue.isEmpty() && numberOfBuffersNeedsToChange) {  버퍼의 수 변경이 필요하지만, 출력 대기 큐(mQueue)에 출력 요청한 인덱스가 남아 있다면, mDequeueCondition.wait(mMutex); 출력 대기 큐가 모두 소비 될 때 까지 기다린다. continue; } if (numberOfBuffersNeedsToChange) { freeAllBuffersLocked();  mSlot의 모든 배열을 초기화 한다.(mSlot에 할당된 모든 그래픽 버퍼가 해지 된다.) mBufferCount = mServerBufferCount; 서버에서 요청한 버퍼 수를 mBufferCount 에 저장한다. if (mBufferCount < minBufferCountNeeded) mBufferCount = minBufferCountNeeded; 버퍼 최소값보다 작으면 버퍼 최소 값으로 저장 한다. returnFlags |= ISurfaceTexture::RELEASE_ALL_BUFFERS; SurfaceTextureClient의 dequeueBuffer함수는 서버에서 RELEASE_ALL_BUFFERS 가 반환되면 freeAllBuffers를 불러 클라이언트에 매핑된 그래픽 버퍼를 모두 해지 한다.} 18
  • 19. 4.그래픽 버퍼 생성(서비스 서버) 2)사용 가능한 버퍼 슬롯의 인덱스 획득 status_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h, uint32_t format, uint32_t usage) { while (tryAgain) { … found = INVALID_BUFFER_SLOT; foundSync = INVALID_BUFFER_SLOT; for (int i = 0; i < mBufferCount; i++) { const int state = mSlots[i].mBufferState; if (state == BufferSlot::FREE) 버퍼의 상태가 free인 값을 검색하여 인덱스를 획득한다. { foundSync = i; found = i; } tryAgain = found == INVALID_BUFFER_SLOT; if (tryAgain) { mDequeueCondition.wait(mMutex); 사용 가능한 버퍼가 없는 경우, FREE인 상태의 버퍼가 생길 때 까지 기다린다. } *outBuf = found; dequeueBuffer() 함수 호출 시 전달 된 인자에 검색에 성공한 BufferSlot 배열의 인덱스를 저장하여, 클라이언트 측으로 전달한다. … 19
  • 20. 4.그래픽 버퍼 생성(서비스 서버) 3)그래픽 버퍼 할당 status_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h, uint32_t format, uint32_t usage) { while (tryAgain) { … const sp<GraphicBuffer>& buffer(mSlots[buf].mGraphicBuffer); 검색된 인덱스의 GraphicBuffer 객체의 참조를 획득한다. 이전에 할당된 그래픽 버퍼가 있다면 재사용이 가능한다. mSlots[buf].mBufferState = BufferSlot::DEQUEUED; 검색한 슬롯의 상태를 DEQUEUED 로 변경한다. if ((buffer == NULL) || needNewBuffer(currentGeometry, requiredGeometry, updatedGeometry) || ((uint32_t(buffer->usage) & usage) != usage)) 그래픽 버퍼를 새로 생성해야 하면(처음 생성 or size 변경) { sp<GraphicBuffer> graphicBuffer( mGraphicBufferAlloc->createGraphicBuffer( w, h, format, usage, &error)); 그래픽 버퍼를 생성한다. mGraphicBufferAlloc은 IGraphicBufferAlloc 서비스 프락시를 가리킨다. mSlots[buf].mGraphicBuffer = graphicBuffer; 생성한 그래픽 버퍼를 해당 슬롯의 mGraphicBuffer 에 저장한다. returnFlags |= ISurfaceTexture::BUFFER_NEEDS_REALLOCATION; 새롭게 할당된 버퍼가 있을 경우 설정하는 value이다. 클라이언트 측에서는 BUFFER_NEEDS_REALLOCATION 이 전달되면 ISurfaceTexture의 requestBuffer() 함수를 호출하여 생성된 그래픽 버퍼를 전달 받는다. } SurfaceFlinger.cpp sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage, status_t* error) { sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage, mBufferSize)); status_t err = graphicBuffer->initCheck(); return graphicBuffer; } 20
  • 21. 4.그래픽 버퍼 생성(서비스 서버) GraphicBuffer.cpp GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h, PixelFormat reqFormat, uint32_t reqUsage, uint32_t bufferSize) : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()), mInitCheck(NO_ERROR), mIndex(-1) { mInitCheck = initSize(w, h, reqFormat, reqUsage, bufferSize); }  mOwner: 그래픽 버퍼의 메모리에 대한 소유자 -ownNone: 애플리케이션 영역에서 그래픽 버퍼가 생성될 때 할당 됨. 하지만 requestBuffer() 함수를 호출하여 그래픽 버퍼를 전달 받을 때 이 값은 ownHandle 로 변경 됨. -ownHandle: 클라이언트에서 사용할 그래픽 버퍼의 경우. -ownData: 서버에서 사용할 그래픽 버퍼의 경우  mBufferMapper: 그래픽 버퍼의 메모리 할당 후 애플리케이션에서 매핑 할 때 사용하는 GraphicBufferMapper 클래스 객체 저장. 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);  GraphicBufferAllocator 클래스의 alloc함수를 호출함. return err; GraphicBufferAllocator:: } GraphicBufferAllocator(): mAllocDev(0) { status_t GraphicBufferAllocator::alloc(…) hw_get_module( { GRALLOC_HARDWARE_MODULE_ID, err = mAllocDev->alloc(mAllocDev, w, h, format, usage, handle, stride); &module); 그래픽 할당 HAL의 alloc 함수를 호출 한다. if (err == 0) { } gralloc_open(module, &mAllocDev); } } 21
  • 22. 4.그래픽 버퍼 생성(서비스 서버) dequeueBuffer 의 result가 BUFFER_NEEDS_REALLOCATION 일경우 mSurfaceTexture->requestBuffer를 호출하여 BufferQueue 의 requestBuffer를 부른다. ISurfaceTexture.cpp status_t BnSurfaceTexture::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { switch(code) { case REQUEST_BUFFER: { CHECK_INTERFACE(ISurfaceTexture, data, reply); int bufferIdx = data.readInt32(); sp<GraphicBuffer> buffer; int result = requestBuffer(bufferIdx, &buffer); reply->writeInt32(buffer != 0); if (buffer != 0) { reply->write(*buffer); 반환된 그래픽 버퍼를 바인더에 쓴다.  이렇게 함으로써 서피스 플링거 영역에 생성된 그래픽 버퍼와 같은 값을 가진 GraphicBuffer 객체를 어플리케이션 영역에 생성 할 수 있게 된다. } reply->writeInt32(result); return NO_ERROR; } break; } BufferQueue.cpp status_t BufferQueue::requestBuffer(int slot, sp<GraphicBuffer>* buf) { *buf = mSlots[slot].mGraphicBuffer; 클라이언트로 부터 전달받은 인덱스에 해당하는 그래픽 버퍼를 GraphicBuffer 에 저장하여 반환한다. return NO_ERROR; } 22
  • 23. 참고.그래픽 버퍼 요청 /생성 과정 Application SurfaceTextureClient BufferQueue 1 2 SurfaceTextureClient BufferQueue에 요청 버퍼 요청 에 요청 버퍼 요청 (dequeubuffer) (dequeubuffer) 0 mSlot[0] 0 mSlot[0] D 9 4 전달 받은 1 mSlot[1] 찾은 FREE Slost의 1 mSlot[1] D GraphicBuffer를 Index를 return함. 사용하기 위해 2 mSlot[2] 2 mSlot[2] F 가상주소를 Mapping 후 … … 그래픽 버퍼를 사용한다. 5 Requestbuffer를 호출해서 할당된 그래픽 버퍼를 전달 받음 Requestbuffer를 3 Status가 FREE인 slot 6 호출시 클라이언트 측에 을 찾고 그래픽 버퍼 빈 GraphicBuffer 를 생성 할당 함. GraphicBuffer GraphicBuffer GraphicBuffer 8 7 그래픽 버퍼 그래픽 버퍼 그래픽 버퍼 클라이언트 측의 서버에서 생성된 GraphicBuffer를 동일한 그래픽 버퍼를 Application에서 사용하기 클라이언트 측의 GraphicBuffer 위해서 전달 한다. 로 읽어 옴. 23
  • 24. 참고자료  안드로이드 미디어 프레임워크 –”개발자가 행복한 세상”  Goolge Jelly bean Source 24