Change how dirty screen, window and viewport areas are tracked for later redrawing

Track dirty viewport areas seperately form general screen redraws.
Maintain a dirty block grid per viewport, with a smaller block size.
Use even smaller block size in viewport map mode.

Use a rectangle array for general screen redraws instead of a block grid.

Add a dirty bit to windows and widgets, to simplify the common case
of repainting a whole window or widget, without catching
neighbouring windows or viewports.
This commit is contained in:
Jonathan G Rennison
2020-02-21 19:45:07 +00:00
parent d740a19e5f
commit 8f442500ea
18 changed files with 626 additions and 182 deletions

View File

@@ -18,6 +18,8 @@
#include "gfx_type.h"
#include "window_type.h"
#include <vector>
static const int WIDGET_LIST_END = -1; ///< indicate the end of widgets' list for vararg functions
/** Bits of the #WWT_MATRIX widget data. */
@@ -42,7 +44,7 @@ enum ArrowWidgetValues {
/**
* Window widget types, nested widget types, and nested widget part types.
*/
enum WidgetType {
enum WidgetType : uint8 {
/* Window widget types. */
WWT_EMPTY, ///< Empty widget, place holder to reserve space in widget array
@@ -106,6 +108,14 @@ enum WidgetType {
NWID_PUSHBUTTON_DROPDOWN = NWID_BUTTON_DROPDOWN | WWB_PUSHBUTTON,
};
/**
* Base widget flags.
*/
enum WidgetBaseFlags : uint8 {
WBF_DIRTY = 1 << 0, ///< Widget is dirty.
};
DECLARE_ENUM_AS_BIT_SET(WidgetBaseFlags)
/** Different forms of sizing nested widgets, using NWidgetBase::AssignSizePosition() */
enum SizingType {
ST_SMALLEST, ///< Initialize nested widget tree to smallest size. Also updates \e current_x and \e current_y.
@@ -157,9 +167,11 @@ public:
inline uint GetVerticalStepSize(SizingType sizing) const;
virtual void Draw(const Window *w) = 0;
virtual void SetDirty(const Window *w) const;
virtual void FillDirtyWidgets(std::vector<NWidgetBase *> &dirty_widgets) = 0;
virtual void SetDirty(Window *w);
WidgetType type; ///< Type of the widget / nested widget.
WidgetBaseFlags base_flags; ///< Widget base flags
uint fill_x; ///< Horizontal fill stepsize (from initial size, \c 0 means not resizable).
uint fill_y; ///< Vertical fill stepsize (from initial size, \c 0 means not resizable).
uint resize_x; ///< Horizontal resize step (\c 0 means not resizable).
@@ -304,6 +316,7 @@ public:
bool IsHighlighted() const override;
TextColour GetHighlightColour() const override;
void SetHighlighted(TextColour highlight_colour) override;
void FillDirtyWidgets(std::vector<NWidgetBase *> &dirty_widgets) override;
NWidgetDisplay disp_flags; ///< Flags that affect display and interaction with the widget.
Colours colour; ///< Colour of this widget.
@@ -420,6 +433,7 @@ public:
void Draw(const Window *w) override;
NWidgetCore *GetWidgetFromPos(int x, int y) override;
void FillDirtyWidgets(std::vector<NWidgetBase *> &dirty_widgets) override;
void SetDisplayedPlane(int plane);
@@ -445,6 +459,7 @@ public:
void Draw(const Window *w) override;
NWidgetCore *GetWidgetFromPos(int x, int y) override;
void FillDirtyWidgets(std::vector<NWidgetBase *> &dirty_widgets) override;
protected:
NWidContainerFlags flags; ///< Flags of the container.
@@ -511,6 +526,7 @@ public:
void FillNestedArray(NWidgetBase **array, uint length) override;
NWidgetCore *GetWidgetFromPos(int x, int y) override;
void FillDirtyWidgets(std::vector<NWidgetBase *> &dirty_widgets) override;
void Draw(const Window *w) override;
protected:
int index; ///< If non-negative, index in the #Window::nested_array.
@@ -540,8 +556,9 @@ public:
void FillNestedArray(NWidgetBase **array, uint length) override;
void Draw(const Window *w) override;
void SetDirty(const Window *w) const override;
void SetDirty(Window *w) override;
NWidgetCore *GetWidgetFromPos(int x, int y) override;
void FillDirtyWidgets(std::vector<NWidgetBase *> &dirty_widgets) override;
};
/**
@@ -564,6 +581,7 @@ public:
void Draw(const Window *w) override;
NWidgetCore *GetWidgetFromPos(int x, int y) override;
NWidgetBase *GetWidgetOfType(WidgetType tp) override;
void FillDirtyWidgets(std::vector<NWidgetBase *> &dirty_widgets) override;
private:
NWidgetPIPContainer *child; ///< Child widget.