您的位置:首页 > 移动开发 > Android开发

Android ISurface PostBuffer 处理流程

2011-06-18 23:11 316 查看
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: