blob: cb6ca45d1afdff8e91490f5da6b053b0ae5710f3 [file] [log] [blame] [edit]
#ifdef RIVE_HAS_METAL
#include "metal/metal_renderer.hpp"
#import <Metal/Metal.h>
#import <QuartzCore/CAMetalLayer.h>
#import <AppKit/NSWindow.h>
/// Implemented in viewer.cpp, must be available before instancing the
/// MetalRenderer.
extern void* viewerNativeWindowHandle;
namespace rive
{
class ViewerMetalRenderer : public MetalRenderer
{
private:
id<CAMetalDrawable> m_FrameDrawable;
id<MTLCommandBuffer> m_FrameCommandBuffer;
id<MTLRenderCommandEncoder> m_FrameCommandEncoder;
id<MTLCommandQueue> m_CommandQueue;
CAMetalLayer* m_MetalLayer;
public:
id<MTLDevice> acquireDevice() override
{
const id<MTLDevice> gpu = MTLCreateSystemDefaultDevice();
m_MetalLayer = [CAMetalLayer layer];
m_MetalLayer.device = gpu;
m_MetalLayer.opaque = YES;
NSWindow* nswindow =
static_cast<NSWindow*>(viewerNativeWindowHandle);
nswindow.contentView.layer = m_MetalLayer;
nswindow.contentView.wantsLayer = YES;
m_CommandQueue = [gpu newCommandQueue];
return gpu;
}
id<MTLRenderCommandEncoder> currentCommandEncoder() override
{
return m_FrameCommandEncoder;
}
void startFrame() override
{
m_FrameDrawable = [m_MetalLayer nextDrawable];
// Get the command buffer from the command queue.
m_FrameCommandBuffer = [m_CommandQueue commandBuffer];
// Get the texture for the next frame.
id<MTLTexture> texture = m_FrameDrawable.texture;
MTLRenderPassDescriptor* passDescriptor =
[MTLRenderPassDescriptor renderPassDescriptor];
passDescriptor.colorAttachments[0].texture = texture;
passDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear;
passDescriptor.colorAttachments[0].storeAction =
MTLStoreActionStore;
passDescriptor.colorAttachments[0].clearColor =
MTLClearColorMake(0.0, 0.0, 0.0, 0.0);
// Get the encoder which we will use for all draw calls on the main
// buffer.
m_FrameCommandEncoder = [m_FrameCommandBuffer
renderCommandEncoderWithDescriptor:passDescriptor];
fillScreen();
}
void endFrame() override
{
[m_FrameCommandEncoder endEncoding];
[m_FrameCommandBuffer presentDrawable:m_FrameDrawable];
[m_FrameCommandBuffer commit];
}
};
LowLevelRenderer* makeRendererMetal() { return new ViewerMetalRenderer(); }
} // namespace rive
#endif