Skip to content

Commit

Permalink
Refactor rendering_metal
Browse files Browse the repository at this point in the history
  • Loading branch information
pthom committed Dec 20, 2023
1 parent 9a1c72e commit 55cc1bb
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 86 deletions.
29 changes: 11 additions & 18 deletions src/hello_imgui/internal/backend_impls/rendering_metal.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@ struct GLFWwindow;

namespace HelloImGui
{
struct MetalGlobals
{
CAMetalLayer* caMetalLayer = nullptr;
id<CAMetalDrawable> caMetalDrawable = nullptr;
id<MTLCommandBuffer> mtlCommandBuffer = nullptr;
id<MTLCommandQueue> mtlCommandQueue = nullptr;
MTLRenderPassDescriptor* mtlRenderPassDescriptor = nullptr;
id <MTLRenderCommandEncoder> mtlRenderCommandEncoder = nullptr;
};
MetalGlobals& GetMetalGlobals();

#ifdef HELLOIMGUI_USE_SDL2
RenderingCallbacks CreateBackendCallbacks_SdlMetal();
Expand All @@ -29,15 +39,7 @@ namespace HelloImGui
{
SDL_Window* sdlWindow = nullptr;
SDL_Renderer* sdlRenderer = nullptr;

CAMetalLayer* caMetalLayer = nullptr;
id<CAMetalDrawable> caMetalDrawable = nullptr;
id<MTLCommandBuffer> mtlCommandBuffer = nullptr;
id<MTLCommandQueue> mtlCommandQueue = nullptr;
MTLRenderPassDescriptor* mtlRenderPassDescriptor = nullptr;
id <MTLRenderCommandEncoder> mtlRenderCommandEncoder = nullptr;
};

SdlMetalGlobals& GetSdlMetalGlobals();
#endif

Expand All @@ -51,17 +53,8 @@ namespace HelloImGui
struct GlfwMetalGlobals
{
GLFWwindow* glfwWindow = nullptr;

id <MTLDevice> mtlDevice = nullptr;

CAMetalLayer* caMetalLayer = nullptr;
id<CAMetalDrawable> caMetalDrawable = nullptr;
id<MTLCommandBuffer> mtlCommandBuffer = nullptr;
id<MTLCommandQueue> mtlCommandQueue = nullptr;
MTLRenderPassDescriptor* mtlRenderPassDescriptor = nullptr;
id <MTLRenderCommandEncoder> mtlRenderCommandEncoder = nullptr;
id<MTLDevice> mtlDevice = nullptr;
};

GlfwMetalGlobals& GetGlfwMetalGlobals();
#endif

Expand Down
13 changes: 13 additions & 0 deletions src/hello_imgui/internal/backend_impls/rendering_metal.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#ifdef HELLOIMGUI_HAS_METAL
#include "rendering_metal.h"

namespace HelloImGui
{
MetalGlobals& GetMetalGlobals()
{
static MetalGlobals sMetalGlobals;
return sMetalGlobals;
}
}

#endif // HELLOIMGUI_HAS_METAL
81 changes: 40 additions & 41 deletions src/hello_imgui/internal/backend_impls/rendering_metal_glfw.mm
Original file line number Diff line number Diff line change
Expand Up @@ -19,49 +19,50 @@

namespace HelloImGui
{
GlfwMetalGlobals gGlfwMetalGlobals;

GlfwMetalGlobals& GetGlfwMetalGlobals()
{
static GlfwMetalGlobals sGlfwMetalGlobals;
return sGlfwMetalGlobals;
}

void PrepareGlfwForMetal_WithWindow_PreImGuiInit(GLFWwindow* glfwWindow)
{
gGlfwMetalGlobals.glfwWindow = glfwWindow;
// gGlfwMetalGlobals.sdlRenderer = SDL_CreateRenderer(sdlWindow, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
// if (gGlfwMetalGlobals.sdlRenderer == nullptr)
// {
// bool Error_SdlCreateRenderer_For_Metal = false;
// IM_ASSERT(Error_SdlCreateRenderer_For_Metal);
// exit(-3);
// }

// Setup Platform/Renderer backends
// gGlfwMetalGlobals.caMetalLayer = (__bridge CAMetalLayer*)SDL_RenderGetMetalLayer(gGlfwMetalGlobals.sdlRenderer);
// gGlfwMetalGlobals.caMetalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;
auto& gMetalGlobals = GetMetalGlobals();
auto& gGlfwMetalGlobals = GetGlfwMetalGlobals();

gGlfwMetalGlobals.glfwWindow = glfwWindow;
gGlfwMetalGlobals.mtlDevice = MTLCreateSystemDefaultDevice();
gGlfwMetalGlobals.mtlCommandQueue = [gGlfwMetalGlobals.mtlDevice newCommandQueue];
gMetalGlobals.mtlCommandQueue = [gGlfwMetalGlobals.mtlDevice newCommandQueue];
}

void PrepareGlfwForMetal_PosImGuiInit()
{
auto& gMetalGlobals = GetMetalGlobals();

auto& gGlfwMetalGlobals = GetGlfwMetalGlobals();
ImGui_ImplGlfw_InitForOther(gGlfwMetalGlobals.glfwWindow, true);
ImGui_ImplMetal_Init(gGlfwMetalGlobals.mtlDevice);

NSWindow *nswin = glfwGetCocoaWindow(gGlfwMetalGlobals.glfwWindow);
gGlfwMetalGlobals.caMetalLayer = [CAMetalLayer layer];
gGlfwMetalGlobals.caMetalLayer.device = gGlfwMetalGlobals.mtlDevice;
gGlfwMetalGlobals.caMetalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;
nswin.contentView.layer = gGlfwMetalGlobals.caMetalLayer;
gMetalGlobals.caMetalLayer = [CAMetalLayer layer];
gMetalGlobals.caMetalLayer.device = gGlfwMetalGlobals.mtlDevice;
gMetalGlobals.caMetalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;
nswin.contentView.layer = gMetalGlobals.caMetalLayer;
nswin.contentView.wantsLayer = YES;

gGlfwMetalGlobals.mtlRenderPassDescriptor = [MTLRenderPassDescriptor new];
gMetalGlobals.mtlRenderPassDescriptor = [MTLRenderPassDescriptor new];
}

void SwapGlfwMetalBuffers()
{
[gGlfwMetalGlobals.mtlRenderCommandEncoder popDebugGroup];
[gGlfwMetalGlobals.mtlRenderCommandEncoder endEncoding];
auto& gMetalGlobals = GetMetalGlobals();

[gGlfwMetalGlobals.mtlCommandBuffer presentDrawable:gGlfwMetalGlobals.caMetalDrawable];
[gGlfwMetalGlobals.mtlCommandBuffer commit];
[gMetalGlobals.mtlRenderCommandEncoder popDebugGroup];
[gMetalGlobals.mtlRenderCommandEncoder endEncoding];

[gMetalGlobals.mtlCommandBuffer presentDrawable:gMetalGlobals.caMetalDrawable];
[gMetalGlobals.mtlCommandBuffer commit];
}

RenderingCallbacks CreateBackendCallbacks_GlfwMetal()
Expand All @@ -70,31 +71,35 @@ RenderingCallbacks CreateBackendCallbacks_GlfwMetal()

callbacks.Impl_NewFrame_3D = []
{
auto& gMetalGlobals = GetMetalGlobals();
auto& gGlfwMetalGlobals = GetGlfwMetalGlobals();

auto Vec4_To_Array = [](ImVec4 v) { return std::array<float, 4>{ v.x, v.y, v.z, v.w }; };

int width, height;
glfwGetFramebufferSize(gGlfwMetalGlobals.glfwWindow, &width, &height);
gGlfwMetalGlobals.caMetalLayer.drawableSize = CGSizeMake(width, height);
gGlfwMetalGlobals.caMetalDrawable = [gGlfwMetalGlobals.caMetalLayer nextDrawable];
gMetalGlobals.caMetalLayer.drawableSize = CGSizeMake(width, height);
gMetalGlobals.caMetalDrawable = [gMetalGlobals.caMetalLayer nextDrawable];

gGlfwMetalGlobals.mtlCommandBuffer = [gGlfwMetalGlobals.mtlCommandQueue commandBuffer];
gMetalGlobals.mtlCommandBuffer = [gMetalGlobals.mtlCommandQueue commandBuffer];
auto clearColor = Vec4_To_Array(HelloImGui::GetRunnerParams()->imGuiWindowParams.backgroundColor);
gGlfwMetalGlobals.mtlRenderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(clearColor[0] * clearColor[3], clearColor[1] * clearColor[3], clearColor[2] * clearColor[3], clearColor[3]);
gGlfwMetalGlobals.mtlRenderPassDescriptor.colorAttachments[0].texture = gGlfwMetalGlobals.caMetalDrawable.texture;
gGlfwMetalGlobals.mtlRenderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear;
gGlfwMetalGlobals.mtlRenderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore;
gGlfwMetalGlobals.mtlRenderCommandEncoder = [
gGlfwMetalGlobals.mtlCommandBuffer renderCommandEncoderWithDescriptor:gGlfwMetalGlobals.mtlRenderPassDescriptor];
[gGlfwMetalGlobals.mtlRenderCommandEncoder pushDebugGroup:@"ImGui demo"];
gMetalGlobals.mtlRenderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(clearColor[0] * clearColor[3], clearColor[1] * clearColor[3], clearColor[2] * clearColor[3], clearColor[3]);
gMetalGlobals.mtlRenderPassDescriptor.colorAttachments[0].texture = gMetalGlobals.caMetalDrawable.texture;
gMetalGlobals.mtlRenderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear;
gMetalGlobals.mtlRenderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore;
gMetalGlobals.mtlRenderCommandEncoder = [
gMetalGlobals.mtlCommandBuffer renderCommandEncoderWithDescriptor:gMetalGlobals.mtlRenderPassDescriptor];
[gMetalGlobals.mtlRenderCommandEncoder pushDebugGroup:@"ImGui demo"];

// Start the Dear ImGui frame
ImGui_ImplMetal_NewFrame(gGlfwMetalGlobals.mtlRenderPassDescriptor);
ImGui_ImplMetal_NewFrame(gMetalGlobals.mtlRenderPassDescriptor);
ImGui_ImplGlfw_NewFrame();
};

callbacks.Impl_RenderDrawData_To_3D = []
{
ImGui_ImplMetal_RenderDrawData(ImGui::GetDrawData(), gGlfwMetalGlobals.mtlCommandBuffer, gGlfwMetalGlobals.mtlRenderCommandEncoder);
auto& gMetalGlobals = GetMetalGlobals();
ImGui_ImplMetal_RenderDrawData(ImGui::GetDrawData(), gMetalGlobals.mtlCommandBuffer, gMetalGlobals.mtlRenderCommandEncoder);
};

// Not implemented for Metal
Expand All @@ -110,12 +115,6 @@ RenderingCallbacks CreateBackendCallbacks_GlfwMetal()
return callbacks;
}

GlfwMetalGlobals& GetGlfwMetalGlobals()
{
return gGlfwMetalGlobals;
}


} // namespace HelloImGui

#endif // HELLOIMGUI_USE_GLFW3
Expand Down
63 changes: 36 additions & 27 deletions src/hello_imgui/internal/backend_impls/rendering_metal_sdl.mm
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#include "rendering_metal.h"

#import <Metal/Metal.h>
#import <QuartzCore/QuartzCore.h>
#include <backends/imgui_impl_metal.h>
#include <array>

Expand All @@ -15,10 +14,17 @@

namespace HelloImGui
{
SdlMetalGlobals gSdlMetalGlobals;
SdlMetalGlobals& GetSdlMetalGlobals()
{
static SdlMetalGlobals sSdlMetalGlobals;
return sSdlMetalGlobals;
}


void PrepareSdlForMetal_WithWindow_PreImGuiInit(SDL_Window* sdlWindow)
{
auto& gMetalGlobals = GetMetalGlobals();
auto& gSdlMetalGlobals = GetSdlMetalGlobals();
gSdlMetalGlobals.sdlWindow = sdlWindow;
gSdlMetalGlobals.sdlRenderer = SDL_CreateRenderer(sdlWindow, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (gSdlMetalGlobals.sdlRenderer == nullptr)
Expand All @@ -29,26 +35,30 @@ void PrepareSdlForMetal_WithWindow_PreImGuiInit(SDL_Window* sdlWindow)
}

// Setup Platform/Renderer backends
gSdlMetalGlobals.caMetalLayer = (__bridge CAMetalLayer*)SDL_RenderGetMetalLayer(gSdlMetalGlobals.sdlRenderer);
gSdlMetalGlobals.caMetalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;
gMetalGlobals.caMetalLayer = (__bridge CAMetalLayer*)SDL_RenderGetMetalLayer(gSdlMetalGlobals.sdlRenderer);
gMetalGlobals.caMetalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;
}

void PrepareSdlForMetal_PosImGuiInit()
{
ImGui_ImplMetal_Init(gSdlMetalGlobals.caMetalLayer.device);
auto& gMetalGlobals = GetMetalGlobals();
auto& gSdlMetalGlobals = GetSdlMetalGlobals();

ImGui_ImplMetal_Init(gMetalGlobals.caMetalLayer.device);
ImGui_ImplSDL2_InitForMetal(gSdlMetalGlobals.sdlWindow);

gSdlMetalGlobals.mtlCommandQueue = [gSdlMetalGlobals.caMetalLayer.device newCommandQueue];
gSdlMetalGlobals.mtlRenderPassDescriptor = [MTLRenderPassDescriptor new];
gMetalGlobals.mtlCommandQueue = [gMetalGlobals.caMetalLayer.device newCommandQueue];
gMetalGlobals.mtlRenderPassDescriptor = [MTLRenderPassDescriptor new];
}

void SwapSdlMetalBuffers()
{
[gSdlMetalGlobals.mtlRenderCommandEncoder popDebugGroup];
[gSdlMetalGlobals.mtlRenderCommandEncoder endEncoding];
auto& gMetalGlobals = GetMetalGlobals();
[gMetalGlobals.mtlRenderCommandEncoder popDebugGroup];
[gMetalGlobals.mtlRenderCommandEncoder endEncoding];

[gSdlMetalGlobals.mtlCommandBuffer presentDrawable:gSdlMetalGlobals.caMetalDrawable];
[gSdlMetalGlobals.mtlCommandBuffer commit];
[gMetalGlobals.mtlCommandBuffer presentDrawable:gMetalGlobals.caMetalDrawable];
[gMetalGlobals.mtlCommandBuffer commit];
}

RenderingCallbacks CreateBackendCallbacks_SdlMetal()
Expand All @@ -57,32 +67,36 @@ RenderingCallbacks CreateBackendCallbacks_SdlMetal()

callbacks.Impl_NewFrame_3D = []
{
auto& gMetalGlobals = GetMetalGlobals();
auto& gSdlMetalGlobals = GetSdlMetalGlobals();

auto Vec4_To_Array = [](ImVec4 v) { return std::array<float, 4>{ v.x, v.y, v.z, v.w }; };

//
// New Frame + Clear color
//
int width, height;
SDL_GetRendererOutputSize(gSdlMetalGlobals.sdlRenderer, &width, &height);
gSdlMetalGlobals.caMetalLayer.drawableSize = CGSizeMake(width, height);
gSdlMetalGlobals.caMetalDrawable = [gSdlMetalGlobals.caMetalLayer nextDrawable];
gMetalGlobals.caMetalLayer.drawableSize = CGSizeMake(width, height);
gMetalGlobals.caMetalDrawable = [gMetalGlobals.caMetalLayer nextDrawable];

gSdlMetalGlobals.mtlCommandBuffer = [gSdlMetalGlobals.mtlCommandQueue commandBuffer];
gMetalGlobals.mtlCommandBuffer = [gMetalGlobals.mtlCommandQueue commandBuffer];
auto clearColor = Vec4_To_Array(HelloImGui::GetRunnerParams()->imGuiWindowParams.backgroundColor);
gSdlMetalGlobals.mtlRenderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(clearColor[0] * clearColor[3], clearColor[1] * clearColor[3], clearColor[2] * clearColor[3], clearColor[3]);
gSdlMetalGlobals.mtlRenderPassDescriptor.colorAttachments[0].texture = gSdlMetalGlobals.caMetalDrawable.texture;
gSdlMetalGlobals.mtlRenderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear;
gSdlMetalGlobals.mtlRenderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore;
gSdlMetalGlobals.mtlRenderCommandEncoder = [gSdlMetalGlobals.mtlCommandBuffer renderCommandEncoderWithDescriptor:gSdlMetalGlobals.mtlRenderPassDescriptor];
[gSdlMetalGlobals.mtlRenderCommandEncoder pushDebugGroup:@"ImGui demo"];
gMetalGlobals.mtlRenderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(clearColor[0] * clearColor[3], clearColor[1] * clearColor[3], clearColor[2] * clearColor[3], clearColor[3]);
gMetalGlobals.mtlRenderPassDescriptor.colorAttachments[0].texture = gMetalGlobals.caMetalDrawable.texture;
gMetalGlobals.mtlRenderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear;
gMetalGlobals.mtlRenderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore;
gMetalGlobals.mtlRenderCommandEncoder = [gMetalGlobals.mtlCommandBuffer renderCommandEncoderWithDescriptor:gMetalGlobals.mtlRenderPassDescriptor];
[gMetalGlobals.mtlRenderCommandEncoder pushDebugGroup:@"ImGui demo"];

// Start the Dear ImGui frame
ImGui_ImplMetal_NewFrame(gSdlMetalGlobals.mtlRenderPassDescriptor);
ImGui_ImplMetal_NewFrame(gMetalGlobals.mtlRenderPassDescriptor);
};

callbacks.Impl_RenderDrawData_To_3D = []
{
ImGui_ImplMetal_RenderDrawData(ImGui::GetDrawData(), gSdlMetalGlobals.mtlCommandBuffer, gSdlMetalGlobals.mtlRenderCommandEncoder);
auto& gMetalGlobals = GetMetalGlobals();
ImGui_ImplMetal_RenderDrawData(ImGui::GetDrawData(), gMetalGlobals.mtlCommandBuffer, gMetalGlobals.mtlRenderCommandEncoder);
};

// Not implemented for Metal
Expand All @@ -98,11 +112,6 @@ RenderingCallbacks CreateBackendCallbacks_SdlMetal()
return callbacks;
}

SdlMetalGlobals& GetSdlMetalGlobals()
{
return gSdlMetalGlobals;
}

} // namespace HelloImGui

#endif // HELLOIMGUI_USE_SDL2
Expand Down

0 comments on commit 55cc1bb

Please sign in to comment.