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

#include "src/gpu/ganesh/GrRecordingContextPriv.h"

#include "include/core/SkColorSpace.h"
#include "src/gpu/ganesh/GrCaps.h"
#include "src/gpu/ganesh/GrDrawingManager.h"
#include "src/gpu/ganesh/GrProxyProvider.h"
#include "src/gpu/ganesh/GrRenderTargetProxy.h"
#include "src/gpu/ganesh/GrSurfaceProxyView.h"

#if SK_GPU_V1
#include "src/gpu/ganesh/v1/Device_v1.h"
#include "src/gpu/ganesh/v1/SurfaceDrawContext_v1.h"
#include "src/gpu/ganesh/v1/SurfaceFillContext_v1.h"
#endif

void GrRecordingContextPriv::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) {
    this->context()->addOnFlushCallbackObject(onFlushCBObject);
}

sk_sp<skgpu::BaseDevice> GrRecordingContextPriv::createDevice(GrColorType colorType,
                                                              sk_sp<GrSurfaceProxy> proxy,
                                                              sk_sp<SkColorSpace> colorSpace,
                                                              GrSurfaceOrigin origin,
                                                              const SkSurfaceProps& props,
                                                              skgpu::BaseDevice::InitContents init) {
#if SK_GPU_V1
    return skgpu::v1::Device::Make(this->context(), colorType, std::move(proxy),
                                   std::move(colorSpace), origin, props, init);
#else
    return nullptr;
#endif
}

sk_sp<skgpu::BaseDevice> GrRecordingContextPriv::createDevice(SkBudgeted budgeted,
                                                              const SkImageInfo& ii,
                                                              SkBackingFit fit,
                                                              int sampleCount,
                                                              GrMipmapped mipmapped,
                                                              GrProtected isProtected,
                                                              GrSurfaceOrigin origin,
                                                              const SkSurfaceProps& props,
                                                              skgpu::BaseDevice::InitContents init) {
#if SK_GPU_V1
    return skgpu::v1::Device::Make(this->context(), budgeted, ii, fit, sampleCount,
                                   mipmapped, isProtected, origin, props, init);
#else
    return nullptr;
#endif
}

void GrRecordingContextPriv::moveRenderTasksToDDL(SkDeferredDisplayList* ddl) {
    this->context()->drawingManager()->moveRenderTasksToDDL(ddl);
}

GrSDFTControl GrRecordingContextPriv::getSDFTControl(bool useSDFTForSmallText) const {
    return GrSDFTControl{
            this->caps()->shaderCaps()->supportsDistanceFieldText(),
            useSDFTForSmallText,
            this->options().fMinDistanceFieldFontSize,
            this->options().fGlyphsAsPathsFontSize};
}

std::unique_ptr<skgpu::SurfaceContext> GrRecordingContextPriv::makeSC(GrSurfaceProxyView readView,
                                                                      const GrColorInfo& info) {
#if SK_GPU_V1
    // It is probably not necessary to check if the context is abandoned here since uses of the
    // SurfaceContext which need the context will mostly likely fail later on w/o an issue.
    // However having this here adds some reassurance in case there is a path that doesn't
    // handle an abandoned context correctly. It also lets us early out of some extra work.
    if (this->context()->abandoned()) {
        return nullptr;
    }
    GrSurfaceProxy* proxy = readView.proxy();
    SkASSERT(proxy && proxy->asTextureProxy());

    std::unique_ptr<skgpu::SurfaceContext> sc;
    if (proxy->asRenderTargetProxy()) {
        // Will we ever want a swizzle that is not the default write swizzle for the format and
        // colorType here? If so we will need to manually pass that in.
        skgpu::Swizzle writeSwizzle;
        if (info.colorType() != GrColorType::kUnknown) {
            writeSwizzle = this->caps()->getWriteSwizzle(proxy->backendFormat(),
                                                         info.colorType());
        }
        GrSurfaceProxyView writeView(readView.refProxy(), readView.origin(), writeSwizzle);
        if (info.alphaType() == kPremul_SkAlphaType ||
            info.alphaType() == kOpaque_SkAlphaType) {
            sc = std::make_unique<skgpu::v1::SurfaceDrawContext>(this->context(),
                                                                 std::move(readView),
                                                                 std::move(writeView),
                                                                 info.colorType(),
                                                                 info.refColorSpace(),
                                                                 SkSurfaceProps());
        } else {
            sc = std::make_unique<skgpu::v1::SurfaceFillContext>(this->context(),
                                                                 std::move(readView),
                                                                 std::move(writeView),
                                                                 info);
        }
    } else {
        sc = std::make_unique<skgpu::SurfaceContext>(this->context(),
                                                     std::move(readView),
                                                     info);
    }
    SkDEBUGCODE(sc->validate();)
    return sc;
#endif
    return nullptr;
}

std::unique_ptr<skgpu::SurfaceContext> GrRecordingContextPriv::makeSC(const GrImageInfo& info,
                                                                      const GrBackendFormat& format,
                                                                      SkBackingFit fit,
                                                                      GrSurfaceOrigin origin,
                                                                      GrRenderable renderable,
                                                                      int sampleCount,
                                                                      GrMipmapped mipmapped,
                                                                      GrProtected isProtected,
                                                                      SkBudgeted budgeted) {
    SkASSERT(renderable == GrRenderable::kYes || sampleCount == 1);
    if (this->abandoned()) {
        return nullptr;
    }
    sk_sp<GrTextureProxy> proxy = this->proxyProvider()->createProxy(format,
                                                                     info.dimensions(),
                                                                     renderable,
                                                                     sampleCount,
                                                                     mipmapped,
                                                                     fit,
                                                                     budgeted,
                                                                     isProtected);
    if (!proxy) {
        return nullptr;
    }

    skgpu::Swizzle swizzle;
    if (info.colorType() != GrColorType::kUnknown &&
        !this->caps()->isFormatCompressed(format)) {
        swizzle = this->caps()->getReadSwizzle(format, info.colorType());
    }

    GrSurfaceProxyView view(std::move(proxy), origin, swizzle);
    return this->makeSC(std::move(view), info.colorInfo());
}

std::unique_ptr<skgpu::SurfaceFillContext> GrRecordingContextPriv::makeSFC(GrImageInfo info,
                                                                           SkBackingFit fit,
                                                                           int sampleCount,
                                                                           GrMipmapped mipmapped,
                                                                           GrProtected isProtected,
                                                                           GrSurfaceOrigin origin,
                                                                           SkBudgeted budgeted) {

#if SK_GPU_V1
    if (info.alphaType() == kPremul_SkAlphaType || info.alphaType() == kOpaque_SkAlphaType) {
        return skgpu::v1::SurfaceDrawContext::Make(this->context(),
                                                   info.colorType(),
                                                   info.refColorSpace(),
                                                   fit,
                                                   info.dimensions(),
                                                   SkSurfaceProps(),
                                                   sampleCount,
                                                   mipmapped,
                                                   isProtected,
                                                   origin,
                                                   budgeted);
    }
    GrBackendFormat format = this->caps()->getDefaultBackendFormat(info.colorType(),
                                                                   GrRenderable::kYes);
    sk_sp<GrTextureProxy> proxy = this->proxyProvider()->createProxy(format,
                                                                     info.dimensions(),
                                                                     GrRenderable::kYes,
                                                                     sampleCount,
                                                                     mipmapped,
                                                                     fit,
                                                                     budgeted,
                                                                     isProtected);
    if (!proxy) {
        return nullptr;
    }
    skgpu::Swizzle readSwizzle  = this->caps()->getReadSwizzle (format, info.colorType());
    skgpu::Swizzle writeSwizzle = this->caps()->getWriteSwizzle(format, info.colorType());

    GrSurfaceProxyView readView(            proxy, origin,  readSwizzle);
    GrSurfaceProxyView writeView(std::move(proxy), origin, writeSwizzle);
    std::unique_ptr<skgpu::SurfaceFillContext> sfc;
    sfc = std::make_unique<skgpu::v1::SurfaceFillContext>(this->context(),
                                                          std::move(readView),
                                                          std::move(writeView),
                                                          info.colorInfo());
    sfc->discard();
    return sfc;
#endif

    return nullptr;
}

std::unique_ptr<skgpu::SurfaceFillContext> GrRecordingContextPriv::makeSFC(
        SkAlphaType alphaType,
        sk_sp<SkColorSpace> colorSpace,
        SkISize dimensions,
        SkBackingFit fit,
        const GrBackendFormat& format,
        int sampleCount,
        GrMipmapped mipmapped,
        GrProtected isProtected,
        skgpu::Swizzle readSwizzle,
        skgpu::Swizzle writeSwizzle,
        GrSurfaceOrigin origin,
        SkBudgeted budgeted) {

#if SK_GPU_V1
    SkASSERT(!dimensions.isEmpty());
    SkASSERT(sampleCount >= 1);
    SkASSERT(format.isValid() && format.backend() == fContext->backend());
    if (alphaType == kPremul_SkAlphaType || alphaType == kOpaque_SkAlphaType) {
        return skgpu::v1::SurfaceDrawContext::Make(this->context(),
                                                   std::move(colorSpace),
                                                   fit,
                                                   dimensions,
                                                   format,
                                                   sampleCount,
                                                   mipmapped,
                                                   isProtected,
                                                   readSwizzle,
                                                   writeSwizzle,
                                                   origin,
                                                   budgeted,
                                                   SkSurfaceProps());
    }

    sk_sp<GrTextureProxy> proxy = this->proxyProvider()->createProxy(format,
                                                                     dimensions,
                                                                     GrRenderable::kYes,
                                                                     sampleCount,
                                                                     mipmapped,
                                                                     fit,
                                                                     budgeted,
                                                                     isProtected);
    if (!proxy) {
        return nullptr;
    }
    GrImageInfo info(GrColorType::kUnknown, alphaType, std::move(colorSpace), dimensions);
    GrSurfaceProxyView readView(            proxy, origin,  readSwizzle);
    GrSurfaceProxyView writeView(std::move(proxy), origin, writeSwizzle);
    std::unique_ptr<skgpu::SurfaceFillContext> sfc;
    sfc = std::make_unique<skgpu::v1::SurfaceFillContext>(this->context(),
                                                          std::move(readView),
                                                          std::move(writeView),
                                                          info.colorInfo());
    sfc->discard();
    return sfc;
#endif

    return nullptr;
}

std::unique_ptr<skgpu::SurfaceFillContext> GrRecordingContextPriv::makeSFCWithFallback(
        GrImageInfo info,
        SkBackingFit fit,
        int sampleCount,
        GrMipmapped mipmapped,
        GrProtected isProtected,
        GrSurfaceOrigin origin,
        SkBudgeted budgeted) {

#if SK_GPU_V1
    if (info.alphaType() == kPremul_SkAlphaType || info.alphaType() == kOpaque_SkAlphaType) {
        return skgpu::v1::SurfaceDrawContext::MakeWithFallback(this->context(),
                                                               info.colorType(),
                                                               info.refColorSpace(),
                                                               fit,
                                                               info.dimensions(),
                                                               SkSurfaceProps(),
                                                               sampleCount,
                                                               mipmapped,
                                                               isProtected,
                                                               origin,
                                                               budgeted);
    }
    const GrCaps* caps = this->caps();

    auto [ct, _] = caps->getFallbackColorTypeAndFormat(info.colorType(), sampleCount);
    if (ct == GrColorType::kUnknown) {
        return nullptr;
    }
    info = info.makeColorType(ct);
    return this->makeSFC(info,
                         fit,
                         sampleCount,
                         mipmapped,
                         isProtected,
                         origin,
                         budgeted);
#endif

    return nullptr;
}

std::unique_ptr<skgpu::SurfaceFillContext> GrRecordingContextPriv::makeSFCFromBackendTexture(
        GrColorInfo info,
        const GrBackendTexture& tex,
        int sampleCount,
        GrSurfaceOrigin origin,
        sk_sp<skgpu::RefCntedCallback> releaseHelper) {

#if SK_GPU_V1
    SkASSERT(sampleCount > 0);

    if (info.alphaType() == kPremul_SkAlphaType || info.alphaType() == kOpaque_SkAlphaType) {
        return skgpu::v1::SurfaceDrawContext::MakeFromBackendTexture(this->context(),
                                                                     info.colorType(),
                                                                     info.refColorSpace(),
                                                                     tex,
                                                                     sampleCount,
                                                                     origin,
                                                                     SkSurfaceProps(),
                                                                     std::move(releaseHelper));
    }

    if (info.colorType() == GrColorType::kUnknown) {
        return nullptr;
    }

    const GrBackendFormat& format = tex.getBackendFormat();
    if (!this->caps()->areColorTypeAndFormatCompatible(info.colorType(), format)) {
        return nullptr;
    }
    skgpu::Swizzle readSwizzle  = this->caps()->getReadSwizzle (format, info.colorType());
    skgpu::Swizzle writeSwizzle = this->caps()->getWriteSwizzle(format, info.colorType());

    sk_sp<GrTextureProxy> proxy(this->proxyProvider()->wrapRenderableBackendTexture(
            tex, sampleCount, kBorrow_GrWrapOwnership, GrWrapCacheable::kNo,
            std::move(releaseHelper)));
    if (!proxy) {
        return nullptr;
    }

    GrSurfaceProxyView readView(            proxy, origin,  readSwizzle);
    GrSurfaceProxyView writeView(std::move(proxy), origin, writeSwizzle);

    return std::make_unique<skgpu::v1::SurfaceFillContext>(this->context(),
                                                           std::move(readView),
                                                           std::move(writeView),
                                                           std::move(info));
#endif

    return nullptr;
}
