surpass/painter/layer_workbench/passes/
skip_trivial_clips.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use std::ops::ControlFlow;

use crate::painter::layer_workbench::passes::PassesSharedState;
use crate::painter::layer_workbench::{Context, Index, LayerWorkbenchState, OptimizerTileWriteOp};
use crate::painter::{Func, LayerProps, Style};

pub fn skip_trivial_clips_pass<'w, 'c, P: LayerProps>(
    workbench: &'w mut LayerWorkbenchState,
    state: &'w mut PassesSharedState,
    context: &'c Context<'_, P>,
) -> ControlFlow<OptimizerTileWriteOp> {
    struct Clip {
        is_full: bool,
        last_layer_id: u32,
        i: Index,
        is_used: bool,
    }

    let mut clip = None;

    for (i, &id) in workbench.ids.iter_masked() {
        let props = context.props.get(id);

        if let Func::Clip(layers) = props.func {
            let is_full = workbench.layer_is_full(context, id, props.fill_rule);

            clip = Some(Clip { is_full, last_layer_id: id + layers as u32, i, is_used: false });

            if is_full {
                // Skip full clips.
                workbench.ids.set_mask(i, false);
            }
        }

        if let Func::Draw(Style { is_clipped: true, .. }) = props.func {
            match clip {
                Some(Clip { is_full, last_layer_id, ref mut is_used, .. })
                    if id <= last_layer_id =>
                {
                    if is_full {
                        // Skip clipping when clip is full.
                        state.skip_clipping.insert(id);
                    } else {
                        *is_used = true;
                    }
                }
                _ => {
                    // Skip layer outside of clip.
                    workbench.ids.set_mask(i, false);
                }
            }
        }

        if let Some(Clip { last_layer_id, i, is_used, .. }) = clip {
            if id > last_layer_id {
                clip = None;

                if !is_used {
                    // Remove unused clips.
                    workbench.ids.set_mask(i, false);
                }
            }
        }
    }

    // Clip layer might be last layer.
    if let Some(Clip { i, is_used, .. }) = clip {
        if !is_used {
            // Remove unused clips.
            workbench.ids.set_mask(i, false);
        }
    }

    ControlFlow::Continue(())
}