//
// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

// Cache.cpp: Implements a cache for various commonly created objects.

#include <limits>

#include "common/angleutils.h"
#include "common/debug.h"
#include "compiler/translator/Cache.h"

namespace sh
{

namespace
{

class TScopedAllocator : angle::NonCopyable
{
  public:
    TScopedAllocator(TPoolAllocator *allocator) : mPreviousAllocator(GetGlobalPoolAllocator())
    {
        SetGlobalPoolAllocator(allocator);
    }
    ~TScopedAllocator() { SetGlobalPoolAllocator(mPreviousAllocator); }

  private:
    TPoolAllocator *mPreviousAllocator;
};

}  // namespace

TCache::TypeKey::TypeKey(TBasicType basicType,
                         TPrecision precision,
                         TQualifier qualifier,
                         unsigned char primarySize,
                         unsigned char secondarySize)
{
    static_assert(sizeof(components) <= sizeof(value), "TypeKey::value is too small");

    const size_t MaxEnumValue = std::numeric_limits<EnumComponentType>::max();

    // TODO: change to static_assert() once we deprecate MSVC 2013 support
    ASSERT(MaxEnumValue >= EbtLast && MaxEnumValue >= EbpLast && MaxEnumValue >= EvqLast &&
           "TypeKey::EnumComponentType is too small");

    value                    = 0;
    components.basicType     = static_cast<EnumComponentType>(basicType);
    components.precision     = static_cast<EnumComponentType>(precision);
    components.qualifier     = static_cast<EnumComponentType>(qualifier);
    components.primarySize   = primarySize;
    components.secondarySize = secondarySize;
}

TCache *TCache::sCache = nullptr;

void TCache::initialize()
{
    if (sCache == nullptr)
    {
        sCache = new TCache();
    }
}

void TCache::destroy()
{
    SafeDelete(sCache);
}

const TType *TCache::getType(TBasicType basicType,
                             TPrecision precision,
                             TQualifier qualifier,
                             unsigned char primarySize,
                             unsigned char secondarySize)
{
    TypeKey key(basicType, precision, qualifier, primarySize, secondarySize);
    auto it = sCache->mTypes.find(key);
    if (it != sCache->mTypes.end())
    {
        return it->second;
    }

    TScopedAllocator scopedAllocator(&sCache->mAllocator);

    TType *type = new TType(basicType, precision, qualifier, primarySize, secondarySize);
    type->realize();
    sCache->mTypes.insert(std::make_pair(key, type));

    return type;
}

}  // namespace sh
