1b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas/*
2b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas * Copyright 2016 Google Inc.
3b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas *
4b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas * Use of this source code is governed by a BSD-style license that can be
5b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas * found in the LICENSE file.
6b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas */
7b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas
8b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas#ifndef SKSL_INTERFACEBLOCK
9b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas#define SKSL_INTERFACEBLOCK
10b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas
11b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas#include "SkSLProgramElement.h"
126b20a559968e1ed0d3aa4ecbd6ddda9e681b4f86Hal Canary#include "SkSLSymbolTable.h"
1322f939e849013b7fc51374c289b5bf37e63dfdb1ethannicholas#include "SkSLVarDeclarations.h"
14b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas
15b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholasnamespace SkSL {
16b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas
17b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas/**
18b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas * An interface block, as in:
19b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas *
20b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas * out gl_PerVertex {
21b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas *   layout(builtin=0) vec4 gl_Position;
22b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas *   layout(builtin=1) float gl_PointSize;
23b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas * };
24b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas *
25b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas * At the IR level, this is represented by a single variable of struct type.
26b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas */
27b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholasstruct InterfaceBlock : public ProgramElement {
2850afc1765511a8d4850fe97aacf8714b609bfd5aEthan Nicholas    InterfaceBlock(Position position, const Variable& var, SkString typeName, SkString instanceName,
2950afc1765511a8d4850fe97aacf8714b609bfd5aEthan Nicholas                   std::vector<std::unique_ptr<Expression>> sizes,
3050afc1765511a8d4850fe97aacf8714b609bfd5aEthan Nicholas                   std::shared_ptr<SymbolTable> typeOwner)
3150afc1765511a8d4850fe97aacf8714b609bfd5aEthan Nicholas    : INHERITED(position, kInterfaceBlock_Kind)
32d598f7981f34811e6f2a949207dc13638852f3f7ethannicholas    , fVariable(std::move(var))
3350afc1765511a8d4850fe97aacf8714b609bfd5aEthan Nicholas    , fTypeName(std::move(typeName))
3450afc1765511a8d4850fe97aacf8714b609bfd5aEthan Nicholas    , fInstanceName(std::move(instanceName))
3550afc1765511a8d4850fe97aacf8714b609bfd5aEthan Nicholas    , fSizes(std::move(sizes))
3650afc1765511a8d4850fe97aacf8714b609bfd5aEthan Nicholas    , fTypeOwner(typeOwner) {}
37b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas
389e1138d56665d13641f8805cd72ae81adc255f79Ethan Nicholas    SkString description() const override {
3950afc1765511a8d4850fe97aacf8714b609bfd5aEthan Nicholas        SkString result = fVariable.fModifiers.description() + fTypeName + " {\n";
4050afc1765511a8d4850fe97aacf8714b609bfd5aEthan Nicholas        const Type* structType = &fVariable.fType;
4150afc1765511a8d4850fe97aacf8714b609bfd5aEthan Nicholas        while (structType->kind() == Type::kArray_Kind) {
4250afc1765511a8d4850fe97aacf8714b609bfd5aEthan Nicholas            structType = &structType->componentType();
4350afc1765511a8d4850fe97aacf8714b609bfd5aEthan Nicholas        }
4450afc1765511a8d4850fe97aacf8714b609bfd5aEthan Nicholas        for (const auto& f : structType->fields()) {
4550afc1765511a8d4850fe97aacf8714b609bfd5aEthan Nicholas            result += f.description() + "\n";
4650afc1765511a8d4850fe97aacf8714b609bfd5aEthan Nicholas        }
4750afc1765511a8d4850fe97aacf8714b609bfd5aEthan Nicholas        result += "}";
4850afc1765511a8d4850fe97aacf8714b609bfd5aEthan Nicholas        if (fInstanceName.size()) {
4950afc1765511a8d4850fe97aacf8714b609bfd5aEthan Nicholas            result += " " + fInstanceName;
5050afc1765511a8d4850fe97aacf8714b609bfd5aEthan Nicholas            for (const auto& size : fSizes) {
5150afc1765511a8d4850fe97aacf8714b609bfd5aEthan Nicholas                result += "[";
5250afc1765511a8d4850fe97aacf8714b609bfd5aEthan Nicholas                if (size) {
5350afc1765511a8d4850fe97aacf8714b609bfd5aEthan Nicholas                    result += size->description();
5450afc1765511a8d4850fe97aacf8714b609bfd5aEthan Nicholas                }
5550afc1765511a8d4850fe97aacf8714b609bfd5aEthan Nicholas                result += "]";
5650afc1765511a8d4850fe97aacf8714b609bfd5aEthan Nicholas            }
57b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas        }
5850afc1765511a8d4850fe97aacf8714b609bfd5aEthan Nicholas        return result + ";";
59b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas    }
60b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas
61d598f7981f34811e6f2a949207dc13638852f3f7ethannicholas    const Variable& fVariable;
6250afc1765511a8d4850fe97aacf8714b609bfd5aEthan Nicholas    const SkString fTypeName;
6350afc1765511a8d4850fe97aacf8714b609bfd5aEthan Nicholas    const SkString fInstanceName;
6450afc1765511a8d4850fe97aacf8714b609bfd5aEthan Nicholas    const std::vector<std::unique_ptr<Expression>> fSizes;
65d598f7981f34811e6f2a949207dc13638852f3f7ethannicholas    const std::shared_ptr<SymbolTable> fTypeOwner;
66b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas
67b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas    typedef ProgramElement INHERITED;
68b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas};
69b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas
70b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas} // namespace
71b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas
72b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas#endif
73