离屏渲染
为什么出现离屏渲染
是否离屏渲染是通过下面的属性进行判断执行的。
bool promotedToLayer() const {
return mLayerProperties.mType == LayerType::None && fitsOnLayer() &&
(mComputedFields.mNeedLayerForFunctors || mLayerProperties.mImageFilter != nullptr ||
mLayerProperties.getStretchEffect().requiresLayer() ||
(!MathUtils::isZero(mPrimitiveFields.mAlpha) && mPrimitiveFields.mAlpha < 1 &&
mPrimitiveFields.mHasOverlappingRendering));
}
LayerType effectiveLayerType() const {
return CC_UNLIKELY(promotedToLayer()) ? LayerType::RenderLayer : mLayerProperties.mType;
}
- 在检查home在文件夹多层模糊的场景下,存在离屏的layer和透明背景,见8.22三层模糊+动态阴影性能测试分析
- 侧边栏在动画过程中alpha值会从0变化到1,此时mHasOverlappingRendering没有重写,所以造成离屏绘制,因为surface的绘制区域较小,所以对他的child绘制的miui阴影造成了裁切问题,jira见BUGOS2-45760,侧边栏通过重写hasOverlappingRendering方法为false,可以实现动画过程中不对layer进行离屏绘制。相关patch见:https://gerrit.pt.mioffice.cn/c/platform/packages/apps/SecurityCenter/+/4394489
参考: https://xiaomi.f.mioffice.cn/docx/doxk4HEqsVu7EjAeM2o78WrVHTc
父布局中设置 View不进行绘制裁剪会扩大渲染面积,降低性能
如下代码:
android:clipChildren="false"
android:clipToPadding="false"上面的代码是设置不进行绘制裁剪,可以让父布局中的子控制绘制可以超出父容器的范围
androidViewGroup代码如果不显示设置默认是裁剪的,即如下代码和不设置是相同效果的
android:clipChildren="true"
android:clipToPadding="true"修改后的代码在现象上会出现view不裁剪问题,不裁剪后
TODO 增加一个Demo进行演示
出现离屏渲染的原因
View在做动画或者view alpha在(0,1)之间,此时可能存在离屏控价
确认离屏渲染
- 打开开发者选项中的显示硬件层更新,复现问题,查看动画过程中是否存在闪绿色的情况,如果存在闪绿色的情况,则存在离屏渲染。
参考:https://xiaomi.f.mioffice.cn/docx/doxk4G1OaiEMJ8PgvEnliwR8GDf
怎么规避离屏渲染
所以针对自定义View(闪绿色区域对应的layout或者View)需要重写hasOverlappingRendering方法来避免离屏渲染。
class view{
....
@Override
public boolean hasOverlappingRendering() {
return false;
}
}
API24中增加了一个强制设置OverlappingRendering的方法,所以可以通过
forceHasOverlappingRendering()方法设置为false,也可以在xml中设置为false。