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