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
?
- mFrameHeap =
new
MemoryHeapBase(frameSize * kBufferCount);
- if
(mFrameHeap->heapID() < 0)
- {
- LOGE("Error creating frame buffer heap"
);
- return
false
;
- }
把memory 註冊到ISurface上
view plain
copy to clipboard
print
?
- ISurface::BufferHeap buffers(displayWidth, displayHeight,
- displayWidth, displayHeight, PIXEL_FORMAT_RGB_565, mFrameHeap);
- 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
?
- case
POST_BUFFER: {
- CHECK_INTERFACE(ISurface, data, reply);
- ssize_t offset = data.readInt32();
- postBuffer(offset);
- return
NO_ERROR;
- } break
;
這裡就調用到了LayerBuffer 中的postBuffer :LayerBuffer::BufferSource::postBuffer(ssize_t offset)
關於surfaceflinger中這幾個layer的概念,也可以參考一醉千年的部落格,我自己暫時還不是很清晰。
view plain
copy to clipboard
print
?
- if
(buffers.heap != 0) {
- buffer = new
LayerBuffer::Buffer(buffers, offset);
- if
(buffer->getStatus() != NO_ERROR)
- buffer.clear();
- setBuffer(buffer);
- mLayer.invalidate();
- }
這裡的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