Chromium Code Reviews| Index: src/effects/gradients/SkGradientShaderPriv.h |
| diff --git a/src/effects/gradients/SkGradientShaderPriv.h b/src/effects/gradients/SkGradientShaderPriv.h |
| index 50ad427e4ae1d5f3aa03f37b79e496d930be5b52..496b603db18cb4d01d77b347564970c1cd5888ec 100644 |
| --- a/src/effects/gradients/SkGradientShaderPriv.h |
| +++ b/src/effects/gradients/SkGradientShaderPriv.h |
| @@ -19,6 +19,8 @@ |
| #include "SkShader.h" |
| #include "SkOnce.h" |
| +#define GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS 1 |
| + |
| static inline void sk_memset32_dither(uint32_t dst[], uint32_t v0, uint32_t v1, |
| int count) { |
| if (count > 0) { |
| @@ -197,17 +199,6 @@ public: |
| kDitherStride16 = kCache16Count, |
| }; |
| - enum GpuColorType { |
| - kTwo_GpuColorType, |
| - kThree_GpuColorType, // Symmetric three color |
| - kTexture_GpuColorType |
| - }; |
| - |
| - // Determines and returns the gradient is a two color gradient, symmetric three color gradient |
| - // or other (texture gradient). If it is two or symmetric three color, the colors array will |
| - // also be filled with the gradient colors |
| - GpuColorType getGpuColorType(SkColor colors[3]) const; |
| - |
| uint32_t getGradFlags() const { return fGradFlags; } |
| protected: |
| @@ -220,7 +211,6 @@ protected: |
| const SkMatrix fPtsToUnit; |
| TileMode fTileMode; |
| TileProc fTileProc; |
| - int fColorCount; |
| uint8_t fGradFlags; |
| struct Rec { |
| @@ -254,9 +244,15 @@ private: |
| public: |
| SkColor* fOrigColors; // original colors, before modulation by paint in context. |
| SkScalar* fOrigPos; // original positions |
| + int fColorCount; |
| + |
| + SkTArray<sk_sp<SkShader>> fSubGradients; |
| bool colorsAreOpaque() const { return fColorsAreOpaque; } |
| + TileMode getTileMode() const { return fTileMode; } |
| + Rec* getRecs() const { return fRecs; } |
| + |
| private: |
| bool fColorsAreOpaque; |
| @@ -336,9 +332,30 @@ public: |
| virtual ~GrGradientEffect(); |
| bool useAtlas() const { return SkToBool(-1 != fRow); } |
| - SkScalar getYCoord() const { return fYCoord; }; |
| + SkScalar getYCoord() const { return fYCoord; } |
| - SkGradientShaderBase::GpuColorType getColorType() const { return fColorType; } |
| + enum ColorType { |
| + kTwo_ColorType, |
| + kThree_ColorType, // Symmetric three color |
| + kTexture_ColorType, |
| + |
| +#if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS |
| + kHardStopCentered_ColorType, // 0, 0.5, 0.5, 1 |
| + kHardStopLeftEdged_ColorType, // 0, 0, 1 |
| + kHardStopRightEdged_ColorType, // 0, 1, 1 |
| +#endif |
| + }; |
| + |
| + ColorType getColorType() const { return fColorType; } |
| + |
| + // Determines the type of gradient, one of: |
| + // - Two-color |
| + // - Symmetric three-color |
| + // - Texture |
| + // - Centered hard stop |
| + // - Left-edged hard stop |
| + // - Right-edged hard stop |
| + ColorType determineColorTypeAndNumHardStops(const SkGradientShaderBase& shader); |
| enum PremulType { |
| kBeforeInterp_PremulType, |
| @@ -348,8 +365,8 @@ public: |
| PremulType getPremulType() const { return fPremulType; } |
| const SkColor* getColors(int pos) const { |
| - SkASSERT(fColorType != SkGradientShaderBase::kTexture_GpuColorType); |
| - SkASSERT((pos-1) <= fColorType); |
| + SkASSERT(fColorType != kTexture_ColorType); |
| + SkASSERT(pos < fColors.count()); |
| return &fColors[pos]; |
| } |
| @@ -376,26 +393,31 @@ protected: |
| private: |
| static const GrCoordSet kCoordSet = kLocal_GrCoordSet; |
| + SkTDArray<SkColor> fColors; |
| + SkTDArray<SkScalar> fPositions; |
| + SkShader::TileMode fTileMode; |
| + |
| GrCoordTransform fCoordTransform; |
| GrTextureAccess fTextureAccess; |
| SkScalar fYCoord; |
| GrTextureStripAtlas* fAtlas; |
| int fRow; |
| bool fIsOpaque; |
| - SkGradientShaderBase::GpuColorType fColorType; |
| - SkColor fColors[3]; // More than 3 colors we use texture |
| - PremulType fPremulType; // This only changes behavior for two and three color special cases. |
| - // It is already baked into to the table for texture gradients. |
| + ColorType fColorType; |
| + PremulType fPremulType; // This is already baked into the table for texture gradients, and |
| + // only changes behavior for gradients that don't use a texture. |
| typedef GrFragmentProcessor INHERITED; |
| }; |
| /////////////////////////////////////////////////////////////////////////////// |
| -// Base class for GLSL gradient effects |
| +// Base class for GL gradient effects |
| class GrGradientEffect::GLSLProcessor : public GrGLSLFragmentProcessor { |
| public: |
| - GLSLProcessor(); |
| + GLSLProcessor() { |
| + fCachedYCoord = SK_ScalarMax; |
| + } |
| protected: |
| void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override; |
| @@ -412,10 +434,10 @@ protected: |
| // should call this method from their emitCode(). |
| void emitUniforms(GrGLSLUniformHandler*, const GrGradientEffect&); |
| - |
| - // emit code that gets a fragment's color from an expression for t; Has branches for 3 separate |
| - // control flows inside -- 2 color gradients, 3 color symmetric gradients (both using |
| - // native GLSL mix), and 4+ color gradients that use the traditional texture lookup. |
| + // Emit code that gets a fragment's color from an expression for t; has branches for |
| + // several control flows inside -- 2-color gradients, 3-color symmetric gradients, 4+ |
| + // color gradients that use the traditional texture lookup, as well as several varieties |
| + // of hard stop gradients |
| void emitColor(GrGLSLFPFragmentBuilder* fragBuilder, |
| GrGLSLUniformHandler* uniformHandler, |
| const GrGLSLCaps* caps, |
| @@ -430,16 +452,28 @@ private: |
| // First bit for premul before/after interp |
| kPremulBeforeInterpKey = 1, |
| - // Next two bits for 2/3 color type (neither means using texture atlas) |
| - kTwoColorKey = 4, |
| - kThreeColorKey = 6, |
| + // Next three bits for 2/3 color type or different special |
| + // hard stop cases (neither means using texture atlas) |
| + kTwoColorKey = 2, |
| + kThreeColorKey = 4, |
| +#if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS |
| + kHardStopCenteredKey = 6, |
| + kHardStopZeroZeroOneKey = 8, |
| + kHardStopZeroOneOneKey = 10, |
| + |
| + // Next two bits for tile mode |
| + kClampTileMode = 16, |
|
bsalomon
2016/08/10 14:33:20
Can you preserve the alignment of the values?
|
| + kRepeatTileMode = 32, |
| + kMirrorTileMode = 48, |
| + |
| + // Lower six bits for premul, 2/3 color type, and tile mode |
| + kReservedBits = 6, |
| +#endif |
| }; |
| SkScalar fCachedYCoord; |
| + GrGLSLProgramDataManager::UniformHandle fColorsUni; |
| GrGLSLProgramDataManager::UniformHandle fFSYUni; |
| - GrGLSLProgramDataManager::UniformHandle fColorStartUni; |
| - GrGLSLProgramDataManager::UniformHandle fColorMidUni; |
| - GrGLSLProgramDataManager::UniformHandle fColorEndUni; |
| typedef GrGLSLFragmentProcessor INHERITED; |
| }; |