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.
This commit is contained in:
parent
b746829692
commit
46eea05a67
8 changed files with 29 additions and 159 deletions
|
@ -2721,7 +2721,8 @@ void display::process_reachmap_changes()
|
|||
|
||||
void display::draw()
|
||||
{
|
||||
draw(true, false);
|
||||
draw_new();
|
||||
//draw(true, false);
|
||||
}
|
||||
|
||||
void display::draw(bool update)
|
||||
|
@ -3208,20 +3209,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
src/events.cpp
103
src/events.cpp
|
@ -161,6 +161,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();
|
||||
}
|
||||
|
@ -385,10 +389,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;
|
||||
}
|
||||
|
@ -404,52 +404,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?
|
||||
|
@ -526,16 +488,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) {
|
||||
|
@ -609,20 +561,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 &&
|
||||
|
@ -656,16 +594,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);
|
||||
}
|
||||
|
@ -675,12 +603,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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -139,9 +139,7 @@ private:
|
|||
void raw_event(const SDL_Event &event);
|
||||
|
||||
/** Fires a draw event. */
|
||||
using events::sdl_handler::draw;
|
||||
void draw();
|
||||
void draw_everything();
|
||||
virtual void draw() override;
|
||||
|
||||
/**
|
||||
* Fires a video resize event.
|
||||
|
@ -348,14 +346,6 @@ void sdl_event_handler::handle_event(const SDL_Event& event)
|
|||
// remove_popup();
|
||||
break;
|
||||
|
||||
case DRAW_EVENT:
|
||||
draw();
|
||||
break;
|
||||
|
||||
case DRAW_ALL_EVENT:
|
||||
draw_everything();
|
||||
break;
|
||||
|
||||
case TIMER_EVENT:
|
||||
execute_timer(reinterpret_cast<size_t>(event.user.data1));
|
||||
break;
|
||||
|
@ -509,15 +499,6 @@ void sdl_event_handler::draw()
|
|||
}
|
||||
}
|
||||
|
||||
void sdl_event_handler::draw_everything()
|
||||
{
|
||||
for(auto dispatcher : dispatchers_) {
|
||||
dynamic_cast<widget&>(*dispatcher).set_is_dirty(true);
|
||||
}
|
||||
|
||||
draw();
|
||||
}
|
||||
|
||||
void sdl_event_handler::video_resize(const point& new_size)
|
||||
{
|
||||
DBG_GUI_E << "Firing: " << SDL_VIDEO_RESIZE << ".\n";
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -58,30 +58,8 @@ 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(DRAW_ALL_EVENT);
|
||||
|
||||
drawEvent.type = DRAW_ALL_EVENT;
|
||||
drawEvent.user = data;
|
||||
SDL_FlushEvent(DRAW_ALL_EVENT);
|
||||
SDL_PushEvent(&drawEvent);
|
||||
}
|
||||
|
||||
} // video2
|
||||
|
||||
|
@ -151,16 +129,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(DRAW_ALL_EVENT);
|
||||
|
||||
drawEvent.type = DRAW_ALL_EVENT;
|
||||
drawEvent.user = data;
|
||||
|
||||
SDL_FlushEvent(DRAW_ALL_EVENT);
|
||||
SDL_PushEvent(&drawEvent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -341,5 +341,4 @@ protected:
|
|||
virtual ~draw_layering();
|
||||
};
|
||||
|
||||
void trigger_full_redraw();
|
||||
}
|
||||
|
|
|
@ -335,11 +335,7 @@ void widget::process_tooltip_string(int mousex, int mousey)
|
|||
}
|
||||
}
|
||||
|
||||
void widget::handle_event(const SDL_Event& event) {
|
||||
if (event.type == DRAW_ALL_EVENT) {
|
||||
set_dirty();
|
||||
draw();
|
||||
}
|
||||
void widget::handle_event(SDL_Event const &/*event*/) {
|
||||
}
|
||||
|
||||
void widget::handle_window_event(const SDL_Event& event) {
|
||||
|
|
Loading…
Add table
Reference in a new issue