xref: /aosp_15_r20/external/skia/src/gpu/graphite/geom/CoverageMaskShape.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2023 Google LLC
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #ifndef skgpu_graphite_geom_CoverageMaskShape_DEFINED
9*c8dee2aaSAndroid Build Coastguard Worker #define skgpu_graphite_geom_CoverageMaskShape_DEFINED
10*c8dee2aaSAndroid Build Coastguard Worker 
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkM44.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkAssert.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkVx.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/geom/Rect.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/geom/Shape.h"
16*c8dee2aaSAndroid Build Coastguard Worker 
17*c8dee2aaSAndroid Build Coastguard Worker namespace skgpu::graphite {
18*c8dee2aaSAndroid Build Coastguard Worker 
19*c8dee2aaSAndroid Build Coastguard Worker class TextureProxy;
20*c8dee2aaSAndroid Build Coastguard Worker 
21*c8dee2aaSAndroid Build Coastguard Worker /**
22*c8dee2aaSAndroid Build Coastguard Worker  * CoverageMaskShape represents a shape for which per-pixel coverage data comes from a
23*c8dee2aaSAndroid Build Coastguard Worker  * texture. This excludes font glyphs that are rendered to a persistent atlas, as those are
24*c8dee2aaSAndroid Build Coastguard Worker  * represented by the SubRunData geometry type.
25*c8dee2aaSAndroid Build Coastguard Worker  *
26*c8dee2aaSAndroid Build Coastguard Worker  * Coverage masks are defined relative to an intermediate coordinate space between the final
27*c8dee2aaSAndroid Build Coastguard Worker  * device space and the original geometry and shading's local space. For atlases and simple cases
28*c8dee2aaSAndroid Build Coastguard Worker  * this intermediate space is pixel-aligned with the final device space, meaning only an integer
29*c8dee2aaSAndroid Build Coastguard Worker  * translation is necessary to align the mask with where the original geometry would have been
30*c8dee2aaSAndroid Build Coastguard Worker  * rendered into the device. In complex cases, the remaining transform may include rotation, skew,
31*c8dee2aaSAndroid Build Coastguard Worker  * or even perspective that has to be applied after some filter effect.
32*c8dee2aaSAndroid Build Coastguard Worker  *
33*c8dee2aaSAndroid Build Coastguard Worker  * Regardless, the DrawParams that records the CoverageMaskShape stores this remaining transform as
34*c8dee2aaSAndroid Build Coastguard Worker  * the "local-to-device" tranform, i.e. "local" refers to the mask's coordinate space. The
35*c8dee2aaSAndroid Build Coastguard Worker  * CoverageMaskShape stores the original local-to-device inverse so that it can reconstruct coords
36*c8dee2aaSAndroid Build Coastguard Worker  * for shading. Like other Geometry types, the bounds() returned by CoverageMaskShape are relative
37*c8dee2aaSAndroid Build Coastguard Worker  * to its local space, so they are identical to its mask size.
38*c8dee2aaSAndroid Build Coastguard Worker  */
39*c8dee2aaSAndroid Build Coastguard Worker class CoverageMaskShape {
40*c8dee2aaSAndroid Build Coastguard Worker     using half2 = skvx::half2;
41*c8dee2aaSAndroid Build Coastguard Worker     using int2 = skvx::int2;
42*c8dee2aaSAndroid Build Coastguard Worker 
43*c8dee2aaSAndroid Build Coastguard Worker public:
44*c8dee2aaSAndroid Build Coastguard Worker     struct MaskInfo {
45*c8dee2aaSAndroid Build Coastguard Worker         // The texture-relative integer UV coordinates of the top-left corner of this shape's
46*c8dee2aaSAndroid Build Coastguard Worker         // coverage mask bounds. This will include the rounded out transformed device space bounds
47*c8dee2aaSAndroid Build Coastguard Worker         // of the shape plus a 1-pixel border.
48*c8dee2aaSAndroid Build Coastguard Worker         half2 fTextureOrigin;
49*c8dee2aaSAndroid Build Coastguard Worker 
50*c8dee2aaSAndroid Build Coastguard Worker         // The width and height of the bounds of the coverage mask shape in device coordinates. This
51*c8dee2aaSAndroid Build Coastguard Worker         // includes the rounded out transformed device space bounds of the shape + a 1-pixel border
52*c8dee2aaSAndroid Build Coastguard Worker         // added for AA.
53*c8dee2aaSAndroid Build Coastguard Worker         half2 fMaskSize;
54*c8dee2aaSAndroid Build Coastguard Worker     };
55*c8dee2aaSAndroid Build Coastguard Worker 
56*c8dee2aaSAndroid Build Coastguard Worker     CoverageMaskShape() = default;
CoverageMaskShape(const Shape & shape,const TextureProxy * proxy,const SkM44 & deviceToLocal,const MaskInfo & maskInfo)57*c8dee2aaSAndroid Build Coastguard Worker     CoverageMaskShape(const Shape& shape,
58*c8dee2aaSAndroid Build Coastguard Worker                       const TextureProxy* proxy,
59*c8dee2aaSAndroid Build Coastguard Worker                       const SkM44& deviceToLocal,
60*c8dee2aaSAndroid Build Coastguard Worker                       const MaskInfo& maskInfo)
61*c8dee2aaSAndroid Build Coastguard Worker             : fTextureProxy(proxy)
62*c8dee2aaSAndroid Build Coastguard Worker             , fDeviceToLocal(deviceToLocal)
63*c8dee2aaSAndroid Build Coastguard Worker             , fInverted(shape.inverted())
64*c8dee2aaSAndroid Build Coastguard Worker             , fMaskInfo(maskInfo) {
65*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(proxy);
66*c8dee2aaSAndroid Build Coastguard Worker     }
67*c8dee2aaSAndroid Build Coastguard Worker     CoverageMaskShape(const CoverageMaskShape&) = default;
68*c8dee2aaSAndroid Build Coastguard Worker 
69*c8dee2aaSAndroid Build Coastguard Worker     ~CoverageMaskShape() = default;
70*c8dee2aaSAndroid Build Coastguard Worker 
71*c8dee2aaSAndroid Build Coastguard Worker     // NOTE: None of the geometry types benefit from move semantics, so we don't bother
72*c8dee2aaSAndroid Build Coastguard Worker     // defining a move assignment operator for CoverageMaskShape.
73*c8dee2aaSAndroid Build Coastguard Worker     CoverageMaskShape& operator=(CoverageMaskShape&&) = delete;
74*c8dee2aaSAndroid Build Coastguard Worker     CoverageMaskShape& operator=(const CoverageMaskShape&) = default;
75*c8dee2aaSAndroid Build Coastguard Worker 
76*c8dee2aaSAndroid Build Coastguard Worker     // Returns the mask-space bounds of the clipped coverage mask shape. For inverse fills this
77*c8dee2aaSAndroid Build Coastguard Worker     // is different from the actual draw bounds stored in the Clip.
bounds()78*c8dee2aaSAndroid Build Coastguard Worker     Rect bounds() const {
79*c8dee2aaSAndroid Build Coastguard Worker         return Rect(0.f, 0.f, (float) this->maskSize().x(), (float) this->maskSize().y());
80*c8dee2aaSAndroid Build Coastguard Worker     }
81*c8dee2aaSAndroid Build Coastguard Worker 
82*c8dee2aaSAndroid Build Coastguard Worker     // The inverse local-to-device matrix.
deviceToLocal()83*c8dee2aaSAndroid Build Coastguard Worker     const SkM44& deviceToLocal() const { return fDeviceToLocal; }
84*c8dee2aaSAndroid Build Coastguard Worker 
85*c8dee2aaSAndroid Build Coastguard Worker     // The texture-relative integer UV coordinates of the top-left corner of this shape's
86*c8dee2aaSAndroid Build Coastguard Worker     // coverage mask bounds.
textureOrigin()87*c8dee2aaSAndroid Build Coastguard Worker     const half2& textureOrigin() const { return fMaskInfo.fTextureOrigin; }
88*c8dee2aaSAndroid Build Coastguard Worker 
89*c8dee2aaSAndroid Build Coastguard Worker     // The width and height of the bounds of the coverage mask shape in device coordinates.
maskSize()90*c8dee2aaSAndroid Build Coastguard Worker     const half2& maskSize() const { return fMaskInfo.fMaskSize; }
91*c8dee2aaSAndroid Build Coastguard Worker 
92*c8dee2aaSAndroid Build Coastguard Worker     // The texture that the shape will be rendered to.
textureProxy()93*c8dee2aaSAndroid Build Coastguard Worker     const TextureProxy* textureProxy() const { return fTextureProxy; }
94*c8dee2aaSAndroid Build Coastguard Worker 
95*c8dee2aaSAndroid Build Coastguard Worker     // Whether or not the shape will be painted according to an inverse fill rule.
inverted()96*c8dee2aaSAndroid Build Coastguard Worker     bool inverted() const { return fInverted; }
97*c8dee2aaSAndroid Build Coastguard Worker 
98*c8dee2aaSAndroid Build Coastguard Worker private:
99*c8dee2aaSAndroid Build Coastguard Worker     const TextureProxy* fTextureProxy;
100*c8dee2aaSAndroid Build Coastguard Worker     SkM44 fDeviceToLocal;
101*c8dee2aaSAndroid Build Coastguard Worker     bool fInverted;
102*c8dee2aaSAndroid Build Coastguard Worker     MaskInfo fMaskInfo;
103*c8dee2aaSAndroid Build Coastguard Worker };
104*c8dee2aaSAndroid Build Coastguard Worker 
105*c8dee2aaSAndroid Build Coastguard Worker }  // namespace skgpu::graphite
106*c8dee2aaSAndroid Build Coastguard Worker 
107*c8dee2aaSAndroid Build Coastguard Worker #endif  // skgpu_graphite_geom_CoverageMaskShape_DEFINED
108