1/* 2 * Copyright 2020 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 8#include "src/gpu/effects/GrMatrixEffect.h" 9 10#include "src/gpu/GrTexture.h" 11#include "src/gpu/effects/GrTextureEffect.h" 12#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h" 13#include "src/gpu/glsl/GrGLSLProgramBuilder.h" 14#include "src/sksl/SkSLUtil.h" 15 16std::unique_ptr<GrFragmentProcessor> GrMatrixEffect::Make( 17 const SkMatrix& matrix, std::unique_ptr<GrFragmentProcessor> child) { 18 if (child->classID() == kGrMatrixEffect_ClassID) { 19 auto me = static_cast<GrMatrixEffect*>(child.get()); 20 // registerChild's sample usage records whether the matrix used has perspective or not, 21 // so we can't add perspective to 'me' if it doesn't already have it. 22 if (me->fMatrix.hasPerspective() || !matrix.hasPerspective()) { 23 me->fMatrix.preConcat(matrix); 24 return child; 25 } 26 } 27 return std::unique_ptr<GrFragmentProcessor>(new GrMatrixEffect(matrix, std::move(child))); 28} 29 30std::unique_ptr<GrFragmentProcessor::ProgramImpl> GrMatrixEffect::onMakeProgramImpl() const { 31 class Impl : public ProgramImpl { 32 public: 33 void emitCode(EmitArgs& args) override { 34 fMatrixVar = args.fUniformHandler->addUniform(&args.fFp, 35 kFragment_GrShaderFlag, 36 kFloat3x3_GrSLType, 37 SkSL::SampleUsage::MatrixUniformName()); 38 args.fFragBuilder->codeAppendf("return %s;\n", 39 this->invokeChildWithMatrix(0, args).c_str()); 40 } 41 42 private: 43 void onSetData(const GrGLSLProgramDataManager& pdman, 44 const GrFragmentProcessor& proc) override { 45 const GrMatrixEffect& mtx = proc.cast<GrMatrixEffect>(); 46 if (auto te = mtx.childProcessor(0)->asTextureEffect()) { 47 SkMatrix m = te->coordAdjustmentMatrix(); 48 m.preConcat(mtx.fMatrix); 49 pdman.setSkMatrix(fMatrixVar, m); 50 } else { 51 pdman.setSkMatrix(fMatrixVar, mtx.fMatrix); 52 } 53 } 54 55 UniformHandle fMatrixVar; 56 }; 57 58 return std::make_unique<Impl>(); 59} 60 61void GrMatrixEffect::onAddToKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {} 62 63bool GrMatrixEffect::onIsEqual(const GrFragmentProcessor& other) const { 64 const GrMatrixEffect& that = other.cast<GrMatrixEffect>(); 65 if (fMatrix != that.fMatrix) return false; 66 return true; 67} 68 69GrMatrixEffect::GrMatrixEffect(const GrMatrixEffect& src) 70 : INHERITED(src) 71 , fMatrix(src.fMatrix) {} 72 73std::unique_ptr<GrFragmentProcessor> GrMatrixEffect::clone() const { 74 return std::unique_ptr<GrFragmentProcessor>(new GrMatrixEffect(*this)); 75} 76