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 "SkGradientShader.h" 12 13 #include "SkArenaAlloc.h" 14 #include "SkMatrix.h" 15 #include "SkShaderBase.h" 16 #include "SkTArray.h" 17 #include "SkTemplates.h" 18 19 class SkColorSpace; 20 class SkColorSpaceXformer; 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 = SkShader::kClamp_TileMode; 31 } 32 33 const SkMatrix* fLocalMatrix; 34 const SkColor4f* fColors; 35 sk_sp<SkColorSpace> fColorSpace; 36 const SkScalar* fPos; 37 int fCount; 38 SkShader::TileMode 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 StageRec&) const override; 81 82 virtual void appendGradientStages(SkArenaAlloc* alloc, SkRasterPipeline* tPipeline, 83 SkRasterPipeline* postPipeline) const = 0; 84 85 template <typename T, typename... Args> CheckedMakeContext(SkArenaAlloc * alloc,Args &&...args)86 static Context* CheckedMakeContext(SkArenaAlloc* alloc, Args&&... args) { 87 auto* ctx = alloc->make<T>(std::forward<Args>(args)...); 88 if (!ctx->isValid()) { 89 return nullptr; 90 } 91 return ctx; 92 } 93 94 struct AutoXformColors { 95 AutoXformColors(const SkGradientShaderBase&, SkColorSpaceXformer*); 96 97 SkAutoSTMalloc<8, SkColor> fColors; 98 }; 99 100 const SkMatrix fPtsToUnit; 101 TileMode fTileMode; 102 uint8_t fGradFlags; 103 104 public: getPos(int i)105 SkScalar getPos(int i) const { 106 SkASSERT(i < fColorCount); 107 return fOrigPos ? fOrigPos[i] : SkIntToScalar(i) / (fColorCount - 1); 108 } 109 getLegacyColor(int i)110 SkColor getLegacyColor(int i) const { 111 SkASSERT(i < fColorCount); 112 return fOrigColors4f[i].toSkColor(); 113 } 114 115 SkColor4f* fOrigColors4f; // original colors, as linear floats 116 SkScalar* fOrigPos; // original positions 117 int fColorCount; 118 sk_sp<SkColorSpace> fColorSpace; // color space of gradient stops 119 colorsAreOpaque()120 bool colorsAreOpaque() const { return fColorsAreOpaque; } 121 getTileMode()122 TileMode getTileMode() const { return fTileMode; } 123 124 private: 125 // Reserve inline space for up to 4 stops. 126 static constexpr size_t kInlineStopCount = 4; 127 static constexpr size_t kInlineStorageSize = (sizeof(SkColor4f) + sizeof(SkScalar)) 128 * kInlineStopCount; 129 SkAutoSTMalloc<kInlineStorageSize, uint8_t> fStorage; 130 131 bool fColorsAreOpaque; 132 133 typedef SkShaderBase INHERITED; 134 }; 135 136 /////////////////////////////////////////////////////////////////////////////// 137 138 struct SkColor4fXformer { 139 SkColor4fXformer(const SkColor4f* colors, int colorCount, SkColorSpace* src, SkColorSpace* dst); 140 141 const SkColor4f* fColors; 142 SkSTArray<4, SkColor4f, true> fStorage; 143 }; 144 145 #endif 146