/*
 * 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 "include/gpu/graphite/Recording.h"

#include "include/core/SkRect.h"
#include "include/core/SkSize.h"
#include "include/gpu/GpuTypes.h"
#include "include/gpu/graphite/GraphiteTypes.h"
#include "include/gpu/graphite/TextureInfo.h"
#include "include/private/base/SkAssert.h"
#include "include/private/base/SkPoint_impl.h"
#include "include/private/base/SkTo.h"
#include "src/core/SkChecksum.h"
#include "src/gpu/RefCntedCallback.h"
#include "src/gpu/graphite/CommandBuffer.h"
#include "src/gpu/graphite/Log.h"
#include "src/gpu/graphite/RecordingPriv.h"
#include "src/gpu/graphite/Resource.h"
#include "src/gpu/graphite/RuntimeEffectDictionary.h"
#include "src/gpu/graphite/Surface_Graphite.h"
#include "src/gpu/graphite/Texture.h"
#include "src/gpu/graphite/TextureProxy.h"
#include "src/gpu/graphite/task/Task.h"
#include "src/gpu/graphite/task/TaskList.h"

#include <functional>
#include <unordered_map>
#include <unordered_set>
#include <utility>

namespace skgpu::graphite { class Context; }

using namespace skia_private;

namespace skgpu::graphite {

Recording::Recording(uint32_t uniqueID,
                     uint32_t recorderID,
                     std::unique_ptr<LazyProxyData> targetProxyData,
                     TArray<sk_sp<RefCntedCallback>>&& finishedProcs)
        : fUniqueID(uniqueID)
        , fRecorderID(recorderID)
        , fRootTaskList(new TaskList)
        , fTargetProxyData(std::move(targetProxyData))
        , fFinishedProcs(std::move(finishedProcs)) {}

Recording::~Recording() {
    // Any finished procs that haven't been passed to a CommandBuffer fail
    this->priv().setFailureResultForFinishedProcs();
}

std::size_t Recording::ProxyHash::operator()(const sk_sp<TextureProxy> &proxy) const {
    return SkGoodHash()(proxy.get());
}

Recording::LazyProxyData::LazyProxyData(const Caps* caps,
                                        SkISize dimensions,
                                        const TextureInfo& textureInfo) {
    auto onInstantiate = [this](ResourceProvider*) {
        SkASSERT(SkToBool(fTarget));
        return std::move(fTarget);
    };

    // If the texture info specifies that mipmapping is required, that implies that the final
    // surface used to instantiate this proxy will be mipmapped, and that the dimensions of that
    // surface are known already.
    fTargetProxy = textureInfo.mipmapped() == Mipmapped::kYes
                           ? TextureProxy::MakeLazy(caps,
                                                    dimensions,
                                                    textureInfo,
                                                    skgpu::Budgeted::kNo,
                                                    Volatile::kYes,
                                                    std::move(onInstantiate))
                           : TextureProxy::MakeFullyLazy(textureInfo,
                                                         skgpu::Budgeted::kNo,
                                                         Volatile::kYes,
                                                         std::move(onInstantiate));
}

Recording::LazyProxyData::~LazyProxyData() = default;

TextureProxy* Recording::LazyProxyData::lazyProxy() { return fTargetProxy.get(); }

sk_sp<TextureProxy> Recording::LazyProxyData::refLazyProxy() { return fTargetProxy; }

bool Recording::LazyProxyData::lazyInstantiate(ResourceProvider* resourceProvider,
                                               sk_sp<Texture> texture) {
    fTarget = std::move(texture);
    return fTargetProxy->lazyInstantiate(resourceProvider);
}

////////////////////////////////////////////////////////////////////////////////
bool RecordingPriv::hasNonVolatileLazyProxies() const {
    return !fRecording->fNonVolatileLazyProxies.empty();
}

bool RecordingPriv::instantiateNonVolatileLazyProxies(ResourceProvider* resourceProvider) {
    SkASSERT(this->hasNonVolatileLazyProxies());

    for (const auto& proxy : fRecording->fNonVolatileLazyProxies) {
        if (!proxy->lazyInstantiate(resourceProvider)) {
            return false;
        }
    }

    // Note: once all the lazy proxies have been instantiated, that's it - there are no more
    // chances to instantiate.
    fRecording->fNonVolatileLazyProxies.clear();
    return true;
}

bool RecordingPriv::hasVolatileLazyProxies() const {
    return !fRecording->fVolatileLazyProxies.empty();
}

bool RecordingPriv::instantiateVolatileLazyProxies(ResourceProvider* resourceProvider) {
    SkASSERT(this->hasVolatileLazyProxies());

    for (const auto& proxy : fRecording->fVolatileLazyProxies) {
        if (!proxy->lazyInstantiate(resourceProvider)) {
            return false;
        }
    }

    return true;
}

void RecordingPriv::deinstantiateVolatileLazyProxies() {
    if (!this->hasVolatileLazyProxies()) {
        return;
    }

    for (const auto& proxy : fRecording->fVolatileLazyProxies) {
        SkASSERT(proxy->isVolatile());
        proxy->deinstantiate();
    }
}

void RecordingPriv::setFailureResultForFinishedProcs() {
    for (int i = 0; i < fRecording->fFinishedProcs.size(); ++i) {
        fRecording->fFinishedProcs[i]->setFailureResult();
    }
    fRecording->fFinishedProcs.clear();
}

TextureProxy* RecordingPriv::deferredTargetProxy() {
    return fRecording->fTargetProxyData ? fRecording->fTargetProxyData->lazyProxy() : nullptr;
}

const Texture* RecordingPriv::setupDeferredTarget(ResourceProvider* resourceProvider,
                                                  Surface* targetSurface,
                                                  SkIVector targetTranslation,
                                                  SkIRect targetClip) {
    SkASSERT(targetSurface && fRecording->fTargetProxyData);

    TextureProxy* surfaceTexture = targetSurface->target().proxy();
    SkASSERT(surfaceTexture->isInstantiated());

    const TextureProxy* targetProxy = fRecording->fTargetProxyData->lazyProxy();
    if (surfaceTexture->mipmapped() != targetProxy->mipmapped()) {
        SKGPU_LOG_E("Deferred canvas mipmap settings don't match instantiating target's.");
        return nullptr;
    }

    // If the deferred canvas's texture proxy is not fully lazy, that means we used it for draws
    // that require specific dimensions and no translation. The only time this happens is when a
    // client requests a mipmapped deferred canvas and we automatically insert commands to
    // regenerate mipmaps.
    if (!targetProxy->isFullyLazy()) {
        SkASSERT(targetProxy->mipmapped() == skgpu::Mipmapped::kYes);
        if (targetProxy->dimensions() != surfaceTexture->dimensions()) {
            SKGPU_LOG_E(
                    "Deferred canvas dimensions don't match instantiating target's dimensions.");
            return nullptr;
        }
        if (!targetTranslation.isZero()) {
            SKGPU_LOG_E(
                    "Replay translation is not allowed when replaying draws to a mipmapped "
                    "deferred canvas.");
            return nullptr;
        }
        if (!targetClip.isEmpty()) {
            SKGPU_LOG_E(
                    "Replay clip is not allowed when replaying draws to a mipmapped deferred "
                    "canvas.");
            return nullptr;
        }
    }

    if (!fRecording->fTargetProxyData->lazyInstantiate(resourceProvider,
                                                       surfaceTexture->refTexture())) {
        SKGPU_LOG_E("Could not instantiate deferred texture proxy.");
        return nullptr;
    }
    return surfaceTexture->texture();
}

bool RecordingPriv::prepareResources(ResourceProvider* resourceProvider,
                                     ScratchResourceManager* scratchManager,
                                     sk_sp<const RuntimeEffectDictionary> rteDict) {
    Task::Status status = fRecording->fRootTaskList->prepareResources(
            resourceProvider, scratchManager, rteDict);
    if (status == Task::Status::kSuccess) {
        fRecording->fRootTaskList->visitProxies([&](const TextureProxy* proxy) {
            if (proxy->isLazy()) {
                if (proxy->isVolatile()) {
                    fRecording->fVolatileLazyProxies.insert(sk_ref_sp(proxy));
                } else {
                    fRecording->fNonVolatileLazyProxies.insert(sk_ref_sp(proxy));
                }
            }
            return true;
        }, /*readsOnly=*/false);
    }

    return status != Task::Status::kFail;
}

bool RecordingPriv::addCommands(Context* context,
                                CommandBuffer* commandBuffer,
                                const Texture* replayTarget,
                                SkIVector targetTranslation,
                                SkIRect targetClip) {
    for (size_t i = 0; i < fRecording->fExtraResourceRefs.size(); ++i) {
        commandBuffer->trackResource(fRecording->fExtraResourceRefs[i]);
    }

    // There's no need to differentiate kSuccess and kDiscard at the root list level; if every task
    // is discarded, the Recording will automatically be a no-op on replay while still correctly
    // notifying any finish procs the client may have added.
    if (fRecording->fRootTaskList->addCommands(
                context, commandBuffer, {replayTarget, targetTranslation, targetClip}) ==
        Task::Status::kFail) {
        return false;
    }
    for (int i = 0; i < fRecording->fFinishedProcs.size(); ++i) {
        commandBuffer->addFinishedProc(std::move(fRecording->fFinishedProcs[i]));
    }
    fRecording->fFinishedProcs.clear();

    return true;
}

void RecordingPriv::addResourceRef(sk_sp<Resource> resource) {
    fRecording->fExtraResourceRefs.push_back(std::move(resource));
}

#if defined(GPU_TEST_UTILS)
bool RecordingPriv::isTargetProxyInstantiated() const {
    return fRecording->fTargetProxyData->lazyProxy()->isInstantiated();
}

int RecordingPriv::numVolatilePromiseImages() const {
    return fRecording->fVolatileLazyProxies.size();
}

int RecordingPriv::numNonVolatilePromiseImages() const {
    return fRecording->fNonVolatileLazyProxies.size();
}

bool RecordingPriv::hasTasks() const {
    return fRecording->fRootTaskList->hasTasks();
}
#endif

} // namespace skgpu::graphite
