| /* | |
| * Copyright 2021 Google Inc. | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #include "src/core/SkMatrixProvider.h" | |
| #include "src/shaders/SkTransformShader.h" | |
| SkTransformShader::SkTransformShader(const SkShaderBase& shader) : fShader{shader} {} | |
| skvm::Color SkTransformShader::onProgram(skvm::Builder* b, | |
| skvm::Coord device, skvm::Coord local, skvm::Color color, | |
| const SkMatrixProvider& matrices, const SkMatrix* localM, | |
| const SkColorInfo& dst, | |
| skvm::Uniforms* uniforms, SkArenaAlloc* alloc) const { | |
| skvm::Coord newLocal = this->applyMatrix(b, matrices.localToDevice(), local, uniforms); | |
| SkSimpleMatrixProvider matrixProvider{SkMatrix::I()}; | |
| return fShader.program( | |
| b, device, newLocal, color, matrixProvider, localM, dst, uniforms, alloc); | |
| } | |
| skvm::Coord SkTransformShader::applyMatrix( | |
| skvm::Builder* b, const SkMatrix& matrix, skvm::Coord local, | |
| skvm::Uniforms* uniforms) const { | |
| fMatrix = uniforms->pushPtr(&fMatrixStorage); | |
| skvm::F32 x = local.x, | |
| y = local.y; | |
| auto dot = [&,x,y](int row) { | |
| return b->mad(x, b->arrayF(fMatrix, 3*row+0), | |
| b->mad(y, b->arrayF(fMatrix, 3*row+1), | |
| b->arrayF(fMatrix, 3*row+2))); | |
| }; | |
| x = dot(0); | |
| y = dot(1); | |
| if (matrix.hasPerspective() || fShader.getLocalMatrix().hasPerspective()) { | |
| x = x * (1.0f / dot(2)); | |
| y = y * (1.0f / dot(2)); | |
| } | |
| return {x, y}; | |
| } | |
| bool SkTransformShader::update(const SkMatrix& ctm) const { | |
| SkMatrix matrix; | |
| if (this->computeTotalInverse(ctm, nullptr, &matrix)) { | |
| for (int i = 0; i < 9; ++i) { | |
| fMatrixStorage[i] = matrix[i]; | |
| } | |
| return true; | |
| } | |
| return false; | |
| } | |
| bool SkTransformShader::onAppendStages(const SkStageRec& rec) const { | |
| // TODO | |
| return false; | |
| } |