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 */
70df1b04db87c3d86ee0b0bd6aa2cb5b6be32cac2Ethan Nicholas
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 *
20bed683addbd2f31da05dc19f24f3257bee30ee8cEthan Nicholas * out sk_PerVertex {
21bed683addbd2f31da05dc19f24f3257bee30ee8cEthan Nicholas *   layout(builtin=0) float4 sk_Position;
22bed683addbd2f31da05dc19f24f3257bee30ee8cEthan Nicholas *   layout(builtin=1) float sk_PointSize;
23b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas * };
24b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas *
25b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas * At the IR level, this is represented by a single variable of struct type.
26b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas */
27b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholasstruct InterfaceBlock : public ProgramElement {
285b5f096a038259b8d9084834f877588a0db80250Ethan Nicholas    InterfaceBlock(int offset, const Variable* var, String typeName, String instanceName,
2950afc1765511a8d4850fe97aacf8714b609bfd5aEthan Nicholas                   std::vector<std::unique_ptr<Expression>> sizes,
3050afc1765511a8d4850fe97aacf8714b609bfd5aEthan Nicholas                   std::shared_ptr<SymbolTable> typeOwner)
315b5f096a038259b8d9084834f877588a0db80250Ethan Nicholas    : INHERITED(offset, kInterfaceBlock_Kind)
328feeff929e57ea63914213f3b14d8f00b287a0adEthan Nicholas    , fVariable(*var)
3350afc1765511a8d4850fe97aacf8714b609bfd5aEthan Nicholas    , fTypeName(std::move(typeName))
3450afc1765511a8d4850fe97aacf8714b609bfd5aEthan Nicholas    , fInstanceName(std::move(instanceName))
3550afc1765511a8d4850fe97aacf8714b609bfd5aEthan Nicholas    , fSizes(std::move(sizes))
3650afc1765511a8d4850fe97aacf8714b609bfd5aEthan Nicholas    , fTypeOwner(typeOwner) {}
37b3058bdb1049ca75d526eb9f11e1a42a49e63585ethannicholas
380df1b04db87c3d86ee0b0bd6aa2cb5b6be32cac2Ethan Nicholas    String description() const override {
390df1b04db87c3d86ee0b0bd6aa2cb5b6be32cac2Ethan Nicholas        String 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;
620df1b04db87c3d86ee0b0bd6aa2cb5b6be32cac2Ethan Nicholas    const String fTypeName;
630df1b04db87c3d86ee0b0bd6aa2cb5b6be32cac2Ethan Nicholas    const String fInstanceName;
64b6ba82ca0a5848afc81633cb1139e4c4807932c9Ethan Nicholas    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