Android之Surface
⼀、Surface是什么
  Handle onto a raw buffer that is being managed by the screen compositor.
  ⼤概意思是处理由屏幕合成器管理的原理缓存区。
⼆、Surface实现原理
  在Surface类⾥有⼀个Canvas对象,在Canvas⾥有⼀个Bitmap,Bitmap是真正的画布。
  Bitmap是什么
  Bitmap缩写是BMP,是⼀种存储像素的数据结构。
三、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
* {@aphics.SurfaceTexture}, {@dia.MediaRecorder}, or
* {@derscript.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},
* {@dia.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 f.WeakReference weak reference} to the consumer it is associated with. By
* itself it will not keep its parent consumer from being reclaimed.</p>
*/
public class Surface implements Parcelable {
……
}
  Surface继承⾃Parcelable,Parcelable是⼀个序列化接⼝,将对象转化为⼆进制流(⼆进制序列)的过程。⼆进制流可以通过Socket传输或者保存到本地。
  在Android中Surface是怎么在进程间传递的,应⽤如何将Surface传递给SurfaceFlinger进程绘制的。
  Java层实现:
  在Parcelable中有两个关键函数:
/**
* 将数据写⼊Parcel对象
*/
public void writeToParcel(Parcel dest, int flags) {}
/**
* 从Parcel对象中读取数据
*/
public void readFromParcel(Parcel source) {}
  先看Parcelable.writeToParcel()函数:
@Override
public void writeToParcel(Parcel dest, int flags) {
synchronized (mLock) {
// NOTE: This must be kept synchronized with the native parceling code
// in frameworks/native/libs/Surface.cpp
dest.writeString(mName);
dest.writeInt(mIsSingleBuffered ? 1 : 0);
nativeWriteToParcel(mNativeObject, dest);
}
}
  dest是⼀个Parcel对象,将name写⼊Parcel对象dest,再调⽤nativeWriteToParcel()函数,将mNativeObject写⼊到Parcel对象。
  mNativeObject是什么?
long mNativeObject; // package scope only for SurfaceControl access
  mNativeObject是Long型变量,存储Native层的对象指针。
  nativeWriteToParcel()函数定义:
private static native void nativeWriteToParcel(long nativeObject, Parcel dest);
  nativeWriteToParcel()函数是Native层函数。
  下⾯看看readFromParcel()函数:
public void readFromParcel(Parcel source) {
synchronized (mLock) {
// nativeReadFromParcel() will either return mNativeObject, or
// create a new native Surface and return it after reducing
// the reference count on mNativeObject.  Either way, it is
// not necessary to call nativeRelease() here.
/
/ NOTE: This must be kept synchronized with the native parceling code
// in frameworks/native/libs/Surface.cpp
mName = adString();
mIsSingleBuffered = adInt() != 0;
setNativeObjectLocked(nativeReadFromParcel(mNativeObject, source));
}
}
  从Surface对象中读取name数据,再调⽤nativeReadFromParcel()函数,通过setNativeObjectLocked()函数将nativeReadFromParcel()函数返回的数据保存起来。
  nativeReadFromParcel()函数定义:
private static native long nativeReadFromParcel(long nativeObject, Parcel source);
  setNativeObjectLocked()函数实现:
private void setNativeObjectLocked(long ptr) {
if (mNativeObject != ptr) {
mNativeObject = ptr;
}
}
  将nativeReadFromParcel()函数返回值赋值给mNativeObject变量。
  Native层:
  源码:frameworks/base/core/jni/android_view_Surface.cpp
  nativeWriteToParcel()函数实现:
static void nativeWriteToParcel(JNIEnv* env, jclass clazz,
jlong nativeObject, jobject parcelObj) {
/
/ (1) 获取parcel对象,从Java层
Parcel* parcel = parcelForJavaObject(env, parcelObj);
if (parcel == NULL) {
jniThrowNullPointerException(env, NULL);
return;
}
// (2) Native层的Surface对象
sp<Surface> self(reinterpret_cast<Surface *>(nativeObject));
android::view::Surface surfaceShim;
if (self != nullptr) {
// (3)
}
// Calling code in Surface.java has already written the name of the Surface
// to the Parcel
surfaceShim.writeToParcel(parcel, /*nameAlreadyWritten*/true);
}
// (3)
sp<IGraphicBufferProducer> GraphicBufferSource::getIGraphicBufferProducer() const {
return mProducer;
}
  (1) 通过parcelFroJavaOjbect()获取Parcel对象:
Parcel* parcelForJavaObject(JNIEnv* env, jobject obj)
{
if (obj) {
Parcel* p = (Parcel*)env->GetLongField(obj, gParcelOffsets.mNativePtr);
if (p != NULL) {
return p;
}
jniThrowException(env, "java/lang/IllegalStateException", "Parcel has been finalized!");
}
return NULL;
}
  (1) 通过JNI调⽤,在Native层通过Native层保存的Java层Parcel指针获取Native层对应Java层的Parcel对象。
  (2) 通过Native层保存的Java层Surface对象指针,在Native层恢复Surface对象。
  (3) 将Native层的IGraphicBufferProducer对象传递给Java层的aphicBufferProducer变量。
  nativeReadFromParcel()函数实现:
static jlong nativeReadFromParcel(JNIEnv* env, jclass clazz,
jlong nativeObject, jobject parcelObj) {
// (1)
Parcel* parcel = parcelForJavaObject(env, parcelObj);
android::view::Surface surfaceShim;进程间通信 共享内存
// (2)
sp<Surface> self(reinterpret_cast<Surface *>(nativeObject));
// update the Surface only if the underlying IGraphicBufferProducer
// has changed.
// (3)
if (self != nullptr
&& (IInterface::asBinder(self->getIGraphicBufferProducer()) ==
IInterface::aphicBufferProducer))) {
// same IGraphicBufferProducer, return ourselves
return ());
}
// (4)
sp<Surface> sur;
if (aphicBufferProducer != nullptr) {
// we have a new IGraphicBufferProducer, create a new Surface for it
sur = new aphicBufferProducer, true);
// and keep a reference before passing to java
sur->incStrong(&sRefBaseOwner);
}
if (self != NULL) {
// and loose the java reference to ourselves
self->decStrong(&sRefBaseOwner);
}
// (5)
return ());
}
  (1) 获取Native层对应Java层的Parcel对象。
  (2) 获取Native层对应Java层的Surface对象。
  (3) 获取IGraphicBufferProducer对象,⼀个Binder对象。
  (4) 通过IGraphicBufferProducer对象创建⼀个新的Surface对象。
  (5) 将Native层的新Surface对象通过JNI调⽤传递给Java层。
  对象Java层的Surface对应Native层的Surface对象,对于Native层的Surface对应Native层的IGraphicBufferProducer对象。
四、总结
  Android App中,⼀个Window对应⼀个Surface对象,应⽤与绘制服务SurfaceFlinger服务的通信是基于共享内存实现的,应⽤中在Java层将Surface对象通过Parcel转化为⼆进制流,并且⼆进制流存储在共享
内存。
  Android每个应⽤都有在共享内存中都会有⼀个SharedClicent,再应⽤的Window对应⼀个Surface,⽽每个Surface对应共享内存的SharedBufferStack。
  Surface中Buffer是没有进程跨进程传递的,应⽤与SurfaceFlinger服务通信传递的是共享内存的物理地址,应⽤将Surface的Buffer写⼊到SharedClient中,再将SharedClient中的SharedBufferStack的地址通过Binder通信传递给SurfaceFlinger。SurfaceFlinger服务通过共享内存的物理地址到SharedClicent读取SharedBufferStack数据。
  在SharedBufferStack中分为双缓冲与三级缓冲,在Android 4.1版本前是双缓冲机制,在4.1版本后是三级缓冲机制。
  SharedBufferStack分为:
FontBuffer:在屏幕中显⽰。
BackBuffer:绘制Buffer。
Triple Buffer:是Android对绘制优化,Vsync垂直同步提供的机制。Triple Buffer是CPU/GPU在空闲时提前准备数据的Buffer。  PS:可以配合⼀⽂⼀起阅读。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。