1 /* 2 * Copyright 2023 Google LLC 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 #ifndef SkTriColorShader_DEFINED 8 #define SkTriColorShader_DEFINED 9 10 #include "include/core/SkMatrix.h" 11 #include "include/core/SkTypes.h" 12 #include "include/private/SkColorData.h" 13 #include "src/shaders/SkShaderBase.h" 14 15 struct SkPoint; 16 struct SkStageRec; 17 18 class SkTriColorShader : public SkShaderBase { 19 public: SkTriColorShader(bool isOpaque,bool usePersp)20 SkTriColorShader(bool isOpaque, bool usePersp) : fIsOpaque(isOpaque), fUsePersp(usePersp) {} 21 type()22 ShaderType type() const override { return ShaderType::kTriColor; } 23 24 // This gets called for each triangle, without re-calling appendStages. 25 bool update(const SkMatrix& ctmInv, 26 const SkPoint pts[], 27 const SkPMColor4f colors[], 28 int index0, 29 int index1, 30 int index2); 31 32 protected: 33 bool appendStages(const SkStageRec& rec, const SkShaders::MatrixRec&) const override; 34 35 private: isOpaque()36 bool isOpaque() const override { return fIsOpaque; } 37 // For serialization. This will never be called. getFactory()38 Factory getFactory() const override { return nullptr; } getTypeName()39 const char* getTypeName() const override { return nullptr; } 40 41 struct Matrix43 { 42 float fMat[12]; // column major 43 44 // Pass a by value, so we don't have to worry about aliasing with this setConcatMatrix4345 void setConcat(const Matrix43 a, const SkMatrix& b) { 46 SkASSERT(!b.hasPerspective()); 47 48 fMat[0] = a.dot(0, b.getScaleX(), b.getSkewY()); 49 fMat[1] = a.dot(1, b.getScaleX(), b.getSkewY()); 50 fMat[2] = a.dot(2, b.getScaleX(), b.getSkewY()); 51 fMat[3] = a.dot(3, b.getScaleX(), b.getSkewY()); 52 53 fMat[4] = a.dot(0, b.getSkewX(), b.getScaleY()); 54 fMat[5] = a.dot(1, b.getSkewX(), b.getScaleY()); 55 fMat[6] = a.dot(2, b.getSkewX(), b.getScaleY()); 56 fMat[7] = a.dot(3, b.getSkewX(), b.getScaleY()); 57 58 fMat[8] = a.dot(0, b.getTranslateX(), b.getTranslateY()) + a.fMat[8]; 59 fMat[9] = a.dot(1, b.getTranslateX(), b.getTranslateY()) + a.fMat[9]; 60 fMat[10] = a.dot(2, b.getTranslateX(), b.getTranslateY()) + a.fMat[10]; 61 fMat[11] = a.dot(3, b.getTranslateX(), b.getTranslateY()) + a.fMat[11]; 62 } 63 64 private: dotMatrix4365 float dot(int index, float x, float y) const { 66 return fMat[index + 0] * x + fMat[index + 4] * y; 67 } 68 }; 69 70 // If fUsePersp, we need both of these matrices, 71 // otherwise we can combine them, and only use fM43 72 73 Matrix43 fM43; 74 SkMatrix fM33; 75 const bool fIsOpaque; 76 const bool fUsePersp; // controls our stages, and what we do in update() 77 }; 78 79 #endif 80