/*
 * Copyright 2016 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#include "GrShaderVar.h"
#include "GrShaderCaps.h"

static const char* type_modifier_string(GrShaderVar::TypeModifier t) {
    switch (t) {
        case GrShaderVar::kNone_TypeModifier: return "";
        case GrShaderVar::kIn_TypeModifier: return "in";
        case GrShaderVar::kInOut_TypeModifier: return "inout";
        case GrShaderVar::kOut_TypeModifier: return "out";
        case GrShaderVar::kUniform_TypeModifier: return "uniform";
    }
    SkFAIL("Unknown shader variable type modifier.");
    return "";
}

void GrShaderVar::setImageStorageFormat(GrImageStorageFormat format) {
    const char* formatStr = nullptr;
    switch (format) {
        case GrImageStorageFormat::kRGBA8:
            formatStr = "rgba8";
            break;
        case GrImageStorageFormat::kRGBA8i:
            formatStr = "rgba8i";
            break;
        case GrImageStorageFormat::kRGBA16f:
            formatStr = "rgba16f";
            break;
        case GrImageStorageFormat::kRGBA32f:
            formatStr = "rgba32f";
            break;
    }
    this->addLayoutQualifier(formatStr);
    SkASSERT(formatStr);
}

void GrShaderVar::setMemoryModel(GrSLMemoryModel model) {
    switch (model) {
        case GrSLMemoryModel::kNone:
            return;
        case GrSLMemoryModel::kCoherent:
            this->addModifier("coherent");
            return;
        case GrSLMemoryModel::kVolatile:
            this->addModifier("volatile");
            return;
    }
    SkFAIL("Unknown memory model.");
}

void GrShaderVar::setRestrict(GrSLRestrict restricted) {
    switch (restricted) {
        case GrSLRestrict::kNo:
            return;
        case GrSLRestrict::kYes:
            this->addModifier("restrict");
            return;
    }
    SkFAIL("Unknown restrict.");
}

void GrShaderVar::setIOType(GrIOType ioType) {
    switch (ioType) {
        case kRW_GrIOType:
            return;
        case kRead_GrIOType:
            this->addModifier("readonly");
            return;
        case kWrite_GrIOType:
            this->addModifier("writeonly");
            return;
    }
    SkFAIL("Unknown io type.");
}

void GrShaderVar::appendDecl(const GrShaderCaps* shaderCaps, SkString* out) const {
    SkASSERT(kDefault_GrSLPrecision == fPrecision || GrSLTypeAcceptsPrecision(fType));
    SkString layout = fLayoutQualifier;
    if (!fLayoutQualifier.isEmpty()) {
        out->appendf("layout(%s) ", fLayoutQualifier.c_str());
    }
    out->append(fExtraModifiers);
    if (this->getTypeModifier() != kNone_TypeModifier) {
        out->append(type_modifier_string(this->getTypeModifier()));
        out->append(" ");
    }
    GrSLType effectiveType = this->getType();
    if (shaderCaps->usesPrecisionModifiers() && GrSLTypeAcceptsPrecision(effectiveType)) {
        // Desktop GLSL has added precision qualifiers but they don't do anything.
        out->appendf("%s ", GrGLSLPrecisionString(fPrecision));
    }
    if (this->isArray()) {
        if (this->isUnsizedArray()) {
            out->appendf("%s %s[]",
                         GrGLSLTypeString(effectiveType),
                         this->getName().c_str());
        } else {
            SkASSERT(this->getArrayCount() > 0);
            out->appendf("%s %s[%d]",
                         GrGLSLTypeString(effectiveType),
                         this->getName().c_str(),
                         this->getArrayCount());
        }
    } else {
        out->appendf("%s %s",
                     GrGLSLTypeString(effectiveType),
                     this->getName().c_str());
    }
}
