///|
fn RenderCommand::save_depth_delta(self : RenderCommand) -> Int {
match self {
SaveCanvas | SaveCanvasLayer(_, _, _, _, _) => 1
RestoreCanvas => -1
_ => 0
}
}
///|
pub(all) struct RenderCommandStats {
command_count : Int
draw_count : Int
state_count : Int
transform_count : Int
clip_count : Int
clear_count : Int
present_count : Int
text_count : Int
resource_declaration_count : Int
image_resource_count : Int
shader_resource_count : Int
filter_resource_count : Int
path_resource_count : Int
text_resource_count : Int
max_save_depth : Int
final_save_depth : Int
unbalanced_restore_count : Int
} derive(Debug, Eq)
///|
pub fn RenderCommandStats::empty() -> RenderCommandStats {
{
command_count: 0,
draw_count: 0,
state_count: 0,
transform_count: 0,
clip_count: 0,
clear_count: 0,
present_count: 0,
text_count: 0,
resource_declaration_count: 0,
image_resource_count: 0,
shader_resource_count: 0,
filter_resource_count: 0,
path_resource_count: 0,
text_resource_count: 0,
max_save_depth: 0,
final_save_depth: 0,
unbalanced_restore_count: 0,
}
}
///|
pub fn RenderCommandStats::is_state_balanced(self : RenderCommandStats) -> Bool {
self.final_save_depth == 0 && self.unbalanced_restore_count == 0
}
///|
fn RenderCommandStats::record_command(
self : RenderCommandStats,
command : RenderCommand,
current_save_depth : Int,
) -> (RenderCommandStats, Int) {
let mut depth = current_save_depth + command.save_depth_delta()
let mut unbalanced_restore_count = self.unbalanced_restore_count
if depth < 0 {
unbalanced_restore_count += 1
depth = 0
}
let draw_increment = if command.is_draw() { 1 } else { 0 }
let state_increment = if command.is_state() { 1 } else { 0 }
let transform_increment = if command.is_transform() { 1 } else { 0 }
let clip_increment = if command.is_clip() { 1 } else { 0 }
let clear_increment = if command.is_clear() { 1 } else { 0 }
let present_increment = if command.is_present() { 1 } else { 0 }
let text_increment = if command.is_text() { 1 } else { 0 }
let resource_declaration_increment = if command.is_resource_declaration() {
1
} else {
0
}
let resource_counts = command.resource_counts()
(
{
command_count: self.command_count + 1,
draw_count: self.draw_count + draw_increment,
state_count: self.state_count + state_increment,
transform_count: self.transform_count + transform_increment,
clip_count: self.clip_count + clip_increment,
clear_count: self.clear_count + clear_increment,
present_count: self.present_count + present_increment,
text_count: self.text_count + text_increment,
resource_declaration_count: self.resource_declaration_count +
resource_declaration_increment,
image_resource_count: self.image_resource_count +
resource_counts.image_resource_count,
shader_resource_count: self.shader_resource_count +
resource_counts.shader_resource_count,
filter_resource_count: self.filter_resource_count +
resource_counts.filter_resource_count,
path_resource_count: self.path_resource_count +
resource_counts.path_resource_count,
text_resource_count: self.text_resource_count +
resource_counts.text_resource_count,
max_save_depth: Int::max(self.max_save_depth, depth),
final_save_depth: depth,
unbalanced_restore_count,
},
depth,
)
}
///|
pub fn RenderCommandList::stats(self : RenderCommandList) -> RenderCommandStats {
for stats = RenderCommandStats::empty(), depth = 0, i = 0
i < self.commands.length()
i = i + 1 {
let (stats, depth) = stats.record_command(self.commands[i], depth)
continue stats, depth, i + 1
} nobreak {
stats
}
}
///|
pub fn RenderCommandList::is_state_balanced(self : RenderCommandList) -> Bool {
self.stats().is_state_balanced()
}