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