Surface

作者: 杨殿生 | 来源:发表于2020-04-30 18:22 被阅读0次

    Surface创建

    public class Surface implements Parcelable {
              long mNativeObject; // package scope only for SurfaceControl access
              private final Canvas mCanvas = new CompatibleCanvas();
    }
    

    他是一个parcelable类型所以可以跨进程传递、mNativeObject存储native层的Surface、mCanvas用于锁定画布提交绘制数据与底层调用skia

    GraphicBufferProducer申请Buffer使用

    Activity在第一次绘制时申请的时候会申请Surface

     private void performTraversals() {
             if (mFirst){
                    relayoutWindow(params, viewVisibility, insetsPending);
            }  
    }
    
     private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
                boolean insetsPending) throws RemoteException {
            int relayoutResult = mWindowSession.relayout(
                    mWindow,····· mSurface);
        }
    

    relayoutWindow会通过WindowSession向WMS发起调用,会把空的Surface传递给WMS,

    WMS端

     public int relayout(IWindow window,···Surface outSurface) {
            int res = mService.relayoutWindow(this, window, ···outSurface);
        }
    
     public int relayoutWindow(){
             result = createSurfaceControl(outSurface, result, win, winAnimator);
          //最后调用
         outSurface.copyFrom(mSurfaceControl);
    }
    

    会创建SurfaceControl 7.0版本是创建了一个WindowSurfaceController包装了一个SurfaceControl,然后执行copyForm()

     /**
         * Copy another surface to this one.  This surface now holds a reference
         * to the same data as the original surface, and is -not- the owner.
         * This is for use by the window manager when returning a window surface
         * back from a client, converting it from the representation being managed
         * by the window manager to the representation the client uses to draw
         * in to it.
         * @hide
         */
        public void copyFrom(SurfaceControl other) {
            long surfaceControlPtr = other.mNativeObject;
            long newNativeObject = nativeCreateFromSurfaceControl(surfaceControlPtr);
            setNativeObjectLocked(newNativeObject);
        }
    

    通过GraphicBufferProducer(Binder对象)生产的一个native的Surface,拷贝一个native的Surface到Java层的Surface,Java层Surface持有引用。然后传递给APP进程

    Surface的本质是GraphicBufferProducer,而不是Buffer
    Surface夸进程传递,本质是GraphicBufferProducer的传递

    Surface绘制原理

    private void performTraversals(){
        ···
        performMeasure()
        ···
        performLayout()
        ···
        performDraw()
    }
    

    performDraw()方法会调用draw

    private void draw(boolean fullRedrawNeeded) {
            Surface surface = mSurface;
            drawSoftware(surface, mAttachInfo, xOffset, yOffset, scalingRequired, dirty);
        }
    

    如果开启硬件加速会使用硬件否则是软件绘制,这里是软件绘制

     private boolean drawSoftware(Surface surface, AttachInfo attachInfo, int xoff, int yoff,
                boolean scalingRequired, Rect dirty) {
                canvas = mSurface.lockCanvas(dirty);
                mView.draw(canvas);  
                surface.unlockCanvasAndPost(canvas);
        
        }
    

    这里为什么一定要用canvas呢,就是因为canvas会在底层调用skia库,绘制我们要绘制图像。

    mSurface.lockCanvas(dirty);申请Buffer

    底层会通过native的Surface,中成员变量GraphicBufferProducer的dequeueBuffer() 申请一块GraphicBuffer,这会向SurfaceFlinger申请一个空闲的buffer,Buffer的传递是传递类似句柄一样的东西,Buffer是存储在一片共享内存中

    Surface 中是有两个buffer的一个是前台buffer一个是后台buffer,前台buffer用于显示,后台buffer用于绘制

    unlockCanvasAndPost(canvas);提交Buffer

    通过GraphicBufferProducer将buffer的句柄提交给SurfaceFlinger
    后台Buffer升级为前台Buffer

    Surface获取Buffer

    参考
    Android Surface创建
    浅析 android 应用界面的展现流程(二)布局与视图的创建

    相关文章

      网友评论

          本文标题:Surface

          本文链接:https://www.haomeiwen.com/subject/cprtghtx.html