surpass/painter/layer_workbench/passes/
skip_trivial_clips.rs

1// Copyright 2022 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::painter::layer_workbench::passes::PassesSharedState;
6use crate::painter::layer_workbench::{Context, Index, LayerWorkbenchState};
7use crate::painter::{Func, LayerProps, Style};
8
9pub fn skip_trivial_clips_pass<'w, 'c, P: LayerProps>(
10    workbench: &'w mut LayerWorkbenchState,
11    state: &'w mut PassesSharedState,
12    context: &'c Context<'_, P>,
13) {
14    struct Clip {
15        is_full: bool,
16        last_layer_id: u32,
17        i: Index,
18        is_used: bool,
19    }
20
21    let mut clip = None;
22
23    for (i, &id) in workbench.ids.iter_masked() {
24        let props = context.props.get(id);
25
26        if let Func::Clip(layers) = props.func {
27            let is_full = workbench.layer_is_full(context, id, props.fill_rule);
28
29            clip = Some(Clip { is_full, last_layer_id: id + layers as u32, i, is_used: false });
30
31            if is_full {
32                // Skip full clips.
33                workbench.ids.set_mask(i, false);
34            }
35        }
36
37        if let Func::Draw(Style { is_clipped: true, .. }) = props.func {
38            match clip {
39                Some(Clip { is_full, last_layer_id, ref mut is_used, .. })
40                    if id <= last_layer_id =>
41                {
42                    if is_full {
43                        // Skip clipping when clip is full.
44                        state.skip_clipping.insert(id);
45                    } else {
46                        *is_used = true;
47                    }
48                }
49                _ => {
50                    // Skip layer outside of clip.
51                    workbench.ids.set_mask(i, false);
52                }
53            }
54        }
55
56        if let Some(Clip { last_layer_id, i, is_used, .. }) = clip {
57            if id > last_layer_id {
58                clip = None;
59
60                if !is_used {
61                    // Remove unused clips.
62                    workbench.ids.set_mask(i, false);
63                }
64            }
65        }
66    }
67
68    // Clip layer might be last layer.
69    if let Some(Clip { i, is_used, .. }) = clip {
70        if !is_used {
71            // Remove unused clips.
72            workbench.ids.set_mask(i, false);
73        }
74    }
75}