/*
 * Copyright 2019 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/mtl/GrMtlCommandBuffer.h"

#include "src/core/SkTraceEvent.h"
#include "src/gpu/ganesh/mtl/GrMtlGpu.h"
#include "src/gpu/ganesh/mtl/GrMtlOpsRenderPass.h"
#include "src/gpu/ganesh/mtl/GrMtlPipelineState.h"
#include "src/gpu/ganesh/mtl/GrMtlRenderCommandEncoder.h"
#include "src/gpu/ganesh/mtl/GrMtlSemaphore.h"
#include "src/gpu/mtl/MtlUtilsPriv.h"

#if !__has_feature(objc_arc)
#error This file must be compiled with Arc. Use -fobjc-arc flag
#endif

GR_NORETAIN_BEGIN

sk_sp<GrMtlCommandBuffer> GrMtlCommandBuffer::Make(id<MTLCommandQueue> queue) {
#ifdef SK_BUILD_FOR_IOS
    if (skgpu::MtlIsAppInBackground()) {
        NSLog(@"GrMtlCommandBuffer: WARNING: Creating MTLCommandBuffer while in background.");
    }
#endif
    id<MTLCommandBuffer> mtlCommandBuffer;
#if GR_METAL_SDK_VERSION >= 230
    if (@available(macOS 11.0, iOS 14.0, *)) {
        MTLCommandBufferDescriptor* desc = [[MTLCommandBufferDescriptor alloc] init];
        desc.errorOptions = MTLCommandBufferErrorOptionEncoderExecutionStatus;
        mtlCommandBuffer = [queue commandBufferWithDescriptor:desc];
    } else {
        mtlCommandBuffer = [queue commandBuffer];
    }
#else
    mtlCommandBuffer = [queue commandBuffer];
#endif
    if (nil == mtlCommandBuffer) {
        return nullptr;
    }

#ifdef SK_ENABLE_MTL_DEBUG_INFO
    mtlCommandBuffer.label = @"GrMtlCommandBuffer::Make";
#endif

    return sk_sp<GrMtlCommandBuffer>(new GrMtlCommandBuffer(mtlCommandBuffer));
}

GrMtlCommandBuffer::~GrMtlCommandBuffer() {
    this->endAllEncoding();
    this->releaseResources();
    this->callFinishedCallbacks();

    fCmdBuffer = nil;
}

void GrMtlCommandBuffer::releaseResources() {
    TRACE_EVENT0("skia.gpu", TRACE_FUNC);

    fTrackedResources.clear();
    fTrackedGrBuffers.clear();
    fTrackedGrSurfaces.clear();
}

id<MTLBlitCommandEncoder> GrMtlCommandBuffer::getBlitCommandEncoder() {
    if (fActiveBlitCommandEncoder) {
        return fActiveBlitCommandEncoder;
    }

    this->endAllEncoding();
    if (fCmdBuffer.status != MTLCommandBufferStatusNotEnqueued) {
        NSLog(@"GrMtlCommandBuffer: tried to create MTLBlitCommandEncoder while in invalid state.");
        return nullptr;
    }
#ifdef SK_BUILD_FOR_IOS
    if (skgpu::MtlIsAppInBackground()) {
        fActiveBlitCommandEncoder = nil;
        NSLog(@"GrMtlCommandBuffer: tried to create MTLBlitCommandEncoder while in background.");
        return nil;
    }
#endif
    fActiveBlitCommandEncoder = [fCmdBuffer blitCommandEncoder];
    fHasWork = true;

    return fActiveBlitCommandEncoder;
}

static bool compatible(const MTLRenderPassAttachmentDescriptor* first,
                       const MTLRenderPassAttachmentDescriptor* second,
                       const GrMtlPipelineState* pipelineState) {
    // From the Metal Best Practices Guide:
    // Check to see if the previous descriptor is compatible with the new one.
    // They are compatible if:
    // * they share the same rendertargets
    // * the first's store actions are either Store or DontCare
    // * the second's load actions are either Load or DontCare
    // * the second doesn't sample from any rendertargets in the first
    bool renderTargetsMatch = (first.texture == second.texture);
    bool storeActionsValid = first.storeAction == MTLStoreActionStore ||
                             first.storeAction == MTLStoreActionDontCare;
    bool loadActionsValid = second.loadAction == MTLLoadActionLoad ||
                            second.loadAction == MTLLoadActionDontCare;
    bool secondDoesntSampleFirst = (!pipelineState ||
                                    pipelineState->doesntSampleAttachment(first));

    // Since we are trying to use the same encoder rather than merging two,
    // we have to check to see if both store actions are mutually compatible.
    bool secondStoreValid = true;
    if (second.storeAction == MTLStoreActionDontCare) {
        secondStoreValid = (first.storeAction == MTLStoreActionDontCare);
        // TODO: if first.storeAction is Store and second.loadAction is Load,
        // we could reset the active RenderCommandEncoder's store action to DontCare
    } else if (second.storeAction == MTLStoreActionStore) {
        if (@available(macOS 10.12, iOS 10.0, tvOS 10.0, *)) {
            secondStoreValid = (first.storeAction == MTLStoreActionStore ||
                                first.storeAction == MTLStoreActionStoreAndMultisampleResolve);
        } else {
            secondStoreValid = (first.storeAction == MTLStoreActionStore);
        }
        // TODO: if the first store action is DontCare we could reset the active
        // RenderCommandEncoder's store action to Store, but it's not clear if it's worth it.
    } else if (second.storeAction == MTLStoreActionMultisampleResolve) {
        if (@available(macOS 10.12, iOS 10.0, tvOS 10.0, *)) {
            secondStoreValid = (first.resolveTexture == second.resolveTexture) &&
                               (first.storeAction == MTLStoreActionMultisampleResolve ||
                                first.storeAction == MTLStoreActionStoreAndMultisampleResolve);
        } else {
            secondStoreValid = (first.resolveTexture == second.resolveTexture) &&
                               (first.storeAction == MTLStoreActionMultisampleResolve);
        }
        // When we first check whether store actions are valid we don't consider resolves,
        // so we need to reset that here.
        storeActionsValid = secondStoreValid;
    } else {
        if (@available(macOS 10.12, iOS 10.0, tvOS 10.0, *)) {
            if (second.storeAction == MTLStoreActionStoreAndMultisampleResolve) {
                secondStoreValid = (first.resolveTexture == second.resolveTexture) &&
                                   (first.storeAction == MTLStoreActionStoreAndMultisampleResolve);
                // TODO: if the first store action is simply MultisampleResolve we could reset
                // the active RenderCommandEncoder's store action to StoreAndMultisampleResolve,
                // but it's not clear if it's worth it.

                // When we first check whether store actions are valid we don't consider resolves,
                // so we need to reset that here.
                storeActionsValid = secondStoreValid;
            }
        }
    }

    return renderTargetsMatch &&
           (nil == first.texture ||
            (storeActionsValid && loadActionsValid && secondDoesntSampleFirst && secondStoreValid));
}

GrMtlRenderCommandEncoder* GrMtlCommandBuffer::getRenderCommandEncoder(
        MTLRenderPassDescriptor* descriptor, const GrMtlPipelineState* pipelineState,
        GrMtlOpsRenderPass* opsRenderPass) {
    if (nil != fPreviousRenderPassDescriptor) {
        if (compatible(fPreviousRenderPassDescriptor.colorAttachments[0],
                       descriptor.colorAttachments[0], pipelineState) &&
            compatible(fPreviousRenderPassDescriptor.stencilAttachment,
                       descriptor.stencilAttachment, pipelineState)) {
            return fActiveRenderCommandEncoder.get();
        }
    }

    return this->getRenderCommandEncoder(descriptor, opsRenderPass);
}

GrMtlRenderCommandEncoder* GrMtlCommandBuffer::getRenderCommandEncoder(
        MTLRenderPassDescriptor* descriptor,
        GrMtlOpsRenderPass* opsRenderPass) {
    this->endAllEncoding();
    if (fCmdBuffer.status != MTLCommandBufferStatusNotEnqueued) {
        NSLog(@"GrMtlCommandBuffer: tried to create MTLRenderCommandEncoder while in bad state.");
        return nullptr;
    }
#ifdef SK_BUILD_FOR_IOS
    if (skgpu::MtlIsAppInBackground()) {
        fActiveRenderCommandEncoder = nullptr;
        NSLog(@"GrMtlCommandBuffer: tried to create MTLRenderCommandEncoder while in background.");
        return nullptr;
    }
#endif
    fActiveRenderCommandEncoder = GrMtlRenderCommandEncoder::Make(
            [fCmdBuffer renderCommandEncoderWithDescriptor:descriptor]);
    if (opsRenderPass) {
        opsRenderPass->initRenderState(fActiveRenderCommandEncoder.get());
    }
    fPreviousRenderPassDescriptor = descriptor;
    fHasWork = true;

    return fActiveRenderCommandEncoder.get();
}

bool GrMtlCommandBuffer::commit(bool waitUntilCompleted) {
    this->endAllEncoding();
    if ([fCmdBuffer status] != MTLCommandBufferStatusNotEnqueued) {
        NSLog(@"GrMtlCommandBuffer: Tried to commit command buffer while in invalid state.\n");
        return false;
    }
#ifdef SK_BUILD_FOR_IOS
    if (skgpu::MtlIsAppInBackground()) {
        NSLog(@"GrMtlCommandBuffer: Tried to commit command buffer while in background.\n");
        return false;
    }
#endif
    [fCmdBuffer commit];
    if (waitUntilCompleted) {
        this->waitUntilCompleted();
#if defined(SK_BUILD_FOR_IOS) && defined(SK_METAL_WAIT_UNTIL_SCHEDULED)
    // If iOS goes into the background we need to make sure all command buffers are scheduled first.
    // We don't have a way of detecting background transition so this guarantees it.
    } else {
        [fCmdBuffer waitUntilScheduled];
#endif
    }

    if ([fCmdBuffer status] == MTLCommandBufferStatusError) {
        SkDebugf("Error submitting command buffer.\n");
        if (NSError* error = [fCmdBuffer error]) {
            NSLog(@"%@", error);
        }
    }

    return ([fCmdBuffer status] != MTLCommandBufferStatusError);
}

void GrMtlCommandBuffer::endAllEncoding() {
    if (fActiveRenderCommandEncoder) {
        fActiveRenderCommandEncoder->endEncoding();
        fActiveRenderCommandEncoder.reset();
        fPreviousRenderPassDescriptor = nil;
    }
    if (fActiveBlitCommandEncoder) {
        [fActiveBlitCommandEncoder endEncoding];
        fActiveBlitCommandEncoder = nil;
    }
}

void GrMtlCommandBuffer::encodeSignalEvent(sk_sp<GrMtlEvent> event, uint64_t eventValue) {
    SkASSERT(fCmdBuffer);
    this->endAllEncoding(); // ensure we don't have any active command encoders
    if (@available(macOS 10.14, iOS 12.0, *)) {
        [fCmdBuffer encodeSignalEvent:event->mtlEvent() value:eventValue];
        this->addResource(std::move(event));
    }
    fHasWork = true;
}

void GrMtlCommandBuffer::encodeWaitForEvent(sk_sp<GrMtlEvent> event, uint64_t eventValue) {
    SkASSERT(fCmdBuffer);
    this->endAllEncoding(); // ensure we don't have any active command encoders
                            // TODO: not sure if needed but probably
    if (@available(macOS 10.14, iOS 12.0, *)) {
        [fCmdBuffer encodeWaitForEvent:event->mtlEvent() value:eventValue];
        this->addResource(std::move(event));
    }
    fHasWork = true;
}

GR_NORETAIN_END
