summaryrefslogtreecommitdiffstats
path: root/gfx/skia/skia/src/shaders/gradients/SkGradientShaderBase.h
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/skia/skia/src/shaders/gradients/SkGradientShaderBase.h')
-rw-r--r--gfx/skia/skia/src/shaders/gradients/SkGradientShaderBase.h192
1 files changed, 192 insertions, 0 deletions
diff --git a/gfx/skia/skia/src/shaders/gradients/SkGradientShaderBase.h b/gfx/skia/skia/src/shaders/gradients/SkGradientShaderBase.h
new file mode 100644
index 0000000000..fc677cfaed
--- /dev/null
+++ b/gfx/skia/skia/src/shaders/gradients/SkGradientShaderBase.h
@@ -0,0 +1,192 @@
+/*
+ * 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 "include/effects/SkGradientShader.h"
+
+#include "include/core/SkMatrix.h"
+#include "include/private/base/SkTArray.h"
+#include "include/private/base/SkTemplates.h"
+#include "src/core/SkVM.h"
+#include "src/shaders/SkShaderBase.h"
+
+#if defined(SK_GRAPHITE)
+#include "src/gpu/graphite/KeyHelpers.h"
+#endif
+
+class SkArenaAlloc;
+class SkColorSpace;
+class SkRasterPipeline;
+class SkReadBuffer;
+class SkWriteBuffer;
+
+class SkGradientShaderBase : public SkShaderBase {
+public:
+ using Interpolation = SkGradientShader::Interpolation;
+
+ struct Descriptor {
+ Descriptor();
+ ~Descriptor();
+
+ Descriptor(const SkColor4f colors[],
+ sk_sp<SkColorSpace> colorSpace,
+ const SkScalar positions[],
+ int colorCount,
+ SkTileMode mode,
+ const Interpolation& interpolation);
+
+ const SkColor4f* fColors;
+ sk_sp<SkColorSpace> fColorSpace;
+ const SkScalar* fPositions;
+ int fColorCount; // length of fColors (and fPositions, if not nullptr)
+ SkTileMode fTileMode;
+ Interpolation fInterpolation;
+ };
+
+ class DescriptorScope : public Descriptor {
+ public:
+ DescriptorScope() {}
+
+ bool unflatten(SkReadBuffer&, SkMatrix* legacyLocalMatrix);
+
+ private:
+ SkSTArray<16, SkColor4f, true> fColorStorage;
+ SkSTArray<16, SkScalar , true> fPositionStorage;
+ };
+
+ SkGradientShaderBase(const Descriptor& desc, const SkMatrix& ptsToUnit);
+ ~SkGradientShaderBase() override;
+
+ bool isOpaque() const override;
+
+ bool interpolateInPremul() const {
+ return fInterpolation.fInPremul == SkGradientShader::Interpolation::InPremul::kYes;
+ }
+
+ const SkMatrix& getGradientMatrix() const { return fPtsToUnit; }
+
+ static bool ValidGradient(const SkColor4f colors[], int count, SkTileMode tileMode,
+ const Interpolation& interpolation);
+
+ static sk_sp<SkShader> MakeDegenerateGradient(const SkColor4f colors[], const SkScalar pos[],
+ int colorCount, sk_sp<SkColorSpace> colorSpace,
+ SkTileMode mode);
+
+ struct ColorStopOptimizer {
+ ColorStopOptimizer(const SkColor4f* colors, const SkScalar* pos, int count,
+ SkTileMode mode);
+
+ const SkColor4f* fColors;
+ const SkScalar* fPos;
+ int fCount;
+ };
+
+ // The default SkScalarNearlyZero threshold of .0024 is too big and causes regressions for svg
+ // gradients defined in the wild.
+ static constexpr SkScalar kDegenerateThreshold = SK_Scalar1 / (1 << 15);
+
+protected:
+ void flatten(SkWriteBuffer&) const override;
+
+ void commonAsAGradient(GradientInfo*) const;
+
+ bool onAsLuminanceColor(SkColor*) const override;
+
+ bool appendStages(const SkStageRec&, const MatrixRec&) const override;
+
+ skvm::Color program(skvm::Builder*,
+ skvm::Coord device,
+ skvm::Coord local,
+ skvm::Color paint,
+ const MatrixRec&,
+ const SkColorInfo& dstCS,
+ skvm::Uniforms* uniforms,
+ SkArenaAlloc* alloc) const override;
+
+ virtual void appendGradientStages(SkArenaAlloc* alloc, SkRasterPipeline* tPipeline,
+ SkRasterPipeline* postPipeline) const = 0;
+
+ // Produce t from (x,y), modifying mask if it should be anything other than ~0.
+ virtual skvm::F32 transformT(skvm::Builder*, skvm::Uniforms*,
+ skvm::Coord coord, skvm::I32* mask) const = 0;
+
+ const SkMatrix fPtsToUnit;
+ SkTileMode fTileMode;
+
+#if defined(SK_GRAPHITE)
+ static void MakeInterpolatedToDst(const skgpu::graphite::KeyContext&,
+ skgpu::graphite::PaintParamsKeyBuilder*,
+ skgpu::graphite::PipelineDataGatherer*,
+ const skgpu::graphite::GradientShaderBlocks::GradientData&,
+ const SkGradientShaderBase::Interpolation&,
+ SkColorSpace* intermediateCS);
+#endif
+
+public:
+ static void AppendGradientFillStages(SkRasterPipeline* p,
+ SkArenaAlloc* alloc,
+ const SkPMColor4f* colors,
+ const SkScalar* positions,
+ int count);
+
+ SkScalar getPos(int i) const {
+ SkASSERT(i < fColorCount);
+ return fPositions ? fPositions[i] : SkIntToScalar(i) / (fColorCount - 1);
+ }
+
+ SkColor getLegacyColor(int i) const {
+ SkASSERT(i < fColorCount);
+ return fColors[i].toSkColor();
+ }
+
+ SkColor4f* fColors; // points into fStorage
+ SkScalar* fPositions; // points into fStorage, or nullptr
+ int fColorCount; // length of fColors (and fPositions, if not nullptr)
+ sk_sp<SkColorSpace> fColorSpace; // color space of gradient stops
+ Interpolation fInterpolation;
+ bool fFirstStopIsImplicit;
+ bool fLastStopIsImplicit;
+
+ bool colorsAreOpaque() const { return fColorsAreOpaque; }
+
+ SkTileMode getTileMode() const { return fTileMode; }
+
+private:
+ // Reserve inline space for up to 4 stops.
+ inline static constexpr size_t kInlineStopCount = 4;
+ inline static constexpr size_t kInlineStorageSize = (sizeof(SkColor4f) + sizeof(SkScalar))
+ * kInlineStopCount;
+ skia_private::AutoSTMalloc<kInlineStorageSize, uint8_t> fStorage;
+
+ bool fColorsAreOpaque;
+
+ using INHERITED = SkShaderBase;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+struct SkColor4fXformer {
+ SkColor4fXformer(const SkGradientShaderBase* shader, SkColorSpace* dst);
+
+ SkSTArray<4, SkPMColor4f, true> fColors;
+ sk_sp<SkColorSpace> fIntermediateColorSpace;
+};
+
+struct SkColorConverter {
+ SkColorConverter(const SkColor* colors, int count);
+
+ SkSTArray<2, SkColor4f, true> fColors4f;
+};
+
+void SkRegisterLinearGradientShaderFlattenable();
+void SkRegisterRadialGradientShaderFlattenable();
+void SkRegisterSweepGradientShaderFlattenable();
+void SkRegisterTwoPointConicalGradientShaderFlattenable();
+
+#endif