From 5c55f3131cde92df4a66387332ce2e85175c04dc Mon Sep 17 00:00:00 2001 From: Omooo <869759698@qq.com> Date: Thu, 26 Mar 2020 11:26:27 +0800 Subject: [PATCH] =?UTF-8?q?Create=20Surface=20=E8=B7=A8=E8=BF=9B=E7=A8=8B?= =?UTF-8?q?=E4=BC=A0=E9=80=92=E5=8E=9F=E7=90=86.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UI 体系相关/Surface 跨进程传递原理.md | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 blogs/Android/Framework/Interview/UI 体系相关/Surface 跨进程传递原理.md diff --git a/blogs/Android/Framework/Interview/UI 体系相关/Surface 跨进程传递原理.md b/blogs/Android/Framework/Interview/UI 体系相关/Surface 跨进程传递原理.md new file mode 100644 index 0000000..6521477 --- /dev/null +++ b/blogs/Android/Framework/Interview/UI 体系相关/Surface 跨进程传递原理.md @@ -0,0 +1,96 @@ +--- +Surface 跨进程传递原理 +--- + +1. 怎么理解 surface,它是一块 buffer 嘛? +2. 如果是,surface 跨进程传递怎么带上这个 buffer? +3. 如果不是,那么 surface 跟 buffer 又是什么关系? +4. surface 到底是怎么跨进程传递的? + +```java +public class Surface implements Parcelable{ + long mNativeObject; + private final Canvas mCanvas = new CompatibleCanvas(); +} + +public void writeToParcel(Parcel dest, int flags){ + synchronized(mLock){ + dest.writeString(mName); + nativeWriteToParcel(mNativeObject, dest); + } +} +public void readFromParcel(Parcel source){ + synchronized(mLock){ + mName = source.readString(); + setNativeObjectLocked(nativeReadFromParcel(mNativeObject, source)); + } +} + +static void nativeWriteToParcel(JNIEnv* env, jclass clazz, jlong nativeObject, jobject parcelObj){ + Parcel* parcel = parcelForJavaObject(env, parcelObj); + sp self(reinterpert_cast(nativeObject)); + parcel->writeStrongBinder(IInterface::asBinder(self->getIGraphicBufferProducer())); +} +Parcel* parcelForJavaObject(JNIEnv* env, jobject obj){ + Parcel* p = env->GetLongField(obj, gParcelOffsets.mNativePtr); + return p; +} +sp getIGraphicBufferProducer() const{ + return mProducer; +} + +static jlong nativeReadFromParcel(JNIEnv* env, jclass clazz, jlong nativeObject, jobject parcelObj){ + Parcel* parcel = parcelForJavaObject(env, parcelObj); + sp self(reinterpret_cast(nativeObject)); + sp binder(parcel->readStrongBinder()); + sp gbp(interface_cast(binder)); + sp sur = new Surface(gbp, true); + return jlong(sur.get()); +} +``` + +#### Activity 的 surface 是怎么跨进程传递的? + +```java +private void performTraversals(){ + final View host = mView; + if(mFirst){ + relayoutResult = relayoutWindow(params, ...); + } +} +int relayoutWindow(WindowManager.LayoutParams params, ...){ + return mWindowSession.relayout(mWindow, ..., mSurface); +} +// WMS +public int relayout(IWindow window, ..., Surface outSurface){ + int res = mService.relayoutWindow(this, window, ..., outSurface); + return res; +} +public int relayoutWindow(Session session, ..., Surface outSurface){ + SurfaceControl surfaceControl = winAnimator.createSurfaceLocked(); + outSurface.copyForm(surfaceControl); +} +public void copyForm(SurfaceControl other){ + long surfaceControlPtr = other.mNativeObject; + long newNativeObject = nativeCreateFromSurfaceControl(surfaceControlPtr); + setNativeObjectLocked(newNativeObject); +} +jlong nativeCreateFromSurfaceControl(JNIEnv* env, jclass clazz, ...){ + sp ctrl(reinterpret_cast(surfaceControlNativeObj)); + sp surface(ctrl->getSurface()); + return reinterpret_cast(surface.get()); +} +sp SurfaceControl::getSurface() const{ + if(mSurfaceData == 0){ + mSurfaceData = new Surface(mGraphicBufferProducer, false); + } + return mSurfaceData; +} +``` + +#### 总结 + +1. Surface 的本质是 GraphicBufferProducer,而不是 buffer +2. Surface 跨进程传递,本质就是 GraphicBufferProducer 的传递 + +Surface 不是一块 buffer,而是一个壳子,里面包含了一个能够生产 buffer 的 Binder 对象,也就是 GBP。Surface 跨进程传递,只是传递 GBP 对象。 \ No newline at end of file