/* * Copyright 2020 Google LLC * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef SkSLSampleUsage_DEFINED #define SkSLSampleUsage_DEFINED #include namespace SkSL { /** * Represents all of the ways that a fragment processor is sampled by its parent. */ struct SampleUsage { enum class Kind { // No sample(child, matrix) call affects the FP. kNone, // The FP is sampled with a matrix whose value is fixed and based only on literals or // uniforms, and thus the transform can be hoisted to the vertex shader (assuming that // its parent can also be hoisted, i.e. not sampled explicitly). kUniform, // The FP is sampled with a non-literal/uniform value, or matrix-sampled multiple times, // and thus the transform cannot be hoisted to the vertex shader. kVariable }; // Make a SampleUsage that corresponds to no sampling of the child at all SampleUsage() = default; // This corresponds to sample(child, color, matrix) calls where every call site in the FP has // the same matrix, and that matrix's value is uniform (some expression only involving literals // and uniform variables). static SampleUsage UniformMatrix(std::string expression, bool hasPerspective = true) { return SampleUsage(Kind::kUniform, std::move(expression), hasPerspective, false, false); } // This corresponds to sample(child, color, matrix) where the 3rd argument is an expression that // can't be hoisted to the vertex shader, or where the expression used is not the same at all // call sites in the FP. static SampleUsage VariableMatrix(bool hasPerspective = true) { return SampleUsage(Kind::kVariable, "", hasPerspective, false, false); } static SampleUsage Explicit() { return SampleUsage(Kind::kNone, "", false, true, false); } static SampleUsage PassThrough() { return SampleUsage(Kind::kNone, "", false, false, true); } SampleUsage merge(const SampleUsage& other); bool isSampled() const { return this->hasMatrix() || fExplicitCoords || fPassThrough; } bool hasMatrix() const { return fKind != Kind::kNone; } bool hasUniformMatrix() const { return fKind == Kind::kUniform; } bool hasVariableMatrix() const { return fKind == Kind::kVariable; } Kind fKind = Kind::kNone; // The uniform expression representing the matrix (only valid when kind == kUniform) std::string fExpression; // FIXME: We can expand this to track a more general matrix type to allow for optimizations on // identity or scale+translate matrices too. bool fHasPerspective = false; bool fExplicitCoords = false; bool fPassThrough = false; SampleUsage(Kind kind, std::string expression, bool hasPerspective, bool explicitCoords, bool passThrough) : fKind(kind) , fExpression(expression) , fHasPerspective(hasPerspective) , fExplicitCoords(explicitCoords) , fPassThrough(passThrough) {} std::string constructor(std::string perspectiveExpression) const; }; } // namespace SkSL #endif