Skip to content

Commit

Permalink
Refactor and cleanup of the drawing dispatch system
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Vultraz committed Aug 12, 2017
1 parent d8f6c31 commit 9d38ce6
Show file tree
Hide file tree
Showing 8 changed files with 30 additions and 160 deletions.
14 changes: 3 additions & 11 deletions src/display.cpp
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
103 changes: 21 additions & 82 deletions src/events.cpp
Expand Up @@ -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();
}
Expand Down Expand Up @@ -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;
}
Expand All @@ -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?
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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 &&
Expand Down Expand Up @@ -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);
}
Expand All @@ -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);
Expand Down
2 changes: 0 additions & 2 deletions src/events.hpp
Expand Up @@ -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
Expand Down
13 changes: 2 additions & 11 deletions src/gui/core/event/handler.cpp
Expand Up @@ -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.
Expand Down Expand Up @@ -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<size_t>(event.user.data1));
break;
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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";
Expand Down
9 changes: 3 additions & 6 deletions src/show_dialog.cpp
Expand Up @@ -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();

Expand All @@ -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 {
Expand Down
42 changes: 0 additions & 42 deletions src/video.cpp
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}
}
Expand Down
1 change: 0 additions & 1 deletion src/video.hpp
Expand Up @@ -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();
}
6 changes: 1 addition & 5 deletions src/widgets/widget.cpp
Expand Up @@ -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) {
Expand Down

0 comments on commit 9d38ce6

Please sign in to comment.