The Battle for Wesnoth  1.17.6+dev
draw_manager Namespace Reference

A global draw management interface. More...


static void update ()
static void layout ()
static void render ()
static bool expose ()
static void wait_for_vsync ()
static void tidy_drawables ()
void invalidate_region (const rect &region)
 Mark a region of the screen as requiring redraw. More...
void invalidate_all ()
 Mark the entire screen as requiring redraw. More...
void sparkle ()
 Ensure that everything which needs to be drawn is drawn. More...
int get_frame_length ()
 Returns the length of one display frame, in milliseconds. More...
void register_drawable (gui2::top_level_drawable *tld)
 Register a top-level drawable. More...
void deregister_drawable (gui2::top_level_drawable *tld)
 Remove a top-level drawable from the drawing stack. More...
void raise_drawable (gui2::top_level_drawable *tld)
 Raise a TLD to the top of the drawing stack. More...

Detailed Description

A global draw management interface.

This interface governs drawing things to the screen in the correct order. Drawable objects must inherit from gui2::top_level_drawable, and may be referred to as "TLD"s.

There is an absolute requirement that events happen in a certain order. This is mostly managed by this interface, which calls the TLD methods in order at most once every vsync.

The order of events is:

  1. General event processing. This is governed by events::pump() and is currently independent of this interface.
  2. Layout and animation. TLDs should ensure their layout information is up-to-date inside gui2::top_level_drawable::layout(). After this call they should know where they are on the screen, and be ready to report it via gui2::top_level_drawable::screen_location(). Animation can also be performed during this stage.
  3. Offscreen rendering. TLDs should perform any offscreen rendering during gui2::top_level_drawable::render(). After this call, all internal drawing buffers should be in a state ready for display.
  4. Drawing to the screen. Drawing to the screen should only ever happen inside gui2::top_level_drawable::expose(). Drawing to the screen at any other point is an error.

The draw manager will call layout(), render() and expose() in the correct order to ensure all TLD objects are laid out correctly and drawn in the correct order.

Drawing order of TLDs is initially set by creation time, but a TLD may be raised to the top of the drawing stack by calling draw_manager::raise_drawable() manually. register_drawable() and deregister_drawable() are called automatically by gui2::top_level_drawable in its constructor and destructor, and do not need to be manually managed.

The drawing process happens inside draw_manager::sparkle(). In general, a game loop should perform two basic steps.

  1. call events::pump() to process events. Anything other than drawing to the screen may happen during this step.
  2. call draw_manager::sparkle() to draw the screen, if necessary.

The main sparkle() function will also rate-limit, so callers do not need to add their own delay to their loops. If vsync is disabled, drawing will happen as frequently as possible. If vsync is enabled, this function will wait for the next screen refresh before drawing. In both cases, if nothing needs to be drawn the function will block for an appropriate length of time before returning.

To ensure they are presented for drawing, any drawable object must call draw_manager::invalidate_region() to indicate that an area of the screen needs to be redrawn. This may be called during any phase other than the draw phase. Invalidating regions during the draw phase is an error and will throw an exception.

Function Documentation

◆ deregister_drawable()

void draw_manager::deregister_drawable ( gui2::top_level_drawable tld)

Remove a top-level drawable from the drawing stack.

Definition at line 277 of file draw_manager.cpp.

References DBG_DM, and WRN_DM.

Referenced by gui2::top_level_drawable::~top_level_drawable().

◆ expose()

static bool draw_manager::expose ( )

◆ get_frame_length()

int draw_manager::get_frame_length ( )

Returns the length of one display frame, in milliseconds.

This will usually be determined by the active monitor's refresh rate.

Definition at line 165 of file draw_manager.cpp.

References video::current_refresh_rate(), and preferences::draw_delay().

Referenced by gui2::dialogs::loading_screen::spin(), gui2::dialogs::file_progress::update_progress(), and wait_for_vsync().

◆ invalidate_all()

void draw_manager::invalidate_all ( )

◆ invalidate_region()

void draw_manager::invalidate_region ( const rect region)

Mark a region of the screen as requiring redraw.

This should be called any time an item changes in such a way as to require redrawing.

This may only be called outside the Draw phase.

Regions are combined to result in a minimal number of draw calls, so this may be called for every invalidation without much concern.

Definition at line 61 of file draw_manager.cpp.

References rect::area(), rect::contains(), DBG_DM, ERR_DM, rect::expand_to_cover(), and rect::minimal_cover().

Referenced by display::draw(), display::draw_invalidated(), display::fade_to(), display::fade_tod_mask(), invalidate_all(), gui::dialog_frame::layout(), gui::widget::queue_redraw(), halo::halo_impl::effect::queue_redraw(), gui2::widget::queue_redraw(), halo::halo_impl::effect::queue_undraw(), display::redraw_minimap(), display::refresh_report(), display::scroll(), font::floating_label::undraw(), font::floating_label::update(), and gui::dialog_frame::~dialog_frame().

◆ layout()

static void draw_manager::layout ( )

◆ raise_drawable()

void draw_manager::raise_drawable ( gui2::top_level_drawable tld)

Raise a TLD to the top of the drawing stack.

Definition at line 294 of file draw_manager.cpp.

References DBG_DM, and ERR_DM.

Referenced by gui::dialog_frame::dialog_frame(), gui2::dialogs::loading_screen::raise(), tooltips::raise_to_top(), and register_drawable().

◆ register_drawable()

void draw_manager::register_drawable ( gui2::top_level_drawable tld)

Register a top-level drawable.

Registered drawables will be drawn in the order of registration, so the most recently-registered drawable will be "on top".

Definition at line 266 of file draw_manager.cpp.

References DBG_DM, and raise_drawable().

Referenced by gui2::top_level_drawable::operator=(), and gui2::top_level_drawable::top_level_drawable().

◆ render()

static void draw_manager::render ( )

Definition at line 203 of file draw_manager.cpp.

References i, and gui2::top_level_drawable::render().

Referenced by sparkle().

◆ sparkle()

void draw_manager::sparkle ( )

Ensure that everything which needs to be drawn is drawn.

This includes making sure window sizes and locations are up to date, updating animation frames, and drawing whatever regions of the screen need drawing or redrawing.

If vsync is enabled, this function will block until the next vblank. If nothing is drawn, it will still block for an appropriate amount of time to simulate vsync, even if vsync is disabled.

Definition at line 125 of file draw_manager.cpp.

References ERR_DM, expose(), video::headless(), layout(), render(), video::render_screen(), video::testing(), tidy_drawables(), update(), and wait_for_vsync().

Referenced by events::draw().

◆ tidy_drawables()

static void draw_manager::tidy_drawables ( )

Definition at line 314 of file draw_manager.cpp.

References DBG_DM, and gui2::dialogs::tip::remove().

Referenced by sparkle().

◆ update()

static void draw_manager::update ( )

◆ wait_for_vsync()

static void draw_manager::wait_for_vsync ( )

Definition at line 178 of file draw_manager.cpp.

References get_frame_length().

Referenced by sparkle().