123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288 |
- /*
- * Copyright 2016 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
- #ifndef SKSL_PROGRAM
- #define SKSL_PROGRAM
- #include <vector>
- #include <memory>
- #include "src/sksl/ir/SkSLBoolLiteral.h"
- #include "src/sksl/ir/SkSLExpression.h"
- #include "src/sksl/ir/SkSLFloatLiteral.h"
- #include "src/sksl/ir/SkSLIntLiteral.h"
- #include "src/sksl/ir/SkSLModifiers.h"
- #include "src/sksl/ir/SkSLProgramElement.h"
- #include "src/sksl/ir/SkSLSymbolTable.h"
- // name of the render target width uniform
- #define SKSL_RTWIDTH_NAME "u_skRTWidth"
- // name of the render target height uniform
- #define SKSL_RTHEIGHT_NAME "u_skRTHeight"
- namespace SkSL {
- class Context;
- /**
- * Represents a fully-digested program, ready for code generation.
- */
- struct Program {
- struct Settings {
- struct Value {
- Value(bool b)
- : fKind(kBool_Kind)
- , fValue(b) {}
- Value(int i)
- : fKind(kInt_Kind)
- , fValue(i) {}
- Value(unsigned int i)
- : fKind(kInt_Kind)
- , fValue(i) {}
- Value(float f)
- : fKind(kFloat_Kind)
- , fValue(f) {}
- std::unique_ptr<Expression> literal(const Context& context, int offset) const {
- switch (fKind) {
- case Program::Settings::Value::kBool_Kind:
- return std::unique_ptr<Expression>(new BoolLiteral(context,
- offset,
- fValue));
- case Program::Settings::Value::kInt_Kind:
- return std::unique_ptr<Expression>(new IntLiteral(context,
- offset,
- fValue));
- case Program::Settings::Value::kFloat_Kind:
- return std::unique_ptr<Expression>(new FloatLiteral(context,
- offset,
- fValue));
- default:
- SkASSERT(false);
- return nullptr;
- }
- }
- enum {
- kBool_Kind,
- kInt_Kind,
- kFloat_Kind,
- } fKind;
- int fValue;
- };
- #if defined(SKSL_STANDALONE) || !SK_SUPPORT_GPU
- const StandaloneShaderCaps* fCaps = &standaloneCaps;
- #else
- const GrShaderCaps* fCaps = nullptr;
- #endif
- // if false, sk_FragCoord is exactly the same as gl_FragCoord. If true, the y coordinate
- // must be flipped.
- bool fFlipY = false;
- // If true the destination fragment color is read sk_FragColor. It must be declared inout.
- bool fFragColorIsInOut = false;
- // if true, Setting objects (e.g. sk_Caps.fbFetchSupport) should be replaced with their
- // constant equivalents during compilation
- bool fReplaceSettings = true;
- // if true, all halfs are forced to be floats
- bool fForceHighPrecision = false;
- // if true, add -0.5 bias to LOD of all texture lookups
- bool fSharpenTextures = false;
- std::unordered_map<String, Value> fArgs;
- };
- struct Inputs {
- // if true, this program requires the render target width uniform to be defined
- bool fRTWidth;
- // if true, this program requires the render target height uniform to be defined
- bool fRTHeight;
- // if true, this program must be recompiled if the flipY setting changes. If false, the
- // program will compile to the same code regardless of the flipY setting.
- bool fFlipY;
- void reset() {
- fRTWidth = false;
- fRTHeight = false;
- fFlipY = false;
- }
- bool isEmpty() {
- return !fRTWidth && !fRTHeight && !fFlipY;
- }
- };
- class iterator {
- public:
- ProgramElement& operator*() {
- if (fIter1 != fEnd1) {
- return **fIter1;
- }
- return **fIter2;
- }
- iterator& operator++() {
- if (fIter1 != fEnd1) {
- ++fIter1;
- return *this;
- }
- ++fIter2;
- return *this;
- }
- bool operator==(const iterator& other) const {
- return fIter1 == other.fIter1 && fIter2 == other.fIter2;
- }
- bool operator!=(const iterator& other) const {
- return !(*this == other);
- }
- private:
- using inner = std::vector<std::unique_ptr<ProgramElement>>::iterator;
- iterator(inner begin1, inner end1, inner begin2, inner end2)
- : fIter1(begin1)
- , fEnd1(end1)
- , fIter2(begin2)
- , fEnd2(end2) {}
- inner fIter1;
- inner fEnd1;
- inner fIter2;
- inner fEnd2;
- friend struct Program;
- };
- class const_iterator {
- public:
- const ProgramElement& operator*() {
- if (fIter1 != fEnd1) {
- return **fIter1;
- }
- return **fIter2;
- }
- const_iterator& operator++() {
- if (fIter1 != fEnd1) {
- ++fIter1;
- return *this;
- }
- ++fIter2;
- return *this;
- }
- bool operator==(const const_iterator& other) const {
- return fIter1 == other.fIter1 && fIter2 == other.fIter2;
- }
- bool operator!=(const const_iterator& other) const {
- return !(*this == other);
- }
- private:
- using inner = std::vector<std::unique_ptr<ProgramElement>>::const_iterator;
- const_iterator(inner begin1, inner end1, inner begin2, inner end2)
- : fIter1(begin1)
- , fEnd1(end1)
- , fIter2(begin2)
- , fEnd2(end2) {}
- inner fIter1;
- inner fEnd1;
- inner fIter2;
- inner fEnd2;
- friend struct Program;
- };
- enum Kind {
- kFragment_Kind,
- kVertex_Kind,
- kGeometry_Kind,
- kFragmentProcessor_Kind,
- kPipelineStage_Kind,
- kGeneric_Kind,
- };
- Program(Kind kind,
- std::unique_ptr<String> source,
- Settings settings,
- std::shared_ptr<Context> context,
- std::vector<std::unique_ptr<ProgramElement>>* inheritedElements,
- std::vector<std::unique_ptr<ProgramElement>> elements,
- std::shared_ptr<SymbolTable> symbols,
- Inputs inputs)
- : fKind(kind)
- , fSource(std::move(source))
- , fSettings(settings)
- , fContext(context)
- , fSymbols(symbols)
- , fInputs(inputs)
- , fInheritedElements(inheritedElements)
- , fElements(std::move(elements)) {}
- iterator begin() {
- if (fInheritedElements) {
- return iterator(fInheritedElements->begin(), fInheritedElements->end(),
- fElements.begin(), fElements.end());
- }
- return iterator(fElements.begin(), fElements.end(), fElements.end(), fElements.end());
- }
- iterator end() {
- if (fInheritedElements) {
- return iterator(fInheritedElements->end(), fInheritedElements->end(),
- fElements.end(), fElements.end());
- }
- return iterator(fElements.end(), fElements.end(), fElements.end(), fElements.end());
- }
- const_iterator begin() const {
- if (fInheritedElements) {
- return const_iterator(fInheritedElements->begin(), fInheritedElements->end(),
- fElements.begin(), fElements.end());
- }
- return const_iterator(fElements.begin(), fElements.end(), fElements.end(), fElements.end());
- }
- const_iterator end() const {
- if (fInheritedElements) {
- return const_iterator(fInheritedElements->end(), fInheritedElements->end(),
- fElements.end(), fElements.end());
- }
- return const_iterator(fElements.end(), fElements.end(), fElements.end(), fElements.end());
- }
- Kind fKind;
- std::unique_ptr<String> fSource;
- Settings fSettings;
- std::shared_ptr<Context> fContext;
- // it's important to keep fElements defined after (and thus destroyed before) fSymbols,
- // because destroying elements can modify reference counts in symbols
- std::shared_ptr<SymbolTable> fSymbols;
- Inputs fInputs;
- bool fIsOptimized = false;
- private:
- std::vector<std::unique_ptr<ProgramElement>>* fInheritedElements;
- std::vector<std::unique_ptr<ProgramElement>> fElements;
- friend class Compiler;
- };
- } // namespace
- #endif
|