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