Chromium Code Reviews| 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 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 121 | 123 |
| 122 const uint16_t* getCache16(); | 124 const uint16_t* getCache16(); |
| 123 const SkPMColor* getCache32(); | 125 const SkPMColor* getCache32(); |
| 124 | 126 |
| 125 SkMallocPixelRef* getCache32PixelRef() const { return fCache32PixelRef; } | 127 SkMallocPixelRef* getCache32PixelRef() const { return fCache32PixelRef; } |
| 126 | 128 |
| 127 unsigned getAlpha() const { return fCacheAlpha; } | 129 unsigned getAlpha() const { return fCacheAlpha; } |
| 128 bool getDither() const { return fCacheDither; } | 130 bool getDither() const { return fCacheDither; } |
| 129 | 131 |
| 130 private: | 132 private: |
| 131 // Working pointers. If either is nullptr, we need to recompute the corr esponding cache values. | 133 // Working pointers. If either is nullptr, we need to recompute the corr esponding |
| 134 // cache values. | |
| 132 uint16_t* fCache16; | 135 uint16_t* fCache16; |
| 133 SkPMColor* fCache32; | 136 SkPMColor* fCache32; |
| 134 | 137 |
| 135 uint16_t* fCache16Storage; // Storage for fCache16, allocated on demand. | 138 uint16_t* fCache16Storage; // Storage for fCache16, allocated on demand. |
| 136 SkMallocPixelRef* fCache32PixelRef; | 139 SkMallocPixelRef* fCache32PixelRef; |
| 137 const unsigned fCacheAlpha; // The alpha value we used when we computed the cache. | 140 const unsigned fCacheAlpha; // The alpha value we used when we computed the cache. |
| 138 // Larger than 8bits so we can sto re uninitialized | 141 // Larger than 8bits so we can sto re uninitialized |
| 139 // value. | 142 // value. |
| 140 const bool fCacheDither; // The dither flag used when we co mputed the cache. | 143 const bool fCacheDither; // The dither flag used when we co mputed the cache. |
| 141 | 144 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 190 kCache32Count = (1 << kCache32Bits), | 193 kCache32Count = (1 << kCache32Bits), |
| 191 kCache32Shift = 16 - kCache32Bits, | 194 kCache32Shift = 16 - kCache32Bits, |
| 192 kSqrt32Shift = 8 - kCache32Bits, | 195 kSqrt32Shift = 8 - kCache32Bits, |
| 193 | 196 |
| 194 /// This value is used to *read* the dither cache; it may be 0 | 197 /// This value is used to *read* the dither cache; it may be 0 |
| 195 /// if dithering is disabled. | 198 /// if dithering is disabled. |
| 196 kDitherStride32 = kCache32Count, | 199 kDitherStride32 = kCache32Count, |
| 197 kDitherStride16 = kCache16Count, | 200 kDitherStride16 = kCache16Count, |
| 198 }; | 201 }; |
| 199 | 202 |
| 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; } | 203 uint32_t getGradFlags() const { return fGradFlags; } |
| 212 | 204 |
| 213 protected: | 205 protected: |
| 214 class GradientShaderBase4fContext; | 206 class GradientShaderBase4fContext; |
| 215 | 207 |
| 216 SkGradientShaderBase(SkReadBuffer& ); | 208 SkGradientShaderBase(SkReadBuffer& ); |
| 217 void flatten(SkWriteBuffer&) const override; | 209 void flatten(SkWriteBuffer&) const override; |
| 218 SK_TO_STRING_OVERRIDE() | 210 SK_TO_STRING_OVERRIDE() |
| 219 | 211 |
| 220 const SkMatrix fPtsToUnit; | 212 const SkMatrix fPtsToUnit; |
| 221 TileMode fTileMode; | 213 TileMode fTileMode; |
| 222 TileProc fTileProc; | 214 TileProc fTileProc; |
| 223 int fColorCount; | |
| 224 uint8_t fGradFlags; | 215 uint8_t fGradFlags; |
| 225 | 216 |
| 226 struct Rec { | 217 struct Rec { |
| 227 SkFixed fPos; // 0...1 | 218 SkFixed fPos; // 0...1 |
| 228 uint32_t fScale; // (1 << 24) / range | 219 uint32_t fScale; // (1 << 24) / range |
| 229 }; | 220 }; |
| 230 Rec* fRecs; | 221 Rec* fRecs; |
| 231 | 222 |
| 232 void commonAsAGradient(GradientInfo*, bool flipGrad = false) const; | 223 void commonAsAGradient(GradientInfo*, bool flipGrad = false) const; |
| 233 | 224 |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 247 private: | 238 private: |
| 248 enum { | 239 enum { |
| 249 kColorStorageCount = 4, // more than this many colors, and we'll use sk_ malloc for the space | 240 kColorStorageCount = 4, // more than this many colors, and we'll use sk_ malloc for the space |
| 250 | 241 |
| 251 kStorageSize = kColorStorageCount * (sizeof(SkColor) + sizeof(SkScalar) + sizeof(Rec)) | 242 kStorageSize = kColorStorageCount * (sizeof(SkColor) + sizeof(SkScalar) + sizeof(Rec)) |
| 252 }; | 243 }; |
| 253 SkColor fStorage[(kStorageSize + 3) >> 2]; | 244 SkColor fStorage[(kStorageSize + 3) >> 2]; |
| 254 public: | 245 public: |
| 255 SkColor* fOrigColors; // original colors, before modulation by paint in c ontext. | 246 SkColor* fOrigColors; // original colors, before modulation by paint in c ontext. |
| 256 SkScalar* fOrigPos; // original positions | 247 SkScalar* fOrigPos; // original positions |
| 248 int fColorCount; | |
| 249 | |
| 250 SkTArray<sk_sp<SkShader>> fSubGradients; | |
| 257 | 251 |
| 258 bool colorsAreOpaque() const { return fColorsAreOpaque; } | 252 bool colorsAreOpaque() const { return fColorsAreOpaque; } |
| 259 | 253 |
| 254 TileMode getTileMode() const { return fTileMode; } | |
| 255 Rec* getRecs() const { return fRecs; } | |
| 256 | |
| 260 private: | 257 private: |
| 261 bool fColorsAreOpaque; | 258 bool fColorsAreOpaque; |
| 262 | 259 |
| 263 GradientShaderCache* refCache(U8CPU alpha, bool dither) const; | 260 GradientShaderCache* refCache(U8CPU alpha, bool dither) const; |
| 264 mutable SkMutex fCacheMutex; | 261 mutable SkMutex fCacheMutex; |
| 265 mutable SkAutoTUnref<GradientShaderCache> fCache; | 262 mutable SkAutoTUnref<GradientShaderCache> fCache; |
| 266 | 263 |
| 267 void initCommon(); | 264 void initCommon(); |
| 268 | 265 |
| 269 typedef SkShader INHERITED; | 266 typedef SkShader INHERITED; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 329 class GLSLProcessor; | 326 class GLSLProcessor; |
| 330 | 327 |
| 331 GrGradientEffect(GrContext* ctx, | 328 GrGradientEffect(GrContext* ctx, |
| 332 const SkGradientShaderBase& shader, | 329 const SkGradientShaderBase& shader, |
| 333 const SkMatrix& matrix, | 330 const SkMatrix& matrix, |
| 334 SkShader::TileMode tileMode); | 331 SkShader::TileMode tileMode); |
| 335 | 332 |
| 336 virtual ~GrGradientEffect(); | 333 virtual ~GrGradientEffect(); |
| 337 | 334 |
| 338 bool useAtlas() const { return SkToBool(-1 != fRow); } | 335 bool useAtlas() const { return SkToBool(-1 != fRow); } |
| 339 SkScalar getYCoord() const { return fYCoord; }; | 336 SkScalar getYCoord() const { return fYCoord; } |
| 340 | 337 |
| 341 SkGradientShaderBase::GpuColorType getColorType() const { return fColorType; } | 338 enum ColorType { |
| 339 kTwo_ColorType, | |
| 340 kThree_ColorType, // Symmetric three color | |
| 341 kTexture_ColorType, | |
| 342 | |
| 343 #if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS | |
| 344 kHardStopCentered_ColorType, // 0, 0.5, 0.5, 1 | |
| 345 kHardStopLeftEdged_ColorType, // 0, 0, 1 | |
| 346 kHardStopRightEdged_ColorType, // 0, 1, 1 | |
| 347 #endif | |
| 348 }; | |
| 349 | |
| 350 ColorType getColorType() const { return fColorType; } | |
| 351 | |
| 352 // Determines the type of gradient, one of: | |
| 353 // - Two-color | |
| 354 // - Symmetric three-color | |
| 355 // - Texture | |
| 356 // - Centered hard stop | |
| 357 // - Left-edged hard stop | |
| 358 // - Right-edged hard stop | |
| 359 ColorType determineColorTypeAndNumHardStops(const SkGradientShaderBase& shad er); | |
| 342 | 360 |
| 343 enum PremulType { | 361 enum PremulType { |
| 344 kBeforeInterp_PremulType, | 362 kBeforeInterp_PremulType, |
| 345 kAfterInterp_PremulType, | 363 kAfterInterp_PremulType, |
| 346 }; | 364 }; |
| 347 | 365 |
| 348 PremulType getPremulType() const { return fPremulType; } | 366 PremulType getPremulType() const { return fPremulType; } |
| 349 | 367 |
| 350 const SkColor* getColors(int pos) const { | 368 const SkColor* getColors(int pos) const { |
| 351 SkASSERT(fColorType != SkGradientShaderBase::kTexture_GpuColorType); | 369 SkASSERT(fColorType != kTexture_ColorType); |
| 352 SkASSERT((pos-1) <= fColorType); | 370 SkASSERT(pos < fColors.count()); |
| 353 return &fColors[pos]; | 371 return &fColors[pos]; |
| 354 } | 372 } |
| 355 | 373 |
| 356 protected: | 374 protected: |
| 357 /** Populates a pair of arrays with colors and stop info to construct a rand om gradient. | 375 /** 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 | 376 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 | 377 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 | 378 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 | 379 size kMaxRandomGradientColors. It may be updated to nullptr, indicating that nullptr should |
| 362 passed to the gradient factory rather than the array. | 380 be passed to the gradient factory rather than the array. |
| 363 */ | 381 */ |
| 364 static const int kMaxRandomGradientColors = 4; | 382 static const int kMaxRandomGradientColors = 4; |
| 365 static int RandomGradientParams(SkRandom* r, | 383 static int RandomGradientParams(SkRandom* r, |
| 366 SkColor colors[kMaxRandomGradientColors], | 384 SkColor colors[kMaxRandomGradientColors], |
| 367 SkScalar** stops, | 385 SkScalar** stops, |
| 368 SkShader::TileMode* tm); | 386 SkShader::TileMode* tm); |
| 369 | 387 |
| 370 bool onIsEqual(const GrFragmentProcessor&) const override; | 388 bool onIsEqual(const GrFragmentProcessor&) const override; |
| 371 | 389 |
| 372 void onComputeInvariantOutput(GrInvariantOutput* inout) const override; | 390 void onComputeInvariantOutput(GrInvariantOutput* inout) const override; |
| 373 | 391 |
| 374 const GrCoordTransform& getCoordTransform() const { return fCoordTransform; } | 392 const GrCoordTransform& getCoordTransform() const { return fCoordTransform; } |
| 375 | 393 |
| 376 private: | 394 private: |
| 377 static const GrCoordSet kCoordSet = kLocal_GrCoordSet; | 395 static const GrCoordSet kCoordSet = kLocal_GrCoordSet; |
| 378 | 396 |
| 397 SkTDArray<SkColor> fColors; | |
| 398 SkTDArray<SkScalar> fPositions; | |
| 399 SkShader::TileMode fTileMode; | |
| 400 | |
| 379 GrCoordTransform fCoordTransform; | 401 GrCoordTransform fCoordTransform; |
| 380 GrTextureAccess fTextureAccess; | 402 GrTextureAccess fTextureAccess; |
| 381 SkScalar fYCoord; | 403 SkScalar fYCoord; |
| 382 GrTextureStripAtlas* fAtlas; | 404 GrTextureStripAtlas* fAtlas; |
| 383 int fRow; | 405 int fRow; |
| 384 bool fIsOpaque; | 406 bool fIsOpaque; |
| 385 SkGradientShaderBase::GpuColorType fColorType; | 407 ColorType fColorType; |
| 386 SkColor fColors[3]; // More than 3 colors we use texture | 408 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. | 409 // 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; | 410 typedef GrFragmentProcessor INHERITED; |
| 390 | 411 |
| 391 }; | 412 }; |
| 392 | 413 |
| 393 /////////////////////////////////////////////////////////////////////////////// | 414 /////////////////////////////////////////////////////////////////////////////// |
| 394 | 415 |
| 395 // Base class for GLSL gradient effects | 416 // Base class for GL gradient effects |
| 396 class GrGradientEffect::GLSLProcessor : public GrGLSLFragmentProcessor { | 417 class GrGradientEffect::GLSLProcessor : public GrGLSLFragmentProcessor { |
| 397 public: | 418 public: |
| 398 GLSLProcessor(); | 419 GLSLProcessor() { |
| 420 fCachedYCoord = SK_ScalarMax; | |
| 421 } | |
| 399 | 422 |
| 400 protected: | 423 protected: |
| 401 void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override ; | 424 void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override ; |
| 402 | 425 |
| 403 protected: | 426 protected: |
| 404 /** | 427 /** |
| 405 * Subclasses must call this. It will return a key for the part of the shade r code controlled | 428 * 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 | 429 * 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. | 430 * emit* functions from their emitCode function. |
| 408 */ | 431 */ |
| 409 static uint32_t GenBaseGradientKey(const GrProcessor&); | 432 static uint32_t GenBaseGradientKey(const GrProcessor&); |
| 410 | 433 |
| 411 // Emits the uniform used as the y-coord to texture samples in derived class es. Subclasses | 434 // Emits the uniform used as the y-coord to texture samples in derived class es. Subclasses |
| 412 // should call this method from their emitCode(). | 435 // should call this method from their emitCode(). |
| 413 void emitUniforms(GrGLSLUniformHandler*, const GrGradientEffect&); | 436 void emitUniforms(GrGLSLUniformHandler*, const GrGradientEffect&); |
| 414 | 437 |
| 415 | 438 // 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 | 439 // 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 | 440 // 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. | 441 // of hard stop gradients |
| 419 void emitColor(GrGLSLFPFragmentBuilder* fragBuilder, | 442 void emitColor(GrGLSLFPFragmentBuilder* fragBuilder, |
| 420 GrGLSLUniformHandler* uniformHandler, | 443 GrGLSLUniformHandler* uniformHandler, |
| 421 const GrGLSLCaps* caps, | 444 const GrGLSLCaps* caps, |
| 422 const GrGradientEffect&, | 445 const GrGradientEffect&, |
| 423 const char* gradientTValue, | 446 const char* gradientTValue, |
| 424 const char* outputColor, | 447 const char* outputColor, |
| 425 const char* inputColor, | 448 const char* inputColor, |
| 426 const SamplerHandle* texSamplers); | 449 const SamplerHandle* texSamplers); |
| 427 | 450 |
| 428 private: | 451 private: |
| 429 enum { | 452 enum { |
| 430 // First bit for premul before/after interp | 453 // First bit for premul before/after interp |
| 431 kPremulBeforeInterpKey = 1, | 454 kPremulBeforeInterpKey = 1, |
|
bsalomon
2016/08/10 15:17:03
missing space before 1?
| |
| 432 | 455 |
| 433 // Next two bits for 2/3 color type (neither means using texture atlas) | 456 // Next three bits for 2/3 color type or different special |
| 434 kTwoColorKey = 4, | 457 // hard stop cases (neither means using texture atlas) |
| 435 kThreeColorKey = 6, | 458 kTwoColorKey = 2, |
| 459 kThreeColorKey = 4, | |
| 460 #if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS | |
| 461 kHardStopCenteredKey = 6, | |
| 462 kHardStopZeroZeroOneKey = 8, | |
| 463 kHardStopZeroOneOneKey = 10, | |
| 464 | |
| 465 // Next two bits for tile mode | |
| 466 kClampTileMode = 16, | |
| 467 kRepeatTileMode = 32, | |
| 468 kMirrorTileMode = 48, | |
| 469 | |
| 470 // Lower six bits for premul, 2/3 color type, and tile mode | |
| 471 kReservedBits = 6, | |
| 472 #endif | |
| 436 }; | 473 }; |
| 437 | 474 |
| 438 SkScalar fCachedYCoord; | 475 SkScalar fCachedYCoord; |
| 476 GrGLSLProgramDataManager::UniformHandle fColorsUni; | |
| 439 GrGLSLProgramDataManager::UniformHandle fFSYUni; | 477 GrGLSLProgramDataManager::UniformHandle fFSYUni; |
| 440 GrGLSLProgramDataManager::UniformHandle fColorStartUni; | |
| 441 GrGLSLProgramDataManager::UniformHandle fColorMidUni; | |
| 442 GrGLSLProgramDataManager::UniformHandle fColorEndUni; | |
| 443 | 478 |
| 444 typedef GrGLSLFragmentProcessor INHERITED; | 479 typedef GrGLSLFragmentProcessor INHERITED; |
| 445 }; | 480 }; |
| 446 | 481 |
| 447 #endif | 482 #endif |
| 448 | 483 |
| 449 #endif | 484 #endif |
| OLD | NEW |