1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/*
2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2016 Google Inc.
3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *
4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be
5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file.
6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */
7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifndef SKSL_LAYOUT
9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define SKSL_LAYOUT
10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkSLString.h"
12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkSLUtil.h"
13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotnamespace SkSL {
15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/**
17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Represents a layout block appearing before a variable declaration, as in:
18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *
19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * layout (location = 0) int x;
20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */
21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstruct Layout {
22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    enum Flag {
23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kOriginUpperLeft_Flag            = 1 <<  0,
24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kOverrideCoverage_Flag           = 1 <<  1,
25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kPushConstant_Flag               = 1 <<  2,
26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kBlendSupportAllEquations_Flag   = 1 <<  3,
27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kBlendSupportMultiply_Flag       = 1 <<  4,
28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kBlendSupportScreen_Flag         = 1 <<  5,
29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kBlendSupportOverlay_Flag        = 1 <<  6,
30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kBlendSupportDarken_Flag         = 1 <<  7,
31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kBlendSupportLighten_Flag        = 1 <<  8,
32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kBlendSupportColorDodge_Flag     = 1 <<  9,
33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kBlendSupportColorBurn_Flag      = 1 << 10,
34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kBlendSupportHardLight_Flag      = 1 << 11,
35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kBlendSupportSoftLight_Flag      = 1 << 12,
36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kBlendSupportDifference_Flag     = 1 << 13,
37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kBlendSupportExclusion_Flag      = 1 << 14,
38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kBlendSupportHSLHue_Flag         = 1 << 15,
39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kBlendSupportHSLSaturation_Flag  = 1 << 16,
40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kBlendSupportHSLColor_Flag       = 1 << 17,
41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kBlendSupportHSLLuminosity_Flag  = 1 << 18
42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    enum Primitive {
45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kUnspecified_Primitive = -1,
46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kPoints_Primitive,
47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kLines_Primitive,
48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kLineStrip_Primitive,
49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kLinesAdjacency_Primitive,
50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kTriangles_Primitive,
51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kTriangleStrip_Primitive,
52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kTrianglesAdjacency_Primitive
53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // These are used by images in GLSL. We only support a subset of what GL supports.
56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    enum class Format {
57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kUnspecified = -1,
58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kRGBA32F,
59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kR32F,
60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kRGBA16F,
61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kR16F,
62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kRGBA8,
63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kR8,
64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kRGBA8I,
65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kR8I,
66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // used by SkSL processors
69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    enum Key {
70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // field is not a key
71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kNo_Key,
72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // field is a key
73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kKey_Key,
74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        // key is 0 or 1 depending on whether the matrix is an identity matrix
75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        kIdentity_Key,
76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    };
77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static const char* FormatToStr(Format format) {
79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        switch (format) {
80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case Format::kUnspecified:  return "";
81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case Format::kRGBA32F:      return "rgba32f";
82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case Format::kR32F:         return "r32f";
83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case Format::kRGBA16F:      return "rgba16f";
84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case Format::kR16F:         return "r16f";
85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case Format::kRGBA8:        return "rgba8";
86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case Format::kR8:           return "r8";
87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case Format::kRGBA8I:       return "rgba8i";
88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case Format::kR8I:          return "r8i";
89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        ABORT("Unexpected format");
91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    static bool ReadFormat(String str, Format* format) {
94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (str == "rgba32f") {
95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            *format = Format::kRGBA32F;
96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return true;
97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        } else if (str == "r32f") {
98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            *format = Format::kR32F;
99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return true;
100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        } else if (str == "rgba16f") {
101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            *format = Format::kRGBA16F;
102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return true;
103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        } else if (str == "r16f") {
104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            *format = Format::kR16F;
105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return true;
106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        } else if (str == "rgba8") {
107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            *format = Format::kRGBA8;
108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return true;
109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        } else if (str == "r8") {
110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            *format = Format::kR8;
111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return true;
112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        } else if (str == "rgba8i") {
113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            *format = Format::kRGBA8I;
114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return true;
115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        } else if (str == "r8i") {
116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            *format = Format::kR8I;
117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            return true;
118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return false;
120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Layout(int flags, int location, int offset, int binding, int index, int set, int builtin,
123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot           int inputAttachmentIndex, Format format, Primitive primitive, int maxVertices,
124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot           int invocations, String when, Key key, StringFragment ctype)
125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    : fFlags(flags)
126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    , fLocation(location)
127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    , fOffset(offset)
128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    , fBinding(binding)
129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    , fIndex(index)
130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    , fSet(set)
131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    , fBuiltin(builtin)
132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    , fInputAttachmentIndex(inputAttachmentIndex)
133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    , fFormat(format)
134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    , fPrimitive(primitive)
135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    , fMaxVertices(maxVertices)
136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    , fInvocations(invocations)
137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    , fWhen(when)
138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    , fKey(key)
139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    , fCType(ctype) {}
140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Layout()
142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    : fFlags(0)
143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    , fLocation(-1)
144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    , fOffset(-1)
145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    , fBinding(-1)
146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    , fIndex(-1)
147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    , fSet(-1)
148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    , fBuiltin(-1)
149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    , fInputAttachmentIndex(-1)
150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    , fFormat(Format::kUnspecified)
151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    , fPrimitive(kUnspecified_Primitive)
152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    , fMaxVertices(-1)
153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    , fInvocations(-1)
154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    , fKey(kNo_Key) {}
155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    String description() const {
157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        String result;
158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        String separator;
159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fLocation >= 0) {
160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            result += separator + "location = " + to_string(fLocation);
161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            separator = ", ";
162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fOffset >= 0) {
164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            result += separator + "offset = " + to_string(fOffset);
165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            separator = ", ";
166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fBinding >= 0) {
168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            result += separator + "binding = " + to_string(fBinding);
169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            separator = ", ";
170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fIndex >= 0) {
172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            result += separator + "index = " + to_string(fIndex);
173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            separator = ", ";
174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fSet >= 0) {
176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            result += separator + "set = " + to_string(fSet);
177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            separator = ", ";
178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fBuiltin >= 0) {
180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            result += separator + "builtin = " + to_string(fBuiltin);
181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            separator = ", ";
182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fInputAttachmentIndex >= 0) {
184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            result += separator + "input_attachment_index = " + to_string(fBuiltin);
185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            separator = ", ";
186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (Format::kUnspecified != fFormat) {
188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            result += separator + FormatToStr(fFormat);
189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            separator = ", ";
190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fFlags & kOriginUpperLeft_Flag) {
192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            result += separator + "origin_upper_left";
193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            separator = ", ";
194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fFlags & kOverrideCoverage_Flag) {
196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            result += separator + "override_coverage";
197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            separator = ", ";
198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fFlags & kBlendSupportAllEquations_Flag) {
200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            result += separator + "blend_support_all_equations";
201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            separator = ", ";
202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fFlags & kBlendSupportMultiply_Flag) {
204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            result += separator + "blend_support_multiply";
205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            separator = ", ";
206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fFlags & kBlendSupportScreen_Flag) {
208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            result += separator + "blend_support_screen";
209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            separator = ", ";
210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fFlags & kBlendSupportOverlay_Flag) {
212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            result += separator + "blend_support_overlay";
213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            separator = ", ";
214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fFlags & kBlendSupportDarken_Flag) {
216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            result += separator + "blend_support_darken";
217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            separator = ", ";
218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fFlags & kBlendSupportLighten_Flag) {
220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            result += separator + "blend_support_lighten";
221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            separator = ", ";
222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fFlags & kBlendSupportColorDodge_Flag) {
224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            result += separator + "blend_support_colordodge";
225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            separator = ", ";
226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fFlags & kBlendSupportColorBurn_Flag) {
228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            result += separator + "blend_support_colorburn";
229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            separator = ", ";
230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fFlags & kBlendSupportHardLight_Flag) {
232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            result += separator + "blend_support_hardlight";
233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            separator = ", ";
234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fFlags & kBlendSupportSoftLight_Flag) {
236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            result += separator + "blend_support_softlight";
237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            separator = ", ";
238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fFlags & kBlendSupportDifference_Flag) {
240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            result += separator + "blend_support_difference";
241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            separator = ", ";
242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fFlags & kBlendSupportExclusion_Flag) {
244fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            result += separator + "blend_support_exclusion";
245fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            separator = ", ";
246fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
247fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fFlags & kBlendSupportHSLHue_Flag) {
248fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            result += separator + "blend_support_hsl_hue";
249fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            separator = ", ";
250fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
251fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fFlags & kBlendSupportHSLSaturation_Flag) {
252fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            result += separator + "blend_support_hsl_saturation";
253fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            separator = ", ";
254fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
255fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fFlags & kBlendSupportHSLColor_Flag) {
256fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            result += separator + "blend_support_hsl_color";
257fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            separator = ", ";
258fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
259fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fFlags & kBlendSupportHSLLuminosity_Flag) {
260fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            result += separator + "blend_support_hsl_luminosity";
261fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            separator = ", ";
262fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
263fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fFlags & kPushConstant_Flag) {
264fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            result += separator + "push_constant";
265fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            separator = ", ";
266fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
267fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        switch (fPrimitive) {
268fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case kPoints_Primitive:
269fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                result += separator + "points";
270fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                separator = ", ";
271fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                break;
272fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case kLines_Primitive:
273fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                result += separator + "lines";
274fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                separator = ", ";
275fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                break;
276fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case kLineStrip_Primitive:
277fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                result += separator + "line_strip";
278fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                separator = ", ";
279fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                break;
280fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case kLinesAdjacency_Primitive:
281fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                result += separator + "lines_adjacency";
282fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                separator = ", ";
283fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                break;
284fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case kTriangles_Primitive:
285fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                result += separator + "triangles";
286fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                separator = ", ";
287fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                break;
288fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case kTriangleStrip_Primitive:
289fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                result += separator + "triangle_strip";
290fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                separator = ", ";
291fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                break;
292fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case kTrianglesAdjacency_Primitive:
293fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                result += separator + "triangles_adjacency";
294fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                separator = ", ";
295fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                break;
296fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            case kUnspecified_Primitive:
297fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot                break;
298fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
299fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fMaxVertices >= 0) {
300fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            result += separator + "max_vertices = " + to_string(fMaxVertices);
301fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            separator = ", ";
302fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
303fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fInvocations >= 0) {
304fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            result += separator + "invocations = " + to_string(fInvocations);
305fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            separator = ", ";
306fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
307fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (fWhen.size()) {
308fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            result += separator + "when = " + fWhen;
309fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            separator = ", ";
310fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
311fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        if (result.size() > 0) {
312fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot            result = "layout (" + result + ")";
313fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        }
314fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return result;
315fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
316fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
317fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool operator==(const Layout& other) const {
318fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return fFlags                == other.fFlags &&
319fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot               fLocation             == other.fLocation &&
320fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot               fOffset               == other.fOffset &&
321fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot               fBinding              == other.fBinding &&
322fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot               fIndex                == other.fIndex &&
323fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot               fSet                  == other.fSet &&
324fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot               fBuiltin              == other.fBuiltin &&
325fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot               fInputAttachmentIndex == other.fInputAttachmentIndex &&
326fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot               fFormat               == other.fFormat &&
327fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot               fPrimitive            == other.fPrimitive &&
328fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot               fMaxVertices          == other.fMaxVertices &&
329fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot               fInvocations          == other.fInvocations;
330fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
331fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
332fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    bool operator!=(const Layout& other) const {
333fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot        return !(*this == other);
334fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    }
335fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
336fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int fFlags;
337fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int fLocation;
338fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int fOffset;
339fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int fBinding;
340fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int fIndex;
341fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int fSet;
342fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // builtin comes from SPIR-V and identifies which particular builtin value this object
343fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // represents.
344fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int fBuiltin;
345fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // input_attachment_index comes from Vulkan/SPIR-V to connect a shader variable to the a
346fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    // corresponding attachment on the subpass in which the shader is being used.
347fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int fInputAttachmentIndex;
348fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Format fFormat;
349fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Primitive fPrimitive;
350fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int fMaxVertices;
351fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    int fInvocations;
352fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    String fWhen;
353fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    Key fKey;
354fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot    StringFragment fCType;
355fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot};
356fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
357fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} // namespace
358fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot
359fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif
360