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

2,059 views

Published on

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
2,059
On SlideShare
0
From Embeds
0
Number of Embeds
307
Actions
Shares
0
Downloads
0
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

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

  1. 1. SurfaceFlingerService(서피스 플링거 연결) 박철희 1
  2. 2. 화면 출력 요청 전 과정 2
  3. 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. 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. 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. 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. 7. 1.서피스 플링거 연결 요청-서피스 클라이언트 리모트 서비스의 역할1.서피스 플링거 서비스의 래퍼: 서피스 플링거 서비스 기능 중 일부를 사용할 수 있도록 제공함 (서피스 생성,삭제,서피스 상태 변경)2.애플리케이션별 레이어 관리: 서피스 클라이언트 별로 서피스에 대한 지역 식별자를 할당하고, DefaultKeyedVector에 지역식별자와 layer를 함께 추가함.3. 레이어 상태 변경:애플리케이션이 서피스의 상태 변경(가로,세로 전환)을 서피스 클라이언트 리모트 서비스에게 요청한다.4.애플리케이션 레이어의 생명 주기 관리: 서피스 생성을 요청한 애플리케이션이 비정상적으로 동작을 종료하더라도 관리하고 있는 서피스와 관련 자원을 서피스 클라이언트의 소멸자에서 자동으로 해제해 준다. (why? Client class는 Refbase class를 상속 받는데 이 Refbase class는 참조하는 곳이 없어질때 자동으로 소멸자를 불러주게 된다.) 7
  8. 8. 2.푸시 버퍼 서피스 생성 요청(서비스 클라이언트) WidowManagerService.javaCamera.java public int relayout(…)public void onCreate(Bundle icicle) {{ int res = relayoutWindow(…); SurfaceHolder holder = mSurfaceView.getHolder(); } holder.addCallback(this); public int relayoutWindow(…) holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); {} Surface surface = win.createSurfaceLocked(); }Surfaceview.java public void setType(int type) { Surface createSurfaceLocked()case SURFACE_TYPE_NORMAL: {case SURFACE_TYPE_PUSH_BUFFERS: mSurface = new Surface mRequestedType = type; ( mSession.mSurfaceSession, if (mWindow != null) { mSession.mPid, updateWindow(false, false); mAttrs.getTitle().toString(), } 0, w, h, mAttrs.format, flags); break; } }} Surface.java public Surface()private void updateWindow(boolean force, boolean redrawNeeded) {{ init(s,pid,name,display,w,h,format,flags); … } final int relayoutResult = mSession.relayout( mWindow, mLayout, mWidth, mHeight, Android_view_surface.cpp visible ? VISIBLE : GONE, false, mWinFrame, mContentInsets, static void Surface_init mVisibleInsets, mConfiguration, mSurface); { surface = client->createSurface (pid, name, dpy, w, h, format, flags); } 8
  9. 9. 2.푸시 버퍼 서피스 생성 요청 (서비스 클라이언트)Android_view_surface.cppstatic void Surface_init{ token 서피스 지역 식별자 surface = client->createSurface(pid, name, dpy, w, h, format, flags);} identity 서피스 전역 식별자 Width,height 서피스 넓이,높이sp<SurfaceControl> SurfaceComposerClient::createSurface(…) format 포맷{ ISurfaceComposerClient::surface_data_t data; p<ISurface> surface = mClient->createSurface(&data, pid, name,display, w, h, format, flags); 서피스 클라이언트의 createSurface를 호출하여 푸시 버퍼 서피스,푸시 버퍼 서피스 핸들을 생성한다. 이때 data 구조체에 생성된 푸시 버퍼 서피스에 대한 정보를 채워준다. 푸시 버퍼 서피스 핸들의 proxy가 surface 변수에 저장된다. if (surface != 0) { result = new SurfaceControl(this, surface, data, w, h, format, flags); return된 Isurface proxy를 이용해서 SurfaceControl class를 생성한다. 이 class는 푸시 버퍼 서피스의 proxy를 획득하거나, 서피스의 상태 변경을 할 수 있게 해 준다. } SurfaceFlinger.cpp sp<ISurface> Client::createSurface(…) { return mFlinger->createSurface(this, pid, name, params, display, w, h, format, flags); SurfaceFlinger의 createSurface를 호출한다. } 9
  10. 10. 3.푸시 버퍼 서피스 생성 요청 (서비스 서버)sp<ISurface> SurfaceFlinger::createSurface(…){ sp<Layer> normalLayer; switch (flags & eFXSurfaceMask) { case eFXSurfaceNormal: if (UNLIKELY(flags & ePushBuffers)) { layer = createPushBuffersSurface(client, d, w, h, flags); 1.푸시 버퍼 서피스 생성,푸시 버퍼 서피스 핸들 생성 } else { normalLayer = createNormalSurface(client, d, w, h, flags, format); 노말 서피스 생성 layer = normalLayer; } break; } if (layer != 0) { layer->initStates(w, h, flags); 2.생성된 layer 상태 초기화 ssize_t token = addClientLayer(client, layer);  3.전역 레이어 목록과 지역 레이어 목록에 추가 surfaceHandle = layer->getSurface();  4.푸시버퍼 서비스 핸들을 가져옴. if (surfaceHandle != 0) {  mClient->createSurface 호출시 넘겨준 surface_data_t 구조체에 값을 채움. params->token = token;  서피스 지역 식별자 params->identity = surfaceHandle->getIdentity();  서피스 전역 식별자 params->width = w; params->height = h; 서피스 넓이, 높이 params->format = format; 서피스 높이} setTransactionFlags(eTransactionNeeded); 서피스 플링거가 합성 시 참조하는 상태 플래그에 설정. return surfaceHandle;  생성된 푸시버퍼 핸들을 return함. 10
  11. 11. 3.푸시 버퍼 서피스 생성 요청 (서비스 서버) 1. 푸시 버퍼 레이어 생성,푸시 버퍼 서피스 핸들 리모트 서비스 생성 layer = createPushBuffersSurface(client, d, w, h, flags);sp<LayerBuffer> SurfaceFlinger::createPushBuffersSurface(..) LayerBase{ sp<LayerBuffer> layer = new LayerBuffer(this, display, client); LayerBuffer생성 자 호출시 LayerBase의 생성자 부터 호출된다. LayerBaseClient layer->initStates(w, h, flags); return layer;} Layer Layer Layer Layer Buffer Blur DimLayerbase.cppLayerBase::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 4LayerBaseClient::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. 12. 3.푸시 버퍼 서피스 생성 요청 (서비스 서버)LayerBuffer::LayerBuffer(SurfaceFlinger* flinger, DisplayID display, const sp<Client>& client) : LayerBaseClient(flinger, display, client), mNeedsBlending(false), mInvalidate(false), mIsReconfiguring(false), mBlitEngine(0){ …}LayBuffer생성자에서는 특별한 동작을 수행하지 않음. RefBase class를 상속했음으로, onFirstRef()가 불림. void LayerBuffer::onFirstRef() { mSurface = new SurfaceLayerBuffer(mFlinger, this); 푸시 버퍼 서피스 핸들 생성 } ISurface Isurface 서비스 프록시의 기능 중 푸시 버퍼 레이어와 관련 된 registerBuffers(), Surface postBuffer(), createOverlay()등의 함수 호출을 LayerBuffer 클래스에 전달하는 래퍼 클래스 이다. SurfaceLayerBuffer LayerBuffer 12
  13. 13. 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 변수로 관리 13
  14. 14. 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);} 14
  15. 15. 3.푸시 버퍼 서피스 생성 요청 (서비스 서버) 4. 푸시버퍼 서비스 핸들을 가져옴 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;} LayerBuffer.cpp의 오버라이딩 된 createSurface를 부른다.LayerBuffer.cppsp<LayerBaseClient::Surface> LayerBuffer::createSurface() const{ LOGE("LayerBuffer::createSurface()"); return mSurface;}

×