blob: e77ca29cee2cd3fb0a0f123afeb52d5df75856b3 [file] [log] [blame]
#include "fiddle_context.hpp"
#include "rive/pls/pls_factory.hpp"
#include "rive/pls/pls_renderer.hpp"
#include "rive/pls/gl/pls_render_context_gl.hpp"
#include "rive/pls/gl/pls_render_target_gl.hpp"
#include "rive/pls/metal/pls_render_context_metal.h"
#include "rive/pls/metal/pls_render_target_metal.h"
#import <Metal/Metal.h>
#import <QuartzCore/CAMetalLayer.h>
#define GLFW_INCLUDE_NONE
#define GLFW_EXPOSE_NATIVE_COCOA
#include "GLFW/glfw3.h"
#include <GLFW/glfw3native.h>
using namespace rive;
using namespace rive::pls;
class FiddleContextMetalPLS : public FiddleContext
{
public:
FiddleContextMetalPLS() { printf("==== MTLDevice: %s ====\n", m_gpu.name.UTF8String); }
float dpiScale() const override
{
NSWindow* nsWindow = glfwGetCocoaWindow(g_window);
return nsWindow.screen.backingScaleFactor;
}
std::unique_ptr<Factory> makeFactory() override { return std::make_unique<PLSFactory>(); }
void onSizeChanged(int width, int height) override
{
NSWindow* nsWindow = glfwGetCocoaWindow(g_window);
nsWindow.contentView.wantsLayer = YES;
float backingScaleFactor = [[nsWindow screen] backingScaleFactor];
m_swapchain = [CAMetalLayer layer];
m_swapchain.device = m_gpu;
m_swapchain.opaque = YES;
m_swapchain.framebufferOnly = YES;
m_swapchain.pixelFormat = MTLPixelFormatBGRA8Unorm;
m_swapchain.contentsScale = backingScaleFactor;
m_swapchain.displaySyncEnabled = NO;
nsWindow.contentView.layer = m_swapchain;
m_renderTarget = m_plsContext->makeRenderTarget(MTLPixelFormatBGRA8Unorm, width, height);
}
void toggleZoomWindow() override {}
std::unique_ptr<Renderer> makeRenderer(int width, int height) override
{
return std::make_unique<PLSRenderer>(m_plsContext.get());
}
void begin() override
{
m_surface = [m_swapchain nextDrawable];
m_renderTarget->setTargetTexture(m_surface.texture);
PLSRenderContext::FrameDescriptor frameDescriptor;
frameDescriptor.renderTarget = m_renderTarget;
frameDescriptor.clearColor = 0xff404040;
frameDescriptor.wireframe = g_wireframe;
frameDescriptor.fillsDisabled = g_disableFill;
frameDescriptor.strokesDisabled = g_disableStroke;
m_plsContext->beginFrame(std::move(frameDescriptor));
}
void end() override
{
m_plsContext->flush();
id<MTLCommandBuffer> commandBuffer = [m_queue commandBuffer];
[commandBuffer presentDrawable:m_surface];
[commandBuffer commit];
}
void shrinkGPUResourcesToFit() final { m_plsContext->shrinkGPUResourcesToFit(); }
private:
id<MTLDevice> m_gpu = MTLCreateSystemDefaultDevice();
id<MTLCommandQueue> m_queue = [m_gpu newCommandQueue];
id<CAMetalDrawable> m_surface = nil;
std::unique_ptr<PLSRenderContextMetal> m_plsContext =
PLSRenderContextMetal::Make(m_gpu, m_queue);
CAMetalLayer* m_swapchain;
rcp<PLSRenderTargetMetal> m_renderTarget;
};
std::unique_ptr<FiddleContext> FiddleContext::MakeMetalPLS()
{
return std::make_unique<FiddleContextMetalPLS>();
}