yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
null_window_backend.cc
Go to the documentation of this file.
1// null_window_backend.cc - Null Window Backend Implementation (Headless)
2
7#include "imgui/backends/imgui_impl_null.h"
8#include "imgui/imgui.h"
9#include "util/log.h"
10
11namespace yaze {
12namespace platform {
13
14namespace {
15
16// Acknowledges texture requests the way a GPU renderer would.
17// ImGui_ImplNullRender_RenderDrawData() (1.93.0) acknowledges WantCreate but
18// never WantUpdates, so an atlas that rasterized new glyphs stayed in
19// WantUpdates and its Updates list grew every frame.
20void AcknowledgeTextureRequests(ImDrawData* draw_data) {
21 if (draw_data->Textures == nullptr) {
22 return;
23 }
24 for (ImTextureData* tex : *draw_data->Textures) {
25 switch (tex->Status) {
26 case ImTextureStatus_WantCreate:
27 case ImTextureStatus_WantUpdates:
28 tex->SetStatus(ImTextureStatus_OK);
29 break;
30 case ImTextureStatus_WantDestroy:
31 tex->SetTexID(ImTextureID_Invalid);
32 tex->SetStatus(ImTextureStatus_Destroyed);
33 break;
34 default:
35 break;
36 }
37 }
38}
39
40} // namespace
41
42absl::Status NullWindowBackend::Initialize(const WindowConfig& config) {
43 LOG_INFO("NullWindowBackend", "Initializing headless window backend...");
44 initialized_ = true;
45 active_ = true;
46 width_ = config.width > 0 ? config.width : 1280;
47 height_ = config.height > 0 ? config.height : 720;
48 return absl::OkStatus();
49}
50
52 LOG_INFO("NullWindowBackend", "Shutting down headless window backend");
53
56 }
57
58 // CRITICAL: Shutdown graphics arena while renderer is still conceptually valid
59 LOG_INFO("NullWindowBackend", "Shutting down graphics arena...");
61
62 initialized_ = false;
63 return absl::OkStatus();
64}
65
67 // No events in headless mode
68 return false;
69}
70
71void NullWindowBackend::ProcessNativeEvent(void* native_event) {
72 // No-op
73}
74
76 WindowStatus status;
77 status.is_active = active_;
78 status.width = width_;
79 status.height = height_;
80 // All other flags false
81 return status;
82}
83
84void NullWindowBackend::GetSize(int* width, int* height) const {
85 if (width)
86 *width = width_;
87 if (height)
88 *height = height_;
89}
90
91void NullWindowBackend::SetSize(int width, int height) {
92 width_ = width;
93 height_ = height;
94}
95
97 // Return true to pretend renderer is initialized
98 return true;
99}
100
102 // Even in headless, we might want a minimal ImGui context for test automation logic
103 // that depends on ImGui::GetIO() or similar, though we won't render.
104 if (ImGui::GetCurrentContext() == nullptr) {
105 IMGUI_CHECKVERSION();
106 ImGui::CreateContext();
107 ImGuiIO& io = ImGui::GetIO();
109 io.ConfigFlags |=
110 ImGuiConfigFlags_DockingEnable; // Required for layout initialization
111 io.IniFilename = nullptr;
112 io.DisplaySize = ImVec2((float)width_, (float)height_);
113 io.DeltaTime = 1.0f / 60.0f;
114
115 // ImGui's null platform + renderer backend sets RendererHasTextures, so
116 // NewFrame() builds the font atlas on demand and RenderImGui()
117 // acknowledges its texture requests. Init it before loading fonts so
118 // the atlas is never baked the legacy way.
119 ImGui_ImplNull_Init();
120
121 // Load standard fonts so panels don't crash accessing them
122 auto status = LoadPackageFonts();
123 if (!status.ok()) {
124 LOG_WARN("NullWindowBackend", "Failed to load package fonts: %s",
125 status.ToString().c_str());
126 }
127
128 imgui_initialized_ = true;
129 }
130 return absl::OkStatus();
131}
132
134 if (imgui_initialized_ && ImGui::GetCurrentContext() != nullptr) {
135 // Inside the imgui_initialized_ guard so the backend is shut down
136 // exactly once, while the context it was set up on still exists.
137 ImGui_ImplNull_Shutdown();
138 ImGui::DestroyContext();
139 imgui_initialized_ = false;
140 }
141}
142
144 if (imgui_initialized_) {
145 ImGui_ImplNull_NewFrame();
146 // The null platform backend always reports 1920x1080; use the size this
147 // backend was configured with instead.
148 ImGuiIO& io = ImGui::GetIO();
149 io.DisplaySize = ImVec2((float)width_, (float)height_);
150 io.DeltaTime = 1.0f / 60.0f;
151 }
152}
153
155 if (imgui_initialized_ && ImGui::GetCurrentContext() != nullptr) {
156 ImGui::Render();
157 if (ImDrawData* draw_data = ImGui::GetDrawData()) {
158 AcknowledgeTextureRequests(draw_data);
159 }
160 }
161}
162
163} // namespace platform
164} // namespace yaze
void Shutdown()
Definition arena.cc:489
static Arena & Get()
Definition arena.cc:24
Defines an abstract interface for all rendering operations.
Definition irenderer.h:60
bool PollEvent(WindowEvent &out_event) override
Poll and process pending events.
absl::Status Shutdown() override
Shutdown the window backend and release resources.
absl::Status Initialize(const WindowConfig &config) override
Initialize the window backend with configuration.
bool InitializeRenderer(gfx::IRenderer *renderer) override
Initialize renderer for this window.
WindowStatus GetStatus() const override
Get current window status.
void SetSize(int width, int height) override
Set window dimensions.
void NewImGuiFrame() override
Start a new ImGui frame.
void RenderImGui(gfx::IRenderer *renderer) override
Render ImGui draw data (and viewports if enabled)
void ShutdownImGui() override
Shutdown ImGui backends.
void GetSize(int *width, int *height) const override
Get window dimensions.
void ProcessNativeEvent(void *native_event) override
Process a native SDL event (for ImGui integration)
absl::Status InitializeImGui(gfx::IRenderer *renderer) override
Initialize ImGui backends for this window/renderer combo.
#define LOG_WARN(category, format,...)
Definition log.h:138
#define LOG_INFO(category, format,...)
Definition log.h:136
void ConfigureImGuiDiagnostics(ImGuiIO &io, ImGuiDiagnosticsBuild build)
Set Dear ImGui's error-recovery and ID-conflict options.
absl::Status LoadPackageFonts()
Window configuration parameters.
Definition iwindow.h:24
Platform-agnostic window event data.
Definition iwindow.h:65
Window backend status information.
Definition iwindow.h:117