Files
DevilutionX/Source/engine/backbuffer_state.cpp
Gleb Mazovetskiy 23f7feba69 BackBufferState: unordered_map -> vector
A vector is a lot more efficient here as we generally
only have a handful (1-3) backbuffers.

Additionally, this avoids a lot of temporary allocations every frame,
which were apparently triggered by `emplace` even if the element
already existed.
2022-11-14 18:13:46 +01:00

109 lines
2.4 KiB
C++

#include "engine/backbuffer_state.hpp"
#include <vector>
#include "engine/dx.h"
#include "utils/enum_traits.h"
namespace devilution {
namespace {
struct RedrawState {
enum {
RedrawNone,
RedrawViewportOnly,
RedrawAll
} Redraw;
std::array<bool, enum_size<PanelDrawComponent>::value> redrawComponents;
};
struct BackbufferState {
RedrawState redrawState;
DrawnCursor cursor;
};
struct BackbufferPtrAndState {
void *ptr;
BackbufferState state;
};
std::vector<BackbufferPtrAndState> States;
BackbufferState &GetBackbufferState()
{
// `PalSurface` is null in headless mode.
void *ptr = PalSurface != nullptr ? PalSurface->pixels : nullptr;
for (BackbufferPtrAndState &ptrAndState : States) {
if (ptrAndState.ptr == ptr)
return ptrAndState.state;
}
States.emplace_back();
BackbufferPtrAndState &ptrAndState = States.back();
ptrAndState.ptr = ptr;
ptrAndState.state.redrawState.Redraw = RedrawState::RedrawAll;
return ptrAndState.state;
}
} // namespace
bool IsRedrawEverything()
{
return GetBackbufferState().redrawState.Redraw == RedrawState::RedrawAll;
}
void RedrawViewport()
{
for (BackbufferPtrAndState &ptrAndState : States) {
if (ptrAndState.state.redrawState.Redraw != RedrawState::RedrawAll) {
ptrAndState.state.redrawState.Redraw = RedrawState::RedrawViewportOnly;
}
}
}
bool IsRedrawViewport()
{
return GetBackbufferState().redrawState.Redraw == RedrawState::RedrawViewportOnly;
}
void RedrawComplete()
{
GetBackbufferState().redrawState.Redraw = RedrawState::RedrawNone;
}
void RedrawEverything()
{
for (BackbufferPtrAndState &ptrAndState : States) {
ptrAndState.state.redrawState.Redraw = RedrawState::RedrawAll;
}
}
void InitBackbufferState()
{
States.clear();
}
void RedrawComponent(PanelDrawComponent component)
{
for (BackbufferPtrAndState &ptrAndState : States) {
ptrAndState.state.redrawState.redrawComponents[static_cast<size_t>(component)] = true;
}
}
bool IsRedrawComponent(PanelDrawComponent component)
{
return GetBackbufferState().redrawState.redrawComponents[static_cast<size_t>(component)];
}
void RedrawComponentComplete(PanelDrawComponent component)
{
GetBackbufferState().redrawState.redrawComponents[static_cast<size_t>(component)] = false;
}
DrawnCursor &GetDrawnCursor()
{
return GetBackbufferState().cursor;
}
} // namespace devilution