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#ifndef SkSLSampleUsage_DEFINED
9#define SkSLSampleUsage_DEFINED
10
11#include "include/core/SkTypes.h"
12
13#include <string>
14
15namespace SkSL {
16
17/**
18 * Represents all of the ways that a fragment processor is sampled by its parent.
19 */
20class SampleUsage {
21public:
22    enum class Kind {
23        // Child is never sampled
24        kNone,
25        // Child is only sampled at the same coordinates as the parent
26        kPassThrough,
27        // Child is sampled with a matrix whose value is uniform
28        kUniformMatrix,
29        // Child is sampled with sk_FragCoord.xy
30        kFragCoord,
31        // Child is sampled using explicit coordinates
32        kExplicit,
33    };
34
35    // Make a SampleUsage that corresponds to no sampling of the child at all
36    SampleUsage() = default;
37
38    SampleUsage(Kind kind, bool hasPerspective) : fKind(kind), fHasPerspective(hasPerspective) {
39        if (kind != Kind::kUniformMatrix) {
40            SkASSERT(!fHasPerspective);
41        }
42    }
43
44    // Child is sampled with a matrix whose value is uniform. The name is fixed.
45    static SampleUsage UniformMatrix(bool hasPerspective) {
46        return SampleUsage(Kind::kUniformMatrix, hasPerspective);
47    }
48
49    static SampleUsage Explicit() {
50        return SampleUsage(Kind::kExplicit, false);
51    }
52
53    static SampleUsage PassThrough() {
54        return SampleUsage(Kind::kPassThrough, false);
55    }
56
57    static SampleUsage FragCoord() { return SampleUsage(Kind::kFragCoord, false); }
58
59    bool operator==(const SampleUsage& that) const {
60        return fKind == that.fKind && fHasPerspective == that.fHasPerspective;
61    }
62
63    bool operator!=(const SampleUsage& that) const { return !(*this == that); }
64
65    // Arbitrary name used by all uniform sampling matrices
66    static const char* MatrixUniformName() { return "matrix"; }
67
68    SampleUsage merge(const SampleUsage& other);
69
70    Kind kind() const { return fKind; }
71
72    bool hasPerspective() const { return fHasPerspective; }
73
74    bool isSampled()       const { return fKind != Kind::kNone; }
75    bool isPassThrough()   const { return fKind == Kind::kPassThrough; }
76    bool isExplicit()      const { return fKind == Kind::kExplicit; }
77    bool isUniformMatrix() const { return fKind == Kind::kUniformMatrix; }
78    bool isFragCoord()     const { return fKind == Kind::kFragCoord; }
79
80    std::string constructor() const;
81
82    void setKind(Kind kind) { fKind = kind; }
83
84private:
85    Kind fKind = Kind::kNone;
86    bool fHasPerspective = false;  // Only valid if fKind is kUniformMatrix
87};
88
89}  // namespace SkSL
90
91#endif
92