Android中,在 HAL 层抽象了 Gralloc 模块,封装了对帧缓冲区的访问操作。加载 Gralloc 模块后,获得一个 gralloc 设备和 fb 设备。通过 gralloc,用户空间申请分配一块图形缓冲区,并且映射到应用程序的地址空间,以便写入想要绘制的内容。随后用户空间程序通过 fb 设备将绘制好的图形缓冲区渲染到帧缓冲区,即显示屏中。当不需要这一块图形缓冲区时,通过 gralloc 设备释放,同时解除映射。
在 Linux 中,一个显示屏被抽象为一个帧缓冲区,注册到 FrameBuffer 中。
- HWComposer:信号源。
产生 VSync 信号,可以由硬件产生,也可以选择软件模拟产生。在 SurfaceFlinger->readyToRun( )的实例化。关键点,SurfaceFinger 派生自 HWComposer::EventHandler并且成为 HWComposer 的信号处理者。当 HWComposer产生 VSync 信号时,会回调SurfaceFlinger->onVSyncReceived( ),后者会将会回调 EventThread->onVSyncReceived( ) - EventThread:是一个事件线程,内部通过 threadLoop( ) 不断得监听事件。当第三方程序调用 EventThread::createEventConnection( )可以认为是希望与 EventThread 产生一个连接,EventThread 返回一个 Connection 对象,在 Connection 对象实例化时,会在 onFirstRef()中调用 EventThread::registerDisplayEventConnection( )将自身加入监听列表。
- MessageQueue mEventQueue:可以认为是消息队列,同时内部提供了 Looper 和 Handler 进行消息处理。在 SurfaceFlinger onFirstRef( )的时候进行 init( )。
- SurfaceFlinger 会通过 MessageQueue::setEventThread(const sp<EventThread>& eventThread)将 MessageQueue 与 EventThread 产生联系
void MessageQueue::setEventThread(const sp<EventThread>& eventThread)
{
mEventThread = eventThread;
mEvents = eventThread->createEventConnection( );
mEventTube = mEvents->getDataChannel( );
mLooper->addFd(mEventTube->getFd( ), 0, ALOOPER_EVENT_INPIT, MessageQueue::cb_eventReceiver,this);
}
这样,MessageQueue 就监听了这个 BitTube mEventTube。当 EventThread 收到事件时,会收集所有有效的注册在案的 Connection,对 Connections 进行遍历,通过 EventThread::Connection::postEvent( ),调用 DisplayEventReceiver::sendEvents(mChannel, &event,1)
//EventThread.cpp
status_t EventThread::Connection::postEvent(const DisplayEventReceiver::Event& event)
{
ssize_t size = DisplayEventReceiver::SendEvents(mChannel, &event, 1);
}
//DisplayEventReceiver.cpp
ssize_t DisplayEventReceiver::sendEvents(const sp<BitTube>& dataChannel, Event const* events, size_t count)
{
return BitTube::sendObject(dataChannel, events, count);
}
//BitTube.cpp
ssize_t BitTube::sendObjects(const sp<BitTube>& tube, void const* events, size_t count, size_t objSize)
{
ssize_t numObjects = 0;
for(ssize_t i=0; i<count; i++){
...
ssize_t size = tube->write(vaddr, objSize);
...
}
...
}
于是当 EventThread 有事件发生,变会遍历其 Connection,像 Connection 的 BitTube 对象写入事件。当写入到 MessageQueue 注册的 Connection 时,MessageQueue 的 Looper 便会监听到事件,回调其 BitTube::getFd( ) 在 looper 中注册的处理函数 MessageQueue::cb_eventReceiver( ),后者通过 DisplayEventReceiver::getEvent( )获得 EventThread 写入到 BitTube 中是 Event,随后 MessageQueue 便通过其内部的 Handler 进行处理消息(MessageQueue 只会处理消息类型为 DisplayEventReceiver::DISPLAY_EVENT_VSYNC的事件,其他时间会被丢弃)。MessageQueue 内部的 Handler 会将消息转交给 SurfaceFlinger 进行处理。
- BitTube 是通过 Socket 进行进程间通信的。
到此 SurfaceFlinger 相关体系从 EventThread 收到消息到 SurfaceFlinger 收到并且处理消息便告一段落。
关于 SurfaceComposerClient
当一个应用程序与 WMS 连接时,WMS 会返回一个 Session 作为应用像 WSM 发起请求的中介。同时会产生一个 SurfaceSession 对象(一个应用程序对应一个 session 对应一个 SurfaceSession)
//Session.java
void windowAddedLocked( ){
if(mSurfaceSession == null){
mSurfaceSession = new SurfaceSession( );
}
}
//SurfaceSession.java
public SurfaceSession( ){
//mNativeClient 就对应一个 SurfaceComposerClient 对象
mNativeClient = nativeCreate( );
}
//android_view_SurfaceSession.cpp
static jint nativeCreate(JNIEnv* env, jclass clazz){
SurfaceComposerClient* client = new SurfaceComposerClient( );
...
}
//SurfaceComposerClient.cpp
SurfaceComposerClient::SurfaceComposerClient( )
: mStatus(NO_INIT),mComposer(Composer::getInstance())
void SurfaceComposerClient::onFirstRef( ){
sp<ISurfaceComposer> sm(ComposerService::getComposerService( ));
if(sm != 0){
//是一个 Client 对象,sm 即为 SurfaceFlinger
sp<ISurfaceComposerClient> conn=sm->createConnection( );
mClient = conn;
}
}
//SurfaceFlinger.cpp
sp<ISurfaceComposerClient> SurfaceFlinger::createConnection( ){
sp<ISurfaceComposerClient> bclient;
sp<Client> client(new Client(this));
status_t err = client->initCheck( );
if(err = NO_ERROR){
bclient = client;
}
return client;
}
//Client.cpp
Client::Client(const sp<SurfaceFlinger>& flinger)
::mFlinger(flinger)
{
}
于是,当一个应用第一个和 WMS 交互时,会实例化一个 Session 作为该应用与 WMS 交互的通道,Session 内部持有一个SurfaceSession对象作为,SurfaceSession在 native 层对应一个 SurfaceComposerClient 对象,SurfaceComposerClient 对象持有一个 Client,于是通过 SurfaceSession->SurfaceComposerClient->Client 与 SurfaceFlinger 进行交互。在 View 体系中的 Surface,SurfaceControl,Layer 都是通过这个 Client 像 SurfaceFlinger 申请创建的。
关于 SurfaceControl 和 Surface
在 APP 与 WMS 交互时,会通过 WMS 实例化一个 SurfaceControl 对象。
//WindowManagerService.java
public int relayoutWindow(...){
SurfaceControl surfaceControl = winAnimator.createSurfaceLocked( );
}
//WindowStateAnimator.java
SurfaceControl createSurfaceLocked( ){
mSurfaceControl = new SurfaceControl(mSession.mSurfaceSession,...);
}
//SurfaceControl.java
public SurfaceControl(SurfaceSession session,...){
...
mNativeObject = nativeCreate(session, name, w, h, format. flags);
}
//android_view_SurfaceControl.cpp
static jint nativeCreate(...){
//client 是 SurfaceComposerClient 对象
sp<SurfaceComposerClient client(android_view_SurfaceSession_getClient(env,seesionObj));
sp<SurfaceControl> surface = client->createSurface(...);
}
//SurfaceComposerClient.cpp
sp<SurfaceControl> SurfaceComposerClient::createSurface(..){
sp<SurfaceControl> sur;
sp<IBinder> handle;
sp<IGraphicBufferProducer> gbp;
status_t err = mClient->createSurface(name, w, h, format, flags, &handle, &gbp);
sur = new SurfaceControl(this, handle, gbp);
}
可以看见,在创建 Java 层的 SurfaceControl 的时候,会用 jni 层层调用,最后通过 SurfaceComposerClient.cpp 创建SurfaceControl 对象。下来看重点看 SurfaceControl 的创建过程。
- 首先看 Surface 的创建。
//status_t Client::createSurface(const String8& name, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp){
class MessageCreateLayer:public MessageBase {
...
virtual bool handler( ){
result = flinger->createLayer(name, client, w, h, format, flags, handle, gbp);
}
}
sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(), name, this, w, h, format, flags, handle, gbp);
mFlinger->postMessageSync(msg);
...
}
MessageCreateLayer 作为一个 Message,在 post 后,会调用其 handler( )方法,于是会调用 SurfaceFlinger::createLayer( )进行 Layer 的创建。
status_t SurfaceFlinger::createLayer(const String8& name, const sp<Client>& client, uint32_t w, uint32_t h, PixelFormat format, uint32_T flags, sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp){
sp<Layer> layer;
swicth(...){
case ... :
result = createNormalLayer(client, name, w, h, flags, format, handle, gbp, &layer);
break;
case ... :
result = createDimLayer(client, name, w, h, flags, handle, gbp, &layer);
}
addClientLayer(client, *handle, *gbp, layer);
}
会根据需要创建的不同 Surface 类型创建不同的 Layer,现在只看 normalLayer
status_t SurfaceFlinger::createNormalLayer(const sp<Client>& client, const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format, sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer){
*outLayer = new Layer(this, client, name, w, h, flags);
status_t err = (*outLayer)->setBuffers(w,h, format, flags);
*handle = (*outLayer)->getHandle();
*gbp = (*outLayer)->getBufferQueue();
}
于是,来看 new Layer( )的实现
//Layer.cpp
Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,...){
...
}
void Layer::onFirstRef( ){
sp<BufferQueue> bq = new SurfaceTextureLayer(mFlinger);
mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mTextName, true, GL_TEXTURE_EXTERNAL_OES, false, bq);
..
mSurfaceFlingerConsumer->setFrameAvailableListener(this);
...
}
创建 Layer 的时候有几个关键点,首先,创建了一个 SurfaceTextureLayer 作为BufferQueue,其次,创建了一个 SurfaceFlingerConsumer作为 consumer,当 APP 对于 Surface 进行 lock 获得一块 Canvas 后,进行 draw,随后进行 unLock(),在 unLock()时,会将 buffer 进行 enqueue,在 BufferQueue 对 buffer 进行 enqueue 时,会回调SurfaceFlingerConsumer(派生自 GLConsumer,派生自 ConsumerBase)中的FrameAvailableListener(Layer 派生自 SurfaceFlingerConsumer::FrameAvailableListener)方法onFrameAvailable(), 该方法会通知 SurfaceFlinger::signalLayerUpdate( )进行刷新。
于是,在 Layer 中,BufferQueue 是 SurfaceTextureLayer,ConsumerBase 为 SurfaceFlingerConsumer,后者的消费回调为 Layer本身 Layer::onFrameAvailable( );
sp<IBinder> Layer::getHandl( ){
class Handle : public BBinder, public LayerCleaer{
...
}
return new Handle(mFlinger, this);
}
于是,返回的 Handle 持有 SurfaceFlinger 和 Layer 本身。
sp<BufferQueue> Layer::getBufferQueue( ) const{
return mSurfaceFlingerConsumer->getBufferQueue();
}
于是,返回的 IGraphicBufferProducer 是 SurfaceTextureLayer对象(派生自 BufferQueue),内部持有 SurfaceFlinger,在 BufferQueue 实例化的时候,会通过 createGraphicBufferAlloc( )向 SurfaceFlinger 申请一个 GraphicBufferAlloc 对象
//SurfaceFlinger.cpp
sp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc( ){
sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc( ));
return gba;
}
于是 SurfaceComposerClient::createSurface( )中的 mClient->createSurface( )便分析完了,通过 mClinent->createSurface( ),在 normal 情况下,创建了一个 Layer 对象,内部持有一个 BufferQueue,ConsumerBase(Layer 作为SurfaceFlingerConsumer::FrameAvailableListener),&handle 对象为 Layer 的内部内,持有 Layer 本身与 SurfaceFlinger,&gbp 是 SurfaceTextureLayer 对象(派生自 BufferQueue),内部像 SurfaceFlinger 申请了一个 GraphicBufferAlloc。
SurfaceControl::SurfaceControl(const sp<SurfaceClient>& client, const sp<IBinder>& handle, const sp<IGraphicBufferProducer>& gbp)
:mClient(client), mHandle(handle), mGraphicBufferProducer(gbp)
{
}
可以看到,SurfaceControl只是简单地持有了 SurfaceComposerClient mClient, Handle mHandle, IGraphicBufferProducer mGraphicBufferProducer对象。真的只是 Control!
于是在 WMS 就为 APP 端生成了一个 SurfaceControl。
在 aidl 中,有客户端调用的 Surface 作为出参(out), 在对 aidl 生成可以发现,客户端的 Surface 并不会作为 Binder 的参数传递给 WSM,而是 WSM 生成了 Surface,将WSM 生成的 Surface 透到客户端,客户端从 WM 透来的 Surface,copy 到客户端的 Surface。
现在WSM有了一个 SurfaceControl,WSM会调用 copyFrom(SurfaceControl)@Surface.java 生成透传给客户端的 Surface 对象了。
//Surface.java
public void copyForm(SurfaceControl other){
int surfaceControlPtr = other.mNativeObject;
int newnativeObject = nativeCreateFromSurfaceControl(surfaceControlPtr);
setNativeObjectLocked(newNativeObject);
}
//android_view_Surface.cpp
static jint nativeCreateFromSurfaceControl(JNIEnv* env, jclass clazz, jint surfaceControlNativeObj){
sp<SurfaceControl> ctl(reinterpret_cast<SurfaceControl *>(surfaceControlNativeObj));
sp<Surface> surface(ctl->getSurface( ));
return reinterpret_cast<jint>(surface.get( ));
}
//SurfaceControl.cpp
sp<Surface> SurfaceControl::getSurface( ) const{
mSurfaceData = new Surface(mGraphicBufferProducer);
return mSurfaceData;
}
于是,outSurface便 copy 完成了,只是简单的从 SurfaceControl中获得 IGraphicBufferProducer,让 Surface.cpp 持有,Surface.java 在 native 端持有该 Surface.cpp。
WSM 将结果传给 APP 时,会将该 outSurface进行writeToParcel(),随后客户端进行readFromParcel(),先看 WSM端的 writeToParcel( )
//Surface.java
public void writeToParcel(Parcel dest, int flags ){
nativeWriteToParcel(mNativeSurface, dest);
}
//android_view_Surface.cpp
static void nativeWriteToParcel(JNIEnv* env, jclass clazz, jint nativeObject, jobject parcelObj){
Parcel* parcel = parcelFroJavaObject(env, parcelObj);
sp<Surface> self(reinterpret_cast<Surface *>(nativeObject));
parcel->writeStrongBinder(self!=0? self->getIGraphicBufferProducet( )->asBinder( ): NULL);
}
同理来看 nativeReadFromParcel( )
static jint nativeReadFromParcel(JNIEnv* env, jcalss clazz, jint nativeObject, jobject parcelObj){
Parcel* parcel = parcelForJavaObject(env, parcelObj);
sp<IBinder> binder(parcel->readStringBinder( ));
sp<Surface> sur;
sp<IGraphicBufferProducer> gpb(interface_cast<IGraphicBufferProducer>(binder));
sur = new Surface(gbp);
}
可以看到,Surface 在 Binder 间通讯的时候,只是将其 IGraphicBufferProducer(normal Layer 来说是 SurfaceTextureLayer)进行传递。IGraphicBufferProducer 是 buffer的生产者,客户端对 buffer 的lock 和 unlock 都是通过 IGraphicBufferProducer 进行的。
继承结构由 SurfaceTextureLayer 派生自 BufferQueue,SurfaceFlingerConsumer派生自 GLConsumer派生自 ConsumerRef派生自 BufferQueue::ConsumerListener
在 Layer::onFirstRef( )中可以看到
sp<BufferQueue> bq = new SurfaceTexturreLayer(mFlinger);
mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mTextureName, true, GL_TEXTURE_EXTERNAL_OES, false, bq);
//ConsumerBase.cpp
ConsumerBase::ConsumerBase(const sp<BufferQueue>& bufferQueue):
mAbandoned(false), mBufferQueue(bufferQueue){
wp<BufferQueue::ConsumerListener> listener;
sp<BufferQueue::ConsumerListener> proxy;
listener = static_cast<BufferQueue::ConsumerListener*>(this);
proxy = new BufferQueue::ProxyConsumerListener(listener);
mBufferQueue->consumerConnect(proxy);
}
于是,在 SurfaceTextureLayer 中的sp<ConsumerListener> mConsumerListener 就是 SurfaceFlingerConsumer 对象本身。那么来看 SurfaceConsumer::onFrameAvailable()方法是在父类 ConsumerBase.cpp 中定义
void ConsumerBase::onFrameAvailable(){
sp<FrameAvailableListener> listener;
listener=mFrameAvailableListener.promote();
listener->onFrameAvailable();
}
那么来看这个 mFrameAvailableListener 是在哪里赋值的
//ConsumerBase.cpp
void ConsumerBase::setFrameAvailableListener(const wp<FrameAvailableListener>& listener){
mFrameAvailableListener = listener;
}
很熟悉,在 Layer::onFirstRef()中
//Layer.cpp
void Layer::onFirstRef( ){
mSurfaceFlingerConsumer->setFrameAvailableListener(this);
}
void Layer::onFrameAvilable( ){
mFlinger->singnalLayerUpdate();
}
兜兜转转,从 BufferQueue->listener->onFrameAvailable() 转到ConsumerBase(Layer 中的 SurfaceFlingerConsumer)->onFrameAvailable()转到 Layer::onFrameAvilable()转到 SurfaceFlinger::signalLayerUpdate();[重点]
在 performDraw()@ViewRootImpl 中调用 draw(fullRedrawNeed),现在只分析软件绘制 drawSoftware()
private boolean drawSoftware(Surface surface, AttachInfo attachInfo, int yoff, boolean caslingRequired, Rect dirty){
Surface surface = mSurface;
Canvas canvas = mSurface.lockCanvas(dirty);
mView.draw(canvas);
surface.unlockCanvasAndPost(canvas);
}
通过 lockCanvas()@Surface 获得一个 Canvas,然后 draw()@View[就是 Application 层可控的地方],绘制完成后 unlockCanvasAndPost()@Surface。
public Canvas lockCanvas(Rect inOutDirty){
nativeLockCanvas(mNativeSurface, mCanvas, inOutDirty);
}
//android_view_Surface.cpp
static void nativeLockCanvas(JNIEnv* env, jclass clazz, jint nativeObject, jobject canvasObj, jobject dirtyRectObj){
ANativeWindow_Buff outBuffer;
Rect dirtyBounds(dirtyRegion.getBounds());
surface->lock(&outBuffer, &dirtyBounds);
Skbitmap bitmap;
bitmap.setPixels(outBuffer.bits);
SkCanvas* nativeCanvas = SKNEW_ARGS(SkCanvas,(bitmap));
swapCanvasPtr(env, canvasObj, nativeCanvas);
nativeCanvas->clipRegion(clipReg);
}
通过 lock()@Surface.cpp 获得一块GraphicBuffer(通过匿名共享内存 ashmem 系统),随后实例化 SkCanvas(java层 Canvas 的 native 实现)。随后客户端进行绘制,然后进行 unlock
//android_view_Surface.cpp
static void nativeUnlockCanvasAndPost(JNIEnv* env, jclass clazz, jint nativeObject, jobject canvasObje){
sp<Surface> surface(reinterpret_cast<Surface *>(nativeObject));
SkCanvas* nativeCanvas=SkNEW(SkCanvas);
swapCanvasPtr(env, canvasObj, nativeCanvas);
surface->unlockAndPost();
}
//Surface.cpp
status_t Surface::unlockAndPost(){
mLockedBuffer->unlock();
queueBuffer(mLockBuffer.get(),-1);
mPostedBuffer=mLockedBuffer;
mLockedBuffer=0;
}
int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd){
int i = getSlotFromBufferLocked(buffer);
IGraphicBufferProducer::QueueBufferOutput output;
IGraphicBufferProducer::QueueBufferInput input(timestamp, crop, mScalingMode, mTransform, fence);
mGraphicBufferProducer->queueBuffer(i, input, &output);
}
//BufferQueue.cpp
status_t BufferQueue::queueBuffer(int buf, const QueueBufferInput& input, QueueBufferOutput* output){
..
listener->onFrameAvailable();
}
前面提到,就转到了 SurfaceFlinger-> signalLayerUpdate()进行更新 buffer
关于 GraphicBuffer
当调用 dequeueBuffer()@BufferQueue.cpp 申请一块 Buffer 时,实际上是通过 createGraphicBuffer()@GraphicBufferAlloc 申请。
//GraphicBufferAlloc.cpp
sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage, status_t* error){
sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
}
//GraphicBuffer.cpp
GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h, PixelFormat reqFormat, uint32_t reqUsage)
: BASE(), oWner(ownData), mBufferMapper(GraphicBufferMapper::get()),
mInitCheck(NO_ERROR), mIndex(-1){
...
mInitCheck=initSize(w, h, reqFormat, reqUsage);
}
重点就是在 initSize()分配内存
status GraphicBuffer::initSize(uint32_t w, uint32_t h, PixelFormat format, uint32_t reqUsage){
GraphicBufferAllocator& allocator = GraphicBufferAllocator::get();
allocator.alloc(w, h, format, reqUsage, &handle, &stride);
}
//GraphicBufferAllocator::GraphicBufferAllocator()
: mAllocDev(0){
hw_module_t const* module;
int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
gralloc_open(module, &mAllocDev);
}
status_t GraphicBufferAllocator::alloc(unit32_t w, uint32_t h, PixelFormat format, int usage, buffer_handle_t* handle, int32_t* stride){
err = mAllocDev->alloc(mAlocDev, w, h, format, usage, handle, stride);
}
可以得知,GraphicBufferAllocator 打开了 gralloc 模块,并且调用改硬件的 open 方法
转:图形缓冲分配过程源码分析
mAllocDev 是 struct alloc_device_t 结构,看这个结构的注释可以知道,这个结构负责分配和释放图形缓冲区
//hardware/libhardware/include/hardware/gralloc.h
typedef struct alloc_device_t {
struct hw_device_t common;
//分配图形缓冲区
int (*alloc)(struct alloc_device_t* dev, int w, int h, int format, int usage, buffer_handle_t* handle, int* stride);
//释放图形缓冲区
int (*free)(struct alloc_device_t *dev, char *buffer, int buffer_len);
void* reserver_proc[7]
}
从上面转:图形缓冲分配过程源码分析可以知道,如果请求分配的途径为 GRALLPC_USAGE_HW_FB,则从 FrameBuffer 系统帧缓存分配空间就。否则从内存分配空间。
如果是从内存分配,则创建一块名为'gralloc-buffer'的匿名共享内存,并且由此构造一个private_handle_t对象。并且映射到当前进程虚拟地址(gralloc_map)。
//native_handle.h
typedef struct native_handle
{
int version;
int numFds;
int numInts;
int data[0];
} native_handle_t
//window.h
typedef const native_handle_t* buffer_handle_t;
//gralloc.cpp
static int gralloc_alloc(alloc_device_t* dev, int w, int h, int format, int usage, buffer_handle_t* pHandle, int* pStride){
if(usage & GRALLOC_USAGE_HW_FB{
err = gralloc_alloc_framebuffer(dev, size, usage, pHandle);
}else{
err = gralloc_alloc_buffer(dev_size_usage, pHandle);
}
}
static int gralloc_alloc_buffer(alloc_dev_t* dev,size_t size, int usage, buffer_handle_t* pHandle){
int fd = -1;
size = roundUpToPageSize(size);
//创建匿名共享内存
fd =ashme_create_region("gralloc-buffer",size);
//根据匿名共享内存,创建 private_handle_t
private_handle_t* hnd = new private_handle_t(fd, size, 0);
gralloc_moudle_t8 moudle = reinterpret_cast<gralloc_moudle_t*>(dev->commom.moudle);
//内存映射
mapBuffer(moudle, hnd);
*pHandle = hnd;
}
//mapper.cpp
int mapBuffer(gralloc_moudle_t const* moudle, private_handle_t* hnd){
void* vaddr;
return gralloc_mao(moudle, hnd, &vaddr);
}
static int gralloc_map(gralloc_moudle_t const* moudle, buffer_handle_t handle, void**vaddr){
private_handle_t* hnd = (private_handle_t*)handle;
size_t size=hnd->size;
void* mappedAddress = mmap(0, size, PROT_READ|PROT_WAIT, MAP_SHARED, hnd->fd, 0);
hnd->base = intprt_t(mmappedAddredd)+hnd->offset;
*vddr=(void)hnd->base;
}
于是,通过匿名共享内存,由 graoolc 分配了一块匿名共享内存,并且映射到了对应的进程。
当调用客户端 lockCanvas( )@Surface.cpp -> nativeLockCanvas( )@android_view_Surface.cpp -> lock( )@Surface.cpp -> dequeueBuffer( )@BufferQueue -> dequeueBuffer( )@BufferQueue 获得 GraphicBuffer。
如果 GraphicBuffer 还未分配内容,则继续走 createGraphicBuffer( )@GraphicBufferAlloc.cpp -> new GraphicBuffer( ) -> initSize( )@GraphicBuffer -> alloc( )@GraphicBufferAllocator.cpp 。随后便从 gralloc 分配一块匿名共享内存,并且映射到当前地址空间。匿名共享内存的信息保存到 buffer_handle_t 中
int version;
int numFds;
int numInts;
int data[0];
由于涉及到了进程间通信,GraphicBuffer 的内存分配是在 SurfaceFlinger 进程进行的。而在应用端调用 lock( )@surface.cpp 需要将 GraphicBuffer 返回给客户端。于是Binder 间通信的 flatten() 和unflatten( )就上场了。
status_t GraphicBuffer::flatten(void* buffer, size_t size, int fds[ ] ,size_t count) const {
size_t sizeNeeded = GraphicBuffer::getFlattenedSize();
size_t fdCountNeeded = GraphicBuffer::getFdCount();
int* buf = static_cast<int*>(buffer);
buf[0] = 'GBFR';
buf[1] = width;
buf[2] = height;
buf[3] = stride;
buf[4] = format;
buf[5] = usage;
buf[6] = 0;
buf[7] = 0;
buf[6] = handle->numFds;
buf[7] = handle->numInts;
native_handle_t const* const h = handle;
memcpy(fds, h->data, h->numFds*sizeof(int));
memcpy(&buf[8], h->data + h->numFds; h->numInts*sizeof(int));
}
status_t GraphicBuffer::unflatten(void const* buffer, size_t size, int fds[], size_t count){
const size_t numFds = buf[6]
const size_t numInts = buf[7]
const size_t sizeNeeded = (8 + numInts) * sizeof(int);
width = buf[1];
height = buf[2];
stride = buf[3];
format = buf[4];
usage = buf[5];
native_handle* h = native_handle_create(numFds, numInts);
memcpy(h->data, fds, numFds*sizeof(int));
memcpy(h->data + bumFds, &buf[8], numInts*sizeof(int));
mBufferMapper.registerBuffer(handle);
}
//native_handle.c
native_handle_t* native_handle_create(int numFds, int numInts){
native_handle_t* h =malloc(sieof(native_handle_t)+sizeof(int)*(numFds+numInts));
h->version = sizeof(native_handle_t);
h->numFds=numFds;
h->numInts=numInts;
return h;
}
//gralloc_priv.h
struct private_handle_t {
struct native_handle nativeHandle;
int fd;
int magic;
int flags;
int size;
int offset;
int base;
int pid
}
网友评论