xref: /aosp_15_r20/external/skia/src/shaders/gradients/SkGradientBaseShader.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2012 Google Inc.
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 SkGradientShaderPriv_DEFINED
9 #define SkGradientShaderPriv_DEFINED
10 
11 #include "include/core/SkBitmap.h"
12 #include "include/core/SkColor.h"
13 #include "include/core/SkColorSpace.h"
14 #include "include/core/SkMatrix.h"
15 #include "include/core/SkRefCnt.h"
16 #include "include/core/SkScalar.h"
17 #include "include/effects/SkGradientShader.h"
18 #include "include/private/SkColorData.h"
19 #include "include/private/base/SkAssert.h"
20 #include "include/private/base/SkTArray.h"
21 #include "include/private/base/SkTemplates.h"
22 #include "src/shaders/SkShaderBase.h"
23 
24 #include <cstddef>
25 #include <cstdint>
26 
27 class SkArenaAlloc;
28 class SkRasterPipeline;
29 class SkReadBuffer;
30 class SkShader;
31 class SkWriteBuffer;
32 enum class SkTileMode;
33 struct SkStageRec;
34 
35 class SkGradientBaseShader : public SkShaderBase {
36 public:
37     using Interpolation = SkGradientShader::Interpolation;
38 
39     struct Descriptor {
40         Descriptor();
41         ~Descriptor();
42 
43         Descriptor(const SkColor4f colors[],
44                    sk_sp<SkColorSpace> colorSpace,
45                    const SkScalar positions[],
46                    int colorCount,
47                    SkTileMode mode,
48                    const Interpolation& interpolation);
49 
50         const SkColor4f* fColors;
51         sk_sp<SkColorSpace> fColorSpace;
52         const SkScalar* fPositions;
53         int fColorCount;  // length of fColors (and fPositions, if not nullptr)
54         SkTileMode fTileMode;
55         Interpolation fInterpolation;
56     };
57 
58     class DescriptorScope : public Descriptor {
59     public:
DescriptorScope()60         DescriptorScope() {}
61 
62         bool unflatten(SkReadBuffer&, SkMatrix* legacyLocalMatrix);
63 
64     private:
65         skia_private::STArray<16, SkColor4f> fColorStorage;
66         skia_private::STArray<16, SkScalar> fPositionStorage;
67     };
68 
69     SkGradientBaseShader(const Descriptor& desc, const SkMatrix& ptsToUnit);
70     ~SkGradientBaseShader() override;
71 
type()72     ShaderType type() const final { return ShaderType::kGradientBase; }
73 
74     bool isOpaque() const override;
75 
interpolateInPremul()76     bool interpolateInPremul() const {
77         return fInterpolation.fInPremul == SkGradientShader::Interpolation::InPremul::kYes;
78     }
79 
getGradientMatrix()80     const SkMatrix& getGradientMatrix() const { return fPtsToUnit; }
getColorCount()81     int getColorCount() const { return fColorCount; }
getPositions()82     const float* getPositions() const { return fPositions; }
getInterpolation()83     const Interpolation& getInterpolation() const { return fInterpolation; }
84 
85     static bool ValidGradient(const SkColor4f colors[],
86                               int count,
87                               SkTileMode tileMode,
88                               const Interpolation& interpolation);
89 
90     static sk_sp<SkShader> MakeDegenerateGradient(const SkColor4f colors[],
91                                                   const SkScalar pos[],
92                                                   int colorCount,
93                                                   sk_sp<SkColorSpace> colorSpace,
94                                                   SkTileMode mode);
95 
96     // The default SkScalarNearlyZero threshold of .0024 is too big and causes regressions for svg
97     // gradients defined in the wild.
98     static constexpr SkScalar kDegenerateThreshold = SK_Scalar1 / (1 << 15);
99 
100 protected:
101     void flatten(SkWriteBuffer&) const override;
102 
103     void commonAsAGradient(GradientInfo*) const;
104 
105     bool onAsLuminanceColor(SkColor4f*) const override;
106 
107     bool appendStages(const SkStageRec&, const SkShaders::MatrixRec&) const override;
108 
109     virtual void appendGradientStages(SkArenaAlloc* alloc,
110                                       SkRasterPipeline* tPipeline,
111                                       SkRasterPipeline* postPipeline) const = 0;
112 
113     const SkMatrix fPtsToUnit;
114     SkTileMode fTileMode;
115 
116 public:
117     static void AppendGradientFillStages(SkRasterPipeline* p,
118                                          SkArenaAlloc* alloc,
119                                          const SkPMColor4f* colors,
120                                          const SkScalar* positions,
121                                          int count);
122 
123     static void AppendInterpolatedToDstStages(SkRasterPipeline* p,
124                                               SkArenaAlloc* alloc,
125                                               bool colorsAreOpaque,
126                                               const Interpolation& interpolation,
127                                               const SkColorSpace* intermediateColorSpace,
128                                               const SkColorSpace* dstColorSpace);
129 
getPos(int i)130     SkScalar getPos(int i) const {
131         SkASSERT(i < fColorCount);
132         return fPositions ? fPositions[i] : SkIntToScalar(i) / (fColorCount - 1);
133     }
134 
getLegacyColor(int i)135     SkColor getLegacyColor(int i) const {
136         SkASSERT(i < fColorCount);
137         return fColors[i].toSkColor();
138     }
139 
140     SkColor4f* fColors;               // points into fStorage
141     SkScalar* fPositions;             // points into fStorage, or nullptr
142     int fColorCount;                  // length of fColors (and fPositions, if not nullptr)
143     sk_sp<SkColorSpace> fColorSpace;  // color space of gradient stops
144     Interpolation fInterpolation;
145     bool fFirstStopIsImplicit;
146     bool fLastStopIsImplicit;
147 
colorsAreOpaque()148     bool colorsAreOpaque() const { return fColorsAreOpaque; }
149 
getTileMode()150     SkTileMode getTileMode() const { return fTileMode; }
151 
cachedBitmap()152     const SkBitmap& cachedBitmap() const { return fColorsAndOffsetsBitmap; }
setCachedBitmap(SkBitmap b)153     void setCachedBitmap(SkBitmap b) const { fColorsAndOffsetsBitmap = b; }
154 
155 private:
156     // When the number of stops exceeds Graphite's uniform-based limit the colors and offsets
157     // are stored in this bitmap. It is stored in the shader so it can be cached with a stable
158     // id and easily regenerated if purged.
159     // TODO(b/293160919) remove this field when we can store bitmaps in the cache by id.
160     mutable SkBitmap fColorsAndOffsetsBitmap;
161 
162     // Reserve inline space for up to 4 stops.
163     inline static constexpr size_t kInlineStopCount = 4;
164     inline static constexpr size_t kInlineStorageSize =
165             (sizeof(SkColor4f) + sizeof(SkScalar)) * kInlineStopCount;
166     skia_private::AutoSTMalloc<kInlineStorageSize, uint8_t> fStorage;
167 
168     bool fColorsAreOpaque;
169 };
170 
171 ///////////////////////////////////////////////////////////////////////////////
172 
173 struct SkColor4fXformer {
174     SkColor4fXformer(const SkGradientBaseShader* shader,
175                      SkColorSpace* dst,
176                      bool forceExplicitPositions = false);
177 
178     using ColorStorage = skia_private::STArray<4, SkPMColor4f>;
179     using PositionStorage = skia_private::STArray<4, float>;
180 
181     ColorStorage fColors;
182     PositionStorage fPositionStorage;
183     float* fPositions;
184     sk_sp<SkColorSpace> fIntermediateColorSpace;
185 };
186 
187 struct SkColorConverter {
188     SkColorConverter(const SkColor* colors, int count);
189 
190     skia_private::STArray<2, SkColor4f> fColors4f;
191 };
192 
193 void SkRegisterConicalGradientShaderFlattenable();
194 void SkRegisterLinearGradientShaderFlattenable();
195 void SkRegisterRadialGradientShaderFlattenable();
196 void SkRegisterSweepGradientShaderFlattenable();
197 
198 #endif
199