/*
 * 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/task/CopyTask.h"

#include "include/private/base/SkAssert.h"
#include "src/gpu/graphite/Buffer.h"
#include "src/gpu/graphite/CommandBuffer.h"
#include "src/gpu/graphite/Log.h"
#include "src/gpu/graphite/Texture.h"  // IWYU pragma: keep
#include "src/gpu/graphite/TextureInfoPriv.h"
#include "src/gpu/graphite/TextureProxy.h"

#include <utility>

namespace skgpu::graphite {

sk_sp<CopyBufferToBufferTask> CopyBufferToBufferTask::Make(const Buffer* srcBuffer,
                                                           size_t srcOffset,
                                                           sk_sp<Buffer> dstBuffer,
                                                           size_t dstOffset,
                                                           size_t size) {
    SkASSERT(srcBuffer);
    SkASSERT(size <= srcBuffer->size() - srcOffset);
    SkASSERT(dstBuffer);
    SkASSERT(size <= dstBuffer->size() - dstOffset);
    return sk_sp<CopyBufferToBufferTask>(new CopyBufferToBufferTask(srcBuffer,
                                                                    srcOffset,
                                                                    std::move(dstBuffer),
                                                                    dstOffset,
                                                                    size));
}

CopyBufferToBufferTask::CopyBufferToBufferTask(const Buffer* srcBuffer,
                                               size_t srcOffset,
                                               sk_sp<Buffer> dstBuffer,
                                               size_t dstOffset,
                                               size_t size)
        : fSrcBuffer(srcBuffer)
        , fSrcOffset(srcOffset)
        , fDstBuffer(std::move(dstBuffer))
        , fDstOffset(dstOffset)
        , fSize(size) {}

CopyBufferToBufferTask::~CopyBufferToBufferTask() = default;

Task::Status CopyBufferToBufferTask::prepareResources(ResourceProvider*,
                                                      ScratchResourceManager*,
                                                      sk_sp<const RuntimeEffectDictionary>) {
    return Status::kSuccess;
}

Task::Status CopyBufferToBufferTask::addCommands(Context*,
                                                 CommandBuffer* commandBuffer,
                                                 ReplayTargetData) {
    if (commandBuffer->copyBufferToBuffer(fSrcBuffer, fSrcOffset, fDstBuffer, fDstOffset, fSize)) {
        return Status::kSuccess;
    } else {
        return Status::kFail;
    }
}

sk_sp<CopyTextureToBufferTask> CopyTextureToBufferTask::Make(sk_sp<TextureProxy> textureProxy,
                                                             SkIRect srcRect,
                                                             sk_sp<Buffer> buffer,
                                                             size_t bufferOffset,
                                                             size_t bufferRowBytes) {
    if (!textureProxy) {
        return nullptr;
    }
    return sk_sp<CopyTextureToBufferTask>(new CopyTextureToBufferTask(std::move(textureProxy),
                                                                      srcRect,
                                                                      std::move(buffer),
                                                                      bufferOffset,
                                                                      bufferRowBytes));
}

CopyTextureToBufferTask::CopyTextureToBufferTask(sk_sp<TextureProxy> textureProxy,
                                                 SkIRect srcRect,
                                                 sk_sp<Buffer> buffer,
                                                 size_t bufferOffset,
                                                 size_t bufferRowBytes)
        : fTextureProxy(std::move(textureProxy))
        , fSrcRect(srcRect)
        , fBuffer(std::move(buffer))
        , fBufferOffset(bufferOffset)
        , fBufferRowBytes(bufferRowBytes) {
}

CopyTextureToBufferTask::~CopyTextureToBufferTask() {}

Task::Status CopyTextureToBufferTask::prepareResources(ResourceProvider* resourceProvider,
                                                       ScratchResourceManager*,
                                                       sk_sp<const RuntimeEffectDictionary>) {
    // If the source texture hasn't been instantiated yet, it means there was no prior task that
    // could have initialized its contents so a readback to a buffer does not make sense.
    SkASSERT(fTextureProxy->isInstantiated() || fTextureProxy->isLazy());
    // TODO: The copy is also a consumer of the source, so it should participate in returning
    // scratch resources like RenderPassTask does. For now, though, all copy tasks side step reuse
    // entirely and they cannot participate until they've been moved into scoping tasks like
    // DrawTask first.
    return Status::kSuccess;
}

Task::Status CopyTextureToBufferTask::addCommands(Context*,
                                                  CommandBuffer* commandBuffer,
                                                  ReplayTargetData) {
    if (commandBuffer->copyTextureToBuffer(fTextureProxy->refTexture(),
                                           fSrcRect,
                                           std::move(fBuffer),
                                           fBufferOffset,
                                           fBufferRowBytes)) {
        // TODO(b/332681367): CopyTextureToBuffer is currently only used for readback operations,
        // which are a one-time event. Should this just default to returning kDiscard?
        return Status::kSuccess;
    } else {
        return Status::kFail;
    }
}

//--------------------------------------------------------------------------------------------------

sk_sp<CopyTextureToTextureTask> CopyTextureToTextureTask::Make(sk_sp<TextureProxy> srcProxy,
                                                               SkIRect srcRect,
                                                               sk_sp<TextureProxy> dstProxy,
                                                               SkIPoint dstPoint,
                                                               int dstLevel) {
    if (!srcProxy || !dstProxy) {
        return nullptr;
    }
    // Texture-to-texture copies do not do format conversions
    TextureFormat srcFormat = TextureInfoPriv::ViewFormat(srcProxy->textureInfo());
    TextureFormat dstFormat = TextureInfoPriv::ViewFormat(dstProxy->textureInfo());
    if (srcFormat != dstFormat) {
        SKGPU_LOG_E("Unable to copy between textures of different formats, src = %s, dst = %s",
                    TextureFormatName(srcFormat), TextureFormatName(dstFormat));
        return nullptr;
    }
    return sk_sp<CopyTextureToTextureTask>(new CopyTextureToTextureTask(std::move(srcProxy),
                                                                        srcRect,
                                                                        std::move(dstProxy),
                                                                        dstPoint,
                                                                        dstLevel));
}

CopyTextureToTextureTask::CopyTextureToTextureTask(sk_sp<TextureProxy> srcProxy,
                                                   SkIRect srcRect,
                                                   sk_sp<TextureProxy> dstProxy,
                                                   SkIPoint dstPoint,
                                                   int dstLevel)
        : fSrcProxy(std::move(srcProxy))
        , fSrcRect(srcRect)
        , fDstProxy(std::move(dstProxy))
        , fDstPoint(dstPoint)
        , fDstLevel(dstLevel) {}

CopyTextureToTextureTask::~CopyTextureToTextureTask() {}

Task::Status CopyTextureToTextureTask::prepareResources(ResourceProvider* resourceProvider,
                                                        ScratchResourceManager*,
                                                        sk_sp<const RuntimeEffectDictionary>) {
    // Do not instantiate the src proxy. If the source texture hasn't been instantiated yet, it
    // means there was no prior task that could have initialized its contents so propagating the
    // undefined contents to the dst does not make sense.
    // TODO(b/333729316): Assert that fSrcProxy is instantiated or lazy; right now it may not be
    // instantatiated if this is a dst readback copy for a scratch Device. In that case, a
    // RenderPassTask will immediately follow this copy task and instantiate the source proxy so
    // that addCommands() has a texture to operate on. That said, the texture's contents will be
    // undefined when the copy is executed ideally it just shouldn't happen.

    // TODO: The copy is also a consumer of the source, so it should participate in returning
    // scratch resources like RenderPassTask does. For now, though, all copy tasks side step reuse
    // entirely and they cannot participate until they've been moved into scoping tasks like
    // DrawTask first. In particular, for texture-to-texture copies, they should be scoped to not
    // invoke pending listeners for a subsequent RenderPassTask.

    // TODO: Use the scratch resource manager to instantiate fDstProxy, although the details of when
    // that texture can be returned need to be worked out. While brittle, all current use cases
    // of scratch texture-to-texture copies have the dst used immediately by the next task, so it
    // could just add a pending listener that returns the texture w/o any read counting.
    if (!TextureProxy::InstantiateIfNotLazy(resourceProvider, fDstProxy.get())) {
        SKGPU_LOG_E("Could not instantiate dst texture proxy for CopyTextureToTextureTask!");
        return Status::kFail;
    }
    return Status::kSuccess;
}

Task::Status CopyTextureToTextureTask::addCommands(Context*,
                                                   CommandBuffer* commandBuffer,
                                                   ReplayTargetData) {
    // prepareResources() doesn't instantiate the source assuming that a prior task will have do so
    // as part of initializing the texture contents.
    SkASSERT(fSrcProxy->isInstantiated());
    if (commandBuffer->copyTextureToTexture(fSrcProxy->refTexture(),
                                            fSrcRect,
                                            fDstProxy->refTexture(),
                                            fDstPoint,
                                            fDstLevel)) {
        // TODO(b/332681367): The calling context should be able to specify whether or not this copy
        // is a repeatable operation (e.g. dst readback copy for blending) or one time (e.g. client
        // asked for a copy of an image or surface).
        return Status::kSuccess;
    } else {
        return Status::kFail;
    }
}

} // namespace skgpu::graphite
