safe sleep CPU in idle

This commit is contained in:
2018-11-08 11:53:50 +07:00
parent f12d7e8e22
commit e5e355c825
5 changed files with 45 additions and 39 deletions

View File

@@ -181,24 +181,27 @@ namespace e2d { namespace time
namespace e2d { namespace time namespace e2d { namespace time
{ {
template < typename TimeTag > template < typename TimeTag, typename T = i64 >
unit<i64, TimeTag> now() noexcept { unit<T, TimeTag> now() noexcept {
namespace ch = std::chrono; namespace ch = std::chrono;
const auto n = ch::high_resolution_clock::now(); const auto n = ch::high_resolution_clock::now();
const auto m = ch::time_point_cast<ch::microseconds>(n); const auto m = ch::time_point_cast<ch::microseconds>(n);
const auto c = m.time_since_epoch().count(); const auto c = m.time_since_epoch().count();
return make_microseconds(c).cast_to<i64>().convert_to<TimeTag>(); return make_microseconds(c).cast_to<T>().template convert_to<TimeTag>();
} }
inline unit<i64, seconds_tag> now_s() noexcept { template < typename T = i64 >
return now<seconds_tag>(); unit<T, seconds_tag> now_s() noexcept {
return now<seconds_tag, T>();
} }
inline unit<i64, milliseconds_tag> now_ms() noexcept { template < typename T = i64 >
return now<milliseconds_tag>(); inline unit<T, milliseconds_tag> now_ms() noexcept {
return now<milliseconds_tag, T>();
} }
inline unit<i64, microseconds_tag> now_us() noexcept { template < typename T = i64 >
return now<microseconds_tag>(); unit<T, microseconds_tag> now_us() noexcept {
return now<microseconds_tag, T>();
} }
}} }}

View File

@@ -26,7 +26,7 @@ namespace
v_color = a_color; v_color = a_color;
v_uv = a_uv; 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; gl_Position = vec4(a_position * s, 1.0) * u_MVP;
} }
)glsl"; )glsl";
@@ -42,7 +42,7 @@ namespace
void main(){ void main(){
vec2 uv = vec2(v_uv.s, 1.0 - v_uv.t); 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); gl_FragColor = v_color * texture2D(u_texture2, uv);
} else { } else {
gl_FragColor = v_color * texture2D(u_texture1, uv); gl_FragColor = v_color * texture2D(u_texture1, uv);
@@ -158,22 +158,22 @@ namespace
.add_vertices(vertex_buffer1_) .add_vertices(vertex_buffer1_)
.add_vertices(vertex_buffer2_); .add_vertices(vertex_buffer2_);
begin_game_time_ = time::now_ms();
return true; return true;
} }
bool frame_tick() final { bool frame_tick() final {
the<window>().set_title(strings::rformat("FPS: %0", the<engine>().frame_rate()));
const keyboard& k = the<input>().keyboard(); const keyboard& k = the<input>().keyboard();
if ( the<window>().should_close() || k.is_key_just_released(keyboard_key::escape) ) { if ( the<window>().should_close() || k.is_key_just_released(keyboard_key::escape) ) {
return false; return false;
} }
const auto game_time = (time::now_ms() - begin_game_time_).cast_to<f32>().value;
const auto framebuffer_size = the<window>().real_size().cast_to<f32>(); const auto framebuffer_size = the<window>().real_size().cast_to<f32>();
const auto projection = math::make_orthogonal_lh_matrix4(framebuffer_size, 0.f, 1.f); const auto projection = math::make_orthogonal_lh_matrix4(framebuffer_size, 0.f, 1.f);
material_.properties() material_.properties()
.property("u_time", game_time) .property("u_time", the<engine>().time())
.property("u_MVP", projection); .property("u_MVP", projection);
the<render>().execute(render::command_block<64>() the<render>().execute(render::command_block<64>()
@@ -193,12 +193,13 @@ namespace
vertex_buffer_ptr vertex_buffer2_; vertex_buffer_ptr vertex_buffer2_;
render::material material_; render::material material_;
render::geometry geometry_; render::geometry geometry_;
milliseconds<i64> begin_game_time_;
}; };
} }
int e2d_main() { 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<engine>(params).start<game>(); modules::initialize<engine>(params).start<game>();
return 0; return 0;
} }

View File

@@ -214,7 +214,6 @@ namespace
.add_vertices(vertex_buffer1_) .add_vertices(vertex_buffer1_)
.add_vertices(vertex_buffer2_); .add_vertices(vertex_buffer2_);
begin_game_time_ = time::now_ms();
return true; return true;
} }
@@ -224,7 +223,6 @@ namespace
return false; return false;
} }
const auto game_time = (time::now_ms() - begin_game_time_).cast_to<f32>().value;
const auto framebuffer_size = the<window>().real_size().cast_to<f32>(); const auto framebuffer_size = the<window>().real_size().cast_to<f32>();
const auto projection = math::make_perspective_lh_matrix4( const auto projection = math::make_perspective_lh_matrix4(
make_deg(45.f), make_deg(45.f),
@@ -233,15 +231,14 @@ namespace
100.f); 100.f);
const auto MVP = 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(the<engine>().time()), 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(the<engine>().time()), 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<engine>().time()), 0.f, 0.f, 1.f) *
math::make_translation_matrix4(0.f, 0.f, 0.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()) * math::make_loot_at_lh_matrix4({0.f,0.f,-3.f}, v3f::zero(), v3f::unit_y()) *
projection; projection;
material_.properties() material_.properties()
.property("u_time", game_time)
.property("u_MVP", MVP); .property("u_MVP", MVP);
the<render>().execute(render::command_block<64>() the<render>().execute(render::command_block<64>()
@@ -260,12 +257,13 @@ namespace
vertex_buffer_ptr vertex_buffer2_; vertex_buffer_ptr vertex_buffer2_;
render::material material_; render::material material_;
render::geometry geometry_; render::geometry geometry_;
milliseconds<i64> begin_game_time_;
}; };
} }
int e2d_main() { 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<engine>(params).start<game>(); modules::initialize<engine>(params).start<game>();
return 0; return 0;
} }

View File

@@ -184,7 +184,6 @@ namespace
.indices(index_buffer_) .indices(index_buffer_)
.add_vertices(vertex_buffer_); .add_vertices(vertex_buffer_);
begin_game_time_ = time::now_ms();
return true; return true;
} }
@@ -194,7 +193,6 @@ namespace
return false; return false;
} }
const auto game_time = (time::now_ms() - begin_game_time_).cast_to<f32>().value;
const auto framebuffer_size = the<window>().real_size().cast_to<f32>(); const auto framebuffer_size = the<window>().real_size().cast_to<f32>();
const auto projection = math::make_perspective_lh_matrix4( const auto projection = math::make_perspective_lh_matrix4(
make_deg(45.f), make_deg(45.f),
@@ -203,15 +201,14 @@ namespace
100.f); 100.f);
const auto MVP = 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(the<engine>().time()), 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(the<engine>().time()), 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<engine>().time()), 0.f, 0.f, 1.f) *
math::make_translation_matrix4(0.f, 0.f, 0.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()) * math::make_loot_at_lh_matrix4({0.f,0.f,-2.f}, v3f::zero(), v3f::unit_y()) *
projection; projection;
material_.properties() material_.properties()
.property("u_time", game_time)
.property("u_MVP", MVP); .property("u_MVP", MVP);
the<render>().execute(render::command_block<64>() the<render>().execute(render::command_block<64>()
@@ -241,12 +238,13 @@ namespace
render::property_block tex_props_; render::property_block tex_props_;
render::material material_; render::material material_;
render::geometry geometry_; render::geometry geometry_;
milliseconds<i64> begin_game_time_;
}; };
} }
int e2d_main() { 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<engine>(params).start<game>(); modules::initialize<engine>(params).start<game>();
return 0; return 0;
} }

View File

@@ -246,7 +246,7 @@ namespace e2d
} }
f32 realtime_time() const noexcept { f32 realtime_time() const noexcept {
const auto delta_us = time::now_us().cast_to<u64>() - init_time_; const auto delta_us = time::now_us<u64>() - init_time_;
return time::to_seconds(delta_us.cast_to<f32>()).value; return time::to_seconds(delta_us.cast_to<f32>()).value;
} }
public: public:
@@ -261,10 +261,16 @@ namespace e2d
second_us / math::numeric_cast<u64>(math::clamp( second_us / math::numeric_cast<u64>(math::clamp(
timer_params_.minimal_framerate(), 1u, 1000u)); timer_params_.minimal_framerate(), 1u, 1000u));
auto now_us = time::now_us().cast_to<u64>(); auto now_us = time::now_us<u64>();
while ( now_us - prev_frame_time_ < minimal_delta_time_us ) { while ( now_us - prev_frame_time_ < minimal_delta_time_us ) {
std::this_thread::yield(); const auto sleep_us = minimal_delta_time_us - (now_us - prev_frame_time_);
now_us = time::now_us().cast_to<u64>(); const auto microsecond = make_microseconds<u64>(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<u64>();
} }
delta_time_us_.store(math::minimized( delta_time_us_.store(math::minimized(
@@ -283,9 +289,9 @@ namespace e2d
} }
private: private:
timer_parameters timer_params_; timer_parameters timer_params_;
microseconds<u64> init_time_{time::now_us().cast_to<u64>()}; microseconds<u64> init_time_{time::now_us<u64>()};
microseconds<u64> prev_frame_time_{time::now_us().cast_to<u64>()}; microseconds<u64> prev_frame_time_{time::now_us<u64>()};
microseconds<u64> prev_frame_rate_time_{time::now_us().cast_to<u64>()}; microseconds<u64> prev_frame_rate_time_{time::now_us<u64>()};
std::atomic<u64> time_us_{0}; std::atomic<u64> time_us_{0};
std::atomic<u64> delta_time_us_{0}; std::atomic<u64> delta_time_us_{0};
std::atomic<u32> frame_rate_{0}; std::atomic<u32> frame_rate_{0};