blob: 55d9a1896cf6538f3fa36e966c70397c3be17eff [file] [log] [blame]
/*
* 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 <string>
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