SurfaceFlinger

Android中韵卤,在 HAL 層抽象了 Gralloc 模塊,封裝了對(duì)幀緩沖區(qū)的訪問操作崇猫。加載 Gralloc 模塊后沈条,獲得一個(gè) gralloc 設(shè)備和 fb 設(shè)備。通過 gralloc诅炉,用戶空間申請(qǐng)分配一塊圖形緩沖區(qū)蜡歹,并且映射到應(yīng)用程序的地址空間,以便寫入想要繪制的內(nèi)容涕烧。隨后用戶空間程序通過 fb 設(shè)備將繪制好的圖形緩沖區(qū)渲染到幀緩沖區(qū)月而,即顯示屏中。當(dāng)不需要這一塊圖形緩沖區(qū)時(shí)议纯,通過 gralloc 設(shè)備釋放父款,同時(shí)解除映射。
在 Linux 中痹扇,一個(gè)顯示屏被抽象為一個(gè)幀緩沖區(qū),注冊(cè)到 FrameBuffer 中溯香。


  • HWComposer:信號(hào)源鲫构。
    產(chǎn)生 VSync 信號(hào),可以由硬件產(chǎn)生玫坛,也可以選擇軟件模擬產(chǎn)生结笨。在 SurfaceFlinger->readyToRun( )的實(shí)例化。關(guān)鍵點(diǎn),SurfaceFinger 派生自 HWComposer::EventHandler并且成為 HWComposer 的信號(hào)處理者炕吸。當(dāng) HWComposer產(chǎn)生 VSync 信號(hào)時(shí)伐憾,會(huì)回調(diào)SurfaceFlinger->onVSyncReceived( ),后者會(huì)將會(huì)回調(diào) EventThread->onVSyncReceived( )
  • EventThread:是一個(gè)事件線程赫模,內(nèi)部通過 threadLoop( ) 不斷得監(jiān)聽事件树肃。當(dāng)?shù)谌匠绦蛘{(diào)用 EventThread::createEventConnection( )可以認(rèn)為是希望與 EventThread 產(chǎn)生一個(gè)連接,EventThread 返回一個(gè) Connection 對(duì)象瀑罗,在 Connection 對(duì)象實(shí)例化時(shí)胸嘴,會(huì)在 onFirstRef()中調(diào)用 EventThread::registerDisplayEventConnection( )將自身加入監(jiān)聽列表。
  • MessageQueue mEventQueue:可以認(rèn)為是消息隊(duì)列斩祭,同時(shí)內(nèi)部提供了 Looper 和 Handler 進(jìn)行消息處理劣像。在 SurfaceFlinger onFirstRef( )的時(shí)候進(jìn)行 init( )。
  • SurfaceFlinger 會(huì)通過 MessageQueue::setEventThread(const sp<EventThread>& eventThread)將 MessageQueue 與 EventThread 產(chǎn)生聯(lián)系
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 就監(jiān)聽了這個(gè) BitTube mEventTube耳奕。當(dāng) EventThread 收到事件時(shí),會(huì)收集所有有效的注冊(cè)在案的 Connection诬像,對(duì) Connections 進(jìn)行遍歷屋群,通過 EventThread::Connection::postEvent( ),調(diào)用 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);
    ...
  }
  ...
}

于是當(dāng) EventThread 有事件發(fā)生颅停,變會(huì)遍歷其 Connection谓晌,像 Connection 的 BitTube 對(duì)象寫入事件。當(dāng)寫入到 MessageQueue 注冊(cè)的 Connection 時(shí)癞揉,MessageQueue 的 Looper 便會(huì)監(jiān)聽到事件纸肉,回調(diào)其 BitTube::getFd( ) 在 looper 中注冊(cè)的處理函數(shù) MessageQueue::cb_eventReceiver( ),后者通過 DisplayEventReceiver::getEvent( )獲得 EventThread 寫入到 BitTube 中是 Event,隨后 MessageQueue 便通過其內(nèi)部的 Handler 進(jìn)行處理消息(MessageQueue 只會(huì)處理消息類型為 DisplayEventReceiver::DISPLAY_EVENT_VSYNC的事件,其他時(shí)間會(huì)被丟棄)喊熟。MessageQueue 內(nèi)部的 Handler 會(huì)將消息轉(zhuǎn)交給 SurfaceFlinger 進(jìn)行處理柏肪。

  • BitTube 是通過 Socket 進(jìn)行進(jìn)程間通信的。
    到此 SurfaceFlinger 相關(guān)體系從 EventThread 收到消息到 SurfaceFlinger 收到并且處理消息便告一段落芥牌。

關(guān)于 SurfaceComposerClient

當(dāng)一個(gè)應(yīng)用程序與 WMS 連接時(shí)烦味,WMS 會(huì)返回一個(gè) Session 作為應(yīng)用像 WSM 發(fā)起請(qǐng)求的中介。同時(shí)會(huì)產(chǎn)生一個(gè) SurfaceSession 對(duì)象(一個(gè)應(yīng)用程序?qū)?yīng)一個(gè) session 對(duì)應(yīng)一個(gè) SurfaceSession)

//Session.java
void windowAddedLocked( ){
  if(mSurfaceSession == null){
    mSurfaceSession = new SurfaceSession( );
  }
}
//SurfaceSession.java
public SurfaceSession( ){
   //mNativeClient 就對(duì)應(yīng)一個(gè) SurfaceComposerClient 對(duì)象
  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){
    //是一個(gè) Client 對(duì)象壁拉,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)
{
}

于是谬俄,當(dāng)一個(gè)應(yīng)用第一個(gè)和 WMS 交互時(shí),會(huì)實(shí)例化一個(gè) Session 作為該應(yīng)用與 WMS 交互的通道弃理,Session 內(nèi)部持有一個(gè)SurfaceSession對(duì)象作為溃论,SurfaceSession在 native 層對(duì)應(yīng)一個(gè) SurfaceComposerClient 對(duì)象,SurfaceComposerClient 對(duì)象持有一個(gè) Client痘昌,于是通過 SurfaceSession->SurfaceComposerClient->Client 與 SurfaceFlinger 進(jìn)行交互钥勋。在 View 體系中的 Surface,SurfaceControl,Layer 都是通過這個(gè) Client 像 SurfaceFlinger 申請(qǐng)創(chuàng)建的炬转。


關(guān)于 SurfaceControl 和 Surface

在 APP 與 WMS 交互時(shí),會(huì)通過 WMS 實(shí)例化一個(gè) SurfaceControl 對(duì)象算灸。

//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 對(duì)象
  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);
}

可以看見扼劈,在創(chuàng)建 Java 層的 SurfaceControl 的時(shí)候,會(huì)用 jni 層層調(diào)用菲驴,最后通過 SurfaceComposerClient.cpp 創(chuàng)建SurfaceControl 對(duì)象荐吵。下來看重點(diǎn)看 SurfaceControl 的創(chuàng)建過程。

  • 首先看 Surface 的創(chuàng)建谢翎。
//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 作為一個(gè) Message捍靠,在 post 后,會(huì)調(diào)用其 handler( )方法森逮,于是會(huì)調(diào)用 SurfaceFlinger::createLayer( )進(jìn)行 Layer 的創(chuàng)建榨婆。

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);
}

會(huì)根據(jù)需要?jiǎng)?chuàng)建的不同 Surface 類型創(chuàng)建不同的 Layer,現(xiàn)在只看 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( )的實(shí)現(xiàn)

//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);
  ...
}

創(chuàng)建 Layer 的時(shí)候有幾個(gè)關(guān)鍵點(diǎn)良风,首先,創(chuàng)建了一個(gè) SurfaceTextureLayer 作為BufferQueue闷供,其次烟央,創(chuàng)建了一個(gè) SurfaceFlingerConsumer作為 consumer,當(dāng) APP 對(duì)于 Surface 進(jìn)行 lock 獲得一塊 Canvas 后歪脏,進(jìn)行 draw疑俭,隨后進(jìn)行 unLock(),在 unLock()時(shí),會(huì)將 buffer 進(jìn)行 enqueue,在 BufferQueue 對(duì) buffer 進(jìn)行 enqueue 時(shí)婿失,會(huì)回調(diào)SurfaceFlingerConsumer(派生自 GLConsumer钞艇,派生自 ConsumerBase)中的FrameAvailableListener(Layer 派生自 SurfaceFlingerConsumer::FrameAvailableListener)方法onFrameAvailable(), 該方法會(huì)通知 SurfaceFlinger::signalLayerUpdate( )進(jìn)行刷新。

于是豪硅,在 Layer 中哩照,BufferQueue 是 SurfaceTextureLayer,ConsumerBase 為 SurfaceFlingerConsumer,后者的消費(fèi)回調(diào)為 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對(duì)象(派生自 BufferQueue)砚著,內(nèi)部持有 SurfaceFlinger,在 BufferQueue 實(shí)例化的時(shí)候次伶,會(huì)通過 createGraphicBufferAlloc( )向 SurfaceFlinger 申請(qǐng)一個(gè) GraphicBufferAlloc 對(duì)象

//SurfaceFlinger.cpp
sp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc( ){
  sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc( ));
  return gba;
}

于是 SurfaceComposerClient::createSurface( )中的 mClient->createSurface( )便分析完了,通過 mClinent->createSurface( ),在 normal 情況下稽穆,創(chuàng)建了一個(gè) Layer 對(duì)象冠王,內(nèi)部持有一個(gè) BufferQueue,ConsumerBase(Layer 作為SurfaceFlingerConsumer::FrameAvailableListener)秧骑,&handle 對(duì)象為 Layer 的內(nèi)部?jī)?nèi)版确,持有 Layer 本身與 SurfaceFlinger,&gbp 是 SurfaceTextureLayer 對(duì)象(派生自 BufferQueue),內(nèi)部像 SurfaceFlinger 申請(qǐng)了一個(gè) GraphicBufferAlloc乎折。

SurfaceControl::SurfaceControl(const sp<SurfaceClient>& client, const sp<IBinder>& handle, const sp<IGraphicBufferProducer>& gbp)
  :mClient(client), mHandle(handle), mGraphicBufferProducer(gbp)
{
}

可以看到绒疗,SurfaceControl只是簡(jiǎn)單地持有了 SurfaceComposerClient mClient, Handle mHandle, IGraphicBufferProducer mGraphicBufferProducer對(duì)象。真的只是 Control!


于是在 WMS 就為 APP 端生成了一個(gè) SurfaceControl骂澄。

在 aidl 中吓蘑,有客戶端調(diào)用的 Surface 作為出參(out), 在對(duì) aidl 生成可以發(fā)現(xiàn)坟冲,客戶端的 Surface 并不會(huì)作為 Binder 的參數(shù)傳遞給 WSM磨镶,而是 WSM 生成了 Surface,將WSM 生成的 Surface 透到客戶端健提,客戶端從 WM 透來的 Surface琳猫,copy 到客戶端的 Surface。

現(xiàn)在WSM有了一個(gè) SurfaceControl私痹,WSM會(huì)調(diào)用 copyFrom(SurfaceControl)@Surface.java 生成透?jìng)鹘o客戶端的 Surface 對(duì)象了脐嫂。

//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 完成了紊遵,只是簡(jiǎn)單的從 SurfaceControl中獲得 IGraphicBufferProducer账千,讓 Surface.cpp 持有,Surface.java 在 native 端持有該 Surface.cpp暗膜。

WSM 將結(jié)果傳給 APP 時(shí)匀奏,會(huì)將該 outSurface進(jìn)行writeToParcel(),隨后客戶端進(jìn)行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 間通訊的時(shí)候学搜,只是將其 IGraphicBufferProducer(normal Layer 來說是 SurfaceTextureLayer)進(jìn)行傳遞娃善。IGraphicBufferProducer 是 buffer的生產(chǎn)者,客戶端對(duì) buffer 的lock 和 unlock 都是通過 IGraphicBufferProducer 進(jìn)行的恒水。
繼承結(jié)構(gòu)由 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 對(duì)象本身钉凌。那么來看 SurfaceConsumer::onFrameAvailable()方法是在父類 ConsumerBase.cpp 中定義

void ConsumerBase::onFrameAvailable(){
  sp<FrameAvailableListener> listener;
  listener=mFrameAvailableListener.promote();
  listener->onFrameAvailable();
}

那么來看這個(gè) 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();
}

兜兜轉(zhuǎn)轉(zhuǎn),從 BufferQueue->listener->onFrameAvailable() 轉(zhuǎn)到ConsumerBase(Layer 中的 SurfaceFlingerConsumer)->onFrameAvailable()轉(zhuǎn)到 Layer::onFrameAvilable()轉(zhuǎn)到 SurfaceFlinger::signalLayerUpdate();[重點(diǎn)]


在 performDraw()@ViewRootImpl 中調(diào)用 draw(fullRedrawNeed)御雕,現(xiàn)在只分析軟件繪制 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 獲得一個(gè) 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(通過匿名共享內(nèi)存 ashmem 系統(tǒng)),隨后實(shí)例化 SkCanvas(java層 Canvas 的 native 實(shí)現(xiàn))捣鲸。隨后客戶端進(jìn)行繪制,然后進(jìn)行 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();
}

前面提到闽坡,就轉(zhuǎn)到了 SurfaceFlinger-> signalLayerUpdate()進(jìn)行更新 buffer


關(guān)于 GraphicBuffer

當(dāng)調(diào)用 dequeueBuffer()@BufferQueue.cpp 申請(qǐng)一塊 Buffer 時(shí)栽惶,實(shí)際上是通過 createGraphicBuffer()@GraphicBufferAlloc 申請(qǐng)愁溜。

//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);
}

重點(diǎn)就是在 initSize()分配內(nèi)存

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 模塊外厂,并且調(diào)用改硬件的 open 方法
轉(zhuǎn):圖形緩沖分配過程源碼分析


mAllocDev 是 struct alloc_device_t 結(jié)構(gòu),看這個(gè)結(jié)構(gòu)的注釋可以知道冕象,這個(gè)結(jié)構(gòu)負(fù)責(zé)分配和釋放圖形緩沖區(qū)

//hardware/libhardware/include/hardware/gralloc.h
typedef struct alloc_device_t {
  struct hw_device_t common;
  //分配圖形緩沖區(qū)
  int (*alloc)(struct alloc_device_t* dev, int w, int h, int format, int usage, buffer_handle_t* handle, int* stride);
  //釋放圖形緩沖區(qū)
  int (*free)(struct alloc_device_t *dev, char *buffer, int buffer_len);
  void* reserver_proc[7]
}

從上面轉(zhuǎn):圖形緩沖分配過程源碼分析可以知道汁蝶,如果請(qǐng)求分配的途徑為 GRALLPC_USAGE_HW_FB渐扮,則從 FrameBuffer 系統(tǒng)幀緩存分配空間就。否則從內(nèi)存分配空間掖棉。
如果是從內(nèi)存分配墓律,則創(chuàng)建一塊名為'gralloc-buffer'的匿名共享內(nèi)存,并且由此構(gòu)造一個(gè)private_handle_t對(duì)象幔亥。并且映射到當(dāng)前進(jìn)程虛擬地址(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);
  //創(chuàng)建匿名共享內(nèi)存
  fd  =ashme_create_region("gralloc-buffer",size);
  //根據(jù)匿名共享內(nèi)存,創(chuàng)建 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);
  //內(nèi)存映射
  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;
}

于是帕棉,通過匿名共享內(nèi)存齐饮,由 graoolc 分配了一塊匿名共享內(nèi)存,并且映射到了對(duì)應(yīng)的進(jìn)程笤昨。
當(dāng)調(diào)用客戶端 lockCanvas( )@Surface.cpp -> nativeLockCanvas( )@android_view_Surface.cpp -> lock( )@Surface.cpp -> dequeueBuffer( )@BufferQueue -> dequeueBuffer( )@BufferQueue 獲得 GraphicBuffer祖驱。
如果 GraphicBuffer 還未分配內(nèi)容,則繼續(xù)走 createGraphicBuffer( )@GraphicBufferAlloc.cpp -> new GraphicBuffer( ) -> initSize( )@GraphicBuffer -> alloc( )@GraphicBufferAllocator.cpp 瞒窒。隨后便從 gralloc 分配一塊匿名共享內(nèi)存捺僻,并且映射到當(dāng)前地址空間。匿名共享內(nèi)存的信息保存到 buffer_handle_t 中

  int version;
  int numFds;
  int numInts;
  int data[0];

由于涉及到了進(jìn)程間通信崇裁,GraphicBuffer 的內(nèi)存分配是在 SurfaceFlinger 進(jìn)程進(jìn)行的匕坯。而在應(yīng)用端調(diào)用 lock( )@surface.cpp 需要將 GraphicBuffer 返回給客戶端。于是Binder 間通信的 flatten() 和unflatten( )就上場(chǎng)了拔稳。

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
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末葛峻,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子巴比,更是在濱河造成了極大的恐慌术奖,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,104評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件轻绞,死亡現(xiàn)場(chǎng)離奇詭異采记,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)政勃,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門唧龄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人奸远,你說我怎么就攤上這事既棺》硇” “怎么了?”我有些...
    開封第一講書人閱讀 168,697評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵丸冕,是天一觀的道長(zhǎng)戏挡。 經(jīng)常有香客問我,道長(zhǎng)晨仑,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,836評(píng)論 1 298
  • 正文 為了忘掉前任拆檬,我火速辦了婚禮洪己,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘竟贯。我一直安慰自己答捕,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評(píng)論 6 397
  • 文/花漫 我一把揭開白布屑那。 她就那樣靜靜地躺著拱镐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪持际。 梳的紋絲不亂的頭發(fā)上沃琅,一...
    開封第一講書人閱讀 52,441評(píng)論 1 310
  • 那天,我揣著相機(jī)與錄音蜘欲,去河邊找鬼益眉。 笑死,一個(gè)胖子當(dāng)著我的面吹牛姥份,可吹牛的內(nèi)容都是我干的郭脂。 我是一名探鬼主播,決...
    沈念sama閱讀 40,992評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼澈歉,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼展鸡!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起埃难,我...
    開封第一講書人閱讀 39,899評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤莹弊,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后涡尘,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體箱硕,經(jīng)...
    沈念sama閱讀 46,457評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評(píng)論 3 341
  • 正文 我和宋清朗相戀三年悟衩,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了剧罩。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,664評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡座泳,死狀恐怖惠昔,靈堂內(nèi)的尸體忽然破棺而出幕与,到底是詐尸還是另有隱情,我是刑警寧澤镇防,帶...
    沈念sama閱讀 36,346評(píng)論 5 350
  • 正文 年R本政府宣布啦鸣,位于F島的核電站,受9級(jí)特大地震影響来氧,放射性物質(zhì)發(fā)生泄漏诫给。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評(píng)論 3 334
  • 文/蒙蒙 一啦扬、第九天 我趴在偏房一處隱蔽的房頂上張望中狂。 院中可真熱鬧,春花似錦扑毡、人聲如沸胃榕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽勋又。三九已至,卻和暖如春换帜,著一層夾襖步出監(jiān)牢的瞬間楔壤,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工惯驼, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留挺邀,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,081評(píng)論 3 377
  • 正文 我出身青樓跳座,卻偏偏與公主長(zhǎng)得像端铛,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子疲眷,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容