일단 여기서 보이는 것은 SurfaceFlinger 가 LayerVector 를 가지고 있다는 것이다.class Client : public RefBase {
public:
SharedClient* ctrlblk;
ClientID cid;
private:int mPid;
uint32_t mBitmap;
SortedVector<uint8_t> mInUse;
Vector< wp<LayerBaseClient> > mLayers;
sp<IMemoryHeap> mCblkHeap;
sp<SurfaceFlinger> mFlinger;
}class GraphicsPlane {
private:
DisplayHardware* mHw;
Transform mTransform;
Transform mOrientationTransform;
Transform mGlobalTransform;
int mOrientation;
}
class SurfaceFlinger : public BnSurfaceComposer, protected Thread {
private:
mutable MessageQueue mEventQueue;
mutable Mutex mStateLock;
State mCurrentState;
State mDrawingState;
volatile int32_t mTransactionFlags;
volatile int32_t mTransactionCount;
Condition mTransactionCV;
bool mResizeTransationPending;
Tokenizer mTokens;
DefaultKeyedVector<ClientID, sp<Client> > mClientsMap;
DefaultKeyedVector<SurfaceID, sp<LayerBaseClient> > mLayerMap;
GraphicPlane mGraphicPlanes[1];
bool mLayersRemoved;
Vector< sp<Client> > mDisconnectedClients;
sp<IMemoryHeap> mServerHeap;
surface_flinger_cblk_t* mServerCblk;
GLuint mWormholeTexName;
nsecs_t mBootTime;
Permission mHardwareTest;
Permission mAccessSurfaceFlinger;
Permission mDump;
Region mDirtyRegion;Region mDirtyRegionRemovedLayer;Region mInvalidRegion;Region mWormholeRegion;bool mVisibleRegionsDirty;bool mDeferReleaseConsole;bool mFreezeDisplay;int32_t mFreezeCount;nsecs_t mFreezeDisplayTime;int mDebugRegion;int mDebugBackground;volatile nsecs_t mDebugInSwapBuffers;nsecs_t mLastSwapBufferTime;volatile nsecs_t mDebugInTransaction;nsecs_t mLastTransactionTime;bool mBootFinished;mutable Barrier mReadyToRunBarrier;enum {eConsoleReleased = 1,eConsoleAcquired = 2};volatile int32_t mConsoleSignals;volatile int32_t mSecureFrameBuffer;class SurfaceFlinger::LayerVector {private:KeyedVector< sp<LayerBase> , size_t> lookup;Vector< sp<LayerBase> > layers;}}
class FreezeLock {
private:
SurfaceFlinger* mFlinger;
}
class BClient : public BnSurfaceFlingerClient {
private:
ClientID mId;
SurfaceFlinger* mFlinger;
sp<IMemoryHeap> mCblk;
}
소스를 보면 Client 에는 레이어를 생성하는 부분은 없다.Client::Client(ClientID clientID, const sp<SurfaceFlinger>& flinger)
: ctrlblk(0), cid(clientID), mPid(0), mBitmap(0), mFlinger(flinger)
{
const int pgsize = getpagesize();
const int cblksize = ((sizeof(SharedClient)+(pgsize-1))&~(pgsize-1));
mCblkHeap = new MemoryHeapBase(cblksize, 0,
"SurfaceFlinger Client control-block");
ctrlblk = static_cast<SharedClient *>(mCblkHeap->getBase());
if (ctrlblk) { // construct the shared structure in-place.
new(ctrlblk) SharedClient;
}
}
status_t Client::bindLayer(const sp<LayerBaseClient>& layer, int32_t id)
{
ssize_t idx = mInUse.indexOf(id);
if (idx < 0)
return NAME_NOT_FOUND;
return mLayers.insertAt(layer, idx);
}
sp<LayerBaseClient> Client::getLayerUser(int32_t i) const {
sp<LayerBaseClient> lbc;
ssize_t idx = mInUse.indexOf(uint8_t(i));
if (idx >= 0) {
lbc = mLayers[idx].promote();
LOGE_IF(lbc==0, "getLayerUser(i=%d), idx=%d is dead", int(i), int(idx));
}
return lbc;
}
SurfaceFlinger 에서 createConnection 과 destroyConnection 으로 Client 를 생성하고 삭제한다.sp<ISurfaceFlingerClient> SurfaceFlinger::createConnection()
{
Mutex::Autolock _l(mStateLock);
uint32_t token = mTokens.acquire();
sp<Client> client = new Client(token, this);
if (client->ctrlblk == 0) {
mTokens.release(token);
return 0;
}
status_t err = mClientsMap.add(token, client);
if (err < 0) {
mTokens.release(token);
return 0;
}
sp<BClient> bclient = new BClient(this, token, client->getControlBlockMemory());
return bclient;
}
void SurfaceFlinger::destroyConnection(ClientID cid){Mutex::Autolock _l(mStateLock);sp<Client> client = mClientsMap.valueFor(cid);if (client != 0) {Vector< wp<LayerBaseClient> > layers(client->getLayers());const size_t count = layers.size();for (size_t i=0 ; i<count ; i++) {sp<LayerBaseClient> layer(layers[i].promote());if (layer != 0) {purgatorizeLayer_l(layer);}}mClientsMap.removeItem(cid);mDisconnectedClients.add(client);setTransactionFlags(eTransactionNeeded);}}
BClient::BClient(SurfaceFlinger *flinger, ClientID cid, const sp<IMemoryHeap>& cblk)
: mId(cid), mFlinger(flinger), mCblk(cblk)
{
}
BClient::~BClient() {
// destroy all resources attached to this client
mFlinger->destroyConnection(mId);
}
sp<IMemoryHeap> BClient::getControlBlock() const {
return mCblk;
}
sp<ISurface> BClient::createSurface(
ISurfaceFlingerClient::surface_data_t* params, int pid,
DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
uint32_t flags)
{
return mFlinger->createSurface(mId, pid, params, display, w, h, format, flags);
}
status_t BClient::destroySurface(SurfaceID sid)
{
sid |= (mId << 16); // add the client-part to id
return mFlinger->removeSurface(sid);
}
status_t BClient::setState(int32_t count, const layer_state_t* states)
{
return mFlinger->setClientState(mId, count, states);
}
찾아보았으나 bindLayer 는 SurfaceFlinger 에서 호출하지 않는다.sp<ISurface> SurfaceFlinger::createSurface(ClientID clientId, int pid,
ISurfaceFlingerClient::surface_data_t* params,
DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
uint32_t flags)
{
sp<LayerBaseClient> layer;
sp<LayerBaseClient::Surface> surfaceHandle;
...
switch (flags & eFXSurfaceMask) {case eFXSurfaceNormal:if (UNLIKELY(flags & ePushBuffers)) {layer = createPushBuffersSurfaceLocked(client, d, id, w, h, flags);} else {layer = createNormalSurfaceLocked(client, d, id, w, h, flags, format);}break;case eFXSurfaceBlur:layer = createBlurSurfaceLocked(client, d, id, w, h, flags);break;case eFXSurfaceDim:layer = createDimSurfaceLocked(client, d, id, w, h, flags);break;}if (layer != 0) {setTransactionFlags(eTransactionNeeded);surfaceHandle = layer->getSurface();if (surfaceHandle != 0) {params->token = surfaceHandle->getToken();params->identity = surfaceHandle->getIdentity();params->width = w;params->height = h;params->format = format;}}return surfaceHandle;}
여기서 레이어를 생성한다.sp<LayerBaseClient> SurfaceFlinger::createNormalSurfaceLocked(
const sp<Client>& client, DisplayID display,
int32_t id, uint32_t w, uint32_t h, uint32_t flags,
PixelFormat& format)
{
// initialize the surfaces
switch (format) { // TODO: take h/w into account
case PIXEL_FORMAT_TRANSPARENT:
case PIXEL_FORMAT_TRANSLUCENT:
format = PIXEL_FORMAT_RGBA_8888;
break;
case PIXEL_FORMAT_OPAQUE:
format = PIXEL_FORMAT_RGB_565;
break;
}
sp<Layer> layer = new Layer(this, display, client, id);
status_t err = layer->setBuffers(w, h, format, flags);
if (LIKELY(err == NO_ERROR)) {
layer->initStates(w, h, flags);
addLayer_l(layer);
} else {
LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
layer.clear();
}
return layer;
}
그럼 Layer 가 초기화 되는부분을 보자.class Layer : public LayerBaseClient {
private:
sp<Surface> mSurface;
bool mSecure;
bool mNoEGLImageForSwBuffers;
int32_t mFrontBufferIndex;
bool mNeedsBlending;
bool mNeedsDithering;
Region mPostedDirtyRegion;
sp<FreezeLock> mFreezeLock;
PixelFormat mFormat;
// protected by mLock
sp<GraphicBuffer> mBuffers[NUM_BUFFERS];
Texture mTextures[NUM_BUFFERS];
sp<GraphicBuffer> mHybridBuffer;
uint32_t mWidth;
uint32_t mHeight;
mutable Mutex mLock;
}
과연 lcbk 가 무엇일까?Layer::Layer(SurfaceFlinger* flinger, DisplayID display,
const sp<Client>& c, int32_t i)
: LayerBaseClient(flinger, display, c, i),
mSecure(false),
mNoEGLImageForSwBuffers(false),
mNeedsBlending(true),
mNeedsDithering(false)
{
// no OpenGL operation is possible here, since we might not be
// in the OpenGL thread.
mFrontBufferIndex = lcblk->getFrontBuffer();
}
class LayerBase : public RefBase {
public:static const uint32_t typeInfo;static const char* const typeID;DisplayID dpy;mutable bool contentDirty;Region visibleRegionScreen;Region transparentRegionScreen;Region coveredRegionScreen;struct State {uint32_t w;uint32_t h;uint32_t requested_w;uint32_t requested_h;uint32_t z;uint8_t alpha;uint8_t flags;uint8_t reserved[2];int32_t sequence; // changes when visible regions can changeuint32_t tint;Transform transform;Region transparentRegion;};protected:sp<SurfaceFlinger> mFlinger;uint32_t mFlags;// cached during validateVisibility()bool mTransformed;bool mUseLinearFiltering;int32_t mOrientation;GLfixed mVertices[4][2];Rect mTransformedBounds;int mLeft;int mTop;// these are protected by an external lockState mCurrentState;State mDrawingState;volatile int32_t mTransactionFlags;// don't change, don't need a lockbool mPremultipliedAlpha;// atomicvolatile int32_t mInvalidate;}class LayerBaseClient : public LayerBase {public:
SharedBufferServer* lcblk;
private:
int32_t mIndex;
mutable Mutex mLock;
mutable wp<Surface> mClientSurface;
const uint32_t mIdentity;
static int32_t sIdentity;
}
LayerBaseClient 함수에서 SharedBufferServer* 형태로 선언되어 있는것을 알 수있다.
그럼 저 변수가 생성되는 부분을 찾아보자.
LayerBase.cpp 파일을 열면 아래 부분이 있다.
여기서 lcblk 변수를 생성하는데 생성자로 client->ctrlblk 가 들어간다.LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
const sp<Client>& client, int32_t i)
: LayerBase(flinger, display), lcblk(NULL), client(client),
mIndex(i), mIdentity(uint32_t(android_atomic_inc(&sIdentity)))
{
lcblk = new SharedBufferServer(
client->ctrlblk, i, NUM_BUFFERS,
mIdentity);
}
이것은 Client 에서 생성된 메모리인데 아마 이 클래스는 고유의 메모리를 같는것이 아니라 Client 에서 생성된 메모리로 서버 역할을 하는듯 하다.
이부분은 메모리 부분이라 나중에 분석하도록 하겠다.
이제 lcblk 가 어디서 생성되는지 알았으니 다시 Layer 로 돌아가자.
레이어는 생성되고나서 setBuffers 함수가 호출되는것을 볼 수있다.
Layer.cpp 파일을 열어서 확인해 보자.
일단 mBuffers 에다가 GraphicsBuffer 를 생성해서 채우는데 이게 무엇일까?status_t Layer::setBuffers( uint32_t w, uint32_t h,
PixelFormat format, uint32_t flags)
{
// this surfaces pixel format
PixelFormatInfo info;
status_t err = getPixelFormatInfo(format, &info);
if (err) return err;
// the display's pixel format
const DisplayHardware& hw(graphicPlane(0).displayHardware());
PixelFormatInfo displayInfo;
getPixelFormatInfo(hw.getFormat(), &displayInfo);
const uint32_t hwFlags = hw.getFlags();
mFormat = format;
mWidth = w;
mHeight = h;
mSecure = (flags & ISurfaceComposer::eSecure) ? true : false;
mNeedsBlending = (info.h_alpha - info.l_alpha) > 0;
mNoEGLImageForSwBuffers = !(hwFlags & DisplayHardware::CACHED_BUFFERS);
// we use the red index
int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED);
int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED);
mNeedsDithering = layerRedsize > displayRedSize;
for (size_t i=0 ; i<NUM_BUFFERS ; i++) {
mBuffers[i] = new GraphicBuffer();
}
mSurface = new SurfaceLayer(mFlinger, clientIndex(), this);
return NO_ERROR;
}
include 를 보니까 "ui/GraphicsBuffer.h" 파일에서 가져오는거 같다. 일단은 현 디렉토리만 분석중이니 넘어가자.
libs 디렉토리와 ui 디렉토리로 나누어 놓은 이유도 있을꺼 같은데 아직은 이유가 무엇인지 알수없다.
그럼 SurfaceLayer 소스를 보기위해 Layer.cpp 파일을 열어서 아래 부분을 찾아보자.
하는일이 아무것도 없다.Layer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger,
SurfaceID id, const sp<Layer>& owner)
: Surface(flinger, id, owner->getIdentity(), owner)
{
}
Layer::SurfaceLayer::~SurfaceLayer()
{
}
결국 그냥 Surface 를 상속받은 껍데기일 뿐이다.
Surface 역시 ui 에 있는데 이제 ui 쪽을 봐야할꺼 같다.
그럼 일단 Surface 를 찾아보도록 하자.
ui 쪽은 libs 쪽처럼 헤더가 붙어있는것이 아니고 나누어져 있다.
헤더는 frameworks/base/include/ui 에 있고 소스는 frameworks/base/libs/ui 에 있다.
나누어져 있다는것은 header 를 여기저기서 가져다 쓸수 있게 만들어둔다는 소리다.
그렇다면 ui 는 윗단에서 가져다 쓸 수 있게 만든것이고 libs 는 그 자체로만 쓸수 있게 만들어 놓은거 같다.
그럼 먼저 Surface.h 파일을 열어보자.
class SurfaceControl : public RefBase {
private:
sp<SurfaceComposerClient> mClient;
sp<ISurface> mSurface;
SurfaceID mToken;
uint32_t mIdentity;
uint32_t mWidth;
uint32_t mHeight;
PixelFormat mFormat;
uint32_t mFlags;
mutable Mutex mLock;
mutable sp<Surface> mSurfaceData;
}
class Surface : public EGLNativeBase<android_native_window_t, Surface, RefBase> {
private:
// constants
sp<SurfaceComposerClient> mClient;
sp<ISurface> mSurface;
SurfaceID mToken;
uint32_t mIdentity;
PixelFormat mFormat;
uint32_t mFlags;
GraphicBufferMapper& mBufferMapper;
SharedBufferClient* mSharedBufferClient;
// protected by mSurfaceLock
Rect mSwapRectangle;
uint32_t mUsage;
// protected by mSurfaceLock. These are also used from lock/unlock
// but in that case, they must be called form the same thread.
sp<GraphicBuffer> mBuffers[2];
mutable Region mDirtyRegion;
// must be used from the lock/unlock thread
sp<GraphicBuffer> mLockedBuffer;
sp<GraphicBuffer> mPostedBuffer;
mutable Region mOldDirtyRegion;
bool mNeedFullUpdate;
// query() must be called from dequeueBuffer() thread
uint32_t mWidth;
uint32_t mHeight;
// Inherently thread-safe
mutable Mutex mSurfaceLock;
mutable Mutex mApiLock;}
그럼 Surface.cpp 파일도 열어보자.
Surface 클래스는 android_native_window_t 구조체를 상속받고 있기 때문에 init 함수에서 해당 구조체를 채워주는 일을 한다.Surface::Surface(const sp<SurfaceControl>& surface)
: mClient(surface->mClient), mSurface(surface->mSurface),
mToken(surface->mToken), mIdentity(surface->mIdentity),
mFormat(surface->mFormat), mFlags(surface->mFlags),
mBufferMapper(GraphicBufferMapper::get()), mSharedBufferClient(NULL),
mWidth(surface->mWidth), mHeight(surface->mHeight)
{
mSharedBufferClient = new SharedBufferClient(
mClient->mControl, mToken, 2, mIdentity);
init();
}
void Surface::init()
{
android_native_window_t::setSwapInterval = setSwapInterval;
android_native_window_t::dequeueBuffer = dequeueBuffer;
android_native_window_t::lockBuffer = lockBuffer;
android_native_window_t::queueBuffer = queueBuffer;
android_native_window_t::query = query;
android_native_window_t::perform = perform;
mSwapRectangle.makeInvalid();
DisplayInfo dinfo;
SurfaceComposerClient::getDisplayInfo(0, &dinfo);
const_cast<float&>(android_native_window_t::xdpi) = dinfo.xdpi;
const_cast<float&>(android_native_window_t::ydpi) = dinfo.ydpi;
// FIXME: set real values here
const_cast<int&>(android_native_window_t::minSwapInterval) = 1;
const_cast<int&>(android_native_window_t::maxSwapInterval) = 1;
const_cast<uint32_t&>(android_native_window_t::flags) = 0;
// be default we request a hardware surface
mUsage = GRALLOC_USAGE_HW_RENDER;
mNeedFullUpdate = false;
}
구조체로 상속할수 있다는것을 첨알았다.
자 이제 더이상 따라갈 수가 없다.
이부분에 대해서는 조금 더 생각해 봐야겠다.



