• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/effects/SkGradientShader.h"
12 
13 #include "include/core/SkMatrix.h"
14 #include "include/private/SkTArray.h"
15 #include "include/private/SkTemplates.h"
16 #include "src/core/SkArenaAlloc.h"
17 #include "src/core/SkVM.h"
18 #include "src/shaders/SkShaderBase.h"
19 
20 class SkColorSpace;
21 class SkRasterPipeline;
22 class SkReadBuffer;
23 class SkWriteBuffer;
24 
25 class SkGradientShaderBase : public SkShaderBase {
26 public:
27     struct Descriptor {
DescriptorDescriptor28         Descriptor() {
29             sk_bzero(this, sizeof(*this));
30             fTileMode = SkTileMode::kClamp;
31         }
32 
33         const SkMatrix*     fLocalMatrix;
34         const SkColor4f*    fColors;
35         sk_sp<SkColorSpace> fColorSpace;
36         const SkScalar*     fPos;
37         int                 fCount;
38         SkTileMode          fTileMode;
39         uint32_t            fGradFlags;
40 
41         void flatten(SkWriteBuffer&) const;
42     };
43 
44     class DescriptorScope : public Descriptor {
45     public:
DescriptorScope()46         DescriptorScope() {}
47 
48         bool unflatten(SkReadBuffer&);
49 
50         // fColors and fPos always point into local memory, so they can be safely mutated
51         //
mutableColors()52         SkColor4f* mutableColors() { return const_cast<SkColor4f*>(fColors); }
mutablePos()53         SkScalar* mutablePos() { return const_cast<SkScalar*>(fPos); }
54 
55     private:
56         SkSTArray<16, SkColor4f, true> fColorStorage;
57         SkSTArray<16, SkScalar , true> fPosStorage;
58         SkMatrix                       fLocalMatrixStorage;
59     };
60 
61     SkGradientShaderBase(const Descriptor& desc, const SkMatrix& ptsToUnit);
62     ~SkGradientShaderBase() override;
63 
64     bool isOpaque() const override;
65 
getGradFlags()66     uint32_t getGradFlags() const { return fGradFlags; }
67 
getGradientMatrix()68     const SkMatrix& getGradientMatrix() const { return fPtsToUnit; }
69 
70 protected:
71     class GradientShaderBase4fContext;
72 
73     SkGradientShaderBase(SkReadBuffer& );
74     void flatten(SkWriteBuffer&) const override;
75 
76     void commonAsAGradient(GradientInfo*) const;
77 
78     bool onAsLuminanceColor(SkColor*) const override;
79 
80     bool onAppendStages(const SkStageRec&) const override;
81 
82     skvm::Color onProgram(skvm::Builder*, skvm::Coord device, skvm::Coord local, skvm::Color paint,
83                           const SkMatrixProvider&, const SkMatrix* localM, const SkColorInfo& dstCS,
84                           skvm::Uniforms* uniforms, SkArenaAlloc* alloc) const override;
85 
86     virtual void appendGradientStages(SkArenaAlloc* alloc, SkRasterPipeline* tPipeline,
87                                       SkRasterPipeline* postPipeline) const = 0;
88 
89     // Produce t from (x,y), modifying mask if it should be anything other than ~0.
90     virtual skvm::F32 transformT(skvm::Builder*, skvm::Uniforms*,
91                                  skvm::Coord coord, skvm::I32* mask) const = 0;
92 
93     template <typename T, typename... Args>
CheckedMakeContext(SkArenaAlloc * alloc,Args &&...args)94     static Context* CheckedMakeContext(SkArenaAlloc* alloc, Args&&... args) {
95         auto* ctx = alloc->make<T>(std::forward<Args>(args)...);
96         if (!ctx->isValid()) {
97             return nullptr;
98         }
99         return ctx;
100     }
101 
102     const SkMatrix fPtsToUnit;
103     SkTileMode      fTileMode;
104     uint8_t        fGradFlags;
105 
106 public:
getPos(int i)107     SkScalar getPos(int i) const {
108         SkASSERT(i < fColorCount);
109         return fOrigPos ? fOrigPos[i] : SkIntToScalar(i) / (fColorCount - 1);
110     }
111 
getLegacyColor(int i)112     SkColor getLegacyColor(int i) const {
113         SkASSERT(i < fColorCount);
114         return fOrigColors4f[i].toSkColor();
115     }
116 
colorsCanConvertToSkColor()117     bool colorsCanConvertToSkColor() const {
118         bool canConvert = true;
119         for (int i = 0; i < fColorCount; ++i) {
120             canConvert &= fOrigColors4f[i].fitsInBytes();
121         }
122         return canConvert;
123     }
124 
125     SkColor4f*          fOrigColors4f; // original colors, as floats
126     SkScalar*           fOrigPos;      // original positions
127     int                 fColorCount;
128     sk_sp<SkColorSpace> fColorSpace;   // color space of gradient stops
129 
colorsAreOpaque()130     bool colorsAreOpaque() const { return fColorsAreOpaque; }
131 
getTileMode()132     SkTileMode getTileMode() const { return fTileMode; }
133 
134 private:
135     // Reserve inline space for up to 4 stops.
136     inline static constexpr size_t kInlineStopCount   = 4;
137     inline static constexpr size_t kInlineStorageSize = (sizeof(SkColor4f) + sizeof(SkScalar))
138                                                * kInlineStopCount;
139     SkAutoSTMalloc<kInlineStorageSize, uint8_t> fStorage;
140 
141     bool                                        fColorsAreOpaque;
142 
143     using INHERITED = SkShaderBase;
144 };
145 
146 ///////////////////////////////////////////////////////////////////////////////
147 
148 struct SkColor4fXformer {
149     SkColor4fXformer(const SkColor4f* colors, int colorCount, SkColorSpace* src, SkColorSpace* dst);
150 
151     const SkColor4f*              fColors;
152     SkSTArray<4, SkColor4f, true> fStorage;
153 };
154 
155 #endif
156