Android ISurface PostBuffer 處理流程

來源:互聯網
上載者:User

1 ISurface 的Create

    想瞭解surface的create 和surfaceflinger 可參考這篇文章,比較詳細:

http://blog.csdn.net/yili_xie/archive/2009/11/12/4803527.aspx

    Android 起步比較早的大牛們挺多,我現在只能一步步踏著革命先烈的後塵。

    每個相應的應用都會有個相應的ISurface 的對象被set進來,例如camera 的cameraService,opencore的MIO。我們只需要知道這麼用就可以了。

2 App調用流程。

    看過code就知道,這個調用是很簡單的。

    先初始化memory

view plain
copy to clipboard
print
?
  1. mFrameHeap = 
    new
     MemoryHeapBase(frameSize * kBufferCount);  
  2. if
     (mFrameHeap->heapID() < 0)  
  3. {  
  4.     LOGE("Error creating frame buffer heap"
    );  
  5.     return
     
    false
    ;  
  6. }  

    把memory 註冊到ISurface上

view plain
copy to clipboard
print
?
  1. ISurface::BufferHeap buffers(displayWidth, displayHeight,  
  2.                              displayWidth, displayHeight, PIXEL_FORMAT_RGB_565, mFrameHeap);  
  3. mSurface->registerBuffers(buffers);  

 調用postBuffer 即可

   mSurface->postBuffer(mFrameBuffers[mFrameBufferIndex]);

   這裡摘抄的是android_surface_output.cpp中的code,  cameraService中的和它沒什麼區別。

   在這裡我們重點要討論的是postBuffer的處理過程。

3 postBuffer 處理過程。(default,我們的系統中不支援overlay)

    在ISurface.cpp中實現了兩個public BpInterface<ISurface>的類:BpSurface BnSurface

    BpSurface 是使用Binder實現服務端的調用。

    BnSurface 是surfaceFlinger 向回的調用。

    我們寫 mSurface->postBuffer實際上調用的是BpSurface::postBuffer

    它的實現是:

    remote()->transact(POST_BUFFER, data, &reply, IBinder::FLAG_ONEWAY);

    (Binder的機制我還不是很清楚)從developer的網站上有對 binder調用這樣的注釋:

The key IBinder API is transact() matched by Binder.onTransact().
These methods allow you to send a call to an IBinder object and receive a
call coming in to a Binder object, respectively. This transaction API
is synchronous, such that a call to transact() does not return until the
target has returned from Binder.onTransact(); this is the expected
behavior when calling an object that exists in the local process, and
the underlying inter-process communication (IPC) mechanism ensures that
these same semantics apply when going across processes.

    也就是說整個binder調用過程是同步的。

    之後回調到:BnSurface::onTransact

view plain
copy to clipboard
print
?
  1. case
     POST_BUFFER: {  
  2.     CHECK_INTERFACE(ISurface, data, reply);  
  3.     ssize_t offset = data.readInt32();  
  4.     postBuffer(offset);  
  5.     return
     NO_ERROR;  
  6. } break
    ;  

    這裡就調用到了LayerBuffer 中的postBuffer :LayerBuffer::BufferSource::postBuffer(ssize_t offset)

    關於surfaceflinger中這幾個layer的概念,也可以參考一醉千年的部落格,我自己暫時還不是很清晰。

view plain
copy to clipboard
print
?
  1. if
     (buffers.heap != 0) {  
  2.     buffer = new
     LayerBuffer::Buffer(buffers, offset);  
  3.     if
     (buffer->getStatus() != NO_ERROR)  
  4.         buffer.clear();  
  5.     setBuffer(buffer);  
  6.     mLayer.invalidate();  
  7. }  

 
     這裡的setBuffer(buffer);會對你要post的buffer做一個記錄。然後通過LayerBase::invalidate()調用mFlinger->signalEvent()

觸發一個事件,就返回了。

     而SurfaceFlinger
會再SurfaceFlinger::threadLoop()中處理這個事件。最終還會調用到
LayerBuffer::BufferSource::onDraw函數。在layer中實現surface中的資料的合成處理等.

   
回到我們對postBuffer的調用,可發現這是兩個進程的處理。client進程調用後只是通知surfaceflinger我要顯示一個
surface,而surfaceflinger什麼時候去處理,什麼時候真正去使用這塊memory,client並不知道。因此binder雖是同步
的調用,而buffer卻是非同步處理。我自己做個實驗,在postBuffer之後立刻去修改post的這塊memory的內容,最終發現應該顯示的內
容被改掉了。而postBuffer之後睡個40ms,螢幕就沒有花,說明在修改memory之前surfaceflinger已經完成了這個
buffer的draw工作。

 

http://blog.csdn.net/saphy/archive/2010/07/01/5707413.aspx

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.