|
|
|
@ -56,6 +56,12 @@ |
|
|
|
|
- (void)enqueueReusableBuffer:(MetalBuffer *)buffer; |
|
|
|
|
- (id<MTLRenderPipelineState>)renderPipelineStateForFrameAndDevice:(id<MTLDevice>)device; |
|
|
|
|
- (void)emptyRenderPipelineStateCache; |
|
|
|
|
- (void)setupRenderState:(ImDrawData *)drawData |
|
|
|
|
commandBuffer:(id<MTLCommandBuffer>)commandBuffer |
|
|
|
|
commandEncoder:(id<MTLRenderCommandEncoder>)commandEncoder |
|
|
|
|
renderPipelineState:(id<MTLRenderPipelineState>)renderPipelineState |
|
|
|
|
vertexBuffer:(MetalBuffer *)vertexBuffer |
|
|
|
|
vertexBufferOffset:(size_t)vertexBufferOffset; |
|
|
|
|
- (void)renderDrawData:(ImDrawData *)drawData |
|
|
|
|
commandBuffer:(id<MTLCommandBuffer>)commandBuffer |
|
|
|
|
commandEncoder:(id<MTLRenderCommandEncoder>)commandEncoder; |
|
|
|
@ -397,16 +403,13 @@ void ImGui_ImplMetal_DestroyDeviceObjects() |
|
|
|
|
[self.renderPipelineStateCache removeAllObjects]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
- (void)renderDrawData:(ImDrawData *)drawData |
|
|
|
|
commandBuffer:(id<MTLCommandBuffer>)commandBuffer |
|
|
|
|
commandEncoder:(id<MTLRenderCommandEncoder>)commandEncoder |
|
|
|
|
- (void)setupRenderState:(ImDrawData *)drawData |
|
|
|
|
commandBuffer:(id<MTLCommandBuffer>)commandBuffer |
|
|
|
|
commandEncoder:(id<MTLRenderCommandEncoder>)commandEncoder |
|
|
|
|
renderPipelineState:(id<MTLRenderPipelineState>)renderPipelineState |
|
|
|
|
vertexBuffer:(MetalBuffer *)vertexBuffer |
|
|
|
|
vertexBufferOffset:(size_t)vertexBufferOffset |
|
|
|
|
{ |
|
|
|
|
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) |
|
|
|
|
int fb_width = (int)(drawData->DisplaySize.x * drawData->FramebufferScale.x); |
|
|
|
|
int fb_height = (int)(drawData->DisplaySize.y * drawData->FramebufferScale.y); |
|
|
|
|
if (fb_width <= 0 || fb_height <= 0 || drawData->CmdListsCount == 0) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
[commandEncoder setCullMode:MTLCullModeNone]; |
|
|
|
|
[commandEncoder setDepthStencilState:g_sharedMetalContext.depthStencilState]; |
|
|
|
|
|
|
|
|
@ -417,12 +420,13 @@ void ImGui_ImplMetal_DestroyDeviceObjects() |
|
|
|
|
{ |
|
|
|
|
.originX = 0.0, |
|
|
|
|
.originY = 0.0, |
|
|
|
|
.width = double(fb_width), |
|
|
|
|
.height = double(fb_height), |
|
|
|
|
.width = (double)(drawData->DisplaySize.x * drawData->FramebufferScale.x), |
|
|
|
|
.height = (double)(drawData->DisplaySize.y * drawData->FramebufferScale.y), |
|
|
|
|
.znear = 0.0, |
|
|
|
|
.zfar = 1.0 |
|
|
|
|
}; |
|
|
|
|
[commandEncoder setViewport:viewport]; |
|
|
|
|
|
|
|
|
|
float L = drawData->DisplayPos.x; |
|
|
|
|
float R = drawData->DisplayPos.x + drawData->DisplaySize.x; |
|
|
|
|
float T = drawData->DisplayPos.y; |
|
|
|
@ -436,18 +440,32 @@ void ImGui_ImplMetal_DestroyDeviceObjects() |
|
|
|
|
{ 0.0f, 0.0f, 1/(F-N), 0.0f }, |
|
|
|
|
{ (R+L)/(L-R), (T+B)/(B-T), N/(F-N), 1.0f }, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
[commandEncoder setVertexBytes:&ortho_projection length:sizeof(ortho_projection) atIndex:1]; |
|
|
|
|
|
|
|
|
|
[commandEncoder setRenderPipelineState:renderPipelineState]; |
|
|
|
|
|
|
|
|
|
[commandEncoder setVertexBuffer:vertexBuffer.buffer offset:0 atIndex:0]; |
|
|
|
|
[commandEncoder setVertexBufferOffset:vertexBufferOffset atIndex:0]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
- (void)renderDrawData:(ImDrawData *)drawData |
|
|
|
|
commandBuffer:(id<MTLCommandBuffer>)commandBuffer |
|
|
|
|
commandEncoder:(id<MTLRenderCommandEncoder>)commandEncoder |
|
|
|
|
{ |
|
|
|
|
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) |
|
|
|
|
int fb_width = (int)(drawData->DisplaySize.x * drawData->FramebufferScale.x); |
|
|
|
|
int fb_height = (int)(drawData->DisplaySize.y * drawData->FramebufferScale.y); |
|
|
|
|
if (fb_width <= 0 || fb_height <= 0 || drawData->CmdListsCount == 0) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
id<MTLRenderPipelineState> renderPipelineState = [self renderPipelineStateForFrameAndDevice:commandBuffer.device]; |
|
|
|
|
|
|
|
|
|
size_t vertexBufferLength = drawData->TotalVtxCount * sizeof(ImDrawVert); |
|
|
|
|
size_t indexBufferLength = drawData->TotalIdxCount * sizeof(ImDrawIdx); |
|
|
|
|
MetalBuffer* vertexBuffer = [self dequeueReusableBufferOfLength:vertexBufferLength device:commandBuffer.device]; |
|
|
|
|
MetalBuffer* indexBuffer = [self dequeueReusableBufferOfLength:indexBufferLength device:commandBuffer.device]; |
|
|
|
|
|
|
|
|
|
id<MTLRenderPipelineState> renderPipelineState = [self renderPipelineStateForFrameAndDevice:commandBuffer.device]; |
|
|
|
|
[commandEncoder setRenderPipelineState:renderPipelineState]; |
|
|
|
|
|
|
|
|
|
[commandEncoder setVertexBuffer:vertexBuffer.buffer offset:0 atIndex:0]; |
|
|
|
|
[self setupRenderState:drawData commandBuffer:commandBuffer commandEncoder:commandEncoder renderPipelineState:renderPipelineState vertexBuffer:vertexBuffer vertexBufferOffset:0]; |
|
|
|
|
|
|
|
|
|
// Will project scissor/clipping rectangles into framebuffer space |
|
|
|
|
ImVec2 clip_off = drawData->DisplayPos; // (0,0) unless using multi-viewports |
|
|
|
@ -471,8 +489,12 @@ void ImGui_ImplMetal_DestroyDeviceObjects() |
|
|
|
|
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; |
|
|
|
|
if (pcmd->UserCallback) |
|
|
|
|
{ |
|
|
|
|
// User callback (registered via ImDrawList::AddCallback) |
|
|
|
|
pcmd->UserCallback(cmd_list, pcmd); |
|
|
|
|
// User callback, registered via ImDrawList::AddCallback() |
|
|
|
|
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.) |
|
|
|
|
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) |
|
|
|
|
[self setupRenderState:drawData commandBuffer:commandBuffer commandEncoder:commandEncoder renderPipelineState:renderPipelineState vertexBuffer:vertexBuffer vertexBufferOffset:vertexBufferOffset]; |
|
|
|
|
else |
|
|
|
|
pcmd->UserCallback(cmd_list, pcmd); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|