SlideShare ist ein Scribd-Unternehmen logo
1 von 14
SurfaceFlingerService
(서피스 상태 변경 및 출력 요청)




                           박철희

                      1
화면 출력 요청 전 과정




                2
1.서피스 상태 변경 -서피스 추가/삭제

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

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

    layer = createPushBuffersSurface(client, d, w, h, flags);

    setTransactionFlags(eTransactionNeeded);

}
                                                           uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
status_t SurfaceFlinger::removeSurface()                   {
{                                                             uint32_t old = android_atomic_or(flags, &mTransactionFlags);
   …                                                          if ((old & flags)==0) { // wake the server up
   setTransactionFlags(eTransactionNeeded);                       signalEvent();
}                                                             }
                                                              return old;
                                                           }




                                                                                                                 3
1.서피스 상태 변경 종류-개별 레이어 상태 변경

2.개별 레이어 상태 변경(크기,zorder)
  -레이어(서피스) 상태 변경은 트랜잭션 시작과 종료 사이에만 가능하다.
  -다수의 상태 변경 함수를 동시에 중첩하여 설정 할 수 있다.
   ex)fade out 의 기능과 같이 메뉴가 투명해 지면서 축소가 되고 위치가 변경이 되는 경우
     “투명,축소,위치변경”이 동시에 실행 된다.
Bootanimation.cpp
status_t BootAnimation::readyToRun()
{
 sp<SurfaceControl> control = session()->createSurface(getpid(), 0, dinfo.w, dinfo.h, PIXEL_FORMAT_RGBA_8888);
   session()->openTransaction();  transaction 시작
   control->setLayer(0x40000000); 서피스의 zorder 변경
   session()->closeTransaction();  transaction 종료
}

1)Transaction 시작
status_t SurfaceComposerClient::openTransaction()
{
   mTransactionOpen++; open된 transaction을 나타내는 mTransactionOpen을 1 증가 시킴.
}

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)
{
   layer_state_t* s = lockLayerState(id);
   dummy layer state 구조체를 생성하고 return 받는다.
   s->what |= ISurfaceComposer::eLayerChanged;
   s->z = z;
   dummy layer state 구조체에 what(상태 변경 이벤트),z(zoder값)을 저장한다.
   unlockLayerState();
   return NO_ERROR;
}

layer_state_t* SurfaceComposerClient::lockLayerState(SurfaceID id)
{
   s = get_state_l(id);
   if (!s) mLock.unlock();
   return s;
}

layer_state_t* SurfaceComposerClient::get_state_l(SurfaceID index)
{
   layer_state_t& dummy(*mPrebuiltLayerState);
   mPrebuiltLayerState는 onFirstRef에서 만들어진 dummy layer state 구조체
   dummy.surface = index; dummy state 구조체에 상태 변경 대상의 layer의 index를 대입
   ssize_t i = mStates.indexOf(dummy);
   if (i < 0) {
       // we don't have it, add an initialized layer_state to our list
       i = mStates.add(dummy); mStates 에 dummy 구조체 추가. 이 mStates의 정보는 SurfaceFlinger쪽으로 전달 됨.
   }
   return mStates.editArray() + i;  추가된 dummy 구조체를 return
}

                                                                                       5
1.서피스 상태 변경 종류- 개별 레이어 상태 변경
3. transaction 종료
SurfaceComposerClient.cpp
status_t SurfaceComposerClient::closeTransaction()
{
   if (mTransactionOpen >= 2) {
        transcation이 2개 이상일 경우에는 서피스 플링거에게 상태 변경을 요청하지 않고, mTransactionOpen만 1 감소
          시키고 return 시킴(빈번한 transaction 처리를 방지하기 위해)
       mTransactionOpen--;
       return NO_ERROR;
   }

    mTransactionOpen = 0;
    const ssize_t count = mStates.size();
    if (count) {
        mClient->setState(count, mStates.array());
        mStates 에 추가된 dummy layer 구조체를 인자로 서피스 클라이언트의 setState함수를 호출 함.
        mStates.clear();
    }
    return NO_ERROR;
}




status_t Client::setState(int32_t count, const layer_state_t* states)
{
   return mFlinger->setClientState(this, count, states);
}




                                                                            6
1.서피스 상태 변경 종류- 개별 레이어 상태 변경


status_t SurfaceFlinger::setClientState(const sp<Client>& client, int32_t count,const layer_state_t* states)
{
   if (what & eLayerChanged) {
           ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
           if (layer->setLayer(s.z)) {
               mCurrentState.layersSortedByZ.removeAt(idx);
               mCurrentState.layersSortedByZ.add(layer);
               // we need traversal (state changed) AND transaction (list changed)
               flags |= eTransactionNeeded|eTraversalNeeded;
               zorder 변경은 개별 레이어의 상태 변경 (eTraversalNeeded) 및 전역 레이어 목록 변경(eTransactionNeeded)
                 이 필요함.
                    }

      if (flags) {
        setTransactionFlags(flags); surfaceflinger의 threadloop으로 signal을 보내서 상태 변경 처리를 한다.
  }




                                                                                                 7
1.서피스 상태 변경 종류-프레임 상태 변경

3.프레임 상태 변경(orientation변경)
  -전역 레이어 목록에 있는 모든 레이어를 회전 각도에 맞게 재 계산해야 함.

int SurfaceComposerClient::setOrientation(DisplayID dpy, int orientation, uint32_t flags)
{
   sp<ISurfaceComposer> sm(getComposerService());
   return sm->setOrientation(dpy, orientation, flags);
}

int SurfaceFlinger::setOrientation(DisplayID dpy, int orientation, uint32_t flags)
{
   if (mCurrentState.orientation != orientation) {  현재 상태 값과 다를 때에만 재 계산 함.
        mCurrentState.orientation = orientation; mCurrentState와 mDrawingState의 orientation을 비교
        setTransactionFlags(eTransactionNeeded);  전역 레이어 목록 변경
        mTransactionCV.wait(mStateLock);  다른 레이어가 변경할 때 까지 기다림.
     }

}

Surfaceflinger의 threadloop에서 transaction을 처리하기 위한 handleTransactionLocked에서 commitTransaction를 호출 함.
void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
{
  commitTransaction();
}

void SurfaceFlinger::commitTransaction()
{
  mTransactionCV.broadcast();  setOrientation에서 기다리고 있는 conditionlock에게 signal 보냄.
}

                                                                                                  8
2.그래픽 버퍼 출력 요청
Ex)Cameraservice의 preview 출력

void CameraService::Client::handlePreviewData(const sp<IMemory>& mem)
{
  ssize_t offset;
  size_t size;
  sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);

    if (!mUseOverlay) {
        if (mSurface != 0) {
            mSurface->postBuffer(offset);
        }
    }
}

void LayerBuffer::postBuffer(ssize_t offset)
{
     source->postBuffer(offset);
}

void LayerBuffer::BufferSource::postBuffer(ssize_t offset)
{
  buffers = mBufferHeap;
  sp<Buffer> buffer;
  if (buffers.heap != 0) {
      buffer = new LayerBuffer::Buffer(buffers, offset, mBufferSize);
      1.offset에 해당하는 메모리 영역을 copybit을 이용할 수 있는 Nativebuffer에 저장
      setBuffer(buffer);2.BufferSource객체의 mBuffer에 생성된 buffer class를 저장한다.
      mLayer.invalidate(); 3.서피스 플링거에게 출력 요청 함.
  }


                                                                              9
2.그래픽 버퍼 출력 요청

1.offset에 해당하는 메모리 영역을 copybit을 이용할 수 있는 Nativebuffer에 저장
buffer = new LayerBuffer::Buffer(buffers, offset, mBufferSize);
LayerBuffer::Buffer::Buffer(const ISurface::BufferHeap& buffers,
     ssize_t offset, size_t bufferSize)                                            struct NativeBuffer {
  : mBufferHeap(buffers), mCurrOffset(offset)                                            copybit_image_t img;
{                                                                                        copybit_rect_t crop;
                                                                                         int hor_stride;
  NativeBuffer& src(mNativeBuffer);                                                      int ver_stride;
   mNativeBuffer에 offset에 해당하는 메모리 영역을 저장함.                                          };
   src.img.base = (void*)(intptr_t(buffers.heap->base()) + offset);
  src.img.handle = 0;



2.BufferSource객체의 mBuffer에 생성된 buffer를 저장한다
void LayerBuffer::BufferSource::setBuffer(const sp<LayerBuffer::Buffer>& buffer)
{
  Mutex::Autolock _l(mBufferSourceLock);
  mBuffer = buffer;
}

Cf.copybit
 :그래픽 공유 메모리의 내용을 EGL_Image(Nativebuffer)로 고속으로 복사하기 위해 사용하는 hardware graphic module.




                                                                                                                10
2.그래픽 버퍼 출력 요청


                                       surfaceflinger

                         layerbuffer               buffersource

                                                   mBufferHeap
                         mSource                  mBuffer


                                                        buffer
                                                  mNativeBuffer
                                                  mBufferHeap




 그래픽 공유
 메모리      NativeBuffer




                                                                  11
2.그래픽 버퍼 출력 요청
3.서피스 플링거에게 출력 요청 함.
void LayerBase::invalidate()
{
  mFlinger->signalEvent();
}
     Surfaceflinger의 threadloop

                                  void SurfaceFlinger::waitForEvent()
                                  {
                                    sp<MessageBase> msg = mEventQueue.waitMessage(timeout);
                                     switch (msg->what) {
                                            case MessageQueue::INVALIDATE:
                                              // invalidate message, just return to the main loop
                                              return;
                                     }
                                  }



                                  void SurfaceFlinger::handleRepaint()
                                  {
                                     layer->draw(clip);
                                  }
                                  Layerbase의 draw함수를 호출한다.
                                    (각 layer의 텍스처 or EGL Image를 생성하고 프레임 버퍼에
                                      이미지를 그려 넣는다.)




                                                                                       12
2.그래픽 버퍼 출력 요청
Layerbase.cpp
void LayerBase::draw(const Region& clip) const
{
  onDraw(clip);
}

LayerBuffer.cpp
void LayerBuffer::BufferSource::onDraw(const Region& clip) const
{
    sp<Buffer> ourBuffer(getBuffer());  postbuffer()에서 생성한 Buffer 인스턴스를 가져온다.
    NativeBuffer src(ourBuffer->getBuffer());
     Buffer class의 copybit 이미지로 사용 가능한 Nativebuffer type의 mNativeBuffer를 가져온다.

      copybit_device_t* copybit = mLayer.mBlitEngine;copybit module을 가져온다.
      err = initTempBuffer(); EGL Image를 생성하고 생성된 image를 NativeBuffer type인 mTempBuffer에 저장한다.

      const NativeBuffer& dst(mTempBuffer);
      err = copybit->stretch(copybit, &dst.img, &src.img,&dst.crop, &src.crop, &clip);
      copybit을 이용하여 src(그래픽 공유 메모리)의 내용을 EGL Image를 가리키고 있는 dst로 copy한다.

      mLayer.drawWithOpenGL(tempClip, mTexture);
      생성된 EGL Image와 클립 정보(EGL image의 출력 영역)를 이용하여 각 레이어가 자신의 출력 영역에 그린다.
}

 status_t LayerBuffer::BufferSource::initTempBuffer() const
{

    sp<GraphicBuffer> buffer = new GraphicBuffer( w, h, HAL_PIXEL_FORMAT_RGB_565,
        GraphicBuffer::USAGE_HW_TEXTURE |
        GraphicBuffer::USAGE_HW_2D | GRALLOC_USAGE_PRIVATE_1);
    EGL image를 위한 buffer 생성

                                                                                           13
2.그래픽 버퍼 출력 요청
 NativeBuffer& dst(mTempBuffer);
 dst.img.handle = (native_handle_t *)buffer->handle;
 NativeBuffer type인 dst에 GraphicBuffer로 생성된 buffer의 handle을 저장한다.
 dst.crop.l = 0;
 dst.crop.t = 0;
 dst.crop.r = w;
 dst.crop.b = h;
 crop에 출력 범위를 지정한다.
 err = mTextureManager.initEglImage(&mTexture, dpy, buffer);
 생성된 buffer를 EGL Image의 버퍼로 지정한다.
 }

                                                   surfaceflinger
                                                                                EGL
                                    layerbuffer             buffersource   NativeBuffer
                                                            mBufferHeap      Graphic
                                    mSource                 mBuffer          Buffer

                                                              buffer
                                                           mNativeBuffer    EGL Image
                                                           mBufferHeap
                                                                                     dst
                                                           mTempBuffer



 그래픽 공유
 메모리               NativeBuffer        Src


                                                      Copybit을 이용한 고속복사
                                                                                14

Weitere ähnliche Inhalte

Was ist angesagt?

Javascript 완벽 가이드 정리
Javascript 완벽 가이드 정리Javascript 완벽 가이드 정리
Javascript 완벽 가이드 정리
ETRIBE_STG
 

Was ist angesagt? (20)

Startup JavaScript 6 - 함수, 스코프, 클로저
Startup JavaScript 6 - 함수, 스코프, 클로저Startup JavaScript 6 - 함수, 스코프, 클로저
Startup JavaScript 6 - 함수, 스코프, 클로저
 
[스프링 스터디 2일차] 서비스 추상화
[스프링 스터디 2일차] 서비스 추상화[스프링 스터디 2일차] 서비스 추상화
[스프링 스터디 2일차] 서비스 추상화
 
Startup JavaScript 4 - 객체
Startup JavaScript 4 - 객체Startup JavaScript 4 - 객체
Startup JavaScript 4 - 객체
 
함수적 사고 2장
함수적 사고 2장함수적 사고 2장
함수적 사고 2장
 
Angular2 가기전 Type script소개
 Angular2 가기전 Type script소개 Angular2 가기전 Type script소개
Angular2 가기전 Type script소개
 
Blockchain 4th dapp programming
Blockchain 4th dapp programmingBlockchain 4th dapp programming
Blockchain 4th dapp programming
 
Redux
ReduxRedux
Redux
 
Ji 개발 리뷰 (신림프로그래머)
Ji 개발 리뷰 (신림프로그래머)Ji 개발 리뷰 (신림프로그래머)
Ji 개발 리뷰 (신림프로그래머)
 
7가지 동시성 모델 - 데이터 병렬성
7가지 동시성 모델 - 데이터 병렬성7가지 동시성 모델 - 데이터 병렬성
7가지 동시성 모델 - 데이터 병렬성
 
Javascript 교육자료 pdf
Javascript 교육자료 pdfJavascript 교육자료 pdf
Javascript 교육자료 pdf
 
Clean code appendix 1
Clean code appendix 1Clean code appendix 1
Clean code appendix 1
 
Blockchain 3rd smart contract programming
Blockchain 3rd smart contract programmingBlockchain 3rd smart contract programming
Blockchain 3rd smart contract programming
 
Javascript 실행 가능한 코드(Executable Code)와 실행 콘텍스트(Execution Context), Lexical En...
Javascript 실행 가능한 코드(Executable Code)와 실행 콘텍스트(Execution Context), Lexical En...Javascript 실행 가능한 코드(Executable Code)와 실행 콘텍스트(Execution Context), Lexical En...
Javascript 실행 가능한 코드(Executable Code)와 실행 콘텍스트(Execution Context), Lexical En...
 
Javascript 완벽 가이드 정리
Javascript 완벽 가이드 정리Javascript 완벽 가이드 정리
Javascript 완벽 가이드 정리
 
GCGC- CGCII 서버 엔진에 적용된 기술 (1)
GCGC- CGCII 서버 엔진에 적용된 기술 (1)GCGC- CGCII 서버 엔진에 적용된 기술 (1)
GCGC- CGCII 서버 엔진에 적용된 기술 (1)
 
EcmaScript6(2015) Overview
EcmaScript6(2015) OverviewEcmaScript6(2015) Overview
EcmaScript6(2015) Overview
 
헷갈리는 자바스크립트 정리
헷갈리는 자바스크립트 정리헷갈리는 자바스크립트 정리
헷갈리는 자바스크립트 정리
 
파이썬+함수이해하기 20160229
파이썬+함수이해하기 20160229파이썬+함수이해하기 20160229
파이썬+함수이해하기 20160229
 
GCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing System
GCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing SystemGCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing System
GCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing System
 
Jupyter notebok tensorboard 실행하기_20160706
Jupyter notebok tensorboard 실행하기_20160706Jupyter notebok tensorboard 실행하기_20160706
Jupyter notebok tensorboard 실행하기_20160706
 

Ähnlich wie Surface flingerservice(서피스 상태 변경 및 출력 요청)

Half sync/Half Async
Half sync/Half AsyncHalf sync/Half Async
Half sync/Half Async
scor7910
 
Effective c++(chapter 5,6)
Effective c++(chapter 5,6)Effective c++(chapter 5,6)
Effective c++(chapter 5,6)
문익 장
 
Smc–state machinecompiler
Smc–state machinecompilerSmc–state machinecompiler
Smc–state machinecompiler
Dong Hyeun Lee
 
Ndc2010 전형규 마비노기2 캐릭터 렌더링 기술
Ndc2010 전형규   마비노기2 캐릭터 렌더링 기술Ndc2010 전형규   마비노기2 캐릭터 렌더링 기술
Ndc2010 전형규 마비노기2 캐릭터 렌더링 기술
henjeon
 
HolubOnPatterns/chapter3_3
HolubOnPatterns/chapter3_3HolubOnPatterns/chapter3_3
HolubOnPatterns/chapter3_3
suitzero
 
[0312 조진현] good bye dx9
[0312 조진현] good bye dx9[0312 조진현] good bye dx9
[0312 조진현] good bye dx9
진현 조
 
Easy gameserver
Easy gameserverEasy gameserver
Easy gameserver
진상 문
 
동기화, 스케줄링
동기화, 스케줄링동기화, 스케줄링
동기화, 스케줄링
xxbdxx
 
[ShaderX5] 4.4 Edge Masking and Per-Texel Depth Extent Propagation For Comput...
[ShaderX5] 4.4 Edge Masking and Per-Texel Depth Extent Propagation For Comput...[ShaderX5] 4.4 Edge Masking and Per-Texel Depth Extent Propagation For Comput...
[ShaderX5] 4.4 Edge Masking and Per-Texel Depth Extent Propagation For Comput...
종빈 오
 
Gpg gems1 1.3
Gpg gems1 1.3Gpg gems1 1.3
Gpg gems1 1.3
david nc
 

Ähnlich wie Surface flingerservice(서피스 상태 변경 및 출력 요청) (20)

Half sync/Half Async
Half sync/Half AsyncHalf sync/Half Async
Half sync/Half Async
 
Effective c++(chapter 5,6)
Effective c++(chapter 5,6)Effective c++(chapter 5,6)
Effective c++(chapter 5,6)
 
Smc–state machinecompiler
Smc–state machinecompilerSmc–state machinecompiler
Smc–state machinecompiler
 
D2 Rain (2/2)
D2 Rain (2/2)D2 Rain (2/2)
D2 Rain (2/2)
 
Startup JavaScript 8 - NPM, Express.JS
Startup JavaScript 8 - NPM, Express.JSStartup JavaScript 8 - NPM, Express.JS
Startup JavaScript 8 - NPM, Express.JS
 
NDC11_슈퍼클래스
NDC11_슈퍼클래스NDC11_슈퍼클래스
NDC11_슈퍼클래스
 
세션1. block chain as a platform
세션1. block chain as a platform세션1. block chain as a platform
세션1. block chain as a platform
 
[143] Modern C++ 무조건 써야 해?
[143] Modern C++ 무조건 써야 해?[143] Modern C++ 무조건 써야 해?
[143] Modern C++ 무조건 써야 해?
 
Javascript 조금 더 잘 알기
Javascript 조금 더 잘 알기Javascript 조금 더 잘 알기
Javascript 조금 더 잘 알기
 
Ndc2010 전형규 마비노기2 캐릭터 렌더링 기술
Ndc2010 전형규   마비노기2 캐릭터 렌더링 기술Ndc2010 전형규   마비노기2 캐릭터 렌더링 기술
Ndc2010 전형규 마비노기2 캐릭터 렌더링 기술
 
HolubOnPatterns/chapter3_3
HolubOnPatterns/chapter3_3HolubOnPatterns/chapter3_3
HolubOnPatterns/chapter3_3
 
20140122 techdays mini 앱 개발 세미나(3) - 센서활용 앱 개발
20140122 techdays mini  앱 개발 세미나(3) - 센서활용 앱 개발20140122 techdays mini  앱 개발 세미나(3) - 센서활용 앱 개발
20140122 techdays mini 앱 개발 세미나(3) - 센서활용 앱 개발
 
[0312 조진현] good bye dx9
[0312 조진현] good bye dx9[0312 조진현] good bye dx9
[0312 조진현] good bye dx9
 
7가지 동시성 모델 - 3장. 함수형 프로그래밍
7가지 동시성 모델 - 3장. 함수형 프로그래밍7가지 동시성 모델 - 3장. 함수형 프로그래밍
7가지 동시성 모델 - 3장. 함수형 프로그래밍
 
Easy gameserver
Easy gameserverEasy gameserver
Easy gameserver
 
동기화, 스케줄링
동기화, 스케줄링동기화, 스케줄링
동기화, 스케줄링
 
[ShaderX5] 4.4 Edge Masking and Per-Texel Depth Extent Propagation For Comput...
[ShaderX5] 4.4 Edge Masking and Per-Texel Depth Extent Propagation For Comput...[ShaderX5] 4.4 Edge Masking and Per-Texel Depth Extent Propagation For Comput...
[ShaderX5] 4.4 Edge Masking and Per-Texel Depth Extent Propagation For Comput...
 
Node.js and react
Node.js and reactNode.js and react
Node.js and react
 
Gpg gems1 1.3
Gpg gems1 1.3Gpg gems1 1.3
Gpg gems1 1.3
 
Side Effect in Compose (Android Jetpack)
Side Effect in Compose (Android Jetpack)Side Effect in Compose (Android Jetpack)
Side Effect in Compose (Android Jetpack)
 

Mehr von fefe7270

Surface flingerservice(서피스플링거서비스초기화)
Surface flingerservice(서피스플링거서비스초기화)Surface flingerservice(서피스플링거서비스초기화)
Surface flingerservice(서피스플링거서비스초기화)
fefe7270
 
Stagefright recorder part1
Stagefright recorder part1Stagefright recorder part1
Stagefright recorder part1
fefe7270
 
Camera camcorder framework overview(ginger bread)
Camera camcorder framework overview(ginger bread)Camera camcorder framework overview(ginger bread)
Camera camcorder framework overview(ginger bread)
fefe7270
 
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
 

Mehr von 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(서피스 상태 변경 및 출력 요청)

  • 1. SurfaceFlingerService (서피스 상태 변경 및 출력 요청) 박철희 1
  • 2. 화면 출력 요청 전 과정 2
  • 3. 1.서피스 상태 변경 -서피스 추가/삭제 1.서피스 추가/삭제 2.개별 레이어 상태 변경(크기,zorder) 3.프레임 상태 변경(orientation변경) 1.서피스 추가/삭제 서피스가 추가 또는 삭제 되면 전역 레이어 목록이 변경되어야 한다. 이를 위해서 추가 또는 삭제 시에 mTransactionFlags 에 eTransactionNeeded을 설정하고 surfaceflinger의 threadloop으로 signal을 보낸다. sp<ISurface> SurfaceFlinger::createSurface(…) { layer = createPushBuffersSurface(client, d, w, h, flags); setTransactionFlags(eTransactionNeeded); } uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) status_t SurfaceFlinger::removeSurface() { { uint32_t old = android_atomic_or(flags, &mTransactionFlags); … if ((old & flags)==0) { // wake the server up setTransactionFlags(eTransactionNeeded); signalEvent(); } } return old; } 3
  • 4. 1.서피스 상태 변경 종류-개별 레이어 상태 변경 2.개별 레이어 상태 변경(크기,zorder) -레이어(서피스) 상태 변경은 트랜잭션 시작과 종료 사이에만 가능하다. -다수의 상태 변경 함수를 동시에 중첩하여 설정 할 수 있다. ex)fade out 의 기능과 같이 메뉴가 투명해 지면서 축소가 되고 위치가 변경이 되는 경우 “투명,축소,위치변경”이 동시에 실행 된다. Bootanimation.cpp status_t BootAnimation::readyToRun() { sp<SurfaceControl> control = session()->createSurface(getpid(), 0, dinfo.w, dinfo.h, PIXEL_FORMAT_RGBA_8888); session()->openTransaction();  transaction 시작 control->setLayer(0x40000000); 서피스의 zorder 변경 session()->closeTransaction();  transaction 종료 } 1)Transaction 시작 status_t SurfaceComposerClient::openTransaction() { mTransactionOpen++; open된 transaction을 나타내는 mTransactionOpen을 1 증가 시킴. } 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) { layer_state_t* s = lockLayerState(id); dummy layer state 구조체를 생성하고 return 받는다. s->what |= ISurfaceComposer::eLayerChanged; s->z = z; dummy layer state 구조체에 what(상태 변경 이벤트),z(zoder값)을 저장한다. unlockLayerState(); return NO_ERROR; } layer_state_t* SurfaceComposerClient::lockLayerState(SurfaceID id) { s = get_state_l(id); if (!s) mLock.unlock(); return s; } layer_state_t* SurfaceComposerClient::get_state_l(SurfaceID index) { layer_state_t& dummy(*mPrebuiltLayerState);  mPrebuiltLayerState는 onFirstRef에서 만들어진 dummy layer state 구조체 dummy.surface = index; dummy state 구조체에 상태 변경 대상의 layer의 index를 대입 ssize_t i = mStates.indexOf(dummy); if (i < 0) { // we don't have it, add an initialized layer_state to our list i = mStates.add(dummy); mStates 에 dummy 구조체 추가. 이 mStates의 정보는 SurfaceFlinger쪽으로 전달 됨. } return mStates.editArray() + i;  추가된 dummy 구조체를 return } 5
  • 6. 1.서피스 상태 변경 종류- 개별 레이어 상태 변경 3. transaction 종료 SurfaceComposerClient.cpp status_t SurfaceComposerClient::closeTransaction() { if (mTransactionOpen >= 2) {  transcation이 2개 이상일 경우에는 서피스 플링거에게 상태 변경을 요청하지 않고, mTransactionOpen만 1 감소 시키고 return 시킴(빈번한 transaction 처리를 방지하기 위해) mTransactionOpen--; return NO_ERROR; } mTransactionOpen = 0; const ssize_t count = mStates.size(); if (count) { mClient->setState(count, mStates.array()); mStates 에 추가된 dummy layer 구조체를 인자로 서피스 클라이언트의 setState함수를 호출 함. mStates.clear(); } return NO_ERROR; } status_t Client::setState(int32_t count, const layer_state_t* states) { return mFlinger->setClientState(this, count, states); } 6
  • 7. 1.서피스 상태 변경 종류- 개별 레이어 상태 변경 status_t SurfaceFlinger::setClientState(const sp<Client>& client, int32_t count,const layer_state_t* states) { if (what & eLayerChanged) { ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); if (layer->setLayer(s.z)) { mCurrentState.layersSortedByZ.removeAt(idx); mCurrentState.layersSortedByZ.add(layer); // we need traversal (state changed) AND transaction (list changed) flags |= eTransactionNeeded|eTraversalNeeded; zorder 변경은 개별 레이어의 상태 변경 (eTraversalNeeded) 및 전역 레이어 목록 변경(eTransactionNeeded) 이 필요함. } if (flags) { setTransactionFlags(flags); surfaceflinger의 threadloop으로 signal을 보내서 상태 변경 처리를 한다. } 7
  • 8. 1.서피스 상태 변경 종류-프레임 상태 변경 3.프레임 상태 변경(orientation변경) -전역 레이어 목록에 있는 모든 레이어를 회전 각도에 맞게 재 계산해야 함. int SurfaceComposerClient::setOrientation(DisplayID dpy, int orientation, uint32_t flags) { sp<ISurfaceComposer> sm(getComposerService()); return sm->setOrientation(dpy, orientation, flags); } int SurfaceFlinger::setOrientation(DisplayID dpy, int orientation, uint32_t flags) { if (mCurrentState.orientation != orientation) {  현재 상태 값과 다를 때에만 재 계산 함. mCurrentState.orientation = orientation; mCurrentState와 mDrawingState의 orientation을 비교 setTransactionFlags(eTransactionNeeded);  전역 레이어 목록 변경 mTransactionCV.wait(mStateLock);  다른 레이어가 변경할 때 까지 기다림. } } Surfaceflinger의 threadloop에서 transaction을 처리하기 위한 handleTransactionLocked에서 commitTransaction를 호출 함. void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) { commitTransaction(); } void SurfaceFlinger::commitTransaction() { mTransactionCV.broadcast();  setOrientation에서 기다리고 있는 conditionlock에게 signal 보냄. } 8
  • 9. 2.그래픽 버퍼 출력 요청 Ex)Cameraservice의 preview 출력 void CameraService::Client::handlePreviewData(const sp<IMemory>& mem) { ssize_t offset; size_t size; sp<IMemoryHeap> heap = mem->getMemory(&offset, &size); if (!mUseOverlay) { if (mSurface != 0) { mSurface->postBuffer(offset); } } } void LayerBuffer::postBuffer(ssize_t offset) { source->postBuffer(offset); } void LayerBuffer::BufferSource::postBuffer(ssize_t offset) { buffers = mBufferHeap; sp<Buffer> buffer; if (buffers.heap != 0) { buffer = new LayerBuffer::Buffer(buffers, offset, mBufferSize); 1.offset에 해당하는 메모리 영역을 copybit을 이용할 수 있는 Nativebuffer에 저장 setBuffer(buffer);2.BufferSource객체의 mBuffer에 생성된 buffer class를 저장한다. mLayer.invalidate(); 3.서피스 플링거에게 출력 요청 함. } 9
  • 10. 2.그래픽 버퍼 출력 요청 1.offset에 해당하는 메모리 영역을 copybit을 이용할 수 있는 Nativebuffer에 저장 buffer = new LayerBuffer::Buffer(buffers, offset, mBufferSize); LayerBuffer::Buffer::Buffer(const ISurface::BufferHeap& buffers, ssize_t offset, size_t bufferSize) struct NativeBuffer { : mBufferHeap(buffers), mCurrOffset(offset) copybit_image_t img; { copybit_rect_t crop; int hor_stride; NativeBuffer& src(mNativeBuffer); int ver_stride;  mNativeBuffer에 offset에 해당하는 메모리 영역을 저장함. }; src.img.base = (void*)(intptr_t(buffers.heap->base()) + offset); src.img.handle = 0; 2.BufferSource객체의 mBuffer에 생성된 buffer를 저장한다 void LayerBuffer::BufferSource::setBuffer(const sp<LayerBuffer::Buffer>& buffer) { Mutex::Autolock _l(mBufferSourceLock); mBuffer = buffer; } Cf.copybit :그래픽 공유 메모리의 내용을 EGL_Image(Nativebuffer)로 고속으로 복사하기 위해 사용하는 hardware graphic module. 10
  • 11. 2.그래픽 버퍼 출력 요청 surfaceflinger layerbuffer buffersource mBufferHeap mSource mBuffer buffer mNativeBuffer mBufferHeap 그래픽 공유 메모리 NativeBuffer 11
  • 12. 2.그래픽 버퍼 출력 요청 3.서피스 플링거에게 출력 요청 함. void LayerBase::invalidate() { mFlinger->signalEvent(); } Surfaceflinger의 threadloop void SurfaceFlinger::waitForEvent() { sp<MessageBase> msg = mEventQueue.waitMessage(timeout); switch (msg->what) { case MessageQueue::INVALIDATE: // invalidate message, just return to the main loop return; } } void SurfaceFlinger::handleRepaint() { layer->draw(clip); } Layerbase의 draw함수를 호출한다. (각 layer의 텍스처 or EGL Image를 생성하고 프레임 버퍼에 이미지를 그려 넣는다.) 12
  • 13. 2.그래픽 버퍼 출력 요청 Layerbase.cpp void LayerBase::draw(const Region& clip) const { onDraw(clip); } LayerBuffer.cpp void LayerBuffer::BufferSource::onDraw(const Region& clip) const { sp<Buffer> ourBuffer(getBuffer());  postbuffer()에서 생성한 Buffer 인스턴스를 가져온다. NativeBuffer src(ourBuffer->getBuffer());  Buffer class의 copybit 이미지로 사용 가능한 Nativebuffer type의 mNativeBuffer를 가져온다. copybit_device_t* copybit = mLayer.mBlitEngine;copybit module을 가져온다. err = initTempBuffer(); EGL Image를 생성하고 생성된 image를 NativeBuffer type인 mTempBuffer에 저장한다. const NativeBuffer& dst(mTempBuffer); err = copybit->stretch(copybit, &dst.img, &src.img,&dst.crop, &src.crop, &clip); copybit을 이용하여 src(그래픽 공유 메모리)의 내용을 EGL Image를 가리키고 있는 dst로 copy한다. mLayer.drawWithOpenGL(tempClip, mTexture); 생성된 EGL Image와 클립 정보(EGL image의 출력 영역)를 이용하여 각 레이어가 자신의 출력 영역에 그린다. } status_t LayerBuffer::BufferSource::initTempBuffer() const { sp<GraphicBuffer> buffer = new GraphicBuffer( w, h, HAL_PIXEL_FORMAT_RGB_565, GraphicBuffer::USAGE_HW_TEXTURE | GraphicBuffer::USAGE_HW_2D | GRALLOC_USAGE_PRIVATE_1); EGL image를 위한 buffer 생성 13
  • 14. 2.그래픽 버퍼 출력 요청 NativeBuffer& dst(mTempBuffer); dst.img.handle = (native_handle_t *)buffer->handle; NativeBuffer type인 dst에 GraphicBuffer로 생성된 buffer의 handle을 저장한다. dst.crop.l = 0; dst.crop.t = 0; dst.crop.r = w; dst.crop.b = h; crop에 출력 범위를 지정한다. err = mTextureManager.initEglImage(&mTexture, dpy, buffer); 생성된 buffer를 EGL Image의 버퍼로 지정한다. } surfaceflinger EGL layerbuffer buffersource NativeBuffer mBufferHeap Graphic mSource mBuffer Buffer buffer mNativeBuffer EGL Image mBufferHeap dst mTempBuffer 그래픽 공유 메모리 NativeBuffer Src Copybit을 이용한 고속복사 14