Skip to content

Commit 471dc26

Browse files
authored
perf(gui): Significantly reduce cost of 2d render elements (TheSuperHackers#2514)
This increases the overall game performance by 20 to 50%
1 parent 2260f53 commit 471dc26

13 files changed

Lines changed: 479 additions & 156 deletions

File tree

Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1942,7 +1942,10 @@ void W3DView::draw()
19421942
/// @todo we might want to consider wiping this iterate out if there is nothing to post draw
19431943
//
19441944
TheGameClient->resetRenderedObjectCount();
1945+
1946+
TheDisplay->beginBatch();
19451947
TheGameClient->iterateDrawablesInRegion( &axisAlignedRegion, drawablePostDraw, this );
1948+
TheDisplay->endBatch();
19461949

19471950
TheGameClient->flushTextBearingDrawables();
19481951

Generals/Code/GameEngine/Include/GameClient/Display.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,12 @@ class Display : public SubsystemInterface
113113
virtual Bool isClippingEnabled() = 0;
114114
virtual void enableClipping( Bool onoff ) = 0;
115115

116+
// TheSuperHackers @performance Batching 2D draw operations to reduce state changes and draw call overhead.
117+
virtual void beginBatch(); ///< start batching 2D draw operations.
118+
virtual void endBatch(); ///< stop batching and flush pending 2D draw operations.
119+
virtual void flush(); ///< flush pending 2D draw operations without ending the batch.
120+
virtual Bool isBatching() const { return m_isBatching; } ///< returns true if currently batching 2D draw operations.
121+
116122
virtual void step() {}; ///< Do one fixed time step
117123
virtual void draw() override; ///< Redraw the entire display
118124
virtual void setTimeOfDay( TimeOfDay tod ) = 0; ///< Set the time of day for this display
@@ -182,11 +188,15 @@ class Display : public SubsystemInterface
182188
virtual Int getLastFrameDrawCalls() = 0; ///< returns the number of draw calls issued in the previous frame
183189

184190
protected:
191+
virtual void onBeginBatch() { }
192+
virtual void onEndBatch() { }
193+
virtual void onFlush() { }
185194

186195
virtual void deleteViews(); ///< delete all views
187196
UnsignedInt m_width, m_height; ///< Dimensions of the display
188197
UnsignedInt m_bitDepth; ///< bit depth of the display
189198
Bool m_windowed; ///< TRUE when windowed, FALSE when fullscreen
199+
Bool m_isBatching;
190200
View *m_viewList; ///< All of the views into the world
191201

192202
// Cinematic text data

Generals/Code/GameEngine/Source/GameClient/Display.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ Display::Display()
6666

6767
m_currentlyPlayingMovie.clear();
6868
m_letterBoxFadeStartTime = 0;
69+
m_isBatching = FALSE;
6970
}
7071

7172
/**
@@ -387,3 +388,32 @@ Display::DebugDisplayCallback *Display::getDebugDisplayCallback()
387388
{
388389
return m_debugDisplayCallback;
389390
}
391+
392+
void Display::beginBatch()
393+
{
394+
if (m_isBatching)
395+
{
396+
return;
397+
}
398+
m_isBatching = TRUE;
399+
onBeginBatch();
400+
}
401+
402+
void Display::endBatch()
403+
{
404+
if (!m_isBatching)
405+
{
406+
return;
407+
}
408+
onFlush();
409+
m_isBatching = FALSE;
410+
onEndBatch();
411+
}
412+
413+
void Display::flush()
414+
{
415+
if (m_isBatching)
416+
{
417+
onFlush();
418+
}
419+
}

Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DDisplay.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ class Render2DClass;
4545
class RTS3DScene;
4646
class RTS2DScene;
4747
class RTS3DInterfaceScene;
48+
class TextureClass;
4849

4950

5051
//=============================================================================
@@ -160,6 +161,10 @@ class W3DDisplay : public Display
160161
void calculateTerrainLOD(); ///< Calculate terrain LOD.
161162
void renderLetterBox(UnsignedInt time); ///< draw letter box border
162163
void updateAverageFPS(); ///< calculate the average fps over the last 30 frames.
164+
void setup2DRenderState(TextureClass *tex, DrawImageMode mode, Bool grayscale);
165+
virtual void onBeginBatch() override;
166+
virtual void onEndBatch() override;
167+
virtual void onFlush() override;
163168

164169
Byte m_initialized; ///< TRUE when system is initialized
165170
LightClass *m_myLight[LightEnvironmentClass::MAX_LIGHTS]; ///< light hack for now
@@ -168,6 +173,12 @@ class W3DDisplay : public Display
168173
Bool m_isClippedEnabled; ///<used by 2D drawing operations to define clip re
169174
Real m_averageFPS; ///<average fps over the last 30 frames.
170175
Real m_currentFPS; ///<current fps value.
176+
177+
TextureClass *m_batchTexture;
178+
DrawImageMode m_batchMode;
179+
Bool m_batchGrayscale;
180+
Bool m_batchNeedsInit;
181+
171182
#if defined(RTS_DEBUG)
172183
Int64 m_timerAtCumuFPSStart;
173184
#endif

0 commit comments

Comments
 (0)