///|
pub fn SunRasterRenderer::render_frame(
self : SunRasterRenderer,
frame : @core.DrawFrame,
) -> @render.RenderFrameResult {
self.render_frame_inner(frame) catch {
err => {
self.record_unsupported_command("RenderFrame", err.message())
@render.RenderFrameResult::new(presented=false)
}
}
}
///|
fn SunRasterRenderer::render_frame_inner(
self : SunRasterRenderer,
frame : @core.DrawFrame,
) -> @render.RenderFrameResult raise SunRendererError {
self.canvas = new_canvas_for_metrics(self.metrics)
self.canvas.clear(sun_color(frame.clear_color))
self.canvas.scale(sx=self.metrics.scale_factor, sy=self.metrics.scale_factor)
self.unsupported_command_count = 0
self.unsupported_command_diagnostics.clear()
let plan = @render_common.lower_draw_commands(frame.commands)
let canvas_scopes : Array[@render_common.PlanScopeKind] = []
let opacity_stack : Array[Double] = []
let blend_mode_stack : Array[@sun_graphics.BlendMode] = []
let layer_spec_stack : Array[SunLayerScope] = []
let rounded_clip_transform_stack : Array[@sun_graphics.Transform] = []
let stats = SunCachedLayerFrameStats::new()
let complete = self.render_cached_command_range(
plan.ops,
0,
plan.ops.length(),
canvas_scopes,
opacity_stack,
blend_mode_stack,
layer_spec_stack,
rounded_clip_transform_stack,
stats,
)
if !canvas_scopes.is_empty() {
for scope in canvas_scopes {
self.record_unsupported_command(
@render_common.plan_scope_push_command(scope),
"command stream ended with an open \{@render_common.plan_scope_name(scope)} scope",
)
}
while !self.canvas_stack.is_empty() {
match self.canvas_stack.pop() {
Some(parent_canvas) => self.canvas = parent_canvas
None => ()
}
}
self.filter_stack.clear()
self.blur_radius_stack.clear()
self.rounded_clip_stack.clear()
rounded_clip_transform_stack.clear()
while !blend_mode_stack.is_empty() {
ignore(blend_mode_stack.pop())
}
while !layer_spec_stack.is_empty() {
ignore(layer_spec_stack.pop())
}
}
if !complete {
return stats.to_render_frame_result(presented=false)
}
match self.platform_view_draw_fn {
Some(draw_fn) => draw_fn()
None => ()
}
let sun_frame = self.read_frame()
self.last_frame = Some(sun_frame)
if (self.target.present)(sun_frame) {
self.present_count = self.present_count + 1
stats.to_render_frame_result(presented=true)
} else {
raise PresentFailed(self.target.description)
}
}