安卓中的Surface理解起来有点抽象,它本质上是什么呢?
一块或几块GraphicBuffer内存的管理类,并提供对buffer的管理方法
还有一种理解方式,它是安卓BufferQueue中,producer一方的引用(代码)。

Surface的本质

我们先来看一下官方源码的注释解释吧:

// frameworks/base/core/java/android/view/Surface.java
/**
 * Handle onto a raw buffer that is being managed by the screen compositor.
 *
 * <p>A Surface is generally created by or from a consumer of image buffers (such as a
 * {@link android.graphics.SurfaceTexture}, {@link android.media.MediaRecorder}, or
 * {@link android.renderscript.Allocation}), and is handed to some kind of producer (such as
 * {@link android.opengl.EGL14#eglCreateWindowSurface(android.opengl.EGLDisplay,android.opengl.EGLConfig,java.lang.Object,int[],int) OpenGL},
 * {@link android.media.MediaPlayer#setSurface MediaPlayer}, or
 * {@link android.hardware.camera2.CameraDevice#createCaptureSession CameraDevice}) to draw
 * into.</p>
 *
 * <p><strong>Note:</strong> A Surface acts like a
 * {@link java.lang.ref.WeakReference weak reference} to the consumer it is associated with. By
 * itself it will not keep its parent consumer from being reclaimed.</p>
 */

Surface指向一块由screen compositor(不知道这个该翻译成啥)管理的一块原生缓存区。
Surface通常由图片buffers的消费者创建,如SurfaceTexture、MediaRecorder,被给到生产者,如OpenGL、MediaPlayer、CameraDevice#createCaptureSession,由生产者往其中写入数据。
对于持有它的消费者来说,Surface就是一个弱引用,它自己不会阻止当前的消费者被回收。

翻译了个大概,注释中基本说明了Surface的本质以及如何创建和使用。总之就是一句话:Surface指向一块内存缓存区,更确切点是一块屏幕缓冲区。

frameworks/base/core/java/android/view/Surface.java中通过JNI调用到了Native层的Surface类,JNI接口在frameworks/base/core/jni/android_view_Surface.cpp中,过于复杂先不多介绍了。

Surface的特性

Surface相关的:SurfaceView、SurfaceTexture、Surfaceflinger、GLSurfaceView、

BufferQueue和Surface的关系

frameworks/native/libs/gui/include/gui/BufferQueueCore.h
一般是在消费者进程调用BufferQueue的createBufferQueue创建BufferQueueCore,BufferQueueProducer和BufferQueueConsumer对象。
BufferQueue采用了binder和共享内存机制,因此可以高效地在进程间传递图形数据,Producer和Consumer可能不在同一进程,GraphicBurffer可以看作是一块共享内存。
使用BufferQueue的地方还有很多,可以在AOSP代码里搜"BufferQueue::createBufferQueue",一般创建BufferQueue的是在消费者进程,GraphicBuffer是在消费者进程里分配,而一系列的调用逻辑,无非就是将BufferQueue在初始化时创建的Producer指针和Consumer指针关联到对应进程中的生产者和消费者上。Surface是BufferQueue中的producter。

native_handle、private_handle_t、ANativeWindowBuffer、ANativeWindow、GraphicBuffer、Surface的关系

https://blog.csdn.net/qwaszx523/article/details/52876793
1、native_handle、native_handle_t是private_handle_t的抽象表示方法,消除平台相关性,方便private_handle_t所表示的memory信息在android各个层次之间传递。而buffer_handle_t是指向他们的指针。

2、ANativeWindowBuffer将buffer_handle_t进行了包装,ANativeWindow和ANativeWindowBuffer都继承于android_native_base_t,定义了common.incRef和common.decRef两个函数指针,但是并没有为函数指针赋值,所以ANativeWindow和ANativeWindowBuffer仍然是抽象类。
GraphicBuffer和Surface通过继承模版类ANativeObjectBase并指定其中一个模版是RefBase,为incRef和decRef两个指针分别赋值为RefBase的incStrong和decStrong,这样可以使用只能指针。ANativeWindow中定义了dequeueBuffer、queuebuffer、cancelBuffer等对buffer的操作,并没有具体的实现。

3、GraphicBuffer继承了ANativeWindowBuffer,Surface继承了ANativeWindow,并且两者都具有的和RefBase同样的incStong decStrong成员函数。两者中都实现了父类中定义的方法。

4、Surface的成员BufferSlot mSlots[NUM_BUFFER_SLOTS]; 可以看作是sp类型的数组,也就是说每个Surface中都包含有NUM_BUFFER_SLOTS个sp。

在这里插入图片描述

相机中的Surface

相机preview与takepicture都使用到Surface去作为生产或消费的数据载体。
1.通常,相机打开后会传两个Surface到CameraServer,一个Surface是用来作为Preview的数据载体,另一个用作拍照时保存图片的数据载体。一般preview的Surface由TextureView或GLSurfaceView关联的SurfaceTexture来提供,保存图片的Surface由ImageReader来提供;
2.Surface会在CameraServer进程中包装创建出流,即一个Surface对应着一个OutputStream,用于HAL层将数据填充回来,当然这里HAL层就相当与该Surface的生产者,而上层的GLSurfaceView和ImageReader相当与Surface的消费者(分别将Surface中的数据预览显示出来和保存成图片消费掉);
3. CameraServer中初始化时会起个RequestThread,不断循环等待处理的request。

参考文献

https://blog.csdn.net/TaylorPotter/article/details/84961801
https://blog.csdn.net/lu1024188315/article/details/74420866

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐