SurfaceFlinger学习笔记(二)之Surface

本系列是基于android Q即android10
SurfaceFlinger学习笔记(一)应用启动流程
SurfaceFlinger学习笔记(二)之Surface
SurfaceFlinger学习笔记(三)之SurfaceFlinger进程
SurfaceFlinger学习笔记(四)之HWC2
SurfaceFlinger学习笔记(五)之HWUI
SurfaceFlinger学习笔记(六)之View Layout Draw过程分析

java层Surface

  1. ViewRootImpl 构造时,会创建一个 Surface,它使用无参构造函数,mSurface仅是一个空壳,而在relayoutWindow之后, mSurface就已经创建好了,继续分析 relayoutWindow,在 relayoutWindow 中会调用 IWindowSession 的 relayout(),这是一个跨进程方法会调用到 WMS 中的 Session.relayout,注意从android10开始传递的是mSurfaceControl,不在传递Surface,最后调用到 WindowManagerService.relayoutWindow,这里首先调用windowForClientLocked从mWindowMap中获取到WindowState,WindowState在构造时创建WindowStateAnimator,然后调用到createSurfaceControl,进而调用到WindowStateAnimator.createSurfaceLocked,创建WindowSurfaceController,调用SurfaceControl的build创建一个SurfaceControl

WindowStateAnimator是一个窗口本身动画类,每一个WindowState都有一个WindowStateAnimator对象成员,管理与之对应WindowState的动画

* frameworks/base/core/java/android/view/ViewRootImpl.java
private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
     boolean insetsPending) throws RemoteException {
     。。。
     //调用IWindowSession的relayOut
     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, frameNumber,
                mTmpFrame, mPendingOverscanInsets, mPendingContentInsets, mPendingVisibleInsets,
                mPendingStableInsets, mPendingOutsets, mPendingBackDropFrame, mPendingDisplayCutout,
                mPendingMergedConfiguration, mSurfaceControl, mTempInsets);
     if (mSurfaceControl.isValid()) {
         mSurface.copyFrom(mSurfaceControl);
     } else {
         destroySurface();
     }
     。。。
}

* frameworks/base/services/core/java/com/android/server/wm/Session.java
class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
  	@Override
    public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs,
            int requestedWidth, int requestedHeight, int viewFlags, int flags, long frameNumber, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets, Rect outVisibleInsets,  Rect outStableInsets, Rect outsets, Rect outBackdropFrame,
            DisplayCutout.ParcelableWrapper cutout, MergedConfiguration mergedConfiguration,
            SurfaceControl outSurfaceControl, InsetsState outInsetsState) {
       。。。
        int res = mService.relayoutWindow(this, window, seq, attrs,
                requestedWidth, requestedHeight, viewFlags, flags, frameNumber,
                outFrame, outOverscanInsets, outContentInsets, outVisibleInsets,
                outStableInsets, outsets, outBackdropFrame, cutout,
                mergedConfiguration, outSurfaceControl, outInsetsState);
        return res;
    }
}

* frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
public int relayoutWindow(Session session, IWindow client, int seq, LayoutParams attrs,
            int requestedWidth, int requestedHeight, int viewVisibility, int flags,
            long frameNumber, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
            Rect outVisibleInsets, Rect outStableInsets, Rect outOutsets, Rect outBackdropFrame,DisplayCutout.ParcelableWrapper outCutout, MergedConfiguration mergedConfiguration, SurfaceControl outSurfaceControl, InsetsState outInsetsState) {
        final WindowState win = windowForClientLocked(session, client, false);
        ...
        WindowStateAnimator winAnimator = win.mWinAnimator;
        ...
        final WindowState win = windowForClientLocked(session, client, false);
        ...
        result = createSurfaceControl(outSurfaceControl, result, win, winAnimator);
        ...
}

private int createSurfaceControl(SurfaceControl outSurfaceControl, int result, WindowState win,
            WindowStateAnimator winAnimator) {
        WindowSurfaceController surfaceController;
      	。。。
        surfaceController = winAnimator.createSurfaceLocked(win.mAttrs.type, win.mOwnerUid);
		。。。
        if (surfaceController != null) {
            surfaceController.getSurfaceControl(outSurfaceControl);
        。。。
}

* frameworks/base/services/core/java/com/android/server/wm/WindowStateAnimator.java
WindowSurfaceController createSurfaceLocked(int windowType, int ownerUid) {
	...
	mSurfaceController = new WindowSurfaceController(mSession.mSurfaceSession,
                    attrs.getTitle().toString(), width, height, format, flags, this,
                    windowType, ownerUid);
    ...
}
* frameworks/base/services/core/java/com/android/server/wm/WindowSurfaceController.java
public WindowSurfaceController(SurfaceSession s, String name, int w, int h, int format,
            int flags, WindowStateAnimator animator, int windowType, int ownerUid) {
    final SurfaceControl.Builder b = win.makeSurface()
                .setParent(win.getSurfaceControl())
                .setName(name)
                .setBufferSize(w, h)
                .setFormat(format)
                .setFlags(flags)
                .setMetadata(METADATA_WINDOW_TYPE, windowType)
                .setMetadata(METADATA_OWNER_UID, ownerUid);
    mSurfaceControl = b.build();
}
  1. SurfaceControl在构造时调用jni方法,nativeCreate,传递一个SurfaceSession,然后通过SurfaceSession 获取SurfaceComposerClient,SurfaceSession 的创建会调用 JNI,在 JNI 调用 SurfaceSession.nativeCreate,创建 SurfaceComposerClient 对象, 作为跟 SurfaceFlinger 通信的代理对象,然后调用SurfaceComposerClient.createSurfaceChecked
* frameworks/base/core/java/android/view/SurfaceControl.java
private SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags, SurfaceControl parent, SparseIntArray metadata)
                    throws OutOfResourcesException, IllegalArgumentException {
      mNativeObject = nativeCreate(session, name, w, h, format, flags,
                    parent != null ? parent.mNativeObject : 0, metaParcel);
}

* frameworks/base/core/jni/android_view_SurfaceControl.cpp
static jlong nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj ...) {
    sp<SurfaceComposerClient> client;
    if (sessionObj != NULL) {
        client = android_view_SurfaceSession_getClient(env, sessionObj);
    } else {
        client = SurfaceComposerClient::getDefault();//调用内部类DefaultComposerClient创建一个单例SurfaceComposerClient
    }
    SurfaceControl *parent = reinterpret_cast<SurfaceControl*>(parentObject);
    sp<SurfaceControl> surface;
    LayerMetadata metadata;
    Parcel* parcel = parcelForJavaObject(env, metadataParcel);
    if (parcel && !parcel->objectsCount()) {
        status_t err = metadata.readFromParcel(parcel);
        ...
    }
    status_t err = client->createSurfaceChecked(
            String8(name.c_str()), w, h, format, &surface, flags, parent, std::move(metadata));
   	...
    surface->incStrong((void *)nativeCreate);
    return reinterpret_cast<jlong>(surface.get());
}
* frameworks/base/core/jni/android_view_SurfaceSession.cpp
sp<SurfaceComposerClient> android_view_SurfaceSession_getClient(
        JNIEnv* env, jobject surfaceSessionObj) {
    return reinterpret_cast<SurfaceComposerClient*>(
            env->GetLongField(surfaceSessionObj, gSurfaceSessionClassInfo.mNativeClient));
}

static jlong nativeCreate(JNIEnv* env, jclass clazz) {
    SurfaceComposerClient* client = new SurfaceComposerClient();
    client->incStrong((void*)nativeCreate);
    return reinterpret_cast<jlong>(client);
}

* frameworks/native/libs/gui/SurfaceComposerClient.cpp
void SurfaceComposerClient::onFirstRef() {
	//getComposerService() 将返回 SF 的 Binder 代理端的 BpSurfaceFlinger 对象
	sp<ISurfaceComposer> sf(ComposerService::getComposerService());
    if (sf != nullptr && mStatus == NO_INIT) {
        sp<ISurfaceComposerClient> conn;
        //先调用 SF 的 createConnection()
        conn = sf->createConnection();
       	...
    }
}
  1. 在WMS的JNI层的SurfaceComposerClient中创建一个native的SurfaceControl(控制、操作Surface的类,比如Surface的Z order值,以及position, 透明度等),并在SurfaceFlinger中创建Surface, 并且会返回SurfaceFlinger中的Handle以及IGraphicsBufferProducer的代理
* frameworks/native/libs/gui/SurfaceComposerClient.cpp
status_t SurfaceComposerClient::createSurfaceChecked(const String8& name, uint32_t w, uint32_t h, PixelFormat format, sp<SurfaceControl>* outSurface, uint32_t flags, SurfaceControl* parent, LayerMetadata metadata) {
    sp<SurfaceControl> sur;
    status_t err = mStatus;
    if (mStatus == NO_ERROR) {
        ...
        err = mClient->createSurface(name, w, h, format, flags, parentHandle, std::move(metadata),&handle, &gbp);
        if (err == NO_ERROR) {
            *outSurface = new SurfaceControl(this, handle, gbp, true /* owned */);
        }
    }
    return err;
}

创建Native层的Surface

在Java端的SurfaceControl创建好后,就开始创建真正的Native的Surface。回忆一下之前说的App端的Surface只是一个空壳,因为它还没有与真正的Native端的Surface联系起来。在ViewRootImpl.relayoutWindow中,传递的是应用侧的mSurfaceControl,在WMS的relayout调用后,返回mSurfaceControl,这里会Session的IWindowSession.Stub中调用SurfaceControl的SurfaceControl(Parcel in)构造函数,然后调用SurfaceControl.readFromParcel,从而使APP的SurfaceControl和WMS的SurfaceControl关联,然后在ViewRootImpl.relayoutWindow中调用mSurface.copyFrom(mSurfaceControl)调用jni方法nativeGetFromSurfaceControl进而创建native层的Surface,Surface继承ANativeWindow

* frameworks/base/core/java/android/view/SurfaceControl.java
public void readFromParcel(Parcel in) {
        mName = in.readString();
        mWidth = in.readInt();
        mHeight = in.readInt();
        long object = 0;
        if (in.readInt() != 0) {
            object = nativeReadFromParcel(in);
        }
        assignNativeObject(object);
}
* frameworks/base/core/java/android/view/Surface.java
 public void copyFrom(SurfaceControl other) {
        long surfaceControlPtr = other.mNativeObject;////获得native surfacecontrol的地址
        long newNativeObject = nativeGetFromSurfaceControl(mNativeObject, surfaceControlPtr);////创建native surface
        synchronized (mLock) {
            if (newNativeObject == mNativeObject) {
                return;
            }
            if (mNativeObject != 0) {
                nativeRelease(mNativeObject);
            }
            setNativeObjectLocked(newNativeObject);//将native surface的地址保存到App端的Surface里
        }
    }
* frameworks/base/core/jni/android_view_Surface.cpp
static jlong nativeGetFromSurfaceControl(JNIEnv* env, jclass clazz, jlong nativeObject, jlong surfaceControlNativeObj) {
    Surface* self(reinterpret_cast<Surface *>(nativeObject));
    sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(surfaceControlNativeObj));
   ...
    sp<Surface> surface(ctrl->getSurface());
    if (surface != NULL) {
        surface->incStrong(&sRefBaseOwner);
    }
    return reinterpret_cast<jlong>(surface.get());
}
* frameworks/native/libs/gui/SurfaceControl.cpp
sp<Surface> SurfaceControl::getSurface() const
{
    Mutex::Autolock _l(mLock);
    if (mSurfaceData == nullptr) {
        return generateSurfaceLocked();
    }
    return mSurfaceData;
}
sp<Surface> SurfaceControl::generateSurfaceLocked() const
{
    mSurfaceData = new Surface(mGraphicBufferProducer, false);
    return mSurfaceData;
}

SurfaceFlinger学习笔记(二)之Surface_第1张图片

Surface Draw流程

最后两个和Surface相关的函数调用:一个是lockCanvas;另外一个是unlockCanvasAndPost。

  1. ViewRootImpl的performTraversals调用draw进行界面绘制,然后调用到mSurface.lockCanvas(dirty),进而进入到jni的nativeLockCanvas,这里先获得一块存储区域,然后将它和Canvas绑定到一起
* frameworks/base/core/java/android/view/Surface.java
public Canvas lockCanvas(Rect inOutDirty) throws Surface.OutOfResourcesException, IllegalArgumentException {
        。。。
        mLockedObject = nativeLockCanvas(mNativeObject, mCanvas, inOutDirty);
        return mCanvas;
}

* frameworks/base/core/jni/android_view_Surface.cpp
static jlong nativeLockCanvas(JNIEnv* env, jclass clazz, jlong nativeObject, jobject canvasObj, jobject dirtyRectObj) {
	// //从Java中的Surface对象中,取出费尽千辛万苦得到的Native的Surface对象
    sp<Surface> surface(reinterpret_cast<Surface *>(nativeObject));
	...
	// dirtyRect表示需要重绘的矩形块,下面根据这个dirtyRect设置dirtyRegion
    Rect dirtyRect(Rect::EMPTY_RECT);
    Rect* dirtyRectPtr = NULL;
    ...
	//调用NativeSurface对象的lock函数,
	//传入了一个参数Surface::SurfaceInfo info和一块表示脏区域的dirtyRegion
    ANativeWindow_Buffer outBuffer;
    status_t err = surface->lock(&outBuffer, dirtyRectPtr);
    ...
    SkImageInfo info = SkImageInfo::Make(outBuffer.width, outBuffer.height,
                                         convertPixelFormat(outBuffer.format),
                                         outBuffer.format == PIXEL_FORMAT_RGBX_8888
                                                 ? kOpaque_SkAlphaType : kPremul_SkAlphaType);

    SkBitmap bitmap;
    ssize_t bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);
    bitmap.setInfo(info, bpr);
    if (outBuffer.width > 0 && outBuffer.height > 0) {
        bitmap.setPixels(outBuffer.bits);
    } else { // be safe with an empty bitmap.
        bitmap.setPixels(NULL);
    }
	//获取native层的Canvas并设置bitmap
    Canvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvasObj);
    nativeCanvas->setBitmap(bitmap);
    if (dirtyRectPtr) {
        nativeCanvas->clipRect(dirtyRect.left, dirtyRect.top,
                dirtyRect.right, dirtyRect.bottom, SkClipOp::kIntersect);
    }
	...
    sp<Surface> lockedSurface(surface);
    lockedSurface->incStrong(&sRefBaseOwner);
    return (jlong) lockedSurface.get();
}
  1. 然后看surface.unlockCanvasAndPost(canvas),mHwuiContext是在lockHardwareCanvas流程中创建的,所以这里mHwuiContext为空,调用到unlockSwCanvasAndPost,进而调用到nativeUnlockCanvasAndPost
* frameworks/base/core/java/android/view/Surface.java
public void unlockCanvasAndPost(Canvas canvas) {
	...
            if (mHwuiContext != null) {
                mHwuiContext.unlockAndPost(canvas);
            } else {
                unlockSwCanvasAndPost(canvas);
            }
}
* frameworks/base/core/jni/android_view_Surface.cpp
static void nativeUnlockCanvasAndPost(JNIEnv* env, jclass clazz,
        jlong nativeObject, jobject canvasObj) {
    ...
    Canvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvasObj);
    nativeCanvas->setBitmap(SkBitmap());
    // 调用Surface对象的unlockAndPost函数。
    status_t err = surface->unlockAndPost();
    if (err < 0) {
        doThrowIAE(env);
    }
}

* frameworks/native/libs/gui/Surface.cpp
status_t Surface::unlockAndPost()
{
	...
    int fd = -1;
    status_t err = mLockedBuffer->unlockAsync(&fd);
    err = queueBuffer(mLockedBuffer.get(), fd);
   ...
}

SurfaceFlinger学习笔记(二)之Surface_第2张图片

你可能感兴趣的:(技术总结,SurfaceFlinger)