aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/effects/gradients/SkGradientShaderPriv.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/effects/gradients/SkGradientShaderPriv.h')
-rw-r--r--src/effects/gradients/SkGradientShaderPriv.h540
1 files changed, 0 insertions, 540 deletions
diff --git a/src/effects/gradients/SkGradientShaderPriv.h b/src/effects/gradients/SkGradientShaderPriv.h
deleted file mode 100644
index 7a66edaffc..0000000000
--- a/src/effects/gradients/SkGradientShaderPriv.h
+++ /dev/null
@@ -1,540 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkGradientShaderPriv_DEFINED
-#define SkGradientShaderPriv_DEFINED
-
-#include "SkGradientBitmapCache.h"
-#include "SkGradientShader.h"
-
-#include "SkArenaAlloc.h"
-#include "SkAutoMalloc.h"
-#include "SkClampRange.h"
-#include "SkColorPriv.h"
-#include "SkColorSpace.h"
-#include "SkOnce.h"
-#include "SkPM4fPriv.h"
-#include "SkRasterPipeline.h"
-#include "SkReadBuffer.h"
-#include "SkShaderBase.h"
-#include "SkUtils.h"
-#include "SkWriteBuffer.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) {
- if (v0 == v1) {
- sk_memset32(dst, v0, count);
- } else {
- int pairs = count >> 1;
- for (int i = 0; i < pairs; i++) {
- *dst++ = v0;
- *dst++ = v1;
- }
- if (count & 1) {
- *dst = v0;
- }
- }
- }
-}
-
-// Clamp
-
-static inline SkFixed clamp_tileproc(SkFixed x) {
- return SkClampMax(x, 0xFFFF);
-}
-
-// Repeat
-
-static inline SkFixed repeat_tileproc(SkFixed x) {
- return x & 0xFFFF;
-}
-
-// Mirror
-
-static inline SkFixed mirror_tileproc(SkFixed x) {
- int s = SkLeftShift(x, 15) >> 31;
- return (x ^ s) & 0xFFFF;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-typedef SkFixed (*TileProc)(SkFixed);
-
-///////////////////////////////////////////////////////////////////////////////
-
-static const TileProc gTileProcs[] = {
- clamp_tileproc,
- repeat_tileproc,
- mirror_tileproc
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-class SkGradientShaderBase : public SkShaderBase {
-public:
- struct Descriptor {
- Descriptor() {
- sk_bzero(this, sizeof(*this));
- fTileMode = SkShader::kClamp_TileMode;
- }
-
- const SkMatrix* fLocalMatrix;
- const SkColor4f* fColors;
- sk_sp<SkColorSpace> fColorSpace;
- const SkScalar* fPos;
- int fCount;
- SkShader::TileMode fTileMode;
- uint32_t fGradFlags;
-
- void flatten(SkWriteBuffer&) const;
- };
-
- class DescriptorScope : public Descriptor {
- public:
- DescriptorScope() {}
-
- bool unflatten(SkReadBuffer&);
-
- // fColors and fPos always point into local memory, so they can be safely mutated
- //
- SkColor4f* mutableColors() { return const_cast<SkColor4f*>(fColors); }
- SkScalar* mutablePos() { return const_cast<SkScalar*>(fPos); }
-
- private:
- enum {
- kStorageCount = 16
- };
- SkColor4f fColorStorage[kStorageCount];
- SkScalar fPosStorage[kStorageCount];
- SkMatrix fLocalMatrixStorage;
- SkAutoMalloc fDynamicStorage;
- };
-
- SkGradientShaderBase(const Descriptor& desc, const SkMatrix& ptsToUnit);
- ~SkGradientShaderBase() override;
-
- // The cache is initialized on-demand when getCache32 is called.
- class GradientShaderCache : public SkRefCnt {
- public:
- GradientShaderCache(U8CPU alpha, bool dither, const SkGradientShaderBase& shader);
- ~GradientShaderCache();
-
- const SkPMColor* getCache32();
-
- SkPixelRef* getCache32PixelRef() const { return fCache32PixelRef.get(); }
-
- unsigned getAlpha() const { return fCacheAlpha; }
- bool getDither() const { return fCacheDither; }
-
- private:
- // Working pointer. If it's nullptr, we need to recompute the cache values.
- SkPMColor* fCache32;
-
- sk_sp<SkPixelRef> fCache32PixelRef;
- const unsigned fCacheAlpha; // The alpha value we used when we computed the cache.
- // Larger than 8bits so we can store uninitialized
- // value.
- const bool fCacheDither; // The dither flag used when we computed the cache.
-
- const SkGradientShaderBase& fShader;
-
- // Make sure we only initialize the cache once.
- SkOnce fCache32InitOnce;
-
- static void initCache32(GradientShaderCache* cache);
-
- static void Build32bitCache(SkPMColor[], SkColor c0, SkColor c1, int count,
- U8CPU alpha, uint32_t gradFlags, bool dither);
- };
-
- class GradientShaderBaseContext : public Context {
- public:
- GradientShaderBaseContext(const SkGradientShaderBase& shader, const ContextRec&);
-
- uint32_t getFlags() const override { return fFlags; }
-
- bool isValid() const;
-
- protected:
- SkMatrix fDstToIndex;
- SkMatrix::MapXYProc fDstToIndexProc;
- uint8_t fDstToIndexClass;
- uint8_t fFlags;
- bool fDither;
-
- sk_sp<GradientShaderCache> fCache;
-
- private:
- typedef Context INHERITED;
- };
-
- bool isOpaque() const override;
-
- enum class GradientBitmapType : uint8_t {
- kLegacy,
- kSRGB,
- kHalfFloat,
- };
-
- void getGradientTableBitmap(SkBitmap*, GradientBitmapType bitmapType) const;
-
- enum {
- /// Seems like enough for visual accuracy. TODO: if pos[] deserves
- /// it, use a larger cache.
- kCache32Bits = 8,
- kCache32Count = (1 << kCache32Bits),
- kCache32Shift = 16 - kCache32Bits,
- kSqrt32Shift = 8 - kCache32Bits,
-
- /// This value is used to *read* the dither cache; it may be 0
- /// if dithering is disabled.
- kDitherStride32 = kCache32Count,
- };
-
- uint32_t getGradFlags() const { return fGradFlags; }
-
-protected:
- struct Rec {
- SkFixed fPos; // 0...1
- uint32_t fScale; // (1 << 24) / range
- };
-
- class GradientShaderBase4fContext;
-
- SkGradientShaderBase(SkReadBuffer& );
- void flatten(SkWriteBuffer&) const override;
- SK_TO_STRING_OVERRIDE()
-
- void commonAsAGradient(GradientInfo*, bool flipGrad = false) const;
-
- bool onAsLuminanceColor(SkColor*) const override;
-
- void initLinearBitmap(SkBitmap* bitmap) const;
-
- /*
- * Takes in pointers to gradient color and Rec info as colorSrc and recSrc respectively.
- * Count is the number of colors in the gradient
- * It will then flip all the color and rec information and return in their respective Dst
- * pointers. It is assumed that space has already been allocated for the Dst pointers.
- * The rec src and dst are only assumed to be valid if count > 2
- */
- static void FlipGradientColors(SkColor* colorDst, Rec* recDst,
- SkColor* colorSrc, Rec* recSrc,
- int count);
-
- bool onAppendStages(SkRasterPipeline* pipeline, SkColorSpace* dstCS, SkArenaAlloc* alloc,
- const SkMatrix& ctm, const SkPaint& paint,
- const SkMatrix* localM) const override;
-
- virtual bool adjustMatrixAndAppendStages(SkArenaAlloc* alloc,
- SkMatrix* matrix,
- SkRasterPipeline* p) const { return false; }
-
- template <typename T, typename... Args>
- static Context* CheckedMakeContext(SkArenaAlloc* alloc, Args&&... args) {
- auto* ctx = alloc->make<T>(std::forward<Args>(args)...);
- if (!ctx->isValid()) {
- return nullptr;
- }
- return ctx;
- }
-
- const SkMatrix fPtsToUnit;
- TileMode fTileMode;
- TileProc fTileProc;
- uint8_t fGradFlags;
- Rec* fRecs;
-
-private:
- enum {
- kColorStorageCount = 4, // more than this many colors, and we'll use sk_malloc for the space
-
- kStorageSize = kColorStorageCount *
- (sizeof(SkColor) + sizeof(SkScalar) + sizeof(Rec) + sizeof(SkColor4f))
- };
- SkColor fStorage[(kStorageSize + 3) >> 2];
-public:
- SkColor* fOrigColors; // original colors, before modulation by paint in context.
- SkColor4f* fOrigColors4f; // original colors, as linear floats
- SkScalar* fOrigPos; // original positions
- int fColorCount;
- sk_sp<SkColorSpace> fColorSpace; // color space of gradient stops
-
- bool colorsAreOpaque() const { return fColorsAreOpaque; }
-
- TileMode getTileMode() const { return fTileMode; }
- Rec* getRecs() const { return fRecs; }
-
-private:
- bool fColorsAreOpaque;
-
- sk_sp<GradientShaderCache> refCache(U8CPU alpha, bool dither) const;
- mutable SkMutex fCacheMutex;
- mutable sk_sp<GradientShaderCache> fCache;
-
- void initCommon();
-
- typedef SkShaderBase INHERITED;
-};
-
-
-static inline int init_dither_toggle(int x, int y) {
- x &= 1;
- y = (y & 1) << 1;
- return (x | y) * SkGradientShaderBase::kDitherStride32;
-}
-
-static inline int next_dither_toggle(int toggle) {
- return toggle ^ SkGradientShaderBase::kDitherStride32;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-#if SK_SUPPORT_GPU
-
-#include "GrColorSpaceXform.h"
-#include "GrCoordTransform.h"
-#include "GrFragmentProcessor.h"
-#include "glsl/GrGLSLColorSpaceXformHelper.h"
-#include "glsl/GrGLSLFragmentProcessor.h"
-#include "glsl/GrGLSLProgramDataManager.h"
-
-class GrInvariantOutput;
-
-/*
- * The interpretation of the texture matrix depends on the sample mode. The
- * texture matrix is applied both when the texture coordinates are explicit
- * and when vertex positions are used as texture coordinates. In the latter
- * case the texture matrix is applied to the pre-view-matrix position
- * values.
- *
- * Normal SampleMode
- * The post-matrix texture coordinates are in normalize space with (0,0) at
- * the top-left and (1,1) at the bottom right.
- * RadialGradient
- * The matrix specifies the radial gradient parameters.
- * (0,0) in the post-matrix space is center of the radial gradient.
- * Radial2Gradient
- * Matrix transforms to space where first circle is centered at the
- * origin. The second circle will be centered (x, 0) where x may be
- * 0 and is provided by setRadial2Params. The post-matrix space is
- * normalized such that 1 is the second radius - first radius.
- * SweepGradient
- * The angle from the origin of texture coordinates in post-matrix space
- * determines the gradient value.
- */
-
- class GrTextureStripAtlas;
-
-// Base class for Gr gradient effects
-class GrGradientEffect : public GrFragmentProcessor {
-public:
- struct CreateArgs {
- CreateArgs(GrContext* context,
- const SkGradientShaderBase* shader,
- const SkMatrix* matrix,
- SkShader::TileMode tileMode,
- sk_sp<GrColorSpaceXform> colorSpaceXform,
- bool gammaCorrect)
- : fContext(context)
- , fShader(shader)
- , fMatrix(matrix)
- , fTileMode(tileMode)
- , fColorSpaceXform(std::move(colorSpaceXform))
- , fGammaCorrect(gammaCorrect) {}
-
- GrContext* fContext;
- const SkGradientShaderBase* fShader;
- const SkMatrix* fMatrix;
- SkShader::TileMode fTileMode;
- sk_sp<GrColorSpaceXform> fColorSpaceXform;
- bool fGammaCorrect;
- };
-
- class GLSLProcessor;
-
- ~GrGradientEffect() override;
-
- bool useAtlas() const { return SkToBool(-1 != fRow); }
- SkScalar getYCoord() const { return fYCoord; }
-
- enum ColorType {
- kTwo_ColorType,
- kThree_ColorType, // Symmetric three color
- kTexture_ColorType,
-
-#if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS
- kSingleHardStop_ColorType, // 0, t, t, 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,
- kAfterInterp_PremulType,
- };
-
- PremulType getPremulType() const { return fPremulType; }
-
- const SkColor* getColors(int pos) const {
- SkASSERT(fColorType != kTexture_ColorType);
- SkASSERT(pos < fColors.count());
- return &fColors[pos];
- }
-
- const SkColor4f* getColors4f(int pos) const {
- SkASSERT(fColorType != kTexture_ColorType);
- SkASSERT(pos < fColors4f.count());
- return &fColors4f[pos];
- }
-
-protected:
- GrGradientEffect(const CreateArgs&, bool isOpaque);
-
- #if GR_TEST_UTILS
- /** Helper struct that stores (and populates) parameters to construct a random gradient.
- If fUseColors4f is true, then the SkColor4f factory should be called, with fColors4f and
- fColorSpace. Otherwise, the SkColor factory should be called, with fColors. fColorCount
- will be the number of color stops in either case, and fColors and fStops can be passed to
- the gradient factory. (The constructor may decide not to use stops, in which case fStops
- will be nullptr). */
- struct RandomGradientParams {
- static const int kMaxRandomGradientColors = 5;
-
- RandomGradientParams(SkRandom* r);
-
- bool fUseColors4f;
- SkColor fColors[kMaxRandomGradientColors];
- SkColor4f fColors4f[kMaxRandomGradientColors];
- sk_sp<SkColorSpace> fColorSpace;
- SkScalar fStopStorage[kMaxRandomGradientColors];
- SkShader::TileMode fTileMode;
- int fColorCount;
- SkScalar* fStops;
- };
- #endif
-
- bool onIsEqual(const GrFragmentProcessor&) const override;
-
- const GrCoordTransform& getCoordTransform() const { return fCoordTransform; }
-
-private:
- static OptimizationFlags OptFlags(bool isOpaque);
-
- // If we're in legacy mode, then fColors will be populated. If we're gamma-correct, then
- // fColors4f and fColorSpaceXform will be populated.
- SkTDArray<SkColor> fColors;
-
- SkTDArray<SkColor4f> fColors4f;
- sk_sp<GrColorSpaceXform> fColorSpaceXform;
-
- SkTDArray<SkScalar> fPositions;
- SkShader::TileMode fTileMode;
-
- GrCoordTransform fCoordTransform;
- TextureSampler fTextureSampler;
- SkScalar fYCoord;
- GrTextureStripAtlas* fAtlas;
- int fRow;
- bool fIsOpaque;
- 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 GL gradient effects
-class GrGradientEffect::GLSLProcessor : public GrGLSLFragmentProcessor {
-public:
- GLSLProcessor() {
- fCachedYCoord = SK_ScalarMax;
- }
-
-protected:
- void onSetData(const GrGLSLProgramDataManager&, const GrFragmentProcessor&) override;
-
-protected:
- /**
- * Subclasses must call this. It will return a key for the part of the shader code controlled
- * by the base class. The subclasses must stick it in their key and then pass it to the below
- * emit* functions from their emitCode function.
- */
- static uint32_t GenBaseGradientKey(const GrProcessor&);
-
- // Emits the uniform used as the y-coord to texture samples in derived classes. Subclasses
- // 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
- // 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 GrShaderCaps* shaderCaps,
- const GrGradientEffect&,
- const char* gradientTValue,
- const char* outputColor,
- const char* inputColor,
- const TextureSamplers&);
-
-private:
- enum {
- // First bit for premul before/after interp
- 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 fHardStopT;
- GrGLSLProgramDataManager::UniformHandle fFSYUni;
- GrGLSLColorSpaceXformHelper fColorSpaceHelper;
-
- typedef GrGLSLFragmentProcessor INHERITED;
-};
-
-#endif
-
-#endif