Make all GrFragmentProcessors GL independent.
[platform/upstream/libSkiaSharp.git] / src / effects / gradients / SkGradientShaderPriv.h
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 "SkGradientBitmapCache.h"
12 #include "SkGradientShader.h"
13 #include "SkClampRange.h"
14 #include "SkColorPriv.h"
15 #include "SkReadBuffer.h"
16 #include "SkWriteBuffer.h"
17 #include "SkMallocPixelRef.h"
18 #include "SkUtils.h"
19 #include "SkShader.h"
20 #include "SkOnce.h"
21
22 static inline void sk_memset32_dither(uint32_t dst[], uint32_t v0, uint32_t v1,
23                                int count) {
24     if (count > 0) {
25         if (v0 == v1) {
26             sk_memset32(dst, v0, count);
27         } else {
28             int pairs = count >> 1;
29             for (int i = 0; i < pairs; i++) {
30                 *dst++ = v0;
31                 *dst++ = v1;
32             }
33             if (count & 1) {
34                 *dst = v0;
35             }
36         }
37     }
38 }
39
40 //  Clamp
41
42 static inline SkFixed clamp_tileproc(SkFixed x) {
43     return SkClampMax(x, 0xFFFF);
44 }
45
46 // Repeat
47
48 static inline SkFixed repeat_tileproc(SkFixed x) {
49     return x & 0xFFFF;
50 }
51
52 // Mirror
53
54 // Visual Studio 2010 (MSC_VER=1600) optimizes bit-shift code incorrectly.
55 // See http://code.google.com/p/skia/issues/detail?id=472
56 #if defined(_MSC_VER) && (_MSC_VER >= 1600)
57 #pragma optimize("", off)
58 #endif
59
60 static inline SkFixed mirror_tileproc(SkFixed x) {
61     int s = x << 15 >> 31;
62     return (x ^ s) & 0xFFFF;
63 }
64
65 #if defined(_MSC_VER) && (_MSC_VER >= 1600)
66 #pragma optimize("", on)
67 #endif
68
69 ///////////////////////////////////////////////////////////////////////////////
70
71 typedef SkFixed (*TileProc)(SkFixed);
72
73 ///////////////////////////////////////////////////////////////////////////////
74
75 static const TileProc gTileProcs[] = {
76     clamp_tileproc,
77     repeat_tileproc,
78     mirror_tileproc
79 };
80
81 ///////////////////////////////////////////////////////////////////////////////
82
83 class SkGradientShaderBase : public SkShader {
84 public:
85     struct Descriptor {
86         Descriptor() {
87             sk_bzero(this, sizeof(*this));
88             fTileMode = SkShader::kClamp_TileMode;
89         }
90
91         const SkMatrix*     fLocalMatrix;
92         const SkColor*      fColors;
93         const SkScalar*     fPos;
94         int                 fCount;
95         SkShader::TileMode  fTileMode;
96         uint32_t            fGradFlags;
97
98         void flatten(SkWriteBuffer&) const;
99     };
100
101     class DescriptorScope : public Descriptor {
102     public:
103         DescriptorScope() {}
104
105         bool unflatten(SkReadBuffer&);
106
107         // fColors and fPos always point into local memory, so they can be safely mutated
108         //
109         SkColor* mutableColors() { return const_cast<SkColor*>(fColors); }
110         SkScalar* mutablePos() { return const_cast<SkScalar*>(fPos); }
111
112     private:
113         enum {
114             kStorageCount = 16
115         };
116         SkColor fColorStorage[kStorageCount];
117         SkScalar fPosStorage[kStorageCount];
118         SkMatrix fLocalMatrixStorage;
119         SkAutoMalloc fDynamicStorage;
120     };
121
122 public:
123     SkGradientShaderBase(const Descriptor& desc, const SkMatrix& ptsToUnit);
124     virtual ~SkGradientShaderBase();
125
126     // The cache is initialized on-demand when getCache16/32 is called.
127     class GradientShaderCache : public SkRefCnt {
128     public:
129         GradientShaderCache(U8CPU alpha, bool dither, const SkGradientShaderBase& shader);
130         ~GradientShaderCache();
131
132         const uint16_t*     getCache16();
133         const SkPMColor*    getCache32();
134
135         SkMallocPixelRef* getCache32PixelRef() const { return fCache32PixelRef; }
136
137         unsigned getAlpha() const { return fCacheAlpha; }
138         bool getDither() const { return fCacheDither; }
139
140     private:
141         // Working pointers. If either is nullptr, we need to recompute the corresponding cache values.
142         uint16_t*   fCache16;
143         SkPMColor*  fCache32;
144
145         uint16_t*         fCache16Storage;    // Storage for fCache16, allocated on demand.
146         SkMallocPixelRef* fCache32PixelRef;
147         const unsigned    fCacheAlpha;        // The alpha value we used when we computed the cache.
148                                               // Larger than 8bits so we can store uninitialized
149                                               // value.
150         const bool        fCacheDither;       // The dither flag used when we computed the cache.
151
152         const SkGradientShaderBase& fShader;
153
154         // Make sure we only initialize the caches once.
155         bool    fCache16Inited, fCache32Inited;
156         SkMutex fCache16Mutex, fCache32Mutex;
157
158         static void initCache16(GradientShaderCache* cache);
159         static void initCache32(GradientShaderCache* cache);
160
161         static void Build16bitCache(uint16_t[], SkColor c0, SkColor c1, int count, bool dither);
162         static void Build32bitCache(SkPMColor[], SkColor c0, SkColor c1, int count,
163                                     U8CPU alpha, uint32_t gradFlags, bool dither);
164     };
165
166     class GradientShaderBaseContext : public SkShader::Context {
167     public:
168         GradientShaderBaseContext(const SkGradientShaderBase& shader, const ContextRec&);
169
170         uint32_t getFlags() const override { return fFlags; }
171
172     protected:
173         SkMatrix    fDstToIndex;
174         SkMatrix::MapXYProc fDstToIndexProc;
175         uint8_t     fDstToIndexClass;
176         uint8_t     fFlags;
177         bool        fDither;
178
179         SkAutoTUnref<GradientShaderCache> fCache;
180
181     private:
182         typedef SkShader::Context INHERITED;
183     };
184
185     bool isOpaque() const override;
186
187     void getGradientTableBitmap(SkBitmap*) const;
188
189     enum {
190         /// Seems like enough for visual accuracy. TODO: if pos[] deserves
191         /// it, use a larger cache.
192         kCache16Bits    = 8,
193         kCache16Count = (1 << kCache16Bits),
194         kCache16Shift   = 16 - kCache16Bits,
195         kSqrt16Shift    = 8 - kCache16Bits,
196
197         /// Seems like enough for visual accuracy. TODO: if pos[] deserves
198         /// it, use a larger cache.
199         kCache32Bits    = 8,
200         kCache32Count   = (1 << kCache32Bits),
201         kCache32Shift   = 16 - kCache32Bits,
202         kSqrt32Shift    = 8 - kCache32Bits,
203
204         /// This value is used to *read* the dither cache; it may be 0
205         /// if dithering is disabled.
206         kDitherStride32 = kCache32Count,
207         kDitherStride16 = kCache16Count,
208     };
209
210     enum GpuColorType {
211         kTwo_GpuColorType,
212         kThree_GpuColorType, // Symmetric three color
213         kTexture_GpuColorType
214     };
215
216     // Determines and returns the gradient is a two color gradient, symmetric three color gradient
217     // or other (texture gradient). If it is two or symmetric three color, the colors array will
218     // also be filled with the gradient colors
219     GpuColorType getGpuColorType(SkColor colors[3]) const;
220
221     uint32_t getGradFlags() const { return fGradFlags; }
222
223 protected:
224     SkGradientShaderBase(SkReadBuffer& );
225     void flatten(SkWriteBuffer&) const override;
226     SK_TO_STRING_OVERRIDE()
227
228     const SkMatrix fPtsToUnit;
229     TileMode    fTileMode;
230     TileProc    fTileProc;
231     int         fColorCount;
232     uint8_t     fGradFlags;
233
234     struct Rec {
235         SkFixed     fPos;   // 0...1
236         uint32_t    fScale; // (1 << 24) / range
237     };
238     Rec*        fRecs;
239
240     void commonAsAGradient(GradientInfo*, bool flipGrad = false) const;
241
242     bool onAsLuminanceColor(SkColor*) const override;
243
244     /*
245      * Takes in pointers to gradient color and Rec info as colorSrc and recSrc respectively.
246      * Count is the number of colors in the gradient
247      * It will then flip all the color and rec information and return in their respective Dst
248      * pointers. It is assumed that space has already been allocated for the Dst pointers.
249      * The rec src and dst are only assumed to be valid if count > 2
250      */
251     static void FlipGradientColors(SkColor* colorDst, Rec* recDst,
252                                    SkColor* colorSrc, Rec* recSrc,
253                                    int count);
254
255 private:
256     enum {
257         kColorStorageCount = 4, // more than this many colors, and we'll use sk_malloc for the space
258
259         kStorageSize = kColorStorageCount * (sizeof(SkColor) + sizeof(SkScalar) + sizeof(Rec))
260     };
261     SkColor     fStorage[(kStorageSize + 3) >> 2];
262     SkColor*    fOrigColors; // original colors, before modulation by paint in context.
263     SkScalar*   fOrigPos;   // original positions
264     bool        fColorsAreOpaque;
265
266     GradientShaderCache* refCache(U8CPU alpha, bool dither) const;
267     mutable SkMutex                           fCacheMutex;
268     mutable SkAutoTUnref<GradientShaderCache> fCache;
269
270     void initCommon();
271
272     typedef SkShader INHERITED;
273 };
274
275 static inline int init_dither_toggle(int x, int y) {
276     x &= 1;
277     y = (y & 1) << 1;
278     return (x | y) * SkGradientShaderBase::kDitherStride32;
279 }
280
281 static inline int next_dither_toggle(int toggle) {
282     return toggle ^ SkGradientShaderBase::kDitherStride32;
283 }
284
285 static inline int init_dither_toggle16(int x, int y) {
286     return ((x ^ y) & 1) * SkGradientShaderBase::kDitherStride16;
287 }
288
289 static inline int next_dither_toggle16(int toggle) {
290     return toggle ^ SkGradientShaderBase::kDitherStride16;
291 }
292
293 ///////////////////////////////////////////////////////////////////////////////
294
295 #if SK_SUPPORT_GPU
296
297 #include "GrCoordTransform.h"
298 #include "GrFragmentProcessor.h"
299 #include "glsl/GrGLSLFragmentProcessor.h"
300 #include "glsl/GrGLSLProgramDataManager.h"
301
302 class GrInvariantOutput;
303
304 /*
305  * The interpretation of the texture matrix depends on the sample mode. The
306  * texture matrix is applied both when the texture coordinates are explicit
307  * and  when vertex positions are used as texture  coordinates. In the latter
308  * case the texture matrix is applied to the pre-view-matrix position
309  * values.
310  *
311  * Normal SampleMode
312  *  The post-matrix texture coordinates are in normalize space with (0,0) at
313  *  the top-left and (1,1) at the bottom right.
314  * RadialGradient
315  *  The matrix specifies the radial gradient parameters.
316  *  (0,0) in the post-matrix space is center of the radial gradient.
317  * Radial2Gradient
318  *   Matrix transforms to space where first circle is centered at the
319  *   origin. The second circle will be centered (x, 0) where x may be
320  *   0 and is provided by setRadial2Params. The post-matrix space is
321  *   normalized such that 1 is the second radius - first radius.
322  * SweepGradient
323  *  The angle from the origin of texture coordinates in post-matrix space
324  *  determines the gradient value.
325  */
326
327  class GrTextureStripAtlas;
328
329 // Base class for Gr gradient effects
330 class GrGradientEffect : public GrFragmentProcessor {
331 public:
332
333     GrGradientEffect(GrContext* ctx,
334                      const SkGradientShaderBase& shader,
335                      const SkMatrix& matrix,
336                      SkShader::TileMode tileMode);
337
338     virtual ~GrGradientEffect();
339
340     bool useAtlas() const { return SkToBool(-1 != fRow); }
341     SkScalar getYCoord() const { return fYCoord; };
342
343     SkGradientShaderBase::GpuColorType getColorType() const { return fColorType; }
344
345     enum PremulType {
346         kBeforeInterp_PremulType,
347         kAfterInterp_PremulType,
348     };
349
350     PremulType getPremulType() const { return fPremulType; }
351
352     const SkColor* getColors(int pos) const {
353         SkASSERT(fColorType != SkGradientShaderBase::kTexture_GpuColorType);
354         SkASSERT((pos-1) <= fColorType);
355         return &fColors[pos];
356     }
357
358 protected:
359
360     /** Populates a pair of arrays with colors and stop info to construct a random gradient.
361         The function decides whether stop values should be used or not. The return value indicates
362         the number of colors, which will be capped by kMaxRandomGradientColors. colors should be
363         sized to be at least kMaxRandomGradientColors. stops is a pointer to an array of at least
364         size kMaxRandomGradientColors. It may be updated to nullptr, indicating that nullptr should be
365         passed to the gradient factory rather than the array.
366     */
367     static const int kMaxRandomGradientColors = 4;
368     static int RandomGradientParams(SkRandom* r,
369                                     SkColor colors[kMaxRandomGradientColors],
370                                     SkScalar** stops,
371                                     SkShader::TileMode* tm);
372
373     bool onIsEqual(const GrFragmentProcessor&) const override;
374
375     void onComputeInvariantOutput(GrInvariantOutput* inout) const override;
376
377     const GrCoordTransform& getCoordTransform() const { return fCoordTransform; }
378
379 private:
380     static const GrCoordSet kCoordSet = kLocal_GrCoordSet;
381
382     GrCoordTransform fCoordTransform;
383     GrTextureAccess fTextureAccess;
384     SkScalar fYCoord;
385     GrTextureStripAtlas* fAtlas;
386     int fRow;
387     bool fIsOpaque;
388     SkGradientShaderBase::GpuColorType fColorType;
389     SkColor fColors[3]; // More than 3 colors we use texture
390     PremulType fPremulType; // This only changes behavior for two and three color special cases.
391                             // It is already baked into to the table for texture gradients.
392     typedef GrFragmentProcessor INHERITED;
393
394 };
395
396 ///////////////////////////////////////////////////////////////////////////////
397
398 // Base class for GL gradient effects
399 class GrGLGradientEffect : public GrGLSLFragmentProcessor {
400 public:
401     GrGLGradientEffect();
402     virtual ~GrGLGradientEffect();
403
404 protected:
405     void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override;
406
407 protected:
408     /**
409      * Subclasses must call this. It will return a key for the part of the shader code controlled
410      * by the base class. The subclasses must stick it in their key and then pass it to the below
411      * emit* functions from their emitCode function.
412      */
413     static uint32_t GenBaseGradientKey(const GrProcessor&);
414
415     // Emits the uniform used as the y-coord to texture samples in derived classes. Subclasses
416     // should call this method from their emitCode().
417     void emitUniforms(GrGLSLFPBuilder* builder, const GrGradientEffect&);
418
419
420     // emit code that gets a fragment's color from an expression for t; Has branches for 3 separate
421     // control flows inside -- 2 color gradients, 3 color symmetric gradients (both using
422     // native GLSL mix), and 4+ color gradients that use the traditional texture lookup.
423     void emitColor(GrGLSLFPBuilder* builder,
424                    const GrGradientEffect&,
425                    const char* gradientTValue,
426                    const char* outputColor,
427                    const char* inputColor,
428                    const TextureSamplerArray& samplers);
429
430 private:
431     enum {
432         kPremulTypeKeyBitCnt = 1,
433         kPremulTypeMask = 1,
434         kPremulBeforeInterpKey = kPremulTypeMask,
435
436         kTwoColorKey = 2 << kPremulTypeKeyBitCnt,
437         kThreeColorKey = 3 << kPremulTypeKeyBitCnt,
438         kColorKeyMask = kTwoColorKey | kThreeColorKey,
439         kColorKeyBitCnt = 2,
440
441         // Subclasses must shift any key bits they produce up by this amount
442         // and combine with the result of GenBaseGradientKey.
443         kBaseKeyBitCnt = (kPremulTypeKeyBitCnt + kColorKeyBitCnt)
444     };
445     GR_STATIC_ASSERT(kBaseKeyBitCnt <= 32);
446
447     SkScalar fCachedYCoord;
448     GrGLSLProgramDataManager::UniformHandle fFSYUni;
449     GrGLSLProgramDataManager::UniformHandle fColorStartUni;
450     GrGLSLProgramDataManager::UniformHandle fColorMidUni;
451     GrGLSLProgramDataManager::UniformHandle fColorEndUni;
452
453     typedef GrGLSLFragmentProcessor INHERITED;
454 };
455
456 #endif
457
458 #endif