OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #ifndef SkGradientShaderPriv_DEFINED | 8 #ifndef SkGradientShaderPriv_DEFINED |
9 #define SkGradientShaderPriv_DEFINED | 9 #define SkGradientShaderPriv_DEFINED |
10 | 10 |
11 #include "SkGradientBitmapCache.h" | 11 #include "SkGradientBitmapCache.h" |
12 #include "SkGradientShader.h" | 12 #include "SkGradientShader.h" |
13 #include "SkClampRange.h" | 13 #include "SkClampRange.h" |
14 #include "SkColorPriv.h" | 14 #include "SkColorPriv.h" |
15 #include "SkReadBuffer.h" | 15 #include "SkReadBuffer.h" |
16 #include "SkWriteBuffer.h" | 16 #include "SkWriteBuffer.h" |
17 #include "SkMallocPixelRef.h" | 17 #include "SkMallocPixelRef.h" |
18 #include "SkUtils.h" | 18 #include "SkUtils.h" |
19 #include "SkShader.h" | 19 #include "SkShader.h" |
20 #include "SkOnce.h" | 20 #include "SkOnce.h" |
21 | 21 |
22 #define GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS 1 | |
23 | |
22 static inline void sk_memset32_dither(uint32_t dst[], uint32_t v0, uint32_t v1, | 24 static inline void sk_memset32_dither(uint32_t dst[], uint32_t v0, uint32_t v1, |
23 int count) { | 25 int count) { |
24 if (count > 0) { | 26 if (count > 0) { |
25 if (v0 == v1) { | 27 if (v0 == v1) { |
26 sk_memset32(dst, v0, count); | 28 sk_memset32(dst, v0, count); |
27 } else { | 29 } else { |
28 int pairs = count >> 1; | 30 int pairs = count >> 1; |
29 for (int i = 0; i < pairs; i++) { | 31 for (int i = 0; i < pairs; i++) { |
30 *dst++ = v0; | 32 *dst++ = v0; |
31 *dst++ = v1; | 33 *dst++ = v1; |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
190 kCache32Count = (1 << kCache32Bits), | 192 kCache32Count = (1 << kCache32Bits), |
191 kCache32Shift = 16 - kCache32Bits, | 193 kCache32Shift = 16 - kCache32Bits, |
192 kSqrt32Shift = 8 - kCache32Bits, | 194 kSqrt32Shift = 8 - kCache32Bits, |
193 | 195 |
194 /// This value is used to *read* the dither cache; it may be 0 | 196 /// This value is used to *read* the dither cache; it may be 0 |
195 /// if dithering is disabled. | 197 /// if dithering is disabled. |
196 kDitherStride32 = kCache32Count, | 198 kDitherStride32 = kCache32Count, |
197 kDitherStride16 = kCache16Count, | 199 kDitherStride16 = kCache16Count, |
198 }; | 200 }; |
199 | 201 |
200 enum GpuColorType { | |
201 kTwo_GpuColorType, | |
202 kThree_GpuColorType, // Symmetric three color | |
203 kTexture_GpuColorType | |
204 }; | |
205 | |
206 // Determines and returns the gradient is a two color gradient, symmetric th ree color gradient | |
207 // or other (texture gradient). If it is two or symmetric three color, the c olors array will | |
208 // also be filled with the gradient colors | |
209 GpuColorType getGpuColorType(SkColor colors[3]) const; | |
210 | |
211 uint32_t getGradFlags() const { return fGradFlags; } | 202 uint32_t getGradFlags() const { return fGradFlags; } |
212 | 203 |
213 protected: | 204 protected: |
214 class GradientShaderBase4fContext; | 205 class GradientShaderBase4fContext; |
215 | 206 |
216 SkGradientShaderBase(SkReadBuffer& ); | 207 SkGradientShaderBase(SkReadBuffer& ); |
217 void flatten(SkWriteBuffer&) const override; | 208 void flatten(SkWriteBuffer&) const override; |
218 SK_TO_STRING_OVERRIDE() | 209 SK_TO_STRING_OVERRIDE() |
219 | 210 |
220 const SkMatrix fPtsToUnit; | 211 const SkMatrix fPtsToUnit; |
221 TileMode fTileMode; | 212 TileMode fTileMode; |
222 TileProc fTileProc; | 213 TileProc fTileProc; |
223 int fColorCount; | |
224 uint8_t fGradFlags; | 214 uint8_t fGradFlags; |
225 | 215 |
226 struct Rec { | 216 struct Rec { |
227 SkFixed fPos; // 0...1 | 217 SkFixed fPos; // 0...1 |
228 uint32_t fScale; // (1 << 24) / range | 218 uint32_t fScale; // (1 << 24) / range |
229 }; | 219 }; |
230 Rec* fRecs; | 220 Rec* fRecs; |
231 | 221 |
232 void commonAsAGradient(GradientInfo*, bool flipGrad = false) const; | 222 void commonAsAGradient(GradientInfo*, bool flipGrad = false) const; |
233 | 223 |
(...skipping 13 matching lines...) Expand all Loading... | |
247 private: | 237 private: |
248 enum { | 238 enum { |
249 kColorStorageCount = 4, // more than this many colors, and we'll use sk_ malloc for the space | 239 kColorStorageCount = 4, // more than this many colors, and we'll use sk_ malloc for the space |
250 | 240 |
251 kStorageSize = kColorStorageCount * (sizeof(SkColor) + sizeof(SkScalar) + sizeof(Rec)) | 241 kStorageSize = kColorStorageCount * (sizeof(SkColor) + sizeof(SkScalar) + sizeof(Rec)) |
252 }; | 242 }; |
253 SkColor fStorage[(kStorageSize + 3) >> 2]; | 243 SkColor fStorage[(kStorageSize + 3) >> 2]; |
254 public: | 244 public: |
255 SkColor* fOrigColors; // original colors, before modulation by paint in c ontext. | 245 SkColor* fOrigColors; // original colors, before modulation by paint in c ontext. |
256 SkScalar* fOrigPos; // original positions | 246 SkScalar* fOrigPos; // original positions |
247 int fColorCount; | |
248 | |
249 SkTArray<sk_sp<SkShader>> fSubGradients; | |
257 | 250 |
258 bool colorsAreOpaque() const { return fColorsAreOpaque; } | 251 bool colorsAreOpaque() const { return fColorsAreOpaque; } |
259 | 252 |
253 TileMode getTileMode() const { return fTileMode; } | |
254 Rec* getRecs() const { return fRecs; } | |
255 | |
260 private: | 256 private: |
261 bool fColorsAreOpaque; | 257 bool fColorsAreOpaque; |
262 | 258 |
263 GradientShaderCache* refCache(U8CPU alpha, bool dither) const; | 259 GradientShaderCache* refCache(U8CPU alpha, bool dither) const; |
264 mutable SkMutex fCacheMutex; | 260 mutable SkMutex fCacheMutex; |
265 mutable SkAutoTUnref<GradientShaderCache> fCache; | 261 mutable SkAutoTUnref<GradientShaderCache> fCache; |
266 | 262 |
267 void initCommon(); | 263 void initCommon(); |
268 | 264 |
269 typedef SkShader INHERITED; | 265 typedef SkShader INHERITED; |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
329 class GLSLProcessor; | 325 class GLSLProcessor; |
330 | 326 |
331 GrGradientEffect(GrContext* ctx, | 327 GrGradientEffect(GrContext* ctx, |
332 const SkGradientShaderBase& shader, | 328 const SkGradientShaderBase& shader, |
333 const SkMatrix& matrix, | 329 const SkMatrix& matrix, |
334 SkShader::TileMode tileMode); | 330 SkShader::TileMode tileMode); |
335 | 331 |
336 virtual ~GrGradientEffect(); | 332 virtual ~GrGradientEffect(); |
337 | 333 |
338 bool useAtlas() const { return SkToBool(-1 != fRow); } | 334 bool useAtlas() const { return SkToBool(-1 != fRow); } |
339 SkScalar getYCoord() const { return fYCoord; }; | 335 SkScalar getYCoord() const { return fYCoord; } |
340 | 336 |
341 SkGradientShaderBase::GpuColorType getColorType() const { return fColorType; } | 337 enum ColorType { |
338 kTwo_ColorType, | |
339 kThree_ColorType, // Symmetric three color | |
340 kTexture_ColorType, | |
341 | |
342 #if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS | |
343 kHardStopCentered_ColorType, // 0, 0.5, 0.5, 1 | |
344 kHardStopLeftEdged_ColorType, // 0, 0, 1 | |
345 kHardStopRightEdged_ColorType, // 0, 1, 1 | |
346 #endif | |
347 }; | |
348 | |
349 ColorType getColorType() const { return fColorType; } | |
350 | |
351 // Determines the type of gradient, one of: | |
352 // - Two-color | |
353 // - Symmetric three-color | |
354 // - Texture | |
355 // - Centered hard stop | |
356 // - Left-edged hard stop | |
357 // - Right-edged hard stop | |
358 ColorType determineColorTypeAndNumHardStops(const SkGradientShaderBase& shad er); | |
342 | 359 |
343 enum PremulType { | 360 enum PremulType { |
344 kBeforeInterp_PremulType, | 361 kBeforeInterp_PremulType, |
345 kAfterInterp_PremulType, | 362 kAfterInterp_PremulType, |
346 }; | 363 }; |
347 | 364 |
348 PremulType getPremulType() const { return fPremulType; } | 365 PremulType getPremulType() const { return fPremulType; } |
349 | 366 |
350 const SkColor* getColors(int pos) const { | 367 const SkColor* getColors(int pos) const { |
351 SkASSERT(fColorType != SkGradientShaderBase::kTexture_GpuColorType); | 368 SkASSERT(fColorType != kTexture_ColorType); |
352 SkASSERT((pos-1) <= fColorType); | 369 SkASSERT(pos < fColors.count()); |
353 return &fColors[pos]; | 370 return &fColors[pos]; |
354 } | 371 } |
355 | 372 |
356 protected: | 373 protected: |
357 /** Populates a pair of arrays with colors and stop info to construct a rand om gradient. | 374 /** Populates a pair of arrays with colors and stop info to construct a rand om gradient. |
358 The function decides whether stop values should be used or not. The retu rn value indicates | 375 The function decides whether stop values should be used or not. The retu rn value indicates |
359 the number of colors, which will be capped by kMaxRandomGradientColors. colors should be | 376 the number of colors, which will be capped by kMaxRandomGradientColors. colors should be |
360 sized to be at least kMaxRandomGradientColors. stops is a pointer to an array of at least | 377 sized to be at least kMaxRandomGradientColors. stops is a pointer to an array of at least |
361 size kMaxRandomGradientColors. It may be updated to nullptr, indicating that nullptr should be | 378 size kMaxRandomGradientColors. It may be updated to nullptr, indicating that nullptr should be |
362 passed to the gradient factory rather than the array. | 379 passed to the gradient factory rather than the array. |
363 */ | 380 */ |
364 static const int kMaxRandomGradientColors = 4; | 381 static const int kMaxRandomGradientColors = 4; |
365 static int RandomGradientParams(SkRandom* r, | 382 static int RandomGradientParams(SkRandom* r, |
366 SkColor colors[kMaxRandomGradientColors], | 383 SkColor colors[kMaxRandomGradientColors], |
367 SkScalar** stops, | 384 SkScalar** stops, |
368 SkShader::TileMode* tm); | 385 SkShader::TileMode* tm); |
369 | 386 |
370 bool onIsEqual(const GrFragmentProcessor&) const override; | 387 bool onIsEqual(const GrFragmentProcessor&) const override; |
371 | 388 |
372 void onComputeInvariantOutput(GrInvariantOutput* inout) const override; | 389 void onComputeInvariantOutput(GrInvariantOutput* inout) const override; |
373 | 390 |
374 const GrCoordTransform& getCoordTransform() const { return fCoordTransform; } | 391 const GrCoordTransform& getCoordTransform() const { return fCoordTransform; } |
375 | 392 |
376 private: | 393 private: |
377 static const GrCoordSet kCoordSet = kLocal_GrCoordSet; | 394 static const GrCoordSet kCoordSet = kLocal_GrCoordSet; |
378 | 395 |
396 SkTDArray<SkColor> fColors; | |
397 SkTDArray<SkScalar> fPositions; | |
398 SkShader::TileMode fTileMode; | |
399 | |
379 GrCoordTransform fCoordTransform; | 400 GrCoordTransform fCoordTransform; |
380 GrTextureAccess fTextureAccess; | 401 GrTextureAccess fTextureAccess; |
381 SkScalar fYCoord; | 402 SkScalar fYCoord; |
382 GrTextureStripAtlas* fAtlas; | 403 GrTextureStripAtlas* fAtlas; |
383 int fRow; | 404 int fRow; |
384 bool fIsOpaque; | 405 bool fIsOpaque; |
385 SkGradientShaderBase::GpuColorType fColorType; | 406 ColorType fColorType; |
386 SkColor fColors[3]; // More than 3 colors we use texture | 407 PremulType fPremulType; // This is already baked into the table for texture gradients, and |
387 PremulType fPremulType; // This only changes behavior for two and three colo r special cases. | 408 // only changes behavior for gradients that don't us e a texture. |
388 // It is already baked into to the table for texture gradients. | |
389 typedef GrFragmentProcessor INHERITED; | 409 typedef GrFragmentProcessor INHERITED; |
390 | 410 |
391 }; | 411 }; |
392 | 412 |
393 /////////////////////////////////////////////////////////////////////////////// | 413 /////////////////////////////////////////////////////////////////////////////// |
394 | 414 |
395 // Base class for GLSL gradient effects | 415 // Base class for GL gradient effects |
396 class GrGradientEffect::GLSLProcessor : public GrGLSLFragmentProcessor { | 416 class GrGradientEffect::GLSLProcessor : public GrGLSLFragmentProcessor { |
397 public: | 417 public: |
398 GLSLProcessor(); | 418 GLSLProcessor() { |
419 fCachedYCoord = SK_ScalarMax; | |
420 } | |
399 | 421 |
400 protected: | 422 protected: |
401 void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override ; | 423 void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override ; |
402 | 424 |
403 protected: | 425 protected: |
404 /** | 426 /** |
405 * Subclasses must call this. It will return a key for the part of the shade r code controlled | 427 * Subclasses must call this. It will return a key for the part of the shade r code controlled |
406 * by the base class. The subclasses must stick it in their key and then pas s it to the below | 428 * by the base class. The subclasses must stick it in their key and then pas s it to the below |
407 * emit* functions from their emitCode function. | 429 * emit* functions from their emitCode function. |
408 */ | 430 */ |
409 static uint32_t GenBaseGradientKey(const GrProcessor&); | 431 static uint32_t GenBaseGradientKey(const GrProcessor&); |
410 | 432 |
411 // Emits the uniform used as the y-coord to texture samples in derived class es. Subclasses | 433 // Emits the uniform used as the y-coord to texture samples in derived class es. Subclasses |
412 // should call this method from their emitCode(). | 434 // should call this method from their emitCode(). |
413 void emitUniforms(GrGLSLUniformHandler*, const GrGradientEffect&); | 435 void emitUniforms(GrGLSLUniformHandler*, const GrGradientEffect&); |
414 | 436 |
415 | 437 // Emit code that gets a fragment's color from an expression for t; has bran ches for |
416 // emit code that gets a fragment's color from an expression for t; Has bran ches for 3 separate | 438 // several control flows inside -- 2-color gradients, 3-color symmetric grad ients, 4+ |
417 // control flows inside -- 2 color gradients, 3 color symmetric gradients (b oth using | 439 // color gradients that use the traditional texture lookup, as well as sever al varieties |
418 // native GLSL mix), and 4+ color gradients that use the traditional texture lookup. | 440 // of hard stop gradients |
419 void emitColor(GrGLSLFPFragmentBuilder* fragBuilder, | 441 void emitColor(GrGLSLFPFragmentBuilder* fragBuilder, |
420 GrGLSLUniformHandler* uniformHandler, | 442 GrGLSLUniformHandler* uniformHandler, |
421 const GrGLSLCaps* caps, | 443 const GrGLSLCaps* caps, |
422 const GrGradientEffect&, | 444 const GrGradientEffect&, |
423 const char* gradientTValue, | 445 const char* gradientTValue, |
424 const char* outputColor, | 446 const char* outputColor, |
425 const char* inputColor, | 447 const char* inputColor, |
426 const SamplerHandle* texSamplers); | 448 const SamplerHandle* texSamplers); |
427 | 449 |
428 private: | 450 private: |
429 enum { | 451 enum { |
430 // First bit for premul before/after interp | 452 // First bit for premul before/after interp |
431 kPremulBeforeInterpKey = 1, | 453 kPremulBeforeInterpKey = 1, |
432 | 454 |
433 // Next two bits for 2/3 color type (neither means using texture atlas) | 455 // Next three bits for 2/3 color type or different special |
434 kTwoColorKey = 4, | 456 // hard stop cases (neither means using texture atlas) |
435 kThreeColorKey = 6, | 457 kTwoColorKey = 2, |
458 kThreeColorKey = 4, | |
459 #if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS | |
460 kHardStopCenteredKey = 6, | |
461 kHardStopZeroZeroOneKey = 8, | |
462 kHardStopZeroOneOneKey = 10, | |
463 | |
464 // Next two bits for tile mode | |
465 kClampTileMode = 16, | |
bsalomon
2016/08/10 14:33:20
Can you preserve the alignment of the values?
| |
466 kRepeatTileMode = 32, | |
467 kMirrorTileMode = 48, | |
468 | |
469 // Lower six bits for premul, 2/3 color type, and tile mode | |
470 kReservedBits = 6, | |
471 #endif | |
436 }; | 472 }; |
437 | 473 |
438 SkScalar fCachedYCoord; | 474 SkScalar fCachedYCoord; |
475 GrGLSLProgramDataManager::UniformHandle fColorsUni; | |
439 GrGLSLProgramDataManager::UniformHandle fFSYUni; | 476 GrGLSLProgramDataManager::UniformHandle fFSYUni; |
440 GrGLSLProgramDataManager::UniformHandle fColorStartUni; | |
441 GrGLSLProgramDataManager::UniformHandle fColorMidUni; | |
442 GrGLSLProgramDataManager::UniformHandle fColorEndUni; | |
443 | 477 |
444 typedef GrGLSLFragmentProcessor INHERITED; | 478 typedef GrGLSLFragmentProcessor INHERITED; |
445 }; | 479 }; |
446 | 480 |
447 #endif | 481 #endif |
448 | 482 |
449 #endif | 483 #endif |
OLD | NEW |