1 /* 2 * Copyright 2012 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SkGradientShaderPriv_DEFINED 9 #define SkGradientShaderPriv_DEFINED 10 11 #include "include/effects/SkGradientShader.h" 12 13 #include "include/core/SkMatrix.h" 14 #include "include/private/SkTArray.h" 15 #include "include/private/SkTemplates.h" 16 #include "src/core/SkArenaAlloc.h" 17 #include "src/core/SkVM.h" 18 #include "src/shaders/SkShaderBase.h" 19 20 class SkColorSpace; 21 class SkRasterPipeline; 22 class SkReadBuffer; 23 class SkWriteBuffer; 24 25 class SkGradientShaderBase : public SkShaderBase { 26 public: 27 struct Descriptor { DescriptorDescriptor28 Descriptor() { 29 sk_bzero(this, sizeof(*this)); 30 fTileMode = SkTileMode::kClamp; 31 } 32 33 const SkMatrix* fLocalMatrix; 34 const SkColor4f* fColors; 35 sk_sp<SkColorSpace> fColorSpace; 36 const SkScalar* fPos; 37 int fCount; 38 SkTileMode fTileMode; 39 uint32_t fGradFlags; 40 41 void flatten(SkWriteBuffer&) const; 42 }; 43 44 class DescriptorScope : public Descriptor { 45 public: DescriptorScope()46 DescriptorScope() {} 47 48 bool unflatten(SkReadBuffer&); 49 50 // fColors and fPos always point into local memory, so they can be safely mutated 51 // mutableColors()52 SkColor4f* mutableColors() { return const_cast<SkColor4f*>(fColors); } mutablePos()53 SkScalar* mutablePos() { return const_cast<SkScalar*>(fPos); } 54 55 private: 56 SkSTArray<16, SkColor4f, true> fColorStorage; 57 SkSTArray<16, SkScalar , true> fPosStorage; 58 SkMatrix fLocalMatrixStorage; 59 }; 60 61 SkGradientShaderBase(const Descriptor& desc, const SkMatrix& ptsToUnit); 62 ~SkGradientShaderBase() override; 63 64 bool isOpaque() const override; 65 getGradFlags()66 uint32_t getGradFlags() const { return fGradFlags; } 67 getGradientMatrix()68 const SkMatrix& getGradientMatrix() const { return fPtsToUnit; } 69 70 protected: 71 class GradientShaderBase4fContext; 72 73 SkGradientShaderBase(SkReadBuffer& ); 74 void flatten(SkWriteBuffer&) const override; 75 76 void commonAsAGradient(GradientInfo*) const; 77 78 bool onAsLuminanceColor(SkColor*) const override; 79 80 bool onAppendStages(const SkStageRec&) const override; 81 82 skvm::Color onProgram(skvm::Builder*, skvm::Coord device, skvm::Coord local, skvm::Color paint, 83 const SkMatrixProvider&, const SkMatrix* localM, const SkColorInfo& dstCS, 84 skvm::Uniforms* uniforms, SkArenaAlloc* alloc) const override; 85 86 virtual void appendGradientStages(SkArenaAlloc* alloc, SkRasterPipeline* tPipeline, 87 SkRasterPipeline* postPipeline) const = 0; 88 89 // Produce t from (x,y), modifying mask if it should be anything other than ~0. 90 virtual skvm::F32 transformT(skvm::Builder*, skvm::Uniforms*, 91 skvm::Coord coord, skvm::I32* mask) const = 0; 92 93 template <typename T, typename... Args> CheckedMakeContext(SkArenaAlloc * alloc,Args &&...args)94 static Context* CheckedMakeContext(SkArenaAlloc* alloc, Args&&... args) { 95 auto* ctx = alloc->make<T>(std::forward<Args>(args)...); 96 if (!ctx->isValid()) { 97 return nullptr; 98 } 99 return ctx; 100 } 101 102 const SkMatrix fPtsToUnit; 103 SkTileMode fTileMode; 104 uint8_t fGradFlags; 105 106 public: getPos(int i)107 SkScalar getPos(int i) const { 108 SkASSERT(i < fColorCount); 109 return fOrigPos ? fOrigPos[i] : SkIntToScalar(i) / (fColorCount - 1); 110 } 111 getLegacyColor(int i)112 SkColor getLegacyColor(int i) const { 113 SkASSERT(i < fColorCount); 114 return fOrigColors4f[i].toSkColor(); 115 } 116 colorsCanConvertToSkColor()117 bool colorsCanConvertToSkColor() const { 118 bool canConvert = true; 119 for (int i = 0; i < fColorCount; ++i) { 120 canConvert &= fOrigColors4f[i].fitsInBytes(); 121 } 122 return canConvert; 123 } 124 125 SkColor4f* fOrigColors4f; // original colors, as floats 126 SkScalar* fOrigPos; // original positions 127 int fColorCount; 128 sk_sp<SkColorSpace> fColorSpace; // color space of gradient stops 129 colorsAreOpaque()130 bool colorsAreOpaque() const { return fColorsAreOpaque; } 131 getTileMode()132 SkTileMode getTileMode() const { return fTileMode; } 133 134 private: 135 // Reserve inline space for up to 4 stops. 136 inline static constexpr size_t kInlineStopCount = 4; 137 inline static constexpr size_t kInlineStorageSize = (sizeof(SkColor4f) + sizeof(SkScalar)) 138 * kInlineStopCount; 139 SkAutoSTMalloc<kInlineStorageSize, uint8_t> fStorage; 140 141 bool fColorsAreOpaque; 142 143 using INHERITED = SkShaderBase; 144 }; 145 146 /////////////////////////////////////////////////////////////////////////////// 147 148 struct SkColor4fXformer { 149 SkColor4fXformer(const SkColor4f* colors, int colorCount, SkColorSpace* src, SkColorSpace* dst); 150 151 const SkColor4f* fColors; 152 SkSTArray<4, SkColor4f, true> fStorage; 153 }; 154 155 #endif 156