From 9d38ce6edc7dc503a0c2a21fc75b1288297cf3ed Mon Sep 17 00:00:00 2001 From: Charles Dang Date: Thu, 29 Jun 2017 18:26:25 +1100 Subject: [PATCH] Refactor and cleanup of the drawing dispatch system Previously, drawing was handled with custom DRAW and DRAW_ALL events which individual event handlers managed. DRAW was used for only-as-needed draws, and DRAW_ALL for drawing everything. As we've switched to accelerated rendering, we've switched to the latter model all the time; everything is always drawn. Both DRAW and DRAW_ALL events aren't needed anymore and have been removed. Instead, we simply call each handler's draw() function directly from events::pump. The two main cases that handled draw events - the display class and GUI2 - just forwarded the event handler calls to their respective draw() functions anyway. Awhile back to unconditionally send draw events to the event queue constantly every 20 ms. However, to prevent draw calls from becoming backed up, the queue already had code to remove all but 1 draw event from the queue anyway, so the actual rate of drawing was still reliant on the rate at which events::pump was called. Therefor this commit should result in no change at the rate the screen is drawn. --- src/display.cpp | 14 +---- src/events.cpp | 103 +++++++-------------------------- src/events.hpp | 2 - src/gui/core/event/handler.cpp | 13 +---- src/show_dialog.cpp | 9 +-- src/video.cpp | 42 -------------- src/video.hpp | 1 - src/widgets/widget.cpp | 6 +- 8 files changed, 30 insertions(+), 160 deletions(-) diff --git a/src/display.cpp b/src/display.cpp index 070367536b0e..6fb66a2c95a2 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -2672,7 +2672,8 @@ void display::process_reachmap_changes() void display::draw() { - draw(true, false); + draw_new(); + //draw(true, false); } void display::draw(bool update) @@ -3159,20 +3160,11 @@ void display::handle_window_event(const SDL_Event& event) } } -void display::handle_event(const SDL_Event& event) +void display::handle_event(const SDL_Event& /*event*/) { if(gui2::dialogs::loading_screen::displaying()) { return; } - - switch(event.type) { - case DRAW_EVENT: - // case DRAW_ALL_EVENT: - draw_new(); - break; - default: - break; - } } display *display::singleton_ = nullptr; diff --git a/src/events.cpp b/src/events.cpp index 494bc19261a0..19cb302d2898 100644 --- a/src/events.cpp +++ b/src/events.cpp @@ -160,6 +160,10 @@ void context::set_focus(const sdl_handler* ptr) void context::add_staging_handlers() { + if(staging_handlers.empty()) { + return; + } + std::copy(staging_handlers.begin(), staging_handlers.end(), std::back_inserter(handlers)); staging_handlers.clear(); } @@ -384,10 +388,6 @@ bool last_resize_event_used = true; static bool remove_on_resize(const SDL_Event& a) { - if(a.type == DRAW_EVENT || a.type == DRAW_ALL_EVENT) { - return true; - } - if(a.type == SHOW_HELPTIP_EVENT) { return true; } @@ -403,52 +403,14 @@ static bool remove_on_resize(const SDL_Event& a) return false; } -/** - * The interval between draw events. - * - * When the window is shown this value is set, the callback function always - * uses this value instead of the parameter send, that way the window can stop - * drawing when it wants. - */ -static int draw_interval = 0; - -SDL_TimerID draw_timer_id; - -/** - * SDL_AddTimer() callback for the draw event. - * - * When this callback is called it pushes a new draw event in the event queue. - * - * @returns The new timer interval, 0 to stop. - */ -static Uint32 draw_timer(Uint32, void*) -{ - // DBG_GUI_E << "Pushing draw event in queue.\n"; - - SDL_Event event; - SDL_UserEvent data; - - data.type = DRAW_EVENT; - data.code = 0; - data.data1 = NULL; - data.data2 = NULL; - - event.type = DRAW_EVENT; - event.user = data; - - SDL_PushEvent(&event); - return draw_interval; -} - void initialise() { - draw_interval = 20; - draw_timer_id = SDL_AddTimer(draw_interval, draw_timer, NULL); + // Add things as necessary. } void finalize() { - SDL_RemoveTimer(draw_timer_id); + // Add things as necessary. } // TODO: I'm uncertain if this is always safe to call at static init; maybe set in main() instead? @@ -525,16 +487,6 @@ void pump() last_resize_event_used = true; } - // Move all draw events to the end of the queue - auto first_draw_event = std::stable_partition(events.begin(), events.end(), - [](const SDL_Event& e) { return e.type != DRAW_EVENT; } - ); - - if(first_draw_event != events.end()) { - // Remove all draw events except one - events.erase(first_draw_event + 1, events.end()); - } - ev_end = events.end(); for(ev_it = events.begin(); ev_it != ev_end; ++ev_it) { @@ -612,20 +564,6 @@ void pump() break; } - case DRAW_ALL_EVENT: { - flip_locker flip_lock(CVideo::get_singleton()); - - /* Iterate backwards as the most recent things will be at the top */ - // FIXME? ^ that isn't happening here. - for(auto& context : event_contexts) { - for(auto handler : context.handlers) { - handler->handle_event(event); - } - } - - continue; // do not do further handling here - } - #ifndef __APPLE__ case SDL_KEYDOWN: { if(event.key.keysym.sym == SDLK_F4 && @@ -659,16 +597,6 @@ void pump() } } - const bool is_draw_event = event.type == DRAW_EVENT || event.type == DRAW_ALL_EVENT; - - if(is_draw_event) { -#ifdef USE_GL_RENDERING - gl::clear_screen(); -#else - CVideo::get_singleton().clear_screen(); -#endif - } - for(auto global_handler : event_contexts.front().handlers) { global_handler->handle_event(event); } @@ -678,12 +606,23 @@ void pump() handler->handle_event(event); } } - - if(is_draw_event) { - CVideo::get_singleton().render_screen(); - } } + // + // Draw things. This is the code that actually makes anything appear on the screen. + // + CVideo& video = CVideo::get_singleton(); + +#ifdef USE_GL_RENDERING + gl::clear_screen(); +#else + video.clear_screen(); +#endif + + raise_draw_event(); + + video.render_screen(); + // Inform the pump monitors that an events::pump() has occurred for(auto monitor : pump_monitors) { monitor->process(info); diff --git a/src/events.hpp b/src/events.hpp index 79518befa285..c71aeb822201 100644 --- a/src/events.hpp +++ b/src/events.hpp @@ -23,10 +23,8 @@ #define DOUBLE_CLICK_EVENT SDL_USEREVENT #define TIMER_EVENT (SDL_USEREVENT + 1) #define HOVER_REMOVE_POPUP_EVENT (SDL_USEREVENT + 2) -#define DRAW_EVENT (SDL_USEREVENT + 3) #define CLOSE_WINDOW_EVENT (SDL_USEREVENT + 4) #define SHOW_HELPTIP_EVENT (SDL_USEREVENT + 5) -#define DRAW_ALL_EVENT (SDL_USEREVENT + 6) #define INVOKE_FUNCTION_EVENT (SDL_USEREVENT + 7) namespace events diff --git a/src/gui/core/event/handler.cpp b/src/gui/core/event/handler.cpp index 327dd99c3451..bcb225bb2f01 100644 --- a/src/gui/core/event/handler.cpp +++ b/src/gui/core/event/handler.cpp @@ -133,8 +133,7 @@ class sdl_event_handler : public events::sdl_handler void raw_event(const SDL_Event &event); /** Fires a draw event. */ - using events::sdl_handler::draw; - void draw(const bool force); + virtual void draw() override; /** * Fires a video resize event. @@ -334,13 +333,6 @@ void sdl_event_handler::handle_event(const SDL_Event& event) // remove_popup(); break; - case DRAW_EVENT: - draw(false); - break; - case DRAW_ALL_EVENT: - draw(true); - break; - case TIMER_EVENT: execute_timer(reinterpret_cast(event.user.data1)); break; @@ -376,7 +368,6 @@ void sdl_event_handler::handle_event(const SDL_Event& event) case SDL_WINDOWEVENT: switch(event.window.event) { case SDL_WINDOWEVENT_EXPOSED: - draw(true); break; case SDL_WINDOWEVENT_RESIZED: @@ -479,7 +470,7 @@ void sdl_event_handler::activate() } } -void sdl_event_handler::draw(const bool /*force*/) +void sdl_event_handler::draw() { // Don't display this event since it floods the screen // DBG_GUI_E << "Firing " << DRAW << ".\n"; diff --git a/src/show_dialog.cpp b/src/show_dialog.cpp index d0301d176582..487d118991e0 100644 --- a/src/show_dialog.cpp +++ b/src/show_dialog.cpp @@ -144,8 +144,8 @@ void dialog_frame::handle_window_event(const SDL_Event& event) { } } -void dialog_frame::handle_event(const SDL_Event& event) { - +void dialog_frame::handle_event(const SDL_Event& /*event*/) { +#if 0 if (event.type == DRAW_ALL_EVENT) { set_dirty(); @@ -155,10 +155,7 @@ void dialog_frame::handle_event(const SDL_Event& event) { } } } - - if (event.type == DRAW_EVENT || event.type == DRAW_ALL_EVENT) { - draw(); - } +#endif } int dialog_frame::bottom_padding() const { diff --git a/src/video.cpp b/src/video.cpp index 8cf82a3d33ac..7d6d09d4ce8e 100644 --- a/src/video.cpp +++ b/src/video.cpp @@ -53,33 +53,6 @@ draw_layering::draw_layering(const bool auto_join) draw_layering::~draw_layering() { draw_layers.remove(this); - - video2::trigger_full_redraw(); -} - -void trigger_full_redraw() { - SDL_Event event; - event.type = SDL_WINDOWEVENT; - event.window.event = SDL_WINDOWEVENT_RESIZED; - event.window.data1 = CVideo::get_singleton().getx(); - event.window.data2 = CVideo::get_singleton().gety(); - - for(const auto& layer : draw_layers) { - layer->handle_window_event(event); - } - - SDL_Event drawEvent; - SDL_UserEvent data; - - data.type = DRAW_ALL_EVENT; - data.code = 0; - data.data1 = nullptr; - data.data2 = nullptr; - - drawEvent.type = DRAW_ALL_EVENT; - drawEvent.user = data; - SDL_FlushEvent(DRAW_ALL_EVENT); - SDL_PushEvent(&drawEvent); } } // video2 @@ -154,21 +127,6 @@ void CVideo::video_event_handler::handle_window_event(const SDL_Event &event) case SDL_WINDOWEVENT_RESTORED: case SDL_WINDOWEVENT_SHOWN: case SDL_WINDOWEVENT_EXPOSED: - //if(display::get_singleton()) - //display::get_singleton()->redraw_everything(); - SDL_Event drawEvent; - SDL_UserEvent data; - - data.type = DRAW_ALL_EVENT; - data.code = 0; - data.data1 = nullptr; - data.data2 = nullptr; - - drawEvent.type = DRAW_ALL_EVENT; - drawEvent.user = data; - - SDL_FlushEvent(DRAW_ALL_EVENT); - SDL_PushEvent(&drawEvent); break; } } diff --git a/src/video.hpp b/src/video.hpp index b9cedd522918..8971106c5bc2 100644 --- a/src/video.hpp +++ b/src/video.hpp @@ -249,5 +249,4 @@ class draw_layering: public events::sdl_handler { draw_layering(const bool auto_join=true); virtual ~draw_layering(); }; -void trigger_full_redraw(); } diff --git a/src/widgets/widget.cpp b/src/widgets/widget.cpp index ec371f2dc65c..59a0e2c479bb 100644 --- a/src/widgets/widget.cpp +++ b/src/widgets/widget.cpp @@ -335,11 +335,7 @@ void widget::process_tooltip_string(int mousex, int mousey) } } -void widget::handle_event(SDL_Event const &event) { - if (event.type == DRAW_ALL_EVENT) { - set_dirty(); - draw(); - } +void widget::handle_event(SDL_Event const &/*event*/) { } void widget::handle_window_event(SDL_Event const &event) {