Examples: Metal: Wrap main event loop body in an @autoreleasepool block to ensure allocations get freed even if underlying system event loop gets paused due to app nap (#2910, #2917)
diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt
index 7ba017b..196f8f8 100644
--- a/docs/CHANGELOG.txt
+++ b/docs/CHANGELOG.txt
@@ -37,6 +37,8 @@
- Misc: Added ImGuiMouseCursor_NotAllowed enum so it can be used by more shared widgets. [@rokups]
- Backends: GLFW, SDL, Win32, OSX, Allegro: Added support for ImGuiMouseCursor_NotAllowed. [@rokups]
- Backends: GLFW: Added support for the missing mouse cursors newly added in GLFW 3.4+. [@rokups]
+- Examples: Metal: Wrapped main loop in @autoreleasepool block to ensure allocations get freed
+ even if underlying system event loop gets paused due to app nap (#2910, #2917). [@bear24rw]
-----------------------------------------------------------------------
diff --git a/examples/example_glfw_metal/main.mm b/examples/example_glfw_metal/main.mm
index 959846a..45dbb37 100644
--- a/examples/example_glfw_metal/main.mm
+++ b/examples/example_glfw_metal/main.mm
@@ -82,77 +82,80 @@
// Main loop
while (!glfwWindowShouldClose(window))
{
- // Poll and handle events (inputs, window resize, etc.)
- // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
- // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
- // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
- // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
- glfwPollEvents();
-
- int width, height;
- glfwGetFramebufferSize(window, &width, &height);
- layer.drawableSize = CGSizeMake(width, height);
- id<CAMetalDrawable> drawable = [layer nextDrawable];
-
- id<MTLCommandBuffer> commandBuffer = [commandQueue commandBuffer];
- renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(clear_color[0], clear_color[1], clear_color[2], clear_color[3]);
- renderPassDescriptor.colorAttachments[0].texture = drawable.texture;
- renderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear;
- renderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore;
- id <MTLRenderCommandEncoder> renderEncoder = [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor];
- [renderEncoder pushDebugGroup:@"ImGui demo"];
-
- // Start the Dear ImGui frame
- ImGui_ImplMetal_NewFrame(renderPassDescriptor);
- ImGui_ImplGlfw_NewFrame();
- ImGui::NewFrame();
-
- // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!).
- if (show_demo_window)
- ImGui::ShowDemoWindow(&show_demo_window);
-
- // 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window.
+ @autoreleasepool
{
- static float f = 0.0f;
- static int counter = 0;
+ // Poll and handle events (inputs, window resize, etc.)
+ // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
+ // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
+ // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
+ // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
+ glfwPollEvents();
- ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it.
+ int width, height;
+ glfwGetFramebufferSize(window, &width, &height);
+ layer.drawableSize = CGSizeMake(width, height);
+ id<CAMetalDrawable> drawable = [layer nextDrawable];
- ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too)
- ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state
- ImGui::Checkbox("Another Window", &show_another_window);
+ id<MTLCommandBuffer> commandBuffer = [commandQueue commandBuffer];
+ renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(clear_color[0], clear_color[1], clear_color[2], clear_color[3]);
+ renderPassDescriptor.colorAttachments[0].texture = drawable.texture;
+ renderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear;
+ renderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore;
+ id <MTLRenderCommandEncoder> renderEncoder = [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor];
+ [renderEncoder pushDebugGroup:@"ImGui demo"];
- ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f
- ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color
+ // Start the Dear ImGui frame
+ ImGui_ImplMetal_NewFrame(renderPassDescriptor);
+ ImGui_ImplGlfw_NewFrame();
+ ImGui::NewFrame();
- if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated)
- counter++;
- ImGui::SameLine();
- ImGui::Text("counter = %d", counter);
+ // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!).
+ if (show_demo_window)
+ ImGui::ShowDemoWindow(&show_demo_window);
- ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
- ImGui::End();
+ // 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window.
+ {
+ static float f = 0.0f;
+ static int counter = 0;
+
+ ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it.
+
+ ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too)
+ ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state
+ ImGui::Checkbox("Another Window", &show_another_window);
+
+ ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f
+ ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color
+
+ if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated)
+ counter++;
+ ImGui::SameLine();
+ ImGui::Text("counter = %d", counter);
+
+ ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
+ ImGui::End();
+ }
+
+ // 3. Show another simple window.
+ if (show_another_window)
+ {
+ ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked)
+ ImGui::Text("Hello from another window!");
+ if (ImGui::Button("Close Me"))
+ show_another_window = false;
+ ImGui::End();
+ }
+
+ // Rendering
+ ImGui::Render();
+ ImGui_ImplMetal_RenderDrawData(ImGui::GetDrawData(), commandBuffer, renderEncoder);
+
+ [renderEncoder popDebugGroup];
+ [renderEncoder endEncoding];
+
+ [commandBuffer presentDrawable:drawable];
+ [commandBuffer commit];
}
-
- // 3. Show another simple window.
- if (show_another_window)
- {
- ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked)
- ImGui::Text("Hello from another window!");
- if (ImGui::Button("Close Me"))
- show_another_window = false;
- ImGui::End();
- }
-
- // Rendering
- ImGui::Render();
- ImGui_ImplMetal_RenderDrawData(ImGui::GetDrawData(), commandBuffer, renderEncoder);
-
- [renderEncoder popDebugGroup];
- [renderEncoder endEncoding];
-
- [commandBuffer presentDrawable:drawable];
- [commandBuffer commit];
}
// Cleanup