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

#ifndef GrBackendSurface_DEFINED
#define GrBackendSurface_DEFINED

#include "include/core/SkRefCnt.h"
#include "include/core/SkSize.h"
#include "include/gpu/GpuTypes.h"
#include "include/gpu/GrTypes.h"
#include "include/gpu/mock/GrMockTypes.h"
#include "include/private/base/SkAPI.h"
#include "include/private/base/SkAnySubclass.h"
#include "include/private/base/SkDebug.h"
#include "include/private/gpu/ganesh/GrTypesPriv.h"

enum class SkTextureCompressionType;
class GrBackendFormatData;
class GrBackendTextureData;
class GrBackendRenderTargetData;

namespace skgpu {
class MutableTextureState;
}

#ifdef SK_DIRECT3D
#include "include/private/gpu/ganesh/GrD3DTypesMinimal.h"
class GrD3DResourceState;
#endif

#if defined(SK_DEBUG) || defined(GR_TEST_UTILS)
class SkString;
#endif

#include <cstddef>
#include <cstdint>
#include <string>
#include <string_view>

class SK_API GrBackendFormat {
public:
    // Creates an invalid backend format.
    GrBackendFormat();
    GrBackendFormat(const GrBackendFormat&);
    GrBackendFormat& operator=(const GrBackendFormat&);
    ~GrBackendFormat();

#ifdef SK_DIRECT3D
    static GrBackendFormat MakeDxgi(DXGI_FORMAT format) {
        return GrBackendFormat(format);
    }
#endif

    static GrBackendFormat MakeMock(GrColorType colorType,
                                    SkTextureCompressionType compression,
                                    bool isStencilFormat = false);

    bool operator==(const GrBackendFormat& that) const;
    bool operator!=(const GrBackendFormat& that) const { return !(*this == that); }

    GrBackendApi backend() const { return fBackend; }
    GrTextureType textureType() const { return fTextureType; }

    /**
     * Gets the channels present in the format as a bitfield of SkColorChannelFlag values.
     * Luminance channels are reported as kGray_SkColorChannelFlag.
     */
    uint32_t channelMask() const;

    GrColorFormatDesc desc() const;

#ifdef SK_DIRECT3D
    /**
     * If the backend API is Direct3D this gets the format as a DXGI_FORMAT and returns true.
     * Otherwise, returns false.
     */
    bool asDxgiFormat(DXGI_FORMAT*) const;
#endif

    /**
     * If the backend API is not Mock these three calls will return kUnknown, kNone or false,
     * respectively. Otherwise, only one of the following can be true. The GrColorType is not
     * kUnknown, the compression type is not kNone, or this is a mock stencil format.
     */
    GrColorType asMockColorType() const;
    SkTextureCompressionType asMockCompressionType() const;
    bool isMockStencilFormat() const;

    // If possible, copies the GrBackendFormat and forces the texture type to be Texture2D. If the
    // GrBackendFormat was for Vulkan and it originally had a GrVkYcbcrConversionInfo, we will
    // remove the conversion and set the format to be VK_FORMAT_R8G8B8A8_UNORM.
    GrBackendFormat makeTexture2D() const;

    // Returns true if the backend format has been initialized.
    bool isValid() const { return fValid; }

#if defined(SK_DEBUG) || defined(GR_TEST_UTILS)
    SkString toStr() const;
#endif

private:
    // Size determined by looking at the GrBackendFormatData subclasses, then guessing-and-checking.
    // Compiler will complain if this is too small - in that case, just increase the number.
    inline constexpr static size_t kMaxSubclassSize = 80;
    using AnyFormatData = SkAnySubclass<GrBackendFormatData, kMaxSubclassSize>;

    friend class GrBackendSurfacePriv;
    friend class GrBackendFormatData;

    // Used by internal factories. Should not be used externally. Use factories like
    // GrBackendFormats::MakeGL instead.
    template <typename FormatData>
    GrBackendFormat(GrTextureType textureType, GrBackendApi api, const FormatData& formatData)
            : fBackend(api), fValid(true), fTextureType(textureType) {
        fFormatData.emplace<FormatData>(formatData);
    }

#ifdef SK_DIRECT3D
    GrBackendFormat(DXGI_FORMAT dxgiFormat);
#endif

    GrBackendFormat(GrColorType, SkTextureCompressionType, bool isStencilFormat);

#ifdef SK_DEBUG
    bool validateMock() const;
#endif

    GrBackendApi fBackend = GrBackendApi::kMock;
    bool fValid = false;
    AnyFormatData fFormatData;

    union {
#ifdef SK_DIRECT3D
        DXGI_FORMAT fDxgiFormat;
#endif
        struct {
            GrColorType fColorType;
            SkTextureCompressionType fCompressionType;
            bool fIsStencilFormat;
        } fMock;
    };
    GrTextureType fTextureType = GrTextureType::kNone;
};

class SK_API GrBackendTexture {
public:
    // Creates an invalid backend texture.
    GrBackendTexture();

#ifdef SK_DIRECT3D
    GrBackendTexture(int width,
                     int height,
                     const GrD3DTextureResourceInfo& d3dInfo,
                     std::string_view label = {});
#endif

    GrBackendTexture(int width,
                     int height,
                     skgpu::Mipmapped,
                     const GrMockTextureInfo& mockInfo,
                     std::string_view label = {});

    GrBackendTexture(const GrBackendTexture& that);

    ~GrBackendTexture();

    GrBackendTexture& operator=(const GrBackendTexture& that);

    SkISize dimensions() const { return {fWidth, fHeight}; }
    int width() const { return fWidth; }
    int height() const { return fHeight; }
    std::string_view getLabel() const { return fLabel; }
    skgpu::Mipmapped mipmapped() const { return fMipmapped; }
    bool hasMipmaps() const { return fMipmapped == skgpu::Mipmapped::kYes; }
    GrBackendApi backend() const {return fBackend; }
    GrTextureType textureType() const { return fTextureType; }

#ifdef SK_DIRECT3D
    // If the backend API is Direct3D, copies a snapshot of the GrD3DTextureResourceInfo struct into
    // the passed in pointer and returns true. This snapshot will set the fResourceState to the
    // current resource state. Otherwise returns false if the backend API is not D3D.
    bool getD3DTextureResourceInfo(GrD3DTextureResourceInfo*) const;

    // Anytime the client changes the D3D12_RESOURCE_STATES of the D3D12_RESOURCE captured by this
    // GrBackendTexture, they must call this function to notify Skia of the changed layout.
    void setD3DResourceState(GrD3DResourceStateEnum);
#endif

    // Get the GrBackendFormat for this texture (or an invalid format if this is not valid).
    GrBackendFormat getBackendFormat() const;

    // If the backend API is Mock, copies a snapshot of the GrMockTextureInfo struct into the passed
    // in pointer and returns true. Otherwise returns false if the backend API is not Mock.
    bool getMockTextureInfo(GrMockTextureInfo*) const;

    // If the client changes any of the mutable backend of the GrBackendTexture they should call
    // this function to inform Skia that those values have changed. The backend API specific state
    // that can be set from this function are:
    //
    // Vulkan: VkImageLayout and QueueFamilyIndex
    void setMutableState(const skgpu::MutableTextureState&);

    // Returns true if we are working with protected content.
    bool isProtected() const;

    // Returns true if the backend texture has been initialized.
    bool isValid() const { return fIsValid; }

    // Returns true if both textures are valid and refer to the same API texture.
    bool isSameTexture(const GrBackendTexture&);

#if defined(GR_TEST_UTILS)
    static bool TestingOnly_Equals(const GrBackendTexture&, const GrBackendTexture&);
#endif

private:
    // Size determined by looking at the GrBackendTextureData subclasses, then guessing-and-checking.
    // Compiler will complain if this is too small - in that case, just increase the number.
    inline constexpr static size_t kMaxSubclassSize = 176;
    using AnyTextureData = SkAnySubclass<GrBackendTextureData, kMaxSubclassSize>;

    friend class GrBackendSurfacePriv;
    friend class GrBackendTextureData;

    // Used by internal factories. Should not be used externally. Use factories like
    // GrBackendTextures::MakeGL instead.
    template <typename TextureData>
    GrBackendTexture(int width,
                     int height,
                     std::string_view label,
                     skgpu::Mipmapped mipped,
                     GrBackendApi backend,
                     GrTextureType texture,
                     const TextureData& textureData)
            : fIsValid(true)
            , fWidth(width)
            , fHeight(height)
            , fLabel(label)
            , fMipmapped(mipped)
            , fBackend(backend)
            , fTextureType(texture) {
        fTextureData.emplace<TextureData>(textureData);
    }

    friend class GrVkGpu;  // for getMutableState
    sk_sp<skgpu::MutableTextureState> getMutableState() const;

#ifdef SK_DIRECT3D
    friend class GrD3DTexture;
    friend class GrD3DGpu;     // for getGrD3DResourceState
    GrBackendTexture(int width,
                     int height,
                     const GrD3DTextureResourceInfo& vkInfo,
                     sk_sp<GrD3DResourceState> state,
                     std::string_view label = {});
    sk_sp<GrD3DResourceState> getGrD3DResourceState() const;
#endif

    // Free and release and resources being held by the GrBackendTexture.
    void cleanup();

    bool fIsValid;
    int fWidth;         //<! width in pixels
    int fHeight;        //<! height in pixels
    const std::string fLabel;
    skgpu::Mipmapped fMipmapped;
    GrBackendApi fBackend;
    GrTextureType fTextureType;
    AnyTextureData fTextureData;

    union {
        GrMockTextureInfo fMockInfo;
#ifdef SK_DIRECT3D
        GrD3DBackendSurfaceInfo fD3DInfo;
#endif
    };
};

class SK_API GrBackendRenderTarget {
public:
    // Creates an invalid backend texture.
    GrBackendRenderTarget();

#ifdef SK_DIRECT3D
    GrBackendRenderTarget(int width,
                          int height,
                          const GrD3DTextureResourceInfo& d3dInfo);
#endif

    GrBackendRenderTarget(int width,
                          int height,
                          int sampleCnt,
                          int stencilBits,
                          const GrMockRenderTargetInfo& mockInfo);

    ~GrBackendRenderTarget();

    GrBackendRenderTarget(const GrBackendRenderTarget& that);
    GrBackendRenderTarget& operator=(const GrBackendRenderTarget&);

    SkISize dimensions() const { return {fWidth, fHeight}; }
    int width() const { return fWidth; }
    int height() const { return fHeight; }
    int sampleCnt() const { return fSampleCnt; }
    int stencilBits() const { return fStencilBits; }
    GrBackendApi backend() const {return fBackend; }
    bool isFramebufferOnly() const { return fFramebufferOnly; }

#ifdef SK_DIRECT3D
    // If the backend API is Direct3D, copies a snapshot of the GrMtlTextureInfo struct into the
    // passed in pointer and returns true. Otherwise returns false if the backend API is not D3D.
    bool getD3DTextureResourceInfo(GrD3DTextureResourceInfo*) const;

    // Anytime the client changes the D3D12_RESOURCE_STATES of the D3D12_RESOURCE captured by this
    // GrBackendTexture, they must call this function to notify Skia of the changed layout.
    void setD3DResourceState(GrD3DResourceStateEnum);
#endif

    // Get the GrBackendFormat for this render target (or an invalid format if this is not valid).
    GrBackendFormat getBackendFormat() const;

    // If the backend API is Mock, copies a snapshot of the GrMockTextureInfo struct into the passed
    // in pointer and returns true. Otherwise returns false if the backend API is not Mock.
    bool getMockRenderTargetInfo(GrMockRenderTargetInfo*) const;

    // If the client changes any of the mutable backend of the GrBackendTexture they should call
    // this function to inform Skia that those values have changed. The backend API specific state
    // that can be set from this function are:
    //
    // Vulkan: VkImageLayout and QueueFamilyIndex
    void setMutableState(const skgpu::MutableTextureState&);

    // Returns true if we are working with protected content.
    bool isProtected() const;

    // Returns true if the backend texture has been initialized.
    bool isValid() const { return fIsValid; }

#if defined(GR_TEST_UTILS)
    static bool TestingOnly_Equals(const GrBackendRenderTarget&, const GrBackendRenderTarget&);
#endif

private:
    // Size determined by looking at the GrBackendRenderTargetData subclasses, then
    // guessing-and-checking. Compiler will complain if this is too small - in that case, just
    // increase the number.
    inline constexpr static size_t kMaxSubclassSize = 176;
    using AnyRenderTargetData = SkAnySubclass<GrBackendRenderTargetData, kMaxSubclassSize>;

    friend class GrBackendSurfacePriv;
    friend class GrBackendRenderTargetData;

    // Used by internal factories. Should not be used externally. Use factories like
    // GrBackendRenderTargets::MakeGL instead.
    template <typename RenderTargetData>
    GrBackendRenderTarget(int width,
                          int height,
                          int sampleCnt,
                          int stencilBits,
                          GrBackendApi backend,
                          bool framebufferOnly,
                          const RenderTargetData& rtData)
            : fIsValid(true)
            , fFramebufferOnly(framebufferOnly)
            , fWidth(width)
            , fHeight(height)
            , fSampleCnt(sampleCnt)
            , fStencilBits(stencilBits)
            , fBackend(backend) {
        fRTData.emplace<RenderTargetData>(rtData);
    }

    friend class GrVkGpu; // for getMutableState
    sk_sp<skgpu::MutableTextureState> getMutableState() const;

#ifdef SK_DIRECT3D
    friend class GrD3DGpu;
    friend class GrD3DRenderTarget;
    GrBackendRenderTarget(int width,
                          int height,
                          const GrD3DTextureResourceInfo& d3dInfo,
                          sk_sp<GrD3DResourceState> state);
    sk_sp<GrD3DResourceState> getGrD3DResourceState() const;
#endif

    // Free and release and resources being held by the GrBackendTexture.
    void cleanup();

    bool fIsValid;
    bool fFramebufferOnly = false;
    int fWidth;         //<! width in pixels
    int fHeight;        //<! height in pixels

    int fSampleCnt;
    int fStencilBits;

    GrBackendApi fBackend;
    AnyRenderTargetData fRTData;

    union {
        GrMockRenderTargetInfo fMockInfo;
#ifdef SK_DIRECT3D
        GrD3DBackendSurfaceInfo fD3DInfo;
#endif
    };
};

#endif
