1/*
2 * Copyright 2021 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef skgpu_MtlBlitCommandEncoder_DEFINED
9#define skgpu_MtlBlitCommandEncoder_DEFINED
10
11#include "include/core/SkRect.h"
12#include "include/core/SkRefCnt.h"
13#include "include/ports/SkCFObject.h"
14
15#import <Metal/Metal.h>
16
17namespace skgpu::mtl {
18
19/**
20 * Wraps a MTLBlitCommandEncoder object
21 */
22class BlitCommandEncoder : public SkRefCnt {
23public:
24    static sk_sp<BlitCommandEncoder> Make(id<MTLCommandBuffer> commandBuffer) {
25        // Adding a retain here to keep our own ref separate from the autorelease pool
26        sk_cfp<id<MTLBlitCommandEncoder>> encoder =
27                sk_ret_cfp<id<MTLBlitCommandEncoder>>([commandBuffer blitCommandEncoder]);
28        return sk_sp<BlitCommandEncoder>(new BlitCommandEncoder(std::move(encoder)));
29    }
30
31    void pushDebugGroup(NSString* string) {
32        [(*fCommandEncoder) pushDebugGroup:string];
33    }
34    void popDebugGroup() {
35        [(*fCommandEncoder) popDebugGroup];
36    }
37#ifdef SK_BUILD_FOR_MAC
38    void synchronizeResource(id<MTLBuffer> buffer) {
39        [(*fCommandEncoder) synchronizeResource: buffer];
40    }
41#endif
42
43    void copyFromTexture(id<MTLTexture> texture,
44                         SkIRect srcRect,
45                         id<MTLBuffer> buffer,
46                         size_t bufferOffset,
47                         size_t bufferRowBytes) {
48        [(*fCommandEncoder) copyFromTexture: texture
49                                sourceSlice: 0
50                                sourceLevel: 0
51                               sourceOrigin: MTLOriginMake(srcRect.left(), srcRect.top(), 0)
52                                 sourceSize: MTLSizeMake(srcRect.width(), srcRect.height(), 1)
53                                   toBuffer: buffer
54                          destinationOffset: bufferOffset
55                     destinationBytesPerRow: bufferRowBytes
56                   destinationBytesPerImage: bufferRowBytes * srcRect.height()];
57    }
58
59    void endEncoding() {
60        [(*fCommandEncoder) endEncoding];
61    }
62
63private:
64    BlitCommandEncoder(sk_cfp<id<MTLBlitCommandEncoder>> encoder)
65        : fCommandEncoder(std::move(encoder)) {}
66
67    sk_cfp<id<MTLBlitCommandEncoder>> fCommandEncoder;
68};
69
70} // namespace skgpu::mtl
71
72#endif // skgpu_MtlBlitCommandEncoder_DEFINED
73