aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/effects/gradients/SkGradientShaderPriv.h
diff options
context:
space:
mode:
authorGravatar fmenozzi <fmenozzi@google.com>2016-08-15 07:03:47 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-08-15 07:03:47 -0700
commitcd9a1d0ec3995ffa0be37fd7f6ec1e194b416818 (patch)
tree6718806dda6dd61f04cf39eb6d54b8c060aa2bde /src/effects/gradients/SkGradientShaderPriv.h
parent997d017eed07f2708be5019e635d74412aec9743 (diff)
Add specialized code for hard stop gradients on GPU
Diffstat (limited to 'src/effects/gradients/SkGradientShaderPriv.h')
-rw-r--r--src/effects/gradients/SkGradientShaderPriv.h109
1 files changed, 72 insertions, 37 deletions
diff --git a/src/effects/gradients/SkGradientShaderPriv.h b/src/effects/gradients/SkGradientShaderPriv.h
index 50ad427e4a..ee30c9b21b 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;
};