forma_render/
consts.rs

1// Copyright 2022 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#![allow(clippy::assertions_on_constants)]
16
17use std::mem;
18
19use crate::cpu::PixelSegment;
20
21pub(crate) const PIXEL_WIDTH: usize = 16;
22pub(crate) const PIXEL_DOUBLE_WIDTH: usize = PIXEL_WIDTH * 2;
23pub(crate) const PIXEL_SHIFT: usize = PIXEL_WIDTH.trailing_zeros() as usize;
24
25pub const MAX_WIDTH: usize = 1 << 16;
26pub const MAX_HEIGHT: usize = 1 << 15;
27
28pub(crate) const MAX_WIDTH_SHIFT: usize = MAX_WIDTH.trailing_zeros() as usize;
29pub(crate) const MAX_HEIGHT_SHIFT: usize = MAX_HEIGHT.trailing_zeros() as usize;
30
31pub mod cpu {
32    pub const TILE_WIDTH: usize = 16;
33    const _: () = assert!(TILE_WIDTH % 16 == 0);
34    const _: () = assert!(TILE_WIDTH <= 128);
35
36    pub(crate) const TILE_WIDTH_SHIFT: usize = TILE_WIDTH.trailing_zeros() as usize;
37
38    pub const TILE_HEIGHT: usize = 16;
39    const _: () = assert!(TILE_HEIGHT % 16 == 0);
40    const _: () = assert!(TILE_HEIGHT <= 128);
41
42    pub(crate) const TILE_HEIGHT_SHIFT: usize = TILE_HEIGHT.trailing_zeros() as usize;
43}
44
45pub mod gpu {
46    pub const TILE_WIDTH: usize = 16;
47    pub const TILE_HEIGHT: usize = 4;
48}
49
50#[derive(Clone, Copy, Debug)]
51pub(crate) enum BitField {
52    TileY,
53    TileX,
54    LayerId,
55    LocalX,
56    LocalY,
57    DoubleAreaMultiplier,
58    Cover,
59}
60
61#[derive(Debug)]
62pub(crate) struct BitFieldMap {
63    lengths: [usize; 7],
64}
65
66impl BitFieldMap {
67    #[inline]
68    pub const fn new<const TW: usize, const TH: usize>() -> Self {
69        let tile_width_shift = TW.trailing_zeros() as usize;
70        let tile_height_shift = TH.trailing_zeros() as usize;
71
72        let mut lengths = [
73            MAX_HEIGHT_SHIFT - tile_height_shift,
74            MAX_WIDTH_SHIFT - tile_width_shift,
75            0,
76            tile_width_shift,
77            tile_height_shift,
78            ((PIXEL_WIDTH + 1) * 2).next_power_of_two().trailing_zeros() as usize,
79            ((PIXEL_WIDTH + 1) * 2).next_power_of_two().trailing_zeros() as usize,
80        ];
81
82        let layer_id_len = mem::size_of::<PixelSegment<TW, TH>>() * 8
83            - lengths[BitField::TileY as usize]
84            - lengths[BitField::TileX as usize]
85            - lengths[BitField::LocalX as usize]
86            - lengths[BitField::LocalY as usize]
87            - lengths[BitField::DoubleAreaMultiplier as usize]
88            - lengths[BitField::Cover as usize];
89
90        lengths[BitField::LayerId as usize] = layer_id_len;
91
92        Self { lengths }
93    }
94
95    #[inline]
96    pub const fn get(&self, bit_field: BitField) -> usize {
97        self.lengths[bit_field as usize]
98    }
99
100    #[inline]
101    pub const fn get_by_index(&self, i: usize) -> usize {
102        self.lengths[i]
103    }
104}
105
106pub const LAYER_LIMIT: usize = (1
107    << BitFieldMap::new::<{ cpu::TILE_WIDTH }, { cpu::TILE_HEIGHT }>().get(BitField::LayerId))
108    - 1;
109const _: () = assert!(
110    LAYER_LIMIT
111        == (1
112            << BitFieldMap::new::<{ gpu::TILE_WIDTH }, { gpu::TILE_HEIGHT }>()
113                .get(BitField::LayerId))
114            - 1,
115    "LAYER_LIMIT must be the same both on cpu and gpu",
116);