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中
基本流程:
- UI线程负责构建操作DisplayList
- 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()
// WindowManagerGlobalpublic 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.javapublic 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指向的DecorViewvoid 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赋值到RenderNodeprivate 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.javapublic 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
更多相关文章
- Android网络编程 HttpUrlConnection HttpClient AsyncTask
- android(18)_数据存储与访问_SQLite数据库_使用SQLiteDatabase操
- Handler、Looper与MessageQueue源码分析
- Error pulling origin: error: Your local changes to the follo
- Android(安卓)suspend底层流程解析
- 深入了解View实现原理以及自定义View详解
- 用Kotlin写响应式编程RxAndroid
- Google ZXing系列讲解(三)——ZXing 目录结构与主体流程
- Android网络请求库——android-async-http