From e5e355c82566d8cfd36c064b75a6824e9e3b14f6 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Thu, 8 Nov 2018 11:53:50 +0700 Subject: [PATCH] safe sleep CPU in idle --- headers/enduro2d/utils/time.hpp | 21 ++++++++++++--------- samples/sources/sample_00/sample_00.cpp | 15 ++++++++------- samples/sources/sample_01/sample_01.cpp | 14 ++++++-------- samples/sources/sample_02/sample_02.cpp | 14 ++++++-------- sources/enduro2d/core/engine.cpp | 20 +++++++++++++------- 5 files changed, 45 insertions(+), 39 deletions(-) diff --git a/headers/enduro2d/utils/time.hpp b/headers/enduro2d/utils/time.hpp index 676e9b63..917434eb 100644 --- a/headers/enduro2d/utils/time.hpp +++ b/headers/enduro2d/utils/time.hpp @@ -181,24 +181,27 @@ namespace e2d { namespace time namespace e2d { namespace time { - template < typename TimeTag > - unit now() noexcept { + template < typename TimeTag, typename T = i64 > + unit now() noexcept { namespace ch = std::chrono; const auto n = ch::high_resolution_clock::now(); const auto m = ch::time_point_cast(n); const auto c = m.time_since_epoch().count(); - return make_microseconds(c).cast_to().convert_to(); + return make_microseconds(c).cast_to().template convert_to(); } - inline unit now_s() noexcept { - return now(); + template < typename T = i64 > + unit now_s() noexcept { + return now(); } - inline unit now_ms() noexcept { - return now(); + template < typename T = i64 > + inline unit now_ms() noexcept { + return now(); } - inline unit now_us() noexcept { - return now(); + template < typename T = i64 > + unit now_us() noexcept { + return now(); } }} diff --git a/samples/sources/sample_00/sample_00.cpp b/samples/sources/sample_00/sample_00.cpp index 64b8f8f4..65b414dc 100644 --- a/samples/sources/sample_00/sample_00.cpp +++ b/samples/sources/sample_00/sample_00.cpp @@ -26,7 +26,7 @@ namespace v_color = a_color; v_uv = a_uv; - float s = 0.7 + 0.3 * (cos(u_time * 0.003) + 1); + float s = 0.7 + 0.3 * (cos(u_time * 3.0) + 1.0); gl_Position = vec4(a_position * s, 1.0) * u_MVP; } )glsl"; @@ -42,7 +42,7 @@ namespace void main(){ vec2 uv = vec2(v_uv.s, 1.0 - v_uv.t); - if ( u_time > 2000 ) { + if ( u_time > 2.0 ) { gl_FragColor = v_color * texture2D(u_texture2, uv); } else { gl_FragColor = v_color * texture2D(u_texture1, uv); @@ -158,22 +158,22 @@ namespace .add_vertices(vertex_buffer1_) .add_vertices(vertex_buffer2_); - begin_game_time_ = time::now_ms(); return true; } bool frame_tick() final { + the().set_title(strings::rformat("FPS: %0", the().frame_rate())); + const keyboard& k = the().keyboard(); if ( the().should_close() || k.is_key_just_released(keyboard_key::escape) ) { return false; } - const auto game_time = (time::now_ms() - begin_game_time_).cast_to().value; const auto framebuffer_size = the().real_size().cast_to(); const auto projection = math::make_orthogonal_lh_matrix4(framebuffer_size, 0.f, 1.f); material_.properties() - .property("u_time", game_time) + .property("u_time", the().time()) .property("u_MVP", projection); the().execute(render::command_block<64>() @@ -193,12 +193,13 @@ namespace vertex_buffer_ptr vertex_buffer2_; render::material material_; render::geometry geometry_; - milliseconds begin_game_time_; }; } int e2d_main() { - auto params = engine::parameters("sample_00", "enduro2d"); + auto params = engine::parameters("sample_00", "enduro2d") + .timer_params(engine::timer_parameters() + .maximal_framerate(100)); modules::initialize(params).start(); return 0; } diff --git a/samples/sources/sample_01/sample_01.cpp b/samples/sources/sample_01/sample_01.cpp index 8bb12fa6..47b307f9 100644 --- a/samples/sources/sample_01/sample_01.cpp +++ b/samples/sources/sample_01/sample_01.cpp @@ -214,7 +214,6 @@ namespace .add_vertices(vertex_buffer1_) .add_vertices(vertex_buffer2_); - begin_game_time_ = time::now_ms(); return true; } @@ -224,7 +223,6 @@ namespace return false; } - const auto game_time = (time::now_ms() - begin_game_time_).cast_to().value; const auto framebuffer_size = the().real_size().cast_to(); const auto projection = math::make_perspective_lh_matrix4( make_deg(45.f), @@ -233,15 +231,14 @@ namespace 100.f); const auto MVP = - math::make_rotation_matrix4(make_rad(game_time) * 0.001f, 1.f, 0.f, 0.f) * - math::make_rotation_matrix4(make_rad(game_time) * 0.001f, 0.f, 1.f, 0.f) * - math::make_rotation_matrix4(make_rad(game_time) * 0.001f, 0.f, 0.f, 1.f) * + math::make_rotation_matrix4(make_rad(the().time()), 1.f, 0.f, 0.f) * + math::make_rotation_matrix4(make_rad(the().time()), 0.f, 1.f, 0.f) * + math::make_rotation_matrix4(make_rad(the().time()), 0.f, 0.f, 1.f) * math::make_translation_matrix4(0.f, 0.f, 0.f) * math::make_loot_at_lh_matrix4({0.f,0.f,-3.f}, v3f::zero(), v3f::unit_y()) * projection; material_.properties() - .property("u_time", game_time) .property("u_MVP", MVP); the().execute(render::command_block<64>() @@ -260,12 +257,13 @@ namespace vertex_buffer_ptr vertex_buffer2_; render::material material_; render::geometry geometry_; - milliseconds begin_game_time_; }; } int e2d_main() { - auto params = engine::parameters("sample_01", "enduro2d"); + auto params = engine::parameters("sample_01", "enduro2d") + .timer_params(engine::timer_parameters() + .maximal_framerate(100)); modules::initialize(params).start(); return 0; } diff --git a/samples/sources/sample_02/sample_02.cpp b/samples/sources/sample_02/sample_02.cpp index e97d7e66..e17e9de2 100644 --- a/samples/sources/sample_02/sample_02.cpp +++ b/samples/sources/sample_02/sample_02.cpp @@ -184,7 +184,6 @@ namespace .indices(index_buffer_) .add_vertices(vertex_buffer_); - begin_game_time_ = time::now_ms(); return true; } @@ -194,7 +193,6 @@ namespace return false; } - const auto game_time = (time::now_ms() - begin_game_time_).cast_to().value; const auto framebuffer_size = the().real_size().cast_to(); const auto projection = math::make_perspective_lh_matrix4( make_deg(45.f), @@ -203,15 +201,14 @@ namespace 100.f); const auto MVP = - math::make_rotation_matrix4(make_rad(game_time) * 0.001f, 1.f, 0.f, 0.f) * - math::make_rotation_matrix4(make_rad(game_time) * 0.001f, 0.f, 1.f, 0.f) * - math::make_rotation_matrix4(make_rad(game_time) * 0.001f, 0.f, 0.f, 1.f) * + math::make_rotation_matrix4(make_rad(the().time()), 1.f, 0.f, 0.f) * + math::make_rotation_matrix4(make_rad(the().time()), 0.f, 1.f, 0.f) * + math::make_rotation_matrix4(make_rad(the().time()), 0.f, 0.f, 1.f) * math::make_translation_matrix4(0.f, 0.f, 0.f) * math::make_loot_at_lh_matrix4({0.f,0.f,-2.f}, v3f::zero(), v3f::unit_y()) * projection; material_.properties() - .property("u_time", game_time) .property("u_MVP", MVP); the().execute(render::command_block<64>() @@ -241,12 +238,13 @@ namespace render::property_block tex_props_; render::material material_; render::geometry geometry_; - milliseconds begin_game_time_; }; } int e2d_main() { - auto params = engine::parameters("sample_02", "enduro2d"); + auto params = engine::parameters("sample_02", "enduro2d") + .timer_params(engine::timer_parameters() + .maximal_framerate(100)); modules::initialize(params).start(); return 0; } diff --git a/sources/enduro2d/core/engine.cpp b/sources/enduro2d/core/engine.cpp index 980dae92..d2ff4efd 100644 --- a/sources/enduro2d/core/engine.cpp +++ b/sources/enduro2d/core/engine.cpp @@ -246,7 +246,7 @@ namespace e2d } f32 realtime_time() const noexcept { - const auto delta_us = time::now_us().cast_to() - init_time_; + const auto delta_us = time::now_us() - init_time_; return time::to_seconds(delta_us.cast_to()).value; } public: @@ -261,10 +261,16 @@ namespace e2d second_us / math::numeric_cast(math::clamp( timer_params_.minimal_framerate(), 1u, 1000u)); - auto now_us = time::now_us().cast_to(); + auto now_us = time::now_us(); while ( now_us - prev_frame_time_ < minimal_delta_time_us ) { - std::this_thread::yield(); - now_us = time::now_us().cast_to(); + const auto sleep_us = minimal_delta_time_us - (now_us - prev_frame_time_); + const auto microsecond = make_microseconds(1000u); + if ( sleep_us > microsecond ) { + std::this_thread::sleep_for(time::to_chrono(sleep_us - microsecond)); + } else { + std::this_thread::yield(); + } + now_us = time::now_us(); } delta_time_us_.store(math::minimized( @@ -283,9 +289,9 @@ namespace e2d } private: timer_parameters timer_params_; - microseconds init_time_{time::now_us().cast_to()}; - microseconds prev_frame_time_{time::now_us().cast_to()}; - microseconds prev_frame_rate_time_{time::now_us().cast_to()}; + microseconds init_time_{time::now_us()}; + microseconds prev_frame_time_{time::now_us()}; + microseconds prev_frame_rate_time_{time::now_us()}; std::atomic time_us_{0}; std::atomic delta_time_us_{0}; std::atomic frame_rate_{0};