Android HWUI(Hardware Accelerated Rendering Engine for UI)是Android系统中用于处理UI渲染的硬件加速引擎。它的主要作用是利用GPU(图形处理单元)来加速UI的渲染过程,从而提高渲染效率和流畅度。以下是Android HWUI工作的主要方式和步骤:
一、基本工作原理
传统软件的UI绘制是依靠CPU来完成的,硬件加速就是将绘制任务交由GPU来执行。
HWUI基于GPU加速,通过Skia Backend与GPU进行交互,将UI绘制任务从CPU转移到GPU上执行。这种方式可以显著提高绘制性能,特别是在高分辨率屏幕和复杂UI场景下。
- GPU相比CPU更加适合完成光栅化、动画变换等耗时任务,在移动设备上比起使用CPU来完成这些任务,GPU会更加省电,带来的用户体验也会更佳。
- 现代移动GPU支持可编程管线,可以高效地开发应用界面的一些特效(吸入、渐变、模糊、阴影)
Skia Backend有两种:SkiaGl和SkiaVk,分别对应后端OpenGLES和Vulkan
二、核心组件
- Skia图形库:
- Skia是HWUI的核心图形库,提供了基础的绘制功能,如图形、文本、位图等。
- 它支持硬件加速渲染,能够充分利用GPU进行并发计算,加快UI界面的渲染速度。
- 代码示例
// 创建画布 Canvas canvas = new Canvas(bitmap); // 绘制矩形 Paint paint = new Paint(); final int color = Color.BLUE; paint.setColor(color); RectF rect = new RectF(0, 0, bitmap.getWidth(), bitmap.getHeight()); canvas.drawRoundRect(rect, 32, 32, paint);
- OpenGL ES/Vulkan:
- OpenGL ES/Vulkan是HWUI与GPU之间的桥梁,负责将Skia生成的绘制命令转化为GPU能够执行的指令序列。
- OpenGL ES 3.0是HWUI的默认版本,具有更好的功能和性能表现。未来HWUI的Backend默认会切换到Vulkan。
- DisplayList:
- DisplayList是HWUI的渲染列表,用于记录绘制操作以及它们的位置、大小等信息。
- 这些操作被显式地缓存起来,以便后续可以更快速地进行处理,并允许视图树中相同的部分在多个帧之间重复使用,从而节约内存和带宽。
- 代码示例
// 创建DisplayList DisplayList displayList = new DisplayList("MyList"); displayList.start(512, 512); //设置宽高 // 添加绘制操作 Paint paint = new Paint(); paint.setColor(Color.RED); paint.setStyle(Paint.Style.FILL); displayList.drawRect(64, 64, 256, 256, paint); // 结束DisplayList displayList.end();
- RenderNode:
- RenderNode是HWUI的渲染节点,对应于视图层次结构中的一个节点。
- 每个View持有一个RenderNode,这些RenderNode组成树形结构,用于管理和组织渲染任务。
- RenderNode负责保存和管理View绘制过程中使用的各种属性,如透明度和边框等。
- 代码示例
// 创建RenderNode RenderNode renderNode = new RenderNode("MyNode"); // 更新RenderNode属性 View view = findViewById(R.id.myView); renderNode.setPosition(view.getLeft(), view.getTop()); renderNode.setElevation(view.getElevation()); Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon); renderNode.setBitmapCache(bitmap); // 添加子节点 RenderNode child = new RenderNode("MyChild"); //更新child属性 renderNode.addChild(child);
- Layers
- Layer是HWUI的另一个重要概念,用于实现UI的专业效果和动画效果。
- 在Android 10及以前的系统中,所有视图都隶属于共享的系统组层级。但是在Android 11及以后的系统中,每个窗口/活动/碎片都将拥有自己的独立图层级别,从而增强了性能和隐私管理。
- 代码示例
// 创建Layer Layer layer = mSurface.getLayer(); layer.setX(100); layer.setY(100); layer.setAlpha(0.5f); // 在Layer上绘制图像和文字 Canvas canvas = layer.lockCanvas(); canvas.drawBitmap(bitmap, 0, 0, paint); canvas.drawText(text, 30, 100, paint); layer.unlockCanvasAndPost(canvas);
- HardwareComposer
- HardwareComposer是Android系统中的硬件合成器,作为HWUI的主要接口之一。
- 它的作用是在GPU输出图像到屏幕之前,对多个应用程序的渲染结果进行混合和组合,从而形成最终的显示内容。
- 在硬件合成情况下,不需要将应用程序的UI渲染成一个帧缓存(FrameBuffer)并上传到系统RAM,从而减少内存和总线带宽的负担。
- 代码示例
RoutingTable routingTable = hwcomposer.createRoutingTable(); routingTable.setOutputConfig(new OutputConfiguration(mDisplayToken, Display.DEFAULT_DISPLAY)); Destination destination = routingTable.createDestination(); destination.setColorMode(ColorMode.SRGB); destination.setBufferStream(bufferStream); surfaceFlinger.setTransactionState(routingTable.getTransaction()); surfaceFlinger.applyTransaction();
- Threaded Rendering(多线程渲染):
- 为了最大化利用CPU性能,HWUI采用了多线程渲染模式。
- 通常包括UI线程和RenderThread(RT线程)。UI线程负责View的绘制逻辑和将绘制命令打包成Skia的绘制命令存储到DisplayList;RT线程则负责取出这些绘制命令并执行实际的渲染操作。
三、工作流程
- UI线程绘制:
- 当View需要被绘制时,UI线程会调用相应的绘制方法(如onDraw())。
- 这些绘制方法通过Canvas类提供的接口进行绘制操作,Canvas的绘制命令会被转化为Skia的绘制命令并存储到DisplayList中。
- RenderThread渲染:
- RenderThread从DisplayList中取出绘制命令,并通过OpenGL ES接口将这些命令发送给GPU执行。
- GPU完成绘制后,将渲染结果输出到屏幕上。
- 性能优化:
- HWUI还采用了多种性能优化技术,如延时渲染列表(Deferred Display List)、绘制命令合并(Draw Op Batching)等。
- 这些技术通过减少GPU的调用次数、优化渲染状态切换等方式来提高渲染效率。
四、总结
Android HWUI通过利用GPU进行硬件加速渲染,显著提高了Android系统的UI渲染性能和流畅度。它通过Skia图形库、OpenGL ES接口、DisplayList、RenderNode以及多线程渲染等技术手段实现了高效的UI渲染过程。同时,HWUI还不断引入新的性能优化技术来进一步提升渲染效率。
标签:HWUI,渲染,RenderNode,UI,GPU,Android,绘制 From: https://www.cnblogs.com/ArsenalfanInECNU/p/18359530