/*
 * Copyright 2021 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "src/gpu/graphite/DrawPass.h"

#include "include/private/SkLog.h"
#include "src/core/SkTraceEvent.h"
#include "src/gpu/graphite/PaintParams.h"
#include "src/gpu/graphite/PaintParamsKey.h"
#include "src/gpu/graphite/PipelineCreationTask.h"
#include "src/gpu/graphite/PipelineData.h"
#include "src/gpu/graphite/PipelineManager.h"
#include "src/gpu/graphite/RenderPassDesc.h"
#include "src/gpu/graphite/Resource.h"  // IWYU pragma: keep
#include "src/gpu/graphite/ResourceProvider.h"
#include "src/gpu/graphite/ResourceTypes.h"
#include "src/gpu/graphite/RuntimeEffectDictionary.h"
#include "src/gpu/graphite/SharedContext.h"
#include "src/gpu/graphite/Texture.h"  // IWYU pragma: keep
#include "src/gpu/graphite/TextureProxy.h"

using namespace skia_private;

namespace skgpu::graphite {

DrawPass::DrawPass(sk_sp<TextureProxy> target,
                   std::pair<LoadOp, StoreOp> ops,
                   std::array<float, 4> clearColor)
        : fTarget(std::move(target))
        , fBounds(SkIRect::MakeEmpty())
        , fOps(ops)
        , fClearColor(clearColor) {}

DrawPass::~DrawPass() = default;

bool DrawPass::prepareResources(ResourceProvider* resourceProvider,
                                sk_sp<const RuntimeEffectDictionary> runtimeDict,
                                const RenderPassDesc& renderPassDesc) {
    TRACE_EVENT0("skia.gpu", TRACE_FUNC);

    SharedContext* sharedContext = resourceProvider->sharedContext();
    PipelineManager* pipelineManager = sharedContext->pipelineManager();

    fPipelineHandles.reserve(fPipelineDescs.size());
    for (const GraphicsPipelineDesc& pipelineDesc : fPipelineDescs) {
        fPipelineHandles.push_back(
                pipelineManager->createHandle(sharedContext,
                                              runtimeDict,
                                              pipelineDesc,
                                              renderPassDesc,
                                              PipelineCreationFlags::kNone));
    }

    // The DrawPass may be long-lived on a Recording and we no longer need the GraphicPipelineDescs
    // once we've created pipeline handles, so we drop the storage for them here.
    fPipelineDescs.clear();

    for (int i = 0; i < fSampledTextures.size(); ++i) {
        // It should not have been possible to draw an Image that has an invalid texture info
        SkASSERT(fSampledTextures[i]->textureInfo().isValid());
        // Tasks should have been ordered to instantiate any scratch textures already, or any
        // client-owned image will have been instantiated at creation. However, if a TextureProxy
        // was cached for reuse across Recordings, it's possible that the initializing Recording
        // failed, leaving the TextureProxy in a bad state (and currently with no way to reconstruct
        // the tasks required to initialize it).
        // TODO(b/409888039): Once TextureProxies track their dependendent tasks to include in all
        // Recordings, this "should" be able to changed to asserts.
        if (!fSampledTextures[i]->isInstantiated() && !fSampledTextures[i]->isLazy()) {
            SKIA_LOG_W("Cannot sample from an uninstantiated TextureProxy, label %s",
                        fSampledTextures[i]->label());
            return false;
        }
    }

    if (fStorageFallbackTexture) {
        SkASSERT(fStorageFallbackTexture->textureInfo().isValid());
        if (!fStorageFallbackTexture->isInstantiated() && !fStorageFallbackTexture->isLazy()) {
            SKIA_LOG_W("Cannot sample from an uninstantiated TextureProxy, label %s",
                        fStorageFallbackTexture->label());
            return false;
        }
    }

    return true;
}

bool DrawPass::addResourceRefs(ResourceProvider* resourceProvider,
                               CommandBuffer* commandBuffer) {
    TRACE_EVENT0_ALWAYS("skia.shaders", "GraphitePipelineUse");

    SharedContext* sharedContext = resourceProvider->sharedContext();
    PipelineManager* pipelineManager = sharedContext->pipelineManager();

    SkASSERT(fPipelineHandles.size() == fPipelineDrawAreas.size());
    for (int i = 0; i < fPipelineHandles.size(); ++i) {
        sk_sp<GraphicsPipeline> pipeline = pipelineManager->resolveHandle(fPipelineHandles[i]);
        if (!pipeline) {
            SKIA_LOG_W("Failed to create Pipeline for draw in RenderPass. Dropping draw!");
            return false;
        }

        fStorageBufferStages |= pipeline->storageBufferStages();

        TRACE_EVENT_INSTANT1_ALWAYS(
                "skia.shaders",
                TRACE_STR_COPY(pipeline->getLabel()),
                TRACE_EVENT_SCOPE_THREAD,
                "area", sk_float_saturate2int(fPipelineDrawAreas[i]));

        commandBuffer->trackResource(std::move(pipeline));
    }

    SkDEBUGCODE(fPipelinesHaveBeenResolved = true;)

    for (int i = 0; i < fSampledTextures.size(); ++i) {
        commandBuffer->trackResource(fSampledTextures[i]->refTexture());
    }

    if (fStorageFallbackTexture) {
        commandBuffer->trackResource(fStorageFallbackTexture->refTexture());
    }

    return true;
}

void DrawPass::setStorageResult(StorageContextResult result) {
    if (std::holds_alternative<BindBufferInfo>(result)) {
        fStorageBufferInfo = std::get<BindBufferInfo>(result);
        SkASSERT(fStorageBufferInfo);
    } else {
        fStorageFallbackTexture = std::move(std::get<sk_sp<TextureProxy>>(result));
        SkASSERT(fStorageFallbackTexture);
    }
}

} // namespace skgpu::graphite
