问题:
硬件加速的原理是什么?
回答:
硬件加速的主要原理是通过将CPU不擅长的图形计算转换成GPU专用指令,让更擅长图形计算的GPU来完成渲染,硬件加速改变了android的绘图模型,能提高绘图的性能,从Android 11开始,渲染通道开始支持硬件加速。
硬件加速通常包含两个阶段,构建阶段和绘制阶段,其中构建阶段主要递归遍历所有视图,将需要执行的操作缓存下来,绘制阶段指的是基于构建结果,将所要执行的操作转交给RenderThread(专门的渲染线程)通过GPU完成渲染和显示。
硬件加速在不同的设备和Android版本上有一定兼容问题,针对比较堵砸的自定义View或东西应根据实际情况综合考虑是否启用硬件加速。
解析:
我们都知道Android系统中Choreographer负责与VSYNC信号配合驱动上层进行UI渲染,当Choreographer接收到VSYNC信号时,会触发提前注册在其内部的CALLBACK_TRAVERSAL开始执行,进而触发ViewRootImpl的doTraversal流程。
在doTraversal中会依此进行View树的measure,layout和draw,这里我们重点看下draw即绘制流程,doTraversal最终调用到draw方法中,在draw方法判断脏区域不为空,开始绘制时,就会区分是否支持硬件绘制,以便处理不同的逻辑,代码如下:
private boolean draw(boolean fullRedrawNeeded) {
...
if (!dirty.isEmpty() || mIsAnimating || accessibilityFocusDirty || mNextDrawUseBlastSync) {
// 启用硬件加速的分支
if (isHardwareEnabled()) {
// If accessibility focus moved, always invalidate the root.
boolean invalidateRoot = accessibilityFocusDirty || mInvalidateRootRequested;
mInvalidateRootRequested = false;
// Draw with hardware renderer.
mIsAnimating = false;
if (mHardwareYOffset != yOffset || mHardwareXOffset != xOffset) {
mHardwareYOffset = yOffset;
mHardwareXOffset = xOffset;
invalidateRoot = true;
}
if (invalidateRoot) {
mAttachInfo.mThreadedRenderer.invalidateRoot();
}
dirty.setEmpty();
// 驱动RenderThread开始绘制
mAttachInfo.mThreadedRenderer.draw(mView, mAttachInfo, this);
} else {
// CPU绘制
if (!drawSoftware(surface, mAttachInfo, xOffset, yOffset,
scalingRequired, dirty, surfaceInsets)) {
return false;
}
}
}
if (animating) {
mFullRedrawNeeded = true;
scheduleTraversals();
}
return useAsyncReport;
}
结合上文,我们可以简单绘制Android系统中,一帧数据的渲染流程,如下图所示: