1 /* 2 * Copyright 2024 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_AnalyticBlurMask_DEFINED 9 #define skgpu_graphite_geom_AnalyticBlurMask_DEFINED 10 11 #include "include/core/SkM44.h" 12 #include "include/core/SkRefCnt.h" 13 #include "src/gpu/graphite/TextureProxy.h" 14 #include "src/gpu/graphite/geom/Rect.h" 15 16 #include <optional> 17 #include <utility> 18 19 class SkMatrix; 20 class SkRRect; 21 struct SkRect; 22 23 namespace skgpu::graphite { 24 25 class Recorder; 26 class Transform; 27 28 /** 29 * AnalyticBlurMask holds the shader inputs used to do an analytic blur over rects, rrects, or 30 * circles. 31 */ 32 class AnalyticBlurMask { 33 public: 34 enum class ShapeType { 35 kRect, 36 kRRect, 37 kCircle, 38 }; 39 40 static_assert(0 == static_cast<int>(ShapeType::kRect), 41 "Blur shader code depends on AnalyticBlurMask::ShapeType"); 42 static_assert(1 == static_cast<int>(ShapeType::kRRect), 43 "Blur shader code depends on AnalyticBlurMask::ShapeType"); 44 static_assert(2 == static_cast<int>(ShapeType::kCircle), 45 "Blur shader code depends on AnalyticBlurMask::ShapeType"); 46 47 AnalyticBlurMask() = delete; 48 49 static std::optional<AnalyticBlurMask> Make(Recorder*, 50 const Transform& localToDevice, 51 float deviceSigma, 52 const SkRRect& srcRRect); 53 drawBounds()54 const Rect& drawBounds() const { return fDrawBounds; } deviceToScaledShape()55 const SkM44& deviceToScaledShape() const { return fDevToScaledShape; } shapeData()56 const Rect& shapeData() const { return fShapeData; } shapeType()57 ShapeType shapeType() const { return fShapeType; } blurData()58 const SkV2& blurData() const { return fBlurData; } refProxy()59 sk_sp<TextureProxy> refProxy() const { return fProxy; } 60 61 private: AnalyticBlurMask(const Rect & drawBounds,const SkM44 & devToScaledShape,ShapeType shapeType,const Rect & shapeData,const SkV2 & blurData,sk_sp<TextureProxy> proxy)62 AnalyticBlurMask(const Rect& drawBounds, 63 const SkM44& devToScaledShape, 64 ShapeType shapeType, 65 const Rect& shapeData, 66 const SkV2& blurData, 67 sk_sp<TextureProxy> proxy) 68 : fDrawBounds(drawBounds) 69 , fDevToScaledShape(devToScaledShape) 70 , fShapeData(shapeData) 71 , fBlurData(blurData) 72 , fShapeType(shapeType) 73 , fProxy(std::move(proxy)) {} 74 75 static std::optional<AnalyticBlurMask> MakeRect(Recorder*, 76 const SkMatrix& localToDevice, 77 float devSigma, 78 const SkRect& srcRect); 79 80 static std::optional<AnalyticBlurMask> MakeCircle(Recorder*, 81 const SkMatrix& localToDevice, 82 float devSigma, 83 const SkRect& srcRect, 84 const SkRect& devRect); 85 86 static std::optional<AnalyticBlurMask> MakeRRect(Recorder* recorder, 87 const SkMatrix& localToDevice, 88 float devSigma, 89 const SkRRect& srcRRect, 90 const SkRRect& devRRect); 91 92 // Draw bounds in local space. 93 Rect fDrawBounds; 94 95 // Transforms device-space coordinates to the shape data's space. 96 SkM44 fDevToScaledShape; 97 98 // Shape data, which can define a rectangle, circle, or rounded rectangle. 99 // This data is in a local space defined by the concatenation of the local-to-device matrix and 100 // fDevToScaledShape. 101 Rect fShapeData; 102 103 // "fBlurData" holds different data depending on the shape type, for the unique needs of the 104 // shape types' respective shaders. 105 // In the rectangle case, it holds: 106 // x = a boolean indicating whether we can use a fast path for sampling the blur integral 107 // because the rectangle is larger than 6*sigma in both dimensions, and 108 // y = the value "1 / (6*sigma)". 109 // In the rounded rectangle case, it holds: 110 // x = the size of the blurred edge, defined as "2*blurRadius + cornerRadius", and 111 // y is unused. 112 // In the circle case, this data is unused. 113 SkV2 fBlurData; 114 115 ShapeType fShapeType; 116 sk_sp<TextureProxy> fProxy; 117 }; 118 119 } // namespace skgpu::graphite 120 121 #endif // skgpu_graphite_geom_AnalyticBlurMask_DEFINED 122