源码:8.1系统
1.Surface implements Parcelable
说明Surface可以直接跨进程传递,无须再封装
2.竟然是跨进程传递,自然涉及的关键方法为writeToParcel、readFromParcel
3.重点分析
1)writeToParcel
Surface.java
public void writeToParcel(Parcel dest, int flags) {
if (dest == null) {
throw new IllegalArgumentException("dest must not be null");
}
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);//1
}
if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) != 0) {
release();
}
}
重点分析注解1:
android_view_Surface.cpp
static void nativeWriteToParcel(JNIEnv* env, jclass clazz,
jlong nativeObject, jobject parcelObj) {
Parcel* parcel = parcelForJavaObject(env, parcelObj);
if (parcel == NULL) {
doThrowNPE(env);
return;
}
sp<Surface> self(reinterpret_cast<Surface *>(nativeObject));
android::view::Surface surfaceShim;
if (self != nullptr) {
surfaceShim.graphicBufferProducer = self->getIGraphicBufferProducer();//重点2
}
// Calling code in Surface.java has already written the name of the Surface
// to the Parcel
surfaceShim.writeToParcel(parcel, /*nameAlreadyWritten*/true);
}
分析重点2:
Surface.cpp
sp<IGraphicBufferProducer> Surface::getIGraphicBufferProducer() const {
return mGraphicBufferProducer;
}
小结:
Surface.writeToParcel的关键对象为mGraphicBufferProducer
2)readFromParcel
Surface.java
public void readFromParcel(Parcel source) {
if (source == null) {
throw new IllegalArgumentException("source must not be null");
}
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 = source.readString();
mIsSingleBuffered = source.readInt() != 0;
setNativeObjectLocked(nativeReadFromParcel(mNativeObject, source));
}
}
重点看nativeReadFromParcel
static jlong nativeReadFromParcel(JNIEnv* env, jclass clazz,
jlong nativeObject, jobject parcelObj) {
Parcel* parcel = parcelForJavaObject(env, parcelObj);
if (parcel == NULL) {
doThrowNPE(env);
return 0;
}
android::view::Surface surfaceShim;
// Calling code in Surface.java has already read the name of the Surface
// from the Parcel
surfaceShim.readFromParcel(parcel, /*nameAlreadyRead*/true);
sp<Surface> self(reinterpret_cast<Surface *>(nativeObject));
// update the Surface only if the underlying IGraphicBufferProducer
// has changed.
if (self != nullptr
&& (IInterface::asBinder(self->getIGraphicBufferProducer()) ==
IInterface::asBinder(surfaceShim.graphicBufferProducer))) {
// same IGraphicBufferProducer, return ourselves
return jlong(self.get());
}
sp<Surface> sur;
if (surfaceShim.graphicBufferProducer != nullptr) {
// we have a new IGraphicBufferProducer, create a new Surface for it
sur = new Surface(surfaceShim.graphicBufferProducer, 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);
}
return jlong(sur.get());
}
关键点为surfaceShim.graphicBufferProducer,这是读取出来的
小结:
Surface.readFromParcel的关键对象为mGraphicBufferProducer
3)总结
Surface跨进程传递的是mGraphicBufferProducer,不是Buffer
4.Activity中的Surface是怎么跨进程传回应用本身?
1)我们知道Activity真正涉及Surface传递的地方,在ViewRootImpl.java,代码跟踪:
ViewRootImpl.java
private void performTraversals() {
······
relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
······
}
private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
boolean insetsPending) throws RemoteException {
······
int relayoutResult = mWindowSession.relayout(
mWindow, mSeq, params,
(int) (mView.getMeasuredWidth() * appScale + 0.5f),
(int) (mView.getMeasuredHeight() * appScale + 0.5f),
viewVisibility, insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0,
mWinFrame, mPendingOverscanInsets, mPendingContentInsets, mPendingVisibleInsets,
mPendingStableInsets, mPendingOutsets, mPendingBackDropFrame,
mPendingMergedConfiguration, mSurface);
······
}
注意:
final Surface mSurface = new Surface();
mSurface没有什么实际的内容,说明对它进行操作的地方,在别处。
Session.java
public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewFlags,
int flags, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
Rect outVisibleInsets, Rect outStableInsets, Rect outsets, Rect outBackdropFrame,
MergedConfiguration mergedConfiguration, Surface outSurface) {
······
int res = mService.relayoutWindow(this, window, seq, attrs,
requestedWidth, requestedHeight, viewFlags, flags,
outFrame, outOverscanInsets, outContentInsets, outVisibleInsets,
outStableInsets, outsets, outBackdropFrame, mergedConfiguration, outSurface);
······
return res;
}
WindowManagerService.java
public int relayoutWindow(Session session, IWindow client, int seq,
WindowManager.LayoutParams attrs, int requestedWidth,
int requestedHeight, int viewVisibility, int flags,
Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
Rect outVisibleInsets, Rect outStableInsets, Rect outOutsets, Rect outBackdropFrame,
MergedConfiguration mergedConfiguration, Surface outSurface) {
······
result = createSurfaceControl(outSurface, result, win, winAnimator);
······
}
ViewRootImpl中的Surface传递到了WindowManagerService中
private int createSurfaceControl(Surface outSurface, int result, WindowState win,
WindowStateAnimator winAnimator) {
······
WindowSurfaceController surfaceController;
try {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "createSurfaceControl");
surfaceController = winAnimator.createSurfaceLocked(win.mAttrs.type, win.mOwnerUid);
} finally {
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
if (surfaceController != null) {
surfaceController.getSurface(outSurface);//1
if (SHOW_TRANSACTIONS) Slog.i(TAG_WM, " OUT SURFACE " + outSurface + ": copied");
} else {
······
}
······
}
WindowSurfaceController.java
void getSurface(Surface outSurface) {
outSurface.copyFrom(mSurfaceControl);//2
}
1.mSurfaceControl为对象SurfaceControlWithBackground(SurfaceControlWithBackground extends SurfaceControl)
2.WindowSurfaceController.getSurface目的,将Surface通过SurfaceControl绑定在一起
3.java层的SurfaceControl会对应native层的SurfaceControl,而native层的SurfaceControl会对应一个native层的Surface
Surface.java
public void copyFrom(SurfaceControl other) {
if (other == null) {
throw new IllegalArgumentException("other must not be null");
}
long surfaceControlPtr = other.mNativeObject;
if (surfaceControlPtr == 0) {
throw new NullPointerException(
"null SurfaceControl native object. Are you using a released SurfaceControl?");
}
long newNativeObject = nativeGetFromSurfaceControl(surfaceControlPtr);//3
synchronized (mLock) {
if (mNativeObject != 0) {
nativeRelease(mNativeObject);
}
setNativeObjectLocked(newNativeObject);
}
}
android_view_Surface.cpp
static jlong nativeGetFromSurfaceControl(JNIEnv* env, jclass clazz,
jlong surfaceControlNativeObj) {
/*
* This is used by the WindowManagerService just after constructing
* a Surface and is necessary for returning the Surface reference to
* the caller. At this point, we should only have a SurfaceControl.
*/
sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(surfaceControlNativeObj));
sp<Surface> surface(ctrl->getSurface());//4
if (surface != NULL) {
surface->incStrong(&sRefBaseOwner);
}
return reinterpret_cast<jlong>(surface.get());
}
SurfaceControl.cpp
sp<Surface> SurfaceControl::getSurface() const
{
Mutex::Autolock _l(mLock);
if (mSurfaceData == 0) {
return generateSurfaceLocked();//5
}
return mSurfaceData;
}
sp<Surface> SurfaceControl::generateSurfaceLocked() const
{
// This surface is always consumed by SurfaceFlinger, so the
// producerControlledByApp value doesn't matter; using false.
mSurfaceData = new Surface(mGraphicBufferProducer, false);
return mSurfaceData;
}
2)小结
Activity本身创建的Surface为空对象,通过系统的SurfaceControl赋予了生机。
提示:
是否还记得SurfaceControl是用来截图的接口文件?
网友评论