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
- mFrameHeap = new MemoryHeapBase(frameSize * kBufferCount);
- if (mFrameHeap->heapID() < 0)
- {
- LOGE("Error creating frame buffer heap" );
- return false ;
- }
把memory 注册到ISurface上
- 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
- 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的概念,也可以参考一醉千年的博客,我自己暂时还不是很清晰。
- 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工作。