Index: src/effects/gradients/SkGradientShaderPriv.h |
diff --git a/src/effects/gradients/SkGradientShaderPriv.h b/src/effects/gradients/SkGradientShaderPriv.h |
index 50ad427e4ae1d5f3aa03f37b79e496d930be5b52..ee30c9b21b03fc5f9a69dbdb13e224418c132981 100644 |
--- a/src/effects/gradients/SkGradientShaderPriv.h |
+++ b/src/effects/gradients/SkGradientShaderPriv.h |
@@ -19,6 +19,10 @@ |
#include "SkShader.h" |
#include "SkOnce.h" |
+#if SK_SUPPORT_GPU |
+ #define GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS 1 |
+#endif |
+ |
static inline void sk_memset32_dither(uint32_t dst[], uint32_t v0, uint32_t v1, |
int count) { |
if (count > 0) { |
@@ -128,7 +132,8 @@ public: |
bool getDither() const { return fCacheDither; } |
private: |
- // Working pointers. If either is nullptr, we need to recompute the corresponding cache values. |
+ // Working pointers. If either is nullptr, we need to recompute the corresponding |
+ // cache values. |
uint16_t* fCache16; |
SkPMColor* fCache32; |
@@ -197,17 +202,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 +214,6 @@ protected: |
const SkMatrix fPtsToUnit; |
TileMode fTileMode; |
TileProc fTileProc; |
- int fColorCount; |
uint8_t fGradFlags; |
struct Rec { |
@@ -254,9 +247,13 @@ private: |
public: |
SkColor* fOrigColors; // original colors, before modulation by paint in context. |
SkScalar* fOrigPos; // original positions |
+ int fColorCount; |
bool colorsAreOpaque() const { return fColorsAreOpaque; } |
+ TileMode getTileMode() const { return fTileMode; } |
+ Rec* getRecs() const { return fRecs; } |
+ |
private: |
bool fColorsAreOpaque; |
@@ -336,9 +333,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 determineColorType(const SkGradientShaderBase& shader); |
enum PremulType { |
kBeforeInterp_PremulType, |
@@ -348,8 +366,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]; |
} |
@@ -358,8 +376,8 @@ protected: |
The function decides whether stop values should be used or not. The return value indicates |
the number of colors, which will be capped by kMaxRandomGradientColors. colors should be |
sized to be at least kMaxRandomGradientColors. stops is a pointer to an array of at least |
- size kMaxRandomGradientColors. It may be updated to nullptr, indicating that nullptr should be |
- passed to the gradient factory rather than the array. |
+ size kMaxRandomGradientColors. It may be updated to nullptr, indicating that nullptr should |
+ be passed to the gradient factory rather than the array. |
*/ |
static const int kMaxRandomGradientColors = 4; |
static int RandomGradientParams(SkRandom* r, |
@@ -376,26 +394,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 +435,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, |
@@ -428,18 +451,30 @@ protected: |
private: |
enum { |
// 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, |
+ kPremulBeforeInterpKey = 1, |
+ |
+ // 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, |
+ 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; |
}; |