blob: bc53b2799aa1806a9c900b6d65ded75645c3c22e [file]
/*
* 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