• 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 "SkGradientShader.h"
12 
13 #include "SkArenaAlloc.h"
14 #include "SkMatrix.h"
15 #include "SkShaderBase.h"
16 #include "SkTArray.h"
17 #include "SkTemplates.h"
18 
19 class SkColorSpace;
20 class SkColorSpaceXformer;
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 = SkShader::kClamp_TileMode;
31         }
32 
33         const SkMatrix*     fLocalMatrix;
34         const SkColor4f*    fColors;
35         sk_sp<SkColorSpace> fColorSpace;
36         const SkScalar*     fPos;
37         int                 fCount;
38         SkShader::TileMode  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 StageRec&) const override;
81 
82     virtual void appendGradientStages(SkArenaAlloc* alloc, SkRasterPipeline* tPipeline,
83                                       SkRasterPipeline* postPipeline) const = 0;
84 
85     template <typename T, typename... Args>
CheckedMakeContext(SkArenaAlloc * alloc,Args &&...args)86     static Context* CheckedMakeContext(SkArenaAlloc* alloc, Args&&... args) {
87         auto* ctx = alloc->make<T>(std::forward<Args>(args)...);
88         if (!ctx->isValid()) {
89             return nullptr;
90         }
91         return ctx;
92     }
93 
94     struct AutoXformColors {
95         AutoXformColors(const SkGradientShaderBase&, SkColorSpaceXformer*);
96 
97         SkAutoSTMalloc<8, SkColor> fColors;
98     };
99 
100     const SkMatrix fPtsToUnit;
101     TileMode       fTileMode;
102     uint8_t        fGradFlags;
103 
104 public:
getPos(int i)105     SkScalar getPos(int i) const {
106         SkASSERT(i < fColorCount);
107         return fOrigPos ? fOrigPos[i] : SkIntToScalar(i) / (fColorCount - 1);
108     }
109 
getLegacyColor(int i)110     SkColor getLegacyColor(int i) const {
111         SkASSERT(i < fColorCount);
112         return fOrigColors4f[i].toSkColor();
113     }
114 
115     SkColor4f*          fOrigColors4f; // original colors, as linear floats
116     SkScalar*           fOrigPos;      // original positions
117     int                 fColorCount;
118     sk_sp<SkColorSpace> fColorSpace;   // color space of gradient stops
119 
colorsAreOpaque()120     bool colorsAreOpaque() const { return fColorsAreOpaque; }
121 
getTileMode()122     TileMode getTileMode() const { return fTileMode; }
123 
124 private:
125     // Reserve inline space for up to 4 stops.
126     static constexpr size_t kInlineStopCount   = 4;
127     static constexpr size_t kInlineStorageSize = (sizeof(SkColor4f) + sizeof(SkScalar))
128                                                * kInlineStopCount;
129     SkAutoSTMalloc<kInlineStorageSize, uint8_t> fStorage;
130 
131     bool                                        fColorsAreOpaque;
132 
133     typedef SkShaderBase INHERITED;
134 };
135 
136 ///////////////////////////////////////////////////////////////////////////////
137 
138 struct SkColor4fXformer {
139     SkColor4fXformer(const SkColor4f* colors, int colorCount, SkColorSpace* src, SkColorSpace* dst);
140 
141     const SkColor4f*              fColors;
142     SkSTArray<4, SkColor4f, true> fStorage;
143 };
144 
145 #endif
146