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

1,159 views
945 views

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,159
On SlideShare
0
From Embeds
0
Number of Embeds
144
Actions
Shares
0
Downloads
0
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

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

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

×