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

#ifndef GrSurfaceInfo_DEFINED
#define GrSurfaceInfo_DEFINED

#include "include/gpu/GrTypes.h"

#ifdef SK_GL
#include "include/private/gpu/ganesh/GrGLTypesPriv.h"
#endif
#ifdef SK_VULKAN
#include "include/private/gpu/ganesh/GrVkTypesPriv.h"
#endif
#ifdef SK_DIRECT3D
#include "include/private/gpu/ganesh/GrD3DTypesMinimal.h"
struct GrD3DSurfaceInfo;
#endif
#ifdef SK_METAL
#include "include/private/gpu/ganesh/GrMtlTypesPriv.h"
#endif
#ifdef SK_DAWN
#include "include/private/gpu/ganesh/GrDawnTypesPriv.h"
#endif
#include "include/private/gpu/ganesh/GrMockTypesPriv.h"

class GrSurfaceInfo {
public:
    GrSurfaceInfo() {}
#ifdef SK_GL
    GrSurfaceInfo(const GrGLSurfaceInfo& glInfo)
            : fBackend(GrBackendApi::kOpenGL)
            , fValid(true)
            , fSampleCount(glInfo.fSampleCount)
            , fLevelCount(glInfo.fLevelCount)
            , fProtected(glInfo.fProtected)
            , fGLSpec(glInfo) {}
#endif
#ifdef SK_VULKAN
    GrSurfaceInfo(const GrVkSurfaceInfo& vkInfo)
            : fBackend(GrBackendApi::kVulkan)
            , fValid(true)
            , fSampleCount(vkInfo.fSampleCount)
            , fLevelCount(vkInfo.fLevelCount)
            , fProtected(vkInfo.fProtected)
            , fVkSpec(vkInfo) {}
#endif
#ifdef SK_DIRECT3D
    GrSurfaceInfo(const GrD3DSurfaceInfo& d3dInfo);
#endif
#ifdef SK_METAL
    GrSurfaceInfo(const GrMtlSurfaceInfo& mtlInfo)
            : fBackend(GrBackendApi::kMetal)
            , fValid(true)
            , fSampleCount(mtlInfo.fSampleCount)
            , fLevelCount(mtlInfo.fLevelCount)
            , fProtected(mtlInfo.fProtected)
            , fMtlSpec(mtlInfo) {}
#endif
#ifdef SK_DAWN
    GrSurfaceInfo(const GrDawnSurfaceInfo& dawnInfo)
            : fBackend(GrBackendApi::kDawn)
            , fValid(true)
            , fSampleCount(dawnInfo.fSampleCount)
            , fLevelCount(dawnInfo.fLevelCount)
            , fProtected(dawnInfo.fProtected)
            , fDawnSpec(dawnInfo) {}
#endif
    GrSurfaceInfo(const GrMockSurfaceInfo& mockInfo)
            : fBackend(GrBackendApi::kMock)
            , fValid(true)
            , fSampleCount(mockInfo.fSampleCount)
            , fLevelCount(mockInfo.fLevelCount)
            , fProtected(mockInfo.fProtected)
            , fMockSpec(mockInfo) {}

    ~GrSurfaceInfo();
    GrSurfaceInfo(const GrSurfaceInfo&) = default;

    bool isValid() const { return fValid; }
    GrBackendApi backend() const { return fBackend; }

    uint32_t numSamples() const { return fSampleCount; }
    uint32_t numMipLevels() const { return fLevelCount; }
    GrProtected isProtected() const { return fProtected; }

#ifdef SK_GL
    bool getGLSurfaceInfo(GrGLSurfaceInfo* info) const {
        if (!this->isValid() || fBackend != GrBackendApi::kOpenGL) {
            return false;
        }
        *info = GrGLTextureSpecToSurfaceInfo(fGLSpec, fSampleCount, fLevelCount, fProtected);
        return true;
    }
#endif
#ifdef SK_VULKAN
    bool getVkSurfaceInfo(GrVkSurfaceInfo* info) const {
        if (!this->isValid() || fBackend != GrBackendApi::kVulkan) {
            return false;
        }
        *info = GrVkImageSpecToSurfaceInfo(fVkSpec, fSampleCount, fLevelCount, fProtected);
        return true;
    }
#endif
#ifdef SK_DIRECT3D
    bool getD3DSurfaceInfo(GrD3DSurfaceInfo*) const;
#endif
#ifdef SK_METAL
    bool getMtlSurfaceInfo(GrMtlSurfaceInfo* info) const {
        if (!this->isValid() || fBackend != GrBackendApi::kMetal) {
            return false;
        }
        *info = GrMtlTextureSpecToSurfaceInfo(fMtlSpec, fSampleCount, fLevelCount, fProtected);
        return true;
    }
#endif
#ifdef SK_DAWN
    bool getDawnSurfaceInfo(GrDawnSurfaceInfo* info) const {
        if (!this->isValid() || fBackend != GrBackendApi::kDawn) {
            return false;
        }
        *info = GrDawnTextureSpecToSurfaceInfo(fDawnSpec, fSampleCount, fLevelCount, fProtected);
        return true;
    }
#endif
    bool getMockSurfaceInfo(GrMockSurfaceInfo* info) const {
        if (!this->isValid() || fBackend != GrBackendApi::kMock) {
            return false;
        }
        *info = GrMockTextureSpecToSurfaceInfo(fMockSpec, fSampleCount, fLevelCount, fProtected);
        return true;
    }

private:
    GrBackendApi fBackend = GrBackendApi::kMock;
    bool fValid = false;

    uint32_t fSampleCount = 1;
    uint32_t fLevelCount = 0;
    GrProtected fProtected = GrProtected::kNo;

    union {
#ifdef SK_GL
        GrGLTextureSpec fGLSpec;
#endif
#ifdef SK_VULKAN
        GrVkImageSpec fVkSpec;
#endif
#ifdef SK_DIRECT3D
        GrD3DTextureResourceSpecHolder fD3DSpec;
#endif
#ifdef SK_METAL
        GrMtlTextureSpec fMtlSpec;
#endif
#ifdef SK_DAWN
        GrDawnTextureSpec fDawnSpec;
#endif
        GrMockTextureSpec fMockSpec;
    };
};

#endif
