| /* |
| * Copyright 2023 Rive |
| */ |
| |
| #include "buffer_ring_metal.h" |
| |
| #include "rive/pls/metal/pls_render_context_metal.h" |
| |
| namespace rive::pls |
| { |
| BufferMetal::BufferMetal(id<MTLDevice> gpu, size_t capacity, size_t itemSizeInBytes) : |
| BufferRingImpl(capacity, itemSizeInBytes) |
| { |
| for (int i = 0; i < kBufferRingSize; ++i) |
| { |
| m_buffers[i] = [gpu newBufferWithLength:capacity * itemSizeInBytes |
| options:MTLResourceStorageModeShared]; |
| } |
| } |
| |
| void* BufferMetal::onMapBuffer(int bufferIdx) { return m_buffers[bufferIdx].contents; } |
| |
| TexelBufferMetal::TexelBufferMetal(id<MTLDevice> gpu, |
| Format format, |
| size_t widthInItems, |
| size_t height, |
| size_t texelsPerItem, |
| MTLTextureUsage extraUsageFlags) : |
| TexelBufferRing(format, widthInItems, height, texelsPerItem) |
| { |
| MTLTextureDescriptor* desc = [[MTLTextureDescriptor alloc] init]; |
| switch (format) |
| { |
| case Format::rgba8: |
| desc.pixelFormat = MTLPixelFormatRGBA8Unorm; |
| break; |
| case Format::rgba32f: |
| desc.pixelFormat = MTLPixelFormatRGBA32Float; |
| break; |
| case Format::rgba32ui: |
| desc.pixelFormat = MTLPixelFormatRGBA32Uint; |
| break; |
| } |
| desc.width = widthInItems * texelsPerItem; |
| desc.height = height; |
| desc.mipmapLevelCount = 1; |
| desc.usage = MTLTextureUsageShaderRead | extraUsageFlags; |
| desc.storageMode = MTLStorageModeShared; |
| desc.textureType = MTLTextureType2D; |
| for (int i = 0; i < kBufferRingSize; ++i) |
| { |
| m_textures[i] = [gpu newTextureWithDescriptor:desc]; |
| } |
| } |
| |
| void TexelBufferMetal::submitTexels(int textureIdx, size_t updateWidthInTexels, size_t updateHeight) |
| { |
| if (updateWidthInTexels > 0 && updateHeight > 0) |
| { |
| MTLRegion region = {MTLOriginMake(0, 0, 0), |
| MTLSizeMake(updateWidthInTexels, updateHeight, 1)}; |
| [m_textures[textureIdx] replaceRegion:region |
| mipmapLevel:0 |
| withBytes:shadowBuffer() |
| bytesPerRow:widthInTexels() * BytesPerPixel(m_format)]; |
| } |
| } |
| } // namespace rive::pls |