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