说说Android--图形系统之Surface

216 阅读1分钟

之前讲到:

原生View绘制流程是通过 ViewRootImpl中的Surface lockCanvas拿到一块数据空间,再通过Canvas往里面填充数据,这期我们看看Surface是如何拿到数据的

简单代码就是

```java

    surface.lockCanvas()
    
    canvas.drawXX()
    
    surface.unlockCanvasAndPost()
```

我们先从surface是如何创建开始说起:

1、首先我们知道setContentView添加View的时候会调用ViewRootImpl的performTravals:

private void performTraversals() {
    //1 layoutWindow
    relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
    //2 测量  
    performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
    // 布局
    performLayout(lp, mWidth, mHeight);
    // 绘制
    performDraw();

}

其中relayoutWindow:会创建 SurfaceControl对象(单独分析 TODO) 通过SurfaceControl真正创建Surface的NativeObject:


    mSurface.copyFrom(mSurfaceControl);

// Surface.java

    public void copyFrom(SurfaceControl other) {
        //生成nativeObject对象
        long newNativeObject = nativeGetFromSurfaceControl(mNativeObject, surfaceControlPtr);
        updateNativeObject(newNativeObject);
    }

所以我们想要知道什么是nativeObject:

//通过JNI调用到
static jlong nativeGetFromSurfaceControl(JNIEnv* env, jclass clazz,
        jlong nativeObject,
        jlong surfaceControlNativeObj) {

    sp<Surface> surface(ctrl->getSurface());
    return reinterpret_cast<jlong>(surface.get());
}
sp<Surface> SurfaceControl::generateSurfaceLocked(){
    mBbq = sp<BLASTBufferQueue>::make("bbq-adapter", mBbqChild, mWidth, mHeight, mFormat);
    mSurfaceData = mBbq->getSurface(true);
    return mSurfaceData;
}

这里创建了一个Native的Surface.cpp,而且出现了BufferQueue(后续分析 SurfaceFlinger和BufferQueue)

image.png

拿到Surface对象后:

通过 Surface.lockCanvas获取Canvas:

    public Canvas lockCanvas(Rect inOutDirty)
            throws Surface.OutOfResourcesException, IllegalArgumentException {
        synchronized (mLock) {
            mLockedObject = nativeLockCanvas(mNativeObject, mCanvas, inOutDirty);
            return mCanvas;
    }

Native层逻辑: