///|
/// 一条降级记录:哪个来源、丢的是什么、这一帧出现了几次。
pub(all) struct DegradeRecord {
source : String
detail : String
count : Int
} derive(Eq, Debug)
///|
pub extend DegradeRecord with Debug::{to_repr}
///|
pub extend DegradeRecord with Eq::{not_equal, equal}
///|
/// 降级诊断日志。投影器不拒绝帧,但必须把"画不出来的东西"记下来,
/// 否则不可投影控件会静默消失,使用者只会看到空白。
///
/// 这个句柄由 composition root 创建并持有:`RendererSession` 会擦掉
/// renderer 具体类型,所以诊断必须能从会话外面拿到。
pub struct DegradeLog {
priv records : Array[DegradeRecord]
}
///|
pub fn DegradeLog::new() -> DegradeLog {
{ records: [], }
}
///|
/// 同一来源合并计数,细节保留首次那条。
pub fn DegradeLog::note(
self : DegradeLog,
source : String,
detail : String,
) -> Unit {
let mut i = 0
while i < self.records.length() {
if self.records[i].source == source {
let previous = self.records[i]
self.records[i] = {
source: previous.source,
detail: previous.detail,
count: previous.count + 1,
}
return
}
i = i + 1
}
self.records.push({ source, detail, count: 1, })
}
///|
pub fn DegradeLog::records(self : DegradeLog) -> Array[DegradeRecord] {
let out : Array[DegradeRecord] = []
for record in self.records {
out.push(record)
}
out
}
///|
pub fn DegradeLog::find(self : DegradeLog, source : String) -> DegradeRecord? {
for record in self.records {
if record.source == source {
return Some(record)
}
}
None
}
///|
/// 被丢弃的项目总数(按来源合并后的次数累加)。
pub fn DegradeLog::total(self : DegradeLog) -> Int {
let mut sum = 0
for record in self.records {
sum = sum + record.count
}
sum
}
///|
pub fn DegradeLog::clear(self : DegradeLog) -> Unit {
self.records.clear()
}
///|
fn brush_is_gradient(brush : @core.Brush) -> Bool {
match brush {
@core.LinearGradient(_) | @core.RadialGradient(_) => true
@core.Solid(_) => false
}
}
///|
/// cell 投影只吃语义树,像素命令一律丢弃。丢弃必须点名,不能沉默。
pub fn note_dropped_commands(
log : DegradeLog,
commands : Array[@core.DrawCommand],
platform_views : Array[@core.PlatformViewPlacement],
) -> Unit {
for command in commands {
match command {
@core.DrawImage(run) =>
log.note(
"draw-image",
"图像源 \{run.source} 没有 cell 表示,已丢弃",
)
@core.DrawPath(path) =>
log.note(
"draw-path",
"矢量路径 \{path.verbs.length()} 段没有 cell 表示,已丢弃",
)
@core.DrawShaderEffect(spec) =>
log.note(
"draw-shader-effect",
"着色器效果 \{spec.name} 没有 cell 表示,已丢弃",
)
@core.DrawShadow(_) =>
log.note("draw-shadow", "阴影没有 cell 表示,已丢弃")
@core.PushFilter(_) =>
log.note("push-filter", "滤镜作用域没有 cell 表示,已丢弃")
@core.FillRoundedRectBrush(_, brush)
| @core.StrokeRoundedRectBrush(_, brush, _) =>
if brush_is_gradient(brush) {
log.note("gradient-brush", "渐变画刷没有 cell 表示,已丢弃")
}
_ => ()
}
}
for view in platform_views {
log.note(
"platform-view",
"平台视图 \{view.kind} (\{view.id}) 不由 cell 投影绘制,已丢弃",
)
}
}