在较早期的 Android 版本中,HWUI 呈现模式分析只有一条阈值线。这条警告线是绿线,表示 16ms 的界限。

前几天看 HWUI 呈现模式分析的时候,注意到其实这个工具已经改成三条线(绿线、黄线、红线)有一段时间了。问了 AI 但幻觉严重,仍然说绿线是 16ms,而且官方的文档说明也没有提供相关信息。

查找了相关源码,得到的结果如下:

  • 绿线:0.8x 帧时间
  • 黄线:1.0x 帧时间
  • 红线:1.5x 帧时间
  • 不管刷新率多少,这里的帧时间,指的都是 16ms

网上的相关信息似乎较少,因此在这里记录一下。其他的信息倒是还可以参考 官方文档,条形图的颜色含义还是没有变的。

相关源码

阈值定义

FrameInfoVisualizer.cpp#L41 定义了三条线的阈值时间比例和颜色定义。

1
2
3
4
5
static constexpr std::array<Threshold, 3> THRESHOLDS{
Threshold{.color = Color::Green_500, .percentFrametime = 0.8f},
Threshold{.color = Color::Lime_500, .percentFrametime = 1.0f},
Threshold{.color = Color::Red_500, .percentFrametime = 1.5f},
};

帧时间

FrameInfoVisualizer#setDestinyFrameInfoVisualizer#drawThreshold 可以看出帧时间基准就是 16ms.

1
2
3
4
5
6
7
8
9
10
void FrameInfoVisualizer::setDensity(float density) {
if (CC_UNLIKELY(mDensity != density)) {
mDensity = density;
// We want the vertical units to scale height relative to a baseline 16ms.
// This keeps the threshold lines consistent across varying refresh rates
mVerticalUnit = static_cast<int>(dpToPx(PROFILE_DRAW_DP_PER_MS, density) * (float)16_ms /
(float)mFrameInterval);
mThresholdStroke = dpToPx(PROFILE_DRAW_THRESHOLD_STROKE_WIDTH, density);
}
}
1
2
3
4
5
6
7
8
9
10
void FrameInfoVisualizer::drawThreshold(IProfileRenderer& renderer) {
SkPaint paint;
for (auto& t : THRESHOLDS) {
paint.setColor(t.color);
float yLocation = renderer.getViewportHeight() -
(ns2ms(mFrameInterval) * t.percentFrametime * mVerticalUnit);
renderer.drawRect(0.0f, yLocation - mThresholdStroke / 2, renderer.getViewportWidth(),
yLocation + mThresholdStroke / 2, paint);
}
}