// Copyright 2020 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "dawn/native/metal/CommandRecordingContext.h"

#include "dawn/common/Assert.h"

namespace dawn::native::metal {

CommandRecordingContext::CommandRecordingContext() = default;

CommandRecordingContext::~CommandRecordingContext() {
    // Commands must be acquired.
    ASSERT(mCommands == nullptr);
}

id<MTLCommandBuffer> CommandRecordingContext::GetCommands() {
    return mCommands.Get();
}

void CommandRecordingContext::MarkUsed() {
    mUsed = true;
}
bool CommandRecordingContext::WasUsed() const {
    return mUsed;
}

MaybeError CommandRecordingContext::PrepareNextCommandBuffer(id<MTLCommandQueue> queue) {
    ASSERT(mCommands == nil);
    ASSERT(!mUsed);

    // The MTLCommandBuffer will be autoreleased by default.
    // The autorelease pool may drain before the command buffer is submitted. Retain so it stays
    // alive.
    mCommands = AcquireNSPRef([[queue commandBuffer] retain]);
    if (mCommands == nil) {
        return DAWN_INTERNAL_ERROR("Failed to allocate an MTLCommandBuffer");
    }

    return {};
}

NSPRef<id<MTLCommandBuffer>> CommandRecordingContext::AcquireCommands() {
    // A blit encoder can be left open from WriteBuffer, make sure we close it.
    if (mCommands != nullptr) {
        EndBlit();
    }

    ASSERT(!mInEncoder);
    mUsed = false;
    return std::move(mCommands);
}

id<MTLBlitCommandEncoder> CommandRecordingContext::EnsureBlit() {
    ASSERT(mCommands != nullptr);

    if (mBlit == nullptr) {
        ASSERT(!mInEncoder);
        mInEncoder = true;

        // The encoder is created autoreleased. Retain it to avoid the autoreleasepool from
        // draining from under us.
        mBlit.Acquire([[*mCommands blitCommandEncoder] retain]);
    }
    return mBlit.Get();
}

void CommandRecordingContext::EndBlit() {
    ASSERT(mCommands != nullptr);

    if (mBlit != nullptr) {
        [*mBlit endEncoding];
        mBlit = nullptr;
        mInEncoder = false;
    }
}

id<MTLComputeCommandEncoder> CommandRecordingContext::BeginCompute() {
    ASSERT(mCommands != nullptr);
    ASSERT(mCompute == nullptr);
    ASSERT(!mInEncoder);

    mInEncoder = true;
    // The encoder is created autoreleased. Retain it to avoid the autoreleasepool from
    // draining from under us.
    mCompute.Acquire([[*mCommands computeCommandEncoder] retain]);
    return mCompute.Get();
}

void CommandRecordingContext::EndCompute() {
    ASSERT(mCommands != nullptr);
    ASSERT(mCompute != nullptr);

    [*mCompute endEncoding];
    mCompute = nullptr;
    mInEncoder = false;
}

id<MTLRenderCommandEncoder> CommandRecordingContext::BeginRender(
    MTLRenderPassDescriptor* descriptor) {
    ASSERT(mCommands != nullptr);
    ASSERT(mRender == nullptr);
    ASSERT(!mInEncoder);

    mInEncoder = true;
    // The encoder is created autoreleased. Retain it to avoid the autoreleasepool from
    // draining from under us.
    mRender.Acquire([[*mCommands renderCommandEncoderWithDescriptor:descriptor] retain]);
    return mRender.Get();
}

void CommandRecordingContext::EndRender() {
    ASSERT(mCommands != nullptr);
    ASSERT(mRender != nullptr);

    [*mRender endEncoding];
    mRender = nullptr;
    mInEncoder = false;
}

}  // namespace dawn::native::metal
