SurfaceFlinger

2019-09-26  本文已影响0人  Wi1ls努力努力再努力

Android中,在 HAL 层抽象了 Gralloc 模块,封装了对帧缓冲区的访问操作。加载 Gralloc 模块后,获得一个 gralloc 设备和 fb 设备。通过 gralloc,用户空间申请分配一块图形缓冲区,并且映射到应用程序的地址空间,以便写入想要绘制的内容。随后用户空间程序通过 fb 设备将绘制好的图形缓冲区渲染到帧缓冲区,即显示屏中。当不需要这一块图形缓冲区时,通过 gralloc 设备释放,同时解除映射。
在 Linux 中,一个显示屏被抽象为一个帧缓冲区,注册到 FrameBuffer 中。


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 进行处理。


关于 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 的创建过程。

//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
}
上一篇下一篇

猜你喜欢

热点阅读