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

#include "GrBackendSurface.h"

#ifdef SK_VULKAN
#include "vk/GrVkTypes.h"
#include "vk/GrVkUtil.h"
#endif

#ifdef SK_VULKAN
GrBackendTexture::GrBackendTexture(int width,
                                   int height,
                                   const GrVkImageInfo& vkInfo)
        : fWidth(width)
        , fHeight(height)
        , fConfig(GrVkFormatToPixelConfig(vkInfo.fFormat))
        , fBackend(kVulkan_GrBackend)
        , fVkInfo(vkInfo) {}
#endif

GrBackendTexture::GrBackendTexture(int width,
                                   int height,
                                   GrPixelConfig config,
                                   const GrGLTextureInfo& glInfo)
        : fWidth(width)
        , fHeight(height)
        , fConfig(config)
        , fBackend(kOpenGL_GrBackend)
        , fGLInfo(glInfo) {}

GrBackendTexture::GrBackendTexture(int width,
                                   int height,
                                   GrPixelConfig config,
                                   const GrMockTextureInfo& mockInfo)
        : fWidth(width)
        , fHeight(height)
        , fConfig(config)
        , fBackend(kMock_GrBackend)
        , fMockInfo(mockInfo) {}

GrBackendTexture::GrBackendTexture(const GrBackendTextureDesc& desc, GrBackend backend)
        : fWidth(desc.fWidth)
        , fHeight(desc.fHeight)
        , fConfig(desc.fConfig)
        , fBackend(backend) {
    switch (backend) {
        case kOpenGL_GrBackend:
            fGLInfo = *reinterpret_cast<const GrGLTextureInfo*>(desc.fTextureHandle);
            break;
#ifdef SK_VULKAN
        case kVulkan_GrBackend: {
            const GrVkImageInfo* vkInfo =
                    reinterpret_cast<const GrVkImageInfo*>(desc.fTextureHandle);
            fConfig = GrVkFormatToPixelConfig(vkInfo->fFormat);
            fVkInfo = *vkInfo;
            break;
        }
#endif
        case kMock_GrBackend:
            fMockInfo = *reinterpret_cast<const GrMockTextureInfo*>(desc.fTextureHandle);
            break;
        default:
            fConfig = kUnknown_GrPixelConfig;
            break;
    }
}

#ifdef SK_VULKAN
const GrVkImageInfo* GrBackendTexture::getVkImageInfo() const {
    if (this->isValid() && kVulkan_GrBackend == fBackend) {
        return &fVkInfo;
    }
    return nullptr;
}
#endif

const GrGLTextureInfo* GrBackendTexture::getGLTextureInfo() const {
    if (this->isValid() && kOpenGL_GrBackend == fBackend) {
        return &fGLInfo;
    }
    return nullptr;
}

const GrMockTextureInfo* GrBackendTexture::getMockTextureInfo() const {
    if (this->isValid() && kMock_GrBackend == fBackend) {
        return &fMockInfo;
    }
    return nullptr;
}

////////////////////////////////////////////////////////////////////////////////////////////////////

#ifdef SK_VULKAN
GrBackendRenderTarget::GrBackendRenderTarget(int width,
                                             int height,
                                             int sampleCnt,
                                             int stencilBits,
                                             const GrVkImageInfo& vkInfo)
        : fWidth(width)
        , fHeight(height)
        , fSampleCnt(sampleCnt)
        , fStencilBits(stencilBits)
        , fConfig(GrVkFormatToPixelConfig(vkInfo.fFormat))
        , fBackend(kVulkan_GrBackend)
        , fVkInfo(vkInfo) {}
#endif

GrBackendRenderTarget::GrBackendRenderTarget(int width,
                                             int height,
                                             int sampleCnt,
                                             int stencilBits,
                                             GrPixelConfig config,
                                             const GrGLFramebufferInfo& glInfo)
        : fWidth(width)
        , fHeight(height)
        , fSampleCnt(sampleCnt)
        , fStencilBits(stencilBits)
        , fConfig(config)
        , fBackend(kOpenGL_GrBackend)
        , fGLInfo(glInfo) {}

GrBackendRenderTarget::GrBackendRenderTarget(const GrBackendRenderTargetDesc& desc,
                                             GrBackend backend)
        : fWidth(desc.fWidth)
        , fHeight(desc.fHeight)
        , fSampleCnt(desc.fSampleCnt)
        , fStencilBits(desc.fStencilBits)
        , fConfig(desc.fConfig)
        , fBackend(backend) {
    if (kOpenGL_GrBackend == backend) {
        fGLInfo.fFBOID = static_cast<GrGLuint>(desc.fRenderTargetHandle);
    } else {
        SkASSERT(kVulkan_GrBackend == backend);
#ifdef SK_VULKAN
        const GrVkImageInfo* vkInfo =
                reinterpret_cast<const GrVkImageInfo*>(desc.fRenderTargetHandle);
        fConfig = GrVkFormatToPixelConfig(vkInfo->fFormat);
        fVkInfo = *vkInfo;
#else
        fConfig = kUnknown_GrPixelConfig;
#endif
    }
}

#ifdef SK_VULKAN
const GrVkImageInfo* GrBackendRenderTarget::getVkImageInfo() const {
    if (kVulkan_GrBackend == fBackend) {
        return &fVkInfo;
    }
    return nullptr;
}
#endif

const GrGLFramebufferInfo* GrBackendRenderTarget::getGLFramebufferInfo() const {
    if (kOpenGL_GrBackend == fBackend) {
        return &fGLInfo;
    }
    return nullptr;
}

