/* * 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 namespace skgpu::graphite { /** * Wraps a MTLMtlBlitCommandEncoder object */ class MtlBlitCommandEncoder : public Resource { public: static sk_sp Make(const SharedContext* sharedContext, id commandBuffer) { @autoreleasepool { // Adding a retain here to keep our own ref separate from the autorelease pool sk_cfp> encoder = sk_ret_cfp>([commandBuffer blitCommandEncoder]); return sk_sp(new MtlBlitCommandEncoder(sharedContext, std::move(encoder))); } } const char* getResourceType() const override { return "Metal Blit Command Encoder"; } void pushDebugGroup(NSString* string) { [(*fCommandEncoder) pushDebugGroup:string]; } void popDebugGroup() { [(*fCommandEncoder) popDebugGroup]; } #ifdef SK_BUILD_FOR_MAC void synchronizeResource(id buffer) { [(*fCommandEncoder) synchronizeResource: buffer]; } #endif void fillBuffer(id buffer, size_t bufferOffset, size_t bytes, uint8_t value) { [(*fCommandEncoder) fillBuffer:buffer range:NSMakeRange(bufferOffset, bytes) value:value]; } void copyFromTexture(id texture, SkIRect srcRect, id 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 buffer, size_t bufferOffset, size_t bufferRowBytes, id 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 srcTexture, SkIRect srcRect, id dstTexture, SkIPoint dstPoint, int mipLevel) { [(*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: mipLevel destinationOrigin: MTLOriginMake(dstPoint.fX, dstPoint.fY, 0)]; } void copyBufferToBuffer(id srcBuffer, size_t srcOffset, id 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> encoder) : Resource(sharedContext, Ownership::kOwned, skgpu::Budgeted::kYes, /*gpuMemorySize=*/0) , fCommandEncoder(std::move(encoder)) {} void freeGpuData() override { fCommandEncoder.reset(); } sk_cfp> fCommandEncoder; }; } // namespace skgpu::graphite #endif // skgpu_graphite_MtlBlitCommandEncoder_DEFINED