//
// Copyright 2019 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.
//
// mtl_format_utils.h:
//      Declares Format conversion utilities classes that convert from angle formats
//      to respective MTLPixelFormat and MTLVertexFormat.
//

#ifndef LIBANGLE_RENDERER_METAL_MTL_FORMAT_UTILS_H_
#define LIBANGLE_RENDERER_METAL_MTL_FORMAT_UTILS_H_

#import <Metal/Metal.h>

#include <unordered_map>

#include "common/angleutils.h"
#include "libANGLE/Caps.h"
#include "libANGLE/formatutils.h"
#include "libANGLE/renderer/copyvertex.h"
#include "libANGLE/renderer/renderer_utils.h"

namespace rx
{
class DisplayMtl;

namespace mtl
{
class ContextDevice;

LoadFunctionMap GetLoadFunctionsMap(GLenum internalFormat, angle::FormatID angleFormat);

struct FormatBase
{
    inline bool operator==(const FormatBase &rhs) const
    {
        return intendedFormatId == rhs.intendedFormatId && actualFormatId == rhs.actualFormatId;
    }

    inline bool operator!=(const FormatBase &rhs) const { return !((*this) == rhs); }

    const angle::Format &actualAngleFormat() const;
    const angle::Format &intendedAngleFormat() const;

    angle::FormatID actualFormatId   = angle::FormatID::NONE;
    angle::FormatID intendedFormatId = angle::FormatID::NONE;
};

struct FormatCaps
{
    bool isRenderable() const { return colorRenderable || depthRenderable; }

    bool filterable           = false;
    bool writable             = false;
    bool colorRenderable      = false;
    bool depthRenderable      = false;
    bool blendable            = false;
    bool multisample          = false;  // can be used as MSAA target
    bool resolve              = false;  // Can be used as resolve target
    bool compressed           = false;
    NSUInteger pixelBytes     = 0;
    NSUInteger pixelBytesMSAA = 0;
    NSUInteger channels       = 0;
    uint8_t alignment         = 0;
};

// Pixel format
struct Format : public FormatBase
{
    Format() = default;

    static angle::FormatID MetalToAngleFormatID(MTLPixelFormat formatMtl);

    const gl::InternalFormat &intendedInternalFormat() const;
    const gl::InternalFormat &actualInternalFormat() const;

    bool valid() const { return metalFormat != MTLPixelFormatInvalid; }
    bool hasDepthAndStencilBits() const
    {
        return actualAngleFormat().depthBits && actualAngleFormat().stencilBits;
    }
    bool hasDepthOrStencilBits() const
    {
        return actualAngleFormat().depthBits || actualAngleFormat().stencilBits;
    }
    bool isPVRTC() const;

    const FormatCaps &getCaps() const { return *caps; }

    // Need conversion between source format and this format?
    bool needConversion(angle::FormatID srcFormatId) const;

    MTLPixelFormat metalFormat = MTLPixelFormatInvalid;

    LoadFunctionMap textureLoadFunctions       = nullptr;
    InitializeTextureDataFunction initFunction = nullptr;

    const FormatCaps *caps = nullptr;

    bool swizzled = false;
    std::array<GLenum, 4> swizzle;

  private:
    void init(const DisplayMtl *display, angle::FormatID intendedFormatId);

    friend class FormatTable;
};

// Vertex format
struct VertexFormat : public FormatBase
{
    VertexFormat() = default;

    MTLVertexFormat metalFormat = MTLVertexFormatInvalid;

    VertexCopyFunction vertexLoadFunction = nullptr;

    uint32_t defaultAlpha = 0;
    // Intended and actual format have same GL type, and possibly only differ in number of
    // components?
    bool actualSameGLType = true;

  private:
    void init(angle::FormatID angleFormatId, bool tightlyPacked = false);

    friend class FormatTable;
};

class FormatTable final : angle::NonCopyable
{
  public:
    FormatTable()  = default;
    ~FormatTable() = default;

    angle::Result initialize(const DisplayMtl *display);

    void generateTextureCaps(const DisplayMtl *display,
                             gl::TextureCapsMap *capsMapOut,
                             std::vector<GLenum> *compressedFormatsOut);

    const Format &getPixelFormat(angle::FormatID angleFormatId) const;
    const FormatCaps &getNativeFormatCaps(MTLPixelFormat mtlFormat) const;

    // tightlyPacked means this format will be used in a tightly packed vertex buffer.
    // In that case, it's easier to just convert everything to float to ensure
    // Metal alignment requirements between 2 elements inside the buffer will be met regardless
    // of how many components each element has.
    const VertexFormat &getVertexFormat(angle::FormatID angleFormatId, bool tightlyPacked) const;

    uint32_t getMaxSamples() const { return mMaxSamples; }

  private:
    void initNativeFormatCapsAutogen(const DisplayMtl *display);
    void initNativeFormatCaps(const DisplayMtl *display);

    void setFormatCaps(MTLPixelFormat formatId,
                       bool filterable,
                       bool writable,
                       bool blendable,
                       bool multisample,
                       bool resolve,
                       bool colorRenderable);

    void setFormatCaps(MTLPixelFormat formatId,
                       bool filterable,
                       bool writable,
                       bool blendable,
                       bool multisample,
                       bool resolve,
                       bool colorRenderable,
                       NSUInteger bytesPerChannel,
                       NSUInteger channels);

    void setFormatCaps(MTLPixelFormat formatId,
                       bool filterable,
                       bool writable,
                       bool blendable,
                       bool multisample,
                       bool resolve,
                       bool colorRenderable,
                       bool depthRenderable);

    void setFormatCaps(MTLPixelFormat formatId,
                       bool filterable,
                       bool writable,
                       bool blendable,
                       bool multisample,
                       bool resolve,
                       bool colorRenderable,
                       bool depthRenderable,
                       NSUInteger bytesPerChannel,
                       NSUInteger channels);

    void setCompressedFormatCaps(MTLPixelFormat formatId, bool filterable);

    void adjustFormatCapsForDevice(const mtl::ContextDevice &device,
                                   MTLPixelFormat id,
                                   bool supportsiOS2,
                                   bool supportsiOS4);

    std::array<Format, angle::kNumANGLEFormats> mPixelFormatTable;
    angle::HashMap<MTLPixelFormat, FormatCaps> mNativePixelFormatCapsTable;
    // One for tightly packed buffers, one for general cases.
    std::array<VertexFormat, angle::kNumANGLEFormats> mVertexFormatTables[2];

    uint32_t mMaxSamples;
};

}  // namespace mtl
}  // namespace rx

#endif /* LIBANGLE_RENDERER_METAL_MTL_FORMAT_UTILS_H_ */
