/*
 * Copyright 2022 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/ComputeTask.h"

#include "include/private/base/SkAssert.h"
#include "src/gpu/graphite/CommandBuffer.h"
#include "src/gpu/graphite/ComputePipeline.h"  // IWYU pragma: keep
#include "src/gpu/graphite/Sampler.h"  // IWYU pragma: keep
#include "src/gpu/graphite/TextureProxy.h"  // IWYU pragma: keep
#include "src/gpu/graphite/compute/DispatchGroup.h"

#include <cstddef>
#include <utility>

namespace skgpu::graphite {

sk_sp<ComputeTask> ComputeTask::Make(DispatchGroupList dispatchGroups) {
    return sk_sp<ComputeTask>(new ComputeTask(std::move(dispatchGroups)));
}

ComputeTask::ComputeTask(DispatchGroupList dispatchGroups)
        : fDispatchGroups(std::move(dispatchGroups)), fChildTasks(fDispatchGroups.size()) {
    for (auto& group : fDispatchGroups) {
        fChildTasks.push_back(group->snapChildTask());
    }
}

ComputeTask::~ComputeTask() = default;

Task::Status ComputeTask::prepareResources(ResourceProvider* provider,
                                           ScratchResourceManager* scratchManager,
                                           sk_sp<const RuntimeEffectDictionary> rtd) {
    for (auto& child : fChildTasks) {
        if (child) {
            Status status = child->prepareResources(provider, scratchManager, rtd);
            if (status == Status::kFail) {
                return Status::kFail;
            } else if (status == Status::kDiscard) {
                child.reset();
            }
        }
    }
    for (const auto& group : fDispatchGroups) {
        // TODO: Allow ComputeTasks to instantiate with scratch textures and return them.
        if (!group->prepareResources(provider)) {
            return Status::kFail;
        }
    }
    return Status::kSuccess;
}

Task::Status ComputeTask::addCommands(Context* ctx,
                                      CommandBuffer* commandBuffer,
                                      ReplayTargetData rtd) {
    if (fDispatchGroups.empty()) {
        return Status::kDiscard;
    }
    SkASSERT(fDispatchGroups.size() == fChildTasks.size());
    const std::unique_ptr<DispatchGroup>* currentSpanPtr = &fDispatchGroups[0];
    size_t currentSpanSize = 0u;
    for (int i = 0; i < fDispatchGroups.size(); ++i) {
        // If the next DispatchGroup has a dependent task, then encode the accumulated span as a
        // compute pass now. CommandBuffer encodes each compute pass with a separate encoder, so
        // the dependent task can use a non-compute encoder if needed.
        Task* child = fChildTasks[i].get();
        if (child) {
            if (currentSpanSize > 0u) {
                if (!commandBuffer->addComputePass({currentSpanPtr, currentSpanSize})) {
                    return Status::kFail;
                }
                currentSpanPtr = &fDispatchGroups[i];
                currentSpanSize = 0u;
            }

            Status status = child->addCommands(ctx, commandBuffer, rtd);
            if (status == Status::kFail) {
                return Status::kFail;
            } else if (status == Status::kDiscard) {
                fChildTasks[i].reset();
            }
        }
        currentSpanSize++;
    }
    return (currentSpanSize == 0u ||
            commandBuffer->addComputePass({currentSpanPtr, currentSpanSize})) ? Status::kSuccess
                                                                              : Status::kFail;
}

}  // namespace skgpu::graphite
