android surfaceflinger 代码,系统的SurfaceFlinger思路以及代码追踪

(mControlMemory->getBase());

}

获得Surface对应的显示缓冲区

虽然在SurfaceFlinger在创建Layer时已经为每个Layer申请了两个缓冲区,但是此时在JAVA层并看不到这两个缓冲区,JAVA层要想在Surface上进行画图操作,必须要先把其中的一个缓冲区绑定到Canvas中,然后所有对该Canvas的画图操作最后都会画到该缓冲区内。下图展现了绑定缓冲区的过程:

uid-27411029-id-3444439.html

图二 绑定缓冲区的过程

开始在Surface画图前,Surface.java会先调用lockCanvas()来得到要进行画图操作的Canvas,lockCanvas会进一步调用本地层的Surface_lockCanvas,本地代码利用JAVA层传入的SurfaceControl对象,通过getSurface() 取得本地层的Surface对象,接着调用该Surface对象的lock()方法,lock()返回了改Surface的信息,其中包括了可用缓冲区的首地址vaddr,该vaddr在Android的2D图形库Skia中,创建了一个bitmap,然后通过Skia库中Canvas的 API:Canvas.setBitmapDevice(bitmap),把该bitmap绑定到Canvas中,最后把这个Canvas返回给JAVA 层,这样JAVA层就可以在该Canvas上进行画图操作,而这些画图操作最终都会画在以vaddr为首地址的缓冲区中。

再看看在Surface的lock()方法中做了什么:

dequeueBuffer(&backBuffer)获取backBuffer

SharedBufferClient->dequeue()获得当前空闲缓冲区的编号

通过缓冲区编号获得真正的GraphicBuffer:backBuffer

如果还没有对Layer中的buffer进行映射(Mapper),getBufferLocked通过ISurface接口重新重新映射

获取frontBuffer

根据两个Buffer的更新区域,把frontBuffer的内容拷贝到backBuffer中,这样保证了两个Buffer中显示内容的同步

backBuffer->lock() 获得backBuffer缓冲区的首地址vaddr

通过info参数返回vaddr

释放Surface对应的显示缓冲区

画图完成后,要想把Surface的内容显示到屏幕上,需要把Canvas中绑定的缓冲区释放,并且把该缓冲区从变成可投递(因为默认只有两个 buffer,所以实际上就是变成了frontBuffer),SurfaceFlinger的工作线程会在适当的刷新时刻,把系统中所有的 frontBuffer混合在一起,然后通过OpenGL刷新到屏幕上。下图展现了解除绑定缓冲区的过程:

uid-27411029-id-3444439.html

图三 解除绑定缓冲区的过程

JAVA层调用unlockCanvasAndPost

进入本地代码:Surface_unlockCanvasAndPost

本地代码利用JAVA层传入的SurfaceControl对象,通过getSurface()取得本地层的Surface对象

绑定一个空的bitmap到Canvas中

调用Surface的unlockAndPost方法

调用GraphicBuffer的unlock(),解锁缓冲区

在queueBuffer()调用了SharedBufferClient的queue(),把该缓冲区更新为可投递状态

SharedClient 和 SharedBufferStack

从前面的讨论可以看到,Canvas绑定缓冲区时,要通过SharedBufferClient的dequeue方法取得空闲的缓冲区,而解除绑定并提交缓冲区投递时,最后也要调用SharedBufferClient的queue方法通知SurfaceFlinger的工作线程。实际上,在 SurfaceFlinger里,每个Layer也会关联一个SharedBufferServer,SurfaceFlinger的工作线程通过 SharedBufferServer管理着Layer的缓冲区,在SurfaceComposerClient建立连接的阶段,SurfaceFlinger就已经为该连接创建了一个SharedClient 对象,SharedClient 对象中包含了一个SharedBufferStack数组,数组的大小是31,每当创建一个Surface,就会占用数组中的一个 SharedBufferStack,然后SurfaceComposerClient端的Surface会创建一个 SharedBufferClient和该SharedBufferStack关联,而SurfaceFlinger端的Layer也会创建 SharedBufferServer和SharedBufferStack关联,实际上每对 SharedBufferClient/SharedBufferServer是控制着同一个SharedBufferStack对象,通过 SharedBufferStack,保证了负责对Surface的画图操作的应用端和负责刷新屏幕的服务端(SurfaceFlinger)可以使用不同的缓冲区,并且让他们之间知道对方何时锁定/释放缓冲区。

SharedClient和SharedBufferStack的代码和头文件分别位于:

/frameworks/base/libs/surfaceflinger_client/SharedBufferStack.cpp

/frameworks/base/include/private/surfaceflinger/SharedBufferStack.h

uid-27411029-id-3444439.html

图四 客户端和服务端缓冲区管理

继续研究SharedClient、SharedBufferStack、SharedBufferClient、 SharedBufferServer的诞生过程。

1. SharedClient

在createConnection阶段,SurfaceFlinger创建Client对象:

spSurfaceFlinger::createConnection()

{

Mutex::Autolock _l(mStateLock);

uint32_t token = mTokens.acquire();

spclient = newClient(token,this);

if(client->ctrlblk == 0) {

mTokens.release(token);

return0;

}

status_t err = mClientsMap.add(token, client);

if(err < 0) {

mTokens.release(token);

return0;

}

spbclient =

newBClient(this, token, client->getControlBlockMemory());

returnbclient;

}

sp

SurfaceFlinger::createConnection()

{

Mutex::Autolock _l(mStateLock);

uint32_t token = mTokens.acquire();

spclient = newClient(token,this);

if(client->ctrlblk == 0) {

mTokens.release(token);

return0;

}

status_t err = mClientsMap.add(token, client);

if(err < 0) {

mTokens.release(token);

return0;

}

spbclient =

newBClient(this, token, client->getControlBlockMemory());

returnbclient;

}spSurfaceFlinger::createConnection()

{

Mutex::Autolock _l(mStateLock);

uint32_t token = mTokens.acquire();

spclient = 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;

}

spbclient =

new BClient(this, token, client->getControlBlockMemory());

return bclient;

}

再进入Client的构造函数中,它分配了4K大小的共享内存,并在这块内存上构建了SharedClient对象:

Client::Client(ClientID clientID,constsp& flinger)

: ctrlblk(0), cid(clientID), mPid(0), mBitmap(0), mFlinger(flinger)

{

constintpgsize = getpagesize();

constintcblksize = ((sizeof(SharedClient)+(pgsize-1))&~(pgsize-1));

mCblkHeap = newMemoryHeapBase(cblksize, 0,

"SurfaceFlinger Client control-block");

ctrlblk = static_cast(mCblkHeap->getBase());

if(ctrlblk) {// construct the shared structure in-place.

new(ctrlblk) SharedClient;

}

}

Client::Client(ClientID

clientID, constsp& flinger)

: ctrlblk(0), cid(clientID), mPid(0), mBitmap(0), mFlinger(flinger)

{

constintpgsize = getpagesize();

constintcblksize =

((sizeof(SharedClient)+(pgsize-1))&~(pgsize-1));

mCblkHeap = newMemoryHeapBase(cblksize, 0,

"SurfaceFlinger Client control-block");

ctrlblk = static_cast

*>(mCblkHeap->getBase());

if(ctrlblk) {// construct the shared structure in-place.

new(ctrlblk) SharedClient;

}

}Client::Client(ClientID

clientID, const sp& 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(mCblkHeap->getBase());

if (ctrlblk) { // construct the shared structure in-place.

new(ctrlblk) SharedClient;

}

}

回到createConnection中,通过Client的getControlBlockMemory()方法获得共享内存块的 IMemoryHeap接口,接着创建ISurfaceFlingerClient的子类BClient,BClient的成员变量mCblk保存了 IMemoryHeap接口指针;

把BClient返回给SurfaceComposerClient,SurfaceComposerClient通过 ISurfaceFlingerClient接口的getControlBlock()方法获得IMemoryHeap接口指针,同时保存在 SurfaceComposerClient的成员变量mControlMemory中;

继续通过IMemoryHeap接口的getBase ()方法获取共享内存的首地址,转换为SharedClient指针后保存在SurfaceComposerClient的成员变量mControl中;

至此,SurfaceComposerClient的成员变量mControl和SurfaceFlinger::Client.ctrlblk 指向了同一个内存块,该内存块上就是SharedClient对象。

2. SharedBufferStack、SharedBufferServer、SharedBufferClient

SharedClient对象中有一个SharedBufferStack数组:

SharedBufferStack surfaces[ NUM_LAYERS_MAX ];

NUM_LAYERS_MAX 被定义为31,这样保证了SharedClient对象的大小正好满足4KB的要求。创建一个新的Surface时,进入SurfaceFlinger的 createSurface函数后,先取在createConnection阶段创建的Client对象,通过Client在 0--NUM_LAYERS_MAX 之间取得一个尚未被使用的编号,这个编号实际上就是SharedBufferStack数组的索引:

int32_t id = client->generateId(pid);

int32_t

id = client->generateId(pid);int32_t

id = client->generateId(pid);

然后以Client对象和索引值以及其他参数,创建不同类型的Layer对象,一普通的Layer对象为例:

layer = createNormalSurfaceLocked(client, d, id,

w, h, flags, format);

layer

= createNormalSurfaceLocked(client, d, id,

w, h, flags, format);layer

= createNormalSurfaceLocked(client, d, id,

w, h, flags, format);

在createNormalSurfaceLocked中创建Layer对象:

splayer =newLayer(this, display, client, id);

sp

layer = newLayer(this, display, client, id);splayer = new Layer(this, display, client, id);

构造Layer时会先构造的父类LayerBaseClient,LayerBaseClient中创建了SharedBufferServer对象,SharedBufferStack 数组的索引值和SharedClient被传入SharedBufferServer对象中。

LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,

constsp& client, int32_t i)

: LayerBase(flinger, display), lcblk(NULL), client(client), mIndex(i),

mIdentity(uint32_t(android_atomic_inc(&sIdentity)))

{

lcblk = newSharedBufferServer(

client->ctrlblk, i, NUM_BUFFERS,

mIdentity);

}

LayerBaseClient::LayerBaseClient(SurfaceFlinger*

flinger, DisplayID display,

constsp& client, int32_t i)

: LayerBase(flinger, display), lcblk(NULL), client(client),

mIndex(i),

mIdentity(uint32_t(android_atomic_inc(&sIdentity)))

{

lcblk = newSharedBufferServer(

client->ctrlblk, i, NUM_BUFFERS,

mIdentity);

}LayerBaseClient::LayerBaseClient(SurfaceFlinger*

flinger, DisplayID display,

const sp& 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);

}

自此,Layer通过lcblk成员变量(SharedBufferServer)和SharedClient共享内存区建立了关联,并且每个Layer 对应于SharedBufferStack 数组中的一项。

回到SurfaceFlinger的客户端Surface.cpp中,Surface的构造函数如下:

Surface::Surface(constsp& 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 = newSharedBufferClient(

mClient->mControl, mToken, 2, mIdentity);

init();

}

Surface::Surface(const

sp& 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 = newSharedBufferClient(

mClient->mControl, mToken, 2, mIdentity);

init();

}Surface::Surface(const

sp& 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();

}

SharedBufferClient构造参数mClient->mControl就是共享内存块中的SharedClient对象,mToken就是SharedBufferStack 数组索引值。到这里我们终于知道,Surface中的 mSharedBufferClient成员和Layer中的lcblk成员(SharedBufferServer),通过SharedClient中的同一个SharedBufferStack,共同管理着Surface(Layer)中的两个缓冲区

补充一点上面说的逻辑结构都是针对一个APK和surfaceflinger来说的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值