From 8d1b91daeee85f3e1e29840c75fb657574322890 Mon Sep 17 00:00:00 2001 From: Tom Poole Date: Wed, 1 Jun 2022 09:21:03 +0100 Subject: [PATCH] macOS: Use MTLStorageModeManaged for shared Metal textures --- .../native/juce_mac_CGMetalLayerRenderer.h | 50 +++++++++++++------ 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/modules/juce_gui_basics/native/juce_mac_CGMetalLayerRenderer.h b/modules/juce_gui_basics/native/juce_mac_CGMetalLayerRenderer.h index 9b266e7842..ba0392956c 100644 --- a/modules/juce_gui_basics/native/juce_mac_CGMetalLayerRenderer.h +++ b/modules/juce_gui_basics/native/juce_mac_CGMetalLayerRenderer.h @@ -108,7 +108,9 @@ public: CGContextRestoreGState (cgContext); } - auto cpuTexture = resources->getCpuTexture(); + resources->signalBufferModifiedByCpu(); + + auto sharedTexture = resources->getSharedTexture(); memoryBlitCommandBuffer.reset ([commandQueue.get() commandBuffer]); @@ -118,11 +120,11 @@ public: [memoryBlitCommandBuffer.get() retain]; auto blitCommandEncoder = [memoryBlitCommandBuffer.get() blitCommandEncoder]; - [blitCommandEncoder copyFromTexture: cpuTexture + [blitCommandEncoder copyFromTexture: sharedTexture sourceSlice: 0 sourceLevel: 0 sourceOrigin: MTLOrigin{} - sourceSize: MTLSize { cpuTexture.width, cpuTexture.height, 1 } + sourceSize: MTLSize { sharedTexture.width, sharedTexture.height, 1 } toTexture: gpuTexture destinationSlice: 0 destinationLevel: 0 @@ -227,21 +229,31 @@ private: const auto allocationSize = cpuRenderMemory.ensureSize (bytesPerRow * (size_t) layer.drawableSize.height); - ObjCObjectHandle> buffer { [metalDevice newBufferWithBytesNoCopy: cpuRenderMemory.get() - length: allocationSize - options: MTLResourceStorageModeShared - deallocator: nullptr] }; + buffer.reset ([metalDevice newBufferWithBytesNoCopy: cpuRenderMemory.get() + length: allocationSize + options: + #if JUCE_MAC + MTLResourceStorageModeManaged + #else + MTLResourceStorageModeShared + #endif + deallocator: nullptr]); auto* textureDesc = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat: layer.pixelFormat width: (NSUInteger) layer.drawableSize.width height: (NSUInteger) layer.drawableSize.height mipmapped: NO]; - textureDesc.storageMode = buffer.get().storageMode; + textureDesc.storageMode = + #if JUCE_MAC + MTLStorageModeManaged; + #else + MTLStorageModeShared; + #endif textureDesc.usage = MTLTextureUsageShaderRead; - cpuTexture.reset ([buffer.get() newTextureWithDescriptor: textureDesc - offset: 0 - bytesPerRow: bytesPerRow]); + sharedTexture.reset ([buffer.get() newTextureWithDescriptor: textureDesc + offset: 0 + bytesPerRow: bytesPerRow]); cgContext.reset (CGBitmapContextCreate (cpuRenderMemory.get(), (size_t) layer.drawableSize.width, @@ -258,9 +270,16 @@ private: gpuTexturePool = std::make_unique (metalDevice, textureDesc); } - CGContextRef getCGContext() const noexcept { return cgContext.get(); } - id getCpuTexture() const noexcept { return cpuTexture.get(); } - id getGpuTexture() noexcept { return gpuTexturePool == nullptr ? nullptr : gpuTexturePool->take(); } + CGContextRef getCGContext() const noexcept { return cgContext.get(); } + id getSharedTexture() const noexcept { return sharedTexture.get(); } + id getGpuTexture() noexcept { return gpuTexturePool == nullptr ? nullptr : gpuTexturePool->take(); } + + void signalBufferModifiedByCpu() + { + #if JUCE_MAC + [buffer.get() didModifyRange: { 0, buffer.get().length }]; + #endif + } private: class AlignedMemory @@ -318,7 +337,8 @@ private: detail::ContextPtr cgContext; - TextureUniquePtr cpuTexture; + ObjCObjectHandle> buffer; + TextureUniquePtr sharedTexture; std::unique_ptr gpuTexturePool; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Resources)