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

#include "ir/SkSLType.h"

namespace SkSL {

class MemoryLayout {
public:
    enum Standard {
        k140_Standard,
        k430_Standard
    };

    MemoryLayout(Standard std) 
    : fStd(std) {}

    static size_t vector_alignment(size_t componentSize, int columns) {
        return componentSize * (columns + columns % 2);
    }

    /** 
     * Rounds up to the nearest multiple of 16 if in std140, otherwise returns the parameter
     * unchanged (std140 requires various things to be rounded up to the nearest multiple of 16,
     * std430 does not).
     */
    size_t roundUpIfNeeded(size_t raw) const {
        switch (fStd) {
            case k140_Standard: return (raw + 15) & ~15;
            case k430_Standard: return raw;
        }
        ABORT("unreachable");
    }

    /**
     * Returns a type's required alignment when used as a standalone variable.
     */
    size_t alignment(const Type& type) const {
        // See OpenGL Spec 7.6.2.2 Standard Uniform Block Layout
        switch (type.kind()) {
            case Type::kScalar_Kind:
                return this->size(type);
            case Type::kVector_Kind:
                return vector_alignment(this->size(type.componentType()), type.columns());
            case Type::kMatrix_Kind:
                return this->roundUpIfNeeded(vector_alignment(this->size(type.componentType()), 
                                                              type.rows()));
            case Type::kArray_Kind:
                return this->roundUpIfNeeded(this->alignment(type.componentType()));
            case Type::kStruct_Kind: {
                size_t result = 0;
                for (const auto& f : type.fields()) {
                    size_t alignment = this->alignment(*f.fType);
                    if (alignment > result) {
                        result = alignment;
                    }
                }
                return this->roundUpIfNeeded(result);
            }
            default:
                ABORT(("cannot determine size of type " + type.name()).c_str());
        }
    }

    /**
     * For matrices and arrays, returns the number of bytes from the start of one entry (row, in
     * the case of matrices) to the start of the next.
     */
    size_t stride(const Type& type) const {
        switch (type.kind()) {
            case Type::kMatrix_Kind: // fall through
            case Type::kArray_Kind:
                return this->alignment(type);
            default:
                ABORT("type does not have a stride");
        }
    }

    /**
     * Returns the size of a type in bytes.
     */
    size_t size(const Type& type) const {
        switch (type.kind()) {
            case Type::kScalar_Kind:
                if (type.name() == "bool") {
                    return 1;
                }
                // FIXME need to take precision into account, once we figure out how we want to
                // handle it...
                return 4;
            case Type::kVector_Kind:
                return type.columns() * this->size(type.componentType());
            case Type::kMatrix_Kind: // fall through
            case Type::kArray_Kind:
                return type.columns() * this->stride(type);
            case Type::kStruct_Kind: {
                size_t total = 0;
                for (const auto& f : type.fields()) {
                    size_t alignment = this->alignment(*f.fType);
                    if (total % alignment != 0) {
                        total += alignment - total % alignment;
                    }
                    ASSERT(total % alignment == 0);
                    total += this->size(*f.fType);
                }
                size_t alignment = this->alignment(type);
                ASSERT(!type.fields().size() || 
                       (0 == alignment % this->alignment(*type.fields()[0].fType)));
                return (total + alignment - 1) & ~(alignment - 1);
            }
            default:
                ABORT(("cannot determine size of type " + type.name()).c_str());
        }
    }

    const Standard fStd;
};

} // namespace

#endif
