3. 1.서피스 플링거 연결 요청
1.Surfaceflinger 검색 및 proxy 획득
ISurfaceComposer
Android_view_Surface.cpp
static void SurfaceSession_init(JNIEnv* env, jobject clazz)
{
sp<SurfaceComposerClient> client = new SurfaceComposerClient;
}
SurfaceComposerClient.cpp
SurfaceComposerClient::SurfaceComposerClient(): mStatus(NO_INIT), mComposer(Composer::getInstance())
{
}
SurfaceComposerClient는 Refbase를 상속받았기 때문에, onFirstRef 가 불린다.
void SurfaceComposerClient::onFirstRef()
{
sp<ISurfaceComposer> sm(getComposerService());
..
3
4. static inline sp<ISurfaceComposer> getComposerService() {
return ComposerService::getComposerService();
}
sp<ISurfaceComposer> ComposerService::getComposerService() {
return ComposerService::getInstance().mComposerService;
}
ComposerService 는 singleton class를 상속받았음으로,
이미 ComposerService 객체가 있으면 그 객체를 return하고,
없으면, ComposerService 의 생성자를 호출해서 객체를 생성한다.
ComposerService::ComposerService()
: Singleton<ComposerService>() {
const String16 name("SurfaceFlinger");
while (getService(name, &mComposerService) != NO_ERROR) {
usleep(250000);
}
SurfaceFlinger service의 proxy(ISurfaceCompser)를 mComposerService 에 저장한다.
}
2.디스플레이 공유 메모리 서비스의 프록시 획득
4
5. 1.서피스 플링거 연결 요청
SurfaceComposerClient.cpp
ComposerService::ComposerService(): Singleton<ComposerService>() {
const String16 name("SurfaceFlinger");
while (getService(name, &mComposerService) != NO_ERROR) {
usleep(250000);
}
SurfaceFlinger service의 proxy(ISurfaceCompser)를 mComposerService 에 저장한다.
mServerCblkMemory = mComposerService->getCblk();
Surface flinger의 getCblk를 이용하여 디스플레이 공유 메모리의 서비스 프락시(IMemoryHep)을 획득한다.
mServerCblk = static_cast<surface_flinger_cblk_t volatile *>(mServerCblkMemory->getBase());
획득한 proxy로 공유메모리의 surface_flinger_cblk_t 구조체의 주소를 획득한다.
}
surface_flinger_cblk_t surfaceflinger
SurfaceComposerClient
connected mServerCblk
ComposerService
Dislay_cblk_t dcblk
mServerCblk w,h:프레임 버퍼 너비,높이
Density,fps
Format,orientation
Xdpi,ydpi
5
6. 1.서피스 플링거 연결 요청
3.서피스 플링거 연결 요청 및 서비스 클라이언트 프락시 획득
ISurfaceComposerClient
void SurfaceComposerClient::onFirstRef()
{
sp<ISurfaceComposer> sm(getComposerService());
if (sm != 0) { ISurfaceComposerClient
sp<ISurfaceComposerClient> conn = sm->createConnection();
Surfaceflinger에 있는 createConnection 가 호출 됨.
} BnSurfaceComposerClient
SurfaceFlinger.cpp
sp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
{ Client
sp<ISurfaceComposerClient> bclient;
sp<Client> client(new Client(this)); ~Client();
status_t err = client->initCheck(); createSurface;
if (err == NO_ERROR) { destroySurface
bclient = client; DefaultKeyedVector< size_t,
} wp<LayerBaseClient> >
return bclient;Client class의 proxy인 ISurfaceComposerClient가 mLayers;
return됨.
} 6
7. 1.서피스 플링거 연결 요청
-서피스 클라이언트 리모트 서비스의 역할
1.서피스 플링거 서비스의 래퍼:
서피스 플링거 서비스 기능 중 일부를 사용할 수 있도록 제공함
(서피스 생성,삭제,서피스 상태 변경)
2.애플리케이션별 레이어 관리:
서피스 클라이언트 별로 서피스에 대한 지역 식별자를 할당하고, DefaultKeyedVector에
지역식별자와 layer를 함께 추가함.
3. 레이어 상태 변경:애플리케이션이 서피스의 상태 변경(가로,세로 전환)을 서피스 클라이언트 리모트
서비스에게 요청한다.
4.애플리케이션 레이어의 생명 주기 관리:
서피스 생성을 요청한 애플리케이션이 비정상적으로 동작을 종료하더라도 관리하고 있는 서피스와
관련 자원을 서피스 클라이언트의 소멸자에서 자동으로 해제해 준다.
(why? Client class는 Refbase class를 상속 받는데 이 Refbase class는 참조하는 곳이 없어질때
자동으로 소멸자를 불러주게 된다.)
7
8. 2.서피스 생성 요청 (서비스 클라이언트)
Surface.java
public Surface()
{
init(s,pid,name,display,w,h,format,flags);
}
Android_view_surface.cpp
struct surface_data_t {
static void Surface_init
int32_t token;
{
int32_t identity;
surface = client->createSurface(pid, name, dpy, w, h, format, flags);
status_t readFromParcel(const Parcel& parcel);
}
status_t writeToParcel(Parcel* parcel) const;
sp<SurfaceControl> SurfaceComposerClient::createSurface(…) };
{
ISurfaceComposerClient::surface_data_t data;
p<ISurface> surface = mClient->createSurface(&data, pid, name,display, w, h, format, flags);
서피스 클라이언트의 createSurface를 호출하여 SurfaceTextureLayer 핸들을 생성한다.
이때 data 구조체에 생성된 서피스에 대한 정보를 채워준다.
SurfaceTextureLayer 핸들에 접근할 수 있는 BSurface Class의 proxy가 surface 변수에 저장된다.
if (surface != 0) {
result = new SurfaceControl(this, surface, data, w, h, format, flags);
return된 Isurface proxy를 이용해서 SurfaceControl class를 생성한다.
이 class는 SurfaceTextureLayer proxy를 획득하거나, 서피스의 상태 변경을 할 수 있게 해 준다.
}
setSurfaceControl(env, clazz, surface);
}
static void setSurfaceControl(JNIEnv* env, jobject clazz, const sp<SurfaceControl>& surface)
{
env->SetIntField(clazz, so.surfaceControl, (int)surface.get()); SurfaceControl를 so.surfaceControl 에 저장한다.
}
8
17. 3.서피스 생성 요청 (서비스 서버)
Client SurfaceFlinger
Client
surfacecomposerclient
surfacetexture
surfacecontrol BSurface
SurfaceTextureLaye
r
layer
surface
surfacetextureclient
17
18. 3.서피스 생성 전체 그림
Android_view_surface.cpp
SurfaceFlingerClient SurfaceFlinger
Client
SurfaceView Surface.java
surfacecomposerclient
Get surfacetexture
H SurfaceControl
{ surfacecontrol BSurface
O
Surfacecontrol SurfaceTextureLayer
L
D }
E layer
R surface
getSurface
{ surfacetextureclient
Surface
}
18
19. 3.푸시 버퍼 서피스 생성 요청 (서비스 서버)
2.생성된 layer 상태 초기화
layer->initStates(w, h, flags);
Layerbase class의 initStates 가 호출됨.
void LayerBase::initStates(uint32_t w, uint32_t h, uint32_t flags)
{
mCurrentState.z = 0; mCurrentState.w = w; mCurrentState.h = h;
mCurrentState.requested_w = w; mCurrentState.requested_h = h;
mCurrentState.sequence = 0;
sequence 값은 드로잉 프레임에서의 레이어와 현재 프레임의 레이어 상태가 변경될 때 1씩 증가
mDrawingState = mCurrentState;
mDrawingState (화면에 출력중인 레이어의 상태 저장)과
mCurrentState(화면 출력을 위해 합성중인 레이어의 상태 저장)를 동일하게 설정
}
3.전역 레이어 목록과 지역 레이어 목록에 추가
ssize_t token = addClientLayer(client, layer);
SurfaceFlinger 1.전역 레이어 목록
-서피스 플링거 서비스에서 생성된 전체 레이어 목록
지역 레이어 목록 -정렬 순서:zorder 순서
전역 레이어 목록 - mCurrentState.layersSortedByZ 변수로 관리
Client 1
layersSortedByZ 2.지역 레이어 목록
mLayers
zorder mIdentity -특정 Client에서 생성된 레이어 목록
Token=1
4 4 -지역 레이어 목록의 레이어는 전역 레이어 목록에
3 1
Token=2 추가됨.
-Client class의 mLayers 변수로 관리
19
20. 3.푸시 버퍼 서피스 생성 요청 (서비스 서버)
ssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
const sp<LayerBaseClient>& lbc)
{
// 지역 레이어 목록에 추가
size_t name = client->attachLayer(lbc);
// 전역 레이어 목록에 추가
addLayer_l(lbc);
return ssize_t(name);
}
size_t Client::attachLayer(const sp<LayerBaseClient>& layer)
{
size_t name = mNameGenerator++;
mLayers.add(name, layer);
return name;
}
status_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer)
{
ssize_t i = mCurrentState.layersSortedByZ.add(layer);
return (i < 0) ? status_t(i) : status_t(NO_ERROR);
}
20
21. 3.푸시 버퍼 서피스 생성 요청 (서비스 서버)
4. SurfaceTexturelayer 핸들을 가져옴
surfaceHandle = layer->getSurface();
Layerbase.cpp의 getSurface가 호출 됨.
sp<LayerBaseClient::Surface> LayerBaseClient::getSurface()
{
sp<Surface> s;
Mutex::Autolock _l(mLock);
s = mClientSurface.promote();
if (s == 0) {
s = createSurface();
mClientSurface = s;
}
return s;
} Layer.cpp의 오버라이딩 된 createSurface를 부른다.
class BSurface : public BnSurface, public LayerCleaner {
Layer.cpp wp<const Layer> mOwner;
sp<ISurface> Layer::createSurface() virtual sp<ISurfaceTexture> getSurfaceTexture() const {
{ sp<ISurfaceTexture> res;
sp<ISurface> sur(new BSurface(mFlinger, this)); sp<const Layer> that( mOwner.promote() );
return sur; if (that != NULL) {
SurfaceTextureLayer에 접근 할 수 있는 res = that->mSurfaceTexture;
}
Bsurface class를 생성하고 proxy인 Isurface를
return res;
return한다.
}
} public:
BSurface(const sp<SurfaceFlinger>& flinger,
const sp<Layer>& layer)
: LayerCleaner(flinger, layer), mOwner(layer) { }
};