blob: 68065102a8363991b8890124c882140562185ad4 [file] [log] [blame]
* Copyright 2023 Google LLC
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
#ifndef SkTriColorShader_DEFINED
#define SkTriColorShader_DEFINED
#include "include/core/SkMatrix.h"
#include "include/core/SkTypes.h"
#include "include/private/SkColorData.h"
#include "src/shaders/SkShaderBase.h"
struct SkPoint;
struct SkStageRec;
class SkTriColorShader : public SkShaderBase {
SkTriColorShader(bool isOpaque, bool usePersp) : fIsOpaque(isOpaque), fUsePersp(usePersp) {}
ShaderType type() const override { return ShaderType::kTriColor; }
// This gets called for each triangle, without re-calling appendStages.
bool update(const SkMatrix& ctmInv,
const SkPoint pts[],
const SkPMColor4f colors[],
int index0,
int index1,
int index2);
bool appendStages(const SkStageRec& rec, const SkShaders::MatrixRec&) const override;
bool isOpaque() const override { return fIsOpaque; }
// For serialization. This will never be called.
Factory getFactory() const override { return nullptr; }
const char* getTypeName() const override { return nullptr; }
struct Matrix43 {
float fMat[12]; // column major
// Pass a by value, so we don't have to worry about aliasing with this
void setConcat(const Matrix43 a, const SkMatrix& b) {
fMat[0] =, b.getScaleX(), b.getSkewY());
fMat[1] =, b.getScaleX(), b.getSkewY());
fMat[2] =, b.getScaleX(), b.getSkewY());
fMat[3] =, b.getScaleX(), b.getSkewY());
fMat[4] =, b.getSkewX(), b.getScaleY());
fMat[5] =, b.getSkewX(), b.getScaleY());
fMat[6] =, b.getSkewX(), b.getScaleY());
fMat[7] =, b.getSkewX(), b.getScaleY());
fMat[8] =, b.getTranslateX(), b.getTranslateY()) + a.fMat[8];
fMat[9] =, b.getTranslateX(), b.getTranslateY()) + a.fMat[9];
fMat[10] =, b.getTranslateX(), b.getTranslateY()) + a.fMat[10];
fMat[11] =, b.getTranslateX(), b.getTranslateY()) + a.fMat[11];
float dot(int index, float x, float y) const {
return fMat[index + 0] * x + fMat[index + 4] * y;
// If fUsePersp, we need both of these matrices,
// otherwise we can combine them, and only use fM43
Matrix43 fM43;
SkMatrix fM33;
const bool fIsOpaque;
const bool fUsePersp; // controls our stages, and what we do in update()