Android Framework层看硬件加速详解手机开发

Android 从Android3.0(API Level 11)开始就支持了硬件加速,在target api >= 14会默认开启,利用GPU代替CPU绘制,软加速是利用Skia,而硬件加速是利用OpenGL绘制。缺点是增加了内存占用。

本文只是在java层去看硬件加速,没有深究jni层如何绘制。

  • RenderNode 每个View都有一个RenderNode与之对应

  • RenderThread jin层会创建一个对应的线程,loop循环接收RenderNode

  • DisplayList jin层将DisplayListCanvas的操作转化到DisplayList

  • DisplayListCanvas java层上canvas缓存所有绘制操作,设置到RenderNode中

基本流程:

  1. UI线程负责构建操作DisplayList
  2. RenderThread线程利用OpenGL去绘制DisplayList的操作

参考之前的文章《View/ViewGroup 绘制流程和疑惑(一)》 可以了解整个View/ViewGroup/ViewRootImpl整体的绘制流程。

硬件加速的绘制流程基本上是一致的,只不过在draw流程上有不同的分歧点。

我们知道,子View的invalidate标记dirty区域,借由着ViewParent的invalidateChildInParent(int[] location, Rect dirty),到顶层的DecorView,最后触发了ViewRootImpl的invalidateChildInParent(),引起schedualTraversals()。

在文章《Android 屏幕刷新机制》讲过Vsync信号到来的时候,才会引起ViewRootImpl的preformTraversals()流程到draw()。


ThreadedRender初始化

在添加窗口WindowManagerGlobal.addView()会调用ViewRootlImpl的setView()

// WindowManagerGlobal 
public void addView(View view, ViewGroup.LayoutParams params, 
            Display display, Window parentWindow) {
    
	root.setView(view, wparams, panelParentView); 
} 
 
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
    
	if (mSurfaceHolder == null) {
    
		enableHardwareAcceleration(attrs); 
    } 
} 
 
private void enableHardwareAcceleration(WindowManager.LayoutParams attrs) {
    
        mAttachInfo.mHardwareAccelerated = false; 
        mAttachInfo.mHardwareAccelerationRequested = false; 
        // 根据标记位,判断是否要硬件加速 
        final boolean hardwareAccelerated = 
                (attrs.flags & WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0; 
 
        if (hardwareAccelerated) {
    
            // 是否支持硬件加速:判断是否支持OpenGL 
            if (!ThreadedRenderer.isAvailable()) {
    
                return; 
            } 
            if (!ThreadedRenderer.sRendererDisabled 
                    || (ThreadedRenderer.sSystemRendererDisabled && forceHwAccelerated)) {
    
                if (mAttachInfo.mThreadedRenderer != null) {
    
                    mAttachInfo.mThreadedRenderer.destroy(); 
                } 
                // 创建ThreadedRender 
                mAttachInfo.mThreadedRenderer = ThreadedRenderer.create(mContext, translucent, 
                        attrs.getTitle().toString()); 
               
            } 
        } 
    } 
 
public static ThreadedRenderer create(Context context, boolean translucent, String name) {
    
    ThreadedRenderer renderer = null; 
    if (isAvailable()) {
    
        renderer = new ThreadedRenderer(context, translucent, name); 
    } 
    return renderer; 
} 
 
ThreadedRenderer(Context context, boolean translucent, String name) {
    
    // jni 创建 RenderNode 
    long rootNodePtr = nCreateRootRenderNode(); 
    // 赋值给根布局的RenderNode 
    mRootNode = RenderNode.adopt(rootNodePtr); 
    // 创建ThreadProxy用来向RenderThread线程提交操作 
    mNativeProxy = nCreateProxy(translucent, rootNodePtr); 
} 

View的RenderNode初始化

// View.java 
public View(Context context) {
    
	mRenderNode = RenderNode.create(getClass().getName(), this); 
} 
 
public static RenderNode create(String name, @Nullable View owningView) {
    
    return new RenderNode(name, owningView); 
} 
 
private RenderNode(String name, View owningView) {
    
    mNativeRenderNode = nCreate(name); 
    NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mNativeRenderNode); 
    mOwningView = owningView; 
} 

Draw() 流程

private void draw(boolean fullRedrawNeeded) {
    
    Surface surface = mSurface; 
    final Rect dirty = mDirty; 
    if (!dirty.isEmpty() || mIsAnimating || accessibilityFocusDirty) {
    
        // 硬件加速 
        if (mAttachInfo.mThreadedRenderer != null && mAttachInfo.mThreadedRenderer.isEnabled()) {
    
            boolean invalidateRoot = accessibilityFocusDirty || mInvalidateRootRequested; 
            mInvalidateRootRequested = false; 
 
            if (invalidateRoot) {
    
                mAttachInfo.mThreadedRenderer.invalidateRoot(); 
            } 
            mAttachInfo.mThreadedRenderer.draw(mView, mAttachInfo, this); 
        } else {
    
        // 软件加速 
            if (!drawSoftware(surface, mAttachInfo, xOffset, yOffset, scalingRequired, dirty)) {
    
                return; 
            } 
        } 
} 

硬件加速:mAttachInfo.mThreadedRenderer.draw(mView, mAttachInfo, this)

软件加速:drawSoftware(surface, mAttachInfo, xOffset, yOffset, scalingRequired, dirty)

// ThreadedRender 
// view指向的DecorView 
void draw(View view, AttachInfo attachInfo, DrawCallbacks callbacks) {
    
    attachInfo.mIgnoreDirtyState = true; 
 
    final Choreographer choreographer = attachInfo.mViewRootImpl.mChoreographer; 
    choreographer.mFrameInfo.markDrawStart(); 
 
    updateRootDisplayList(view, callbacks);int syncResult = nSyncAndDrawFrame(mNativeProxy, frameInfo, frameInfo.length); 
} 
 
// 更新所有RenderNode 创建DisplayListCanvas赋值到RenderNode 
private void updateRootDisplayList(View view, DrawCallbacks callbacks) {
    
    updateViewTreeDisplayList(view); 
 
    if (mRootNodeNeedsUpdate || !mRootNode.isValid()) {
    
        DisplayListCanvas canvas = mRootNode.start(mSurfaceWidth, mSurfaceHeight); 
        try {
    
            final int saveCount = canvas.save(); 
            canvas.translate(mInsetLeft, mInsetTop); 
            callbacks.onPreDraw(canvas); 
 
            canvas.insertReorderBarrier(); 
            canvas.drawRenderNode(view.updateDisplayListIfDirty()); 
            canvas.insertInorderBarrier(); 
 
            callbacks.onPostDraw(canvas); 
            canvas.restoreToCount(saveCount); 
            mRootNodeNeedsUpdate = false; 
        } finally {
    
            mRootNode.end(canvas); 
        } 
    } 
} 
 
// 
private void updateViewTreeDisplayList(View view) {
    
    ... 
    view.updateDisplayListIfDirty(); 
} 

RenderedThread从DecorView开始,往所有的ViewGroup/View更新RenderNode

// View.java 
public RenderNode updateDisplayListIfDirty() {
    
    final RenderNode renderNode = mRenderNode; 
    final DisplayListCanvas canvas = renderNode.start(width, height); 
    canvas.setHighContrastText(mAttachInfo.mHighContrastText); 
 
	try {
    
        if (layerType == LAYER_TYPE_SOFTWARE) {
    
            buildDrawingCache(true); 
            Bitmap cache = getDrawingCache(true); 
            if (cache != null) {
    
                canvas.drawBitmap(cache, 0, 0, mLayerPaint); 
            } 
        } else {
    
           // 如果是ViewGroup,自身不用绘制,直接递归子View 
           if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
    
               dispatchDraw(canvas); 
           } else {
    
               draw(canvas); 
           } 
        } 
     } finally {
    
        renderNode.end(canvas); 
        setDisplayListProperties(renderNode); 
     } 
     return renderNode; 
} 
 
public void end(DisplayListCanvas canvas) {
    
    long displayList = canvas.finishRecording(); 
    nSetDisplayList(mNativeRenderNode, displayList); 
    canvas.recycle(); 
} 

从RenderNode获取DisplayListCanvas,将所有操作写入到DisplayListCanvas,最后交给RenderNode,完成构建DisplayList。最后调用nSyncAndDrawFrame

参考:
https://www.jianshu.com/p/7bf306c09c7e
https://www.jb51.net/article/143618.htm

原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/tech/app/6241.html

(0)
上一篇 2021年7月17日 00:44
下一篇 2021年7月17日 00:44

相关推荐

发表回复

登录后才能评论