@@ -52,6 +52,27 @@ void UImGui::RendererInternal::tick(void* rendererInstance) noexcept
52
52
{
53
53
auto & inst = *(static_cast <RendererInternal*>(rendererInstance));
54
54
static double deltaTime = 0 .0f ;
55
+
56
+ #ifndef __EMSCRIPTEN__
57
+ inst.bIdling = false ;
58
+ if (inst.data .idleFrameRate > 0 .0f && inst.data .bEnablePowerSavingMode )
59
+ {
60
+ const double waitTimeout = 1.0 / inst.data .idleFrameRate ;
61
+
62
+ Timer timer;
63
+ timer.start ();
64
+
65
+ glfwWaitEventsTimeout (waitTimeout);
66
+
67
+ timer.stop ();
68
+ const double elapsed = timer.get ();
69
+ const double duration = elapsed - waitTimeout;
70
+ const double idleExpected = 1.0 / inst.data .idleFrameRate ;
71
+
72
+ inst.bIdling = duration > (idleExpected * 0.9 );
73
+ }
74
+ #endif
75
+
55
76
glfwPollEvents ();
56
77
57
78
const double now = glfwGetTime ();
@@ -61,6 +82,48 @@ void UImGui::RendererInternal::tick(void* rendererInstance) noexcept
61
82
// Updates the state of the keybindings
62
83
Global::get ().window .updateKeyState ();
63
84
85
+ #ifdef __EMSCRIPTEN__
86
+ if (inst.data .idleFrameRate > 0 .0f && inst.data .bEnablePowerSavingMode )
87
+ {
88
+ ImGuiContext& g = *ImGui::GetCurrentContext ();
89
+ bool bHasInputEvent = !g.InputEventsQueue .empty ();
90
+
91
+ static double lastRefreshTime = 0 .0f ;
92
+ static double accumulatedTime = 0 .0f ;
93
+ accumulatedTime += deltaTime;
94
+
95
+ bool bShouldIdle = false ;
96
+ if (bHasInputEvent)
97
+ {
98
+ inst.bIdling = false ;
99
+ bShouldIdle = false ;
100
+ }
101
+ else
102
+ {
103
+ inst.bIdling = true ;
104
+ if ((accumulatedTime - lastRefreshTime) < 1.0 / inst.data .idleFrameRate )
105
+ bShouldIdle = true ;
106
+ else
107
+ bShouldIdle = false ;
108
+ }
109
+
110
+ if (!bShouldIdle)
111
+ {
112
+ lastRefreshTime = accumulatedTime;
113
+ accumulatedTime = 0 .0f ;
114
+ }
115
+ else
116
+ {
117
+ lastRefreshTime = 0 .0f ;
118
+ return ;
119
+ }
120
+ }
121
+ #endif
122
+
123
+ // Do not render if the window is minimised
124
+ if (Window::getWindowIconified ())
125
+ glfwWaitEvents ();
126
+
64
127
inst.renderer ->renderStart (deltaTime);
65
128
GUIRenderer::beginUI (static_cast <float >(deltaTime), inst.renderer );
66
129
inst.renderer ->renderEnd (deltaTime);
@@ -90,6 +153,15 @@ void UImGui::RendererInternal::loadConfig() noexcept
90
153
data.bUsingVSync = node[" v-sync" ].as <bool >();
91
154
if (node[" msaa-samples" ])
92
155
data.msaaSamples = node[" msaa-samples" ].as <uint32_t >();
156
+
157
+ const auto & powerSaving = node[" power-saving" ];
158
+ if (powerSaving)
159
+ {
160
+ if (powerSaving[" enabled" ])
161
+ data.bEnablePowerSavingMode = powerSaving[" enabled" ].as <bool >();
162
+ if (powerSaving[" idle-frames" ])
163
+ data.idleFrameRate = powerSaving[" idle-frames" ].as <float >();
164
+ }
93
165
}
94
166
95
167
void UImGui::RendererInternal::saveConfig () const noexcept
@@ -100,6 +172,10 @@ void UImGui::RendererInternal::saveConfig() const noexcept
100
172
out << YAML::Key << " vulkan" << YAML::Value << data.bVulkan ;
101
173
out << YAML::Key << " v-sync" << YAML::Value << data.bUsingVSync ;
102
174
out << YAML::Key << " msaa-samples" << YAML::Value << data.msaaSamples ;
175
+ out << YAML::Key << " power-saving" << YAML::Value << YAML::BeginMap;
176
+ out << YAML::Key << " enabled" << YAML::Value << data.bEnablePowerSavingMode ;
177
+ out << YAML::Key << " idle-frames" << YAML::Value << data.idleFrameRate ;
178
+ out << YAML::EndMap;
103
179
104
180
std::ofstream fout ((Instance::get ()->initInfo .configDir + " Core/Renderer.yaml" ).c_str ());
105
181
fout << out.c_str ();
0 commit comments