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 "experimental/graphite/src/Resource.h" 12 #include "include/core/SkRect.h" 13 #include "include/core/SkRefCnt.h" 14 #include "include/ports/SkCFObject.h" 15 16 #import <Metal/Metal.h> 17 18 namespace skgpu::mtl { 19 20 /** 21 * Wraps a MTLBlitCommandEncoder object 22 */ 23 class BlitCommandEncoder : public Resource { 24 public: Make(const skgpu::Gpu * gpu,id<MTLCommandBuffer> commandBuffer)25 static sk_sp<BlitCommandEncoder> Make(const skgpu::Gpu* gpu, 26 id<MTLCommandBuffer> commandBuffer) { 27 // Adding a retain here to keep our own ref separate from the autorelease pool 28 sk_cfp<id<MTLBlitCommandEncoder>> encoder = 29 sk_ret_cfp<id<MTLBlitCommandEncoder>>([commandBuffer blitCommandEncoder]); 30 return sk_sp<BlitCommandEncoder>(new BlitCommandEncoder(gpu, std::move(encoder))); 31 } 32 pushDebugGroup(NSString * string)33 void pushDebugGroup(NSString* string) { 34 [(*fCommandEncoder) pushDebugGroup:string]; 35 } popDebugGroup()36 void popDebugGroup() { 37 [(*fCommandEncoder) popDebugGroup]; 38 } 39 #ifdef SK_BUILD_FOR_MAC synchronizeResource(id<MTLBuffer> buffer)40 void synchronizeResource(id<MTLBuffer> buffer) { 41 [(*fCommandEncoder) synchronizeResource: buffer]; 42 } 43 #endif 44 copyFromTexture(id<MTLTexture> texture,SkIRect srcRect,id<MTLBuffer> buffer,size_t bufferOffset,size_t bufferRowBytes)45 void copyFromTexture(id<MTLTexture> texture, 46 SkIRect srcRect, 47 id<MTLBuffer> buffer, 48 size_t bufferOffset, 49 size_t bufferRowBytes) { 50 [(*fCommandEncoder) copyFromTexture: texture 51 sourceSlice: 0 52 sourceLevel: 0 53 sourceOrigin: MTLOriginMake(srcRect.left(), srcRect.top(), 0) 54 sourceSize: MTLSizeMake(srcRect.width(), srcRect.height(), 1) 55 toBuffer: buffer 56 destinationOffset: bufferOffset 57 destinationBytesPerRow: bufferRowBytes 58 destinationBytesPerImage: bufferRowBytes * srcRect.height()]; 59 } 60 copyFromBuffer(id<MTLBuffer> buffer,size_t bufferOffset,size_t bufferRowBytes,id<MTLTexture> texture,SkIRect dstRect,unsigned int dstLevel)61 void copyFromBuffer(id<MTLBuffer> buffer, 62 size_t bufferOffset, 63 size_t bufferRowBytes, 64 id<MTLTexture> texture, 65 SkIRect dstRect, 66 unsigned int dstLevel) { 67 [(*fCommandEncoder) copyFromBuffer: buffer 68 sourceOffset: bufferOffset 69 sourceBytesPerRow: bufferRowBytes 70 sourceBytesPerImage: bufferRowBytes * dstRect.height() 71 sourceSize: MTLSizeMake(dstRect.width(), dstRect.height(), 1) 72 toTexture: texture 73 destinationSlice: 0 74 destinationLevel: dstLevel 75 destinationOrigin: MTLOriginMake(dstRect.left(), dstRect.top(), 0)]; 76 } 77 endEncoding()78 void endEncoding() { 79 [(*fCommandEncoder) endEncoding]; 80 } 81 82 private: BlitCommandEncoder(const skgpu::Gpu * gpu,sk_cfp<id<MTLBlitCommandEncoder>> encoder)83 BlitCommandEncoder(const skgpu::Gpu* gpu, sk_cfp<id<MTLBlitCommandEncoder>> encoder) 84 : Resource(gpu), fCommandEncoder(std::move(encoder)) {} 85 onFreeGpuData()86 void onFreeGpuData() override { 87 fCommandEncoder.reset(); 88 } 89 90 sk_cfp<id<MTLBlitCommandEncoder>> fCommandEncoder; 91 }; 92 93 } // namespace skgpu::mtl 94 95 #endif // skgpu_MtlBlitCommandEncoder_DEFINED 96