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
![](https://img.haomeiwen.com/i13417162/896fcee1d6b7f748.png)
网友评论