/*
 * Copyright 2021 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef skgpu_graphite_MtlBlitCommandEncoder_DEFINED
#define skgpu_graphite_MtlBlitCommandEncoder_DEFINED

#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/ports/SkCFObject.h"
#include "src/gpu/graphite/Resource.h"

#import <Metal/Metal.h>

namespace skgpu::graphite {

/**
 * Wraps a MTLMtlBlitCommandEncoder object
 */
class MtlBlitCommandEncoder : public Resource {
public:
    static sk_sp<MtlBlitCommandEncoder> Make(const SharedContext* sharedContext,
                                             id<MTLCommandBuffer> commandBuffer) {
        // Adding a retain here to keep our own ref separate from the autorelease pool
        sk_cfp<id<MTLBlitCommandEncoder>> encoder =
                sk_ret_cfp<id<MTLBlitCommandEncoder>>([commandBuffer blitCommandEncoder]);
        return sk_sp<MtlBlitCommandEncoder>(new MtlBlitCommandEncoder(sharedContext,
                                                                      std::move(encoder)));
    }

    void pushDebugGroup(NSString* string) {
        [(*fCommandEncoder) pushDebugGroup:string];
    }
    void popDebugGroup() {
        [(*fCommandEncoder) popDebugGroup];
    }
#ifdef SK_BUILD_FOR_MAC
    void synchronizeResource(id<MTLBuffer> buffer) {
        [(*fCommandEncoder) synchronizeResource: buffer];
    }
#endif

    void fillBuffer(id<MTLBuffer> buffer, size_t bufferOffset, size_t bytes, uint8_t value) {
        [(*fCommandEncoder) fillBuffer:buffer
                                 range:NSMakeRange(bufferOffset, bytes)
                                 value:value];
    }

    void copyFromTexture(id<MTLTexture> texture,
                         SkIRect srcRect,
                         id<MTLBuffer> buffer,
                         size_t bufferOffset,
                         size_t bufferRowBytes) {
        [(*fCommandEncoder) copyFromTexture: texture
                                sourceSlice: 0
                                sourceLevel: 0
                               sourceOrigin: MTLOriginMake(srcRect.left(), srcRect.top(), 0)
                                 sourceSize: MTLSizeMake(srcRect.width(), srcRect.height(), 1)
                                   toBuffer: buffer
                          destinationOffset: bufferOffset
                     destinationBytesPerRow: bufferRowBytes
                   destinationBytesPerImage: bufferRowBytes * srcRect.height()];
    }

    void copyFromBuffer(id<MTLBuffer> buffer,
                        size_t bufferOffset,
                        size_t bufferRowBytes,
                        id<MTLTexture> texture,
                        SkIRect dstRect,
                        unsigned int dstLevel) {
        [(*fCommandEncoder) copyFromBuffer: buffer
                              sourceOffset: bufferOffset
                         sourceBytesPerRow: bufferRowBytes
                       sourceBytesPerImage: bufferRowBytes * dstRect.height()
                                sourceSize: MTLSizeMake(dstRect.width(), dstRect.height(), 1)
                                 toTexture: texture
                          destinationSlice: 0
                          destinationLevel: dstLevel
                         destinationOrigin: MTLOriginMake(dstRect.left(), dstRect.top(), 0)];
    }

    void copyTextureToTexture(id<MTLTexture> srcTexture,
                              SkIRect srcRect,
                              id<MTLTexture> dstTexture,
                              SkIPoint dstPoint) {
        [(*fCommandEncoder) copyFromTexture: srcTexture
                                sourceSlice: 0
                                sourceLevel: 0
                               sourceOrigin: MTLOriginMake(srcRect.x(), srcRect.y(), 0)
                                 sourceSize: MTLSizeMake(srcRect.width(), srcRect.height(), 1)
                                  toTexture: dstTexture
                           destinationSlice: 0
                           destinationLevel: 0
                          destinationOrigin: MTLOriginMake(dstPoint.fX, dstPoint.fY, 0)];
    }

    void copyBufferToBuffer(id<MTLBuffer> srcBuffer,
                            size_t srcOffset,
                            id<MTLBuffer> dstBuffer,
                            size_t dstOffset,
                            size_t size) {
        [(*fCommandEncoder) copyFromBuffer: srcBuffer
                              sourceOffset: srcOffset
                                  toBuffer: dstBuffer
                         destinationOffset: dstOffset
                                      size: size];
    }

    void endEncoding() {
        [(*fCommandEncoder) endEncoding];
    }

private:
    MtlBlitCommandEncoder(const SharedContext* sharedContext,
                          sk_cfp<id<MTLBlitCommandEncoder>> encoder)
            : Resource(sharedContext, Ownership::kOwned, skgpu::Budgeted::kYes, /*gpuMemorySize=*/0)
            , fCommandEncoder(std::move(encoder)) {}

    void freeGpuData() override {
        fCommandEncoder.reset();
    }

    sk_cfp<id<MTLBlitCommandEncoder>> fCommandEncoder;
};

} // namespace skgpu::graphite

#endif // skgpu_graphite_MtlBlitCommandEncoder_DEFINED
