summaryrefslogtreecommitdiff
path: root/src/blitter
diff options
context:
space:
mode:
authorJonathan G Rennison <j.g.rennison@gmail.com>2018-01-16 23:23:52 +0000
committerPeterN <peter@fuzzle.org>2019-01-24 11:12:06 +0000
commitdb924a4681f019a6372f5192693af5aede36d080 (patch)
tree210488cfd3c478b086e353c10826ee834d605d6b /src/blitter
parented325ada887f09904b3351020903899a033c6b51 (diff)
downloadopenttd-db924a4681f019a6372f5192693af5aede36d080.tar.xz
Codechange: [Blitter] Change DrawLine to be templated
This is remove per-pixel overheads due to use of the SetPixel virtual method. These overheads included: * expensive virtual method call which prevents inlining * palette lookup for every pixel * branch on whether palette animation is enabled on every pixel Regenerate project files.
Diffstat (limited to 'src/blitter')
-rw-r--r--src/blitter/32bpp_anim.cpp19
-rw-r--r--src/blitter/32bpp_anim.hpp1
-rw-r--r--src/blitter/32bpp_base.cpp9
-rw-r--r--src/blitter/32bpp_base.hpp1
-rw-r--r--src/blitter/8bpp_base.cpp8
-rw-r--r--src/blitter/8bpp_base.hpp1
-rw-r--r--src/blitter/base.hpp4
-rw-r--r--src/blitter/common.hpp (renamed from src/blitter/base.cpp)19
8 files changed, 53 insertions, 9 deletions
diff --git a/src/blitter/32bpp_anim.cpp b/src/blitter/32bpp_anim.cpp
index 98ae22b00..27b1fbd5b 100644
--- a/src/blitter/32bpp_anim.cpp
+++ b/src/blitter/32bpp_anim.cpp
@@ -12,6 +12,7 @@
#include "../stdafx.h"
#include "../video/video_driver.hpp"
#include "32bpp_anim.hpp"
+#include "common.hpp"
#include "../table/sprites.h"
@@ -321,6 +322,24 @@ void Blitter_32bppAnim::SetPixel(void *video, int x, int y, uint8 colour)
this->anim_buf[this->ScreenToAnimOffset((uint32 *)video) + x + y * this->anim_buf_pitch] = colour | (DEFAULT_BRIGHTNESS << 8);
}
+void Blitter_32bppAnim::DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash)
+{
+ const Colour c = LookupColourInPalette(colour);
+
+ if (_screen_disable_anim) {
+ this->DrawLineGeneric(x, y, x2, y2, screen_width, screen_height, width, dash, [&](int x, int y) {
+ *((Colour *)video + x + y * _screen.pitch) = c;
+ });
+ } else {
+ uint16 * const offset_anim_buf = this->anim_buf + this->ScreenToAnimOffset((uint32 *)video);
+ const uint16 anim_colour = colour | (DEFAULT_BRIGHTNESS << 8);
+ this->DrawLineGeneric(x, y, x2, y2, screen_width, screen_height, width, dash, [&](int x, int y) {
+ *((Colour *)video + x + y * _screen.pitch) = c;
+ offset_anim_buf[x + y * this->anim_buf_pitch] = anim_colour;
+ });
+ }
+}
+
void Blitter_32bppAnim::DrawRect(void *video, int width, int height, uint8 colour)
{
if (_screen_disable_anim) {
diff --git a/src/blitter/32bpp_anim.hpp b/src/blitter/32bpp_anim.hpp
index da33ec95b..ecf6dcfca 100644
--- a/src/blitter/32bpp_anim.hpp
+++ b/src/blitter/32bpp_anim.hpp
@@ -40,6 +40,7 @@ public:
/* virtual */ void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom);
/* virtual */ void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal);
/* virtual */ void SetPixel(void *video, int x, int y, uint8 colour);
+ /* virtual */ void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash);
/* virtual */ void DrawRect(void *video, int width, int height, uint8 colour);
/* virtual */ void CopyFromBuffer(void *video, const void *src, int width, int height);
/* virtual */ void CopyToBuffer(const void *video, void *dst, int width, int height);
diff --git a/src/blitter/32bpp_base.cpp b/src/blitter/32bpp_base.cpp
index c396e4541..b2e66b0be 100644
--- a/src/blitter/32bpp_base.cpp
+++ b/src/blitter/32bpp_base.cpp
@@ -11,6 +11,7 @@
#include "../stdafx.h"
#include "32bpp_base.hpp"
+#include "common.hpp"
#include "../safeguards.h"
@@ -24,6 +25,14 @@ void Blitter_32bppBase::SetPixel(void *video, int x, int y, uint8 colour)
*((Colour *)video + x + y * _screen.pitch) = LookupColourInPalette(colour);
}
+void Blitter_32bppBase::DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash)
+{
+ const Colour c = LookupColourInPalette(colour);
+ this->DrawLineGeneric(x, y, x2, y2, screen_width, screen_height, width, dash, [=](int x, int y) {
+ *((Colour *)video + x + y * _screen.pitch) = c;
+ });
+}
+
void Blitter_32bppBase::DrawRect(void *video, int width, int height, uint8 colour)
{
Colour colour32 = LookupColourInPalette(colour);
diff --git a/src/blitter/32bpp_base.hpp b/src/blitter/32bpp_base.hpp
index 9b7627170..697593da6 100644
--- a/src/blitter/32bpp_base.hpp
+++ b/src/blitter/32bpp_base.hpp
@@ -23,6 +23,7 @@ public:
/* virtual */ uint8 GetScreenDepth() { return 32; }
/* virtual */ void *MoveTo(void *video, int x, int y);
/* virtual */ void SetPixel(void *video, int x, int y, uint8 colour);
+ /* virtual */ void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash);
/* virtual */ void DrawRect(void *video, int width, int height, uint8 colour);
/* virtual */ void CopyFromBuffer(void *video, const void *src, int width, int height);
/* virtual */ void CopyToBuffer(const void *video, void *dst, int width, int height);
diff --git a/src/blitter/8bpp_base.cpp b/src/blitter/8bpp_base.cpp
index eab6eaa0d..dccfda3d7 100644
--- a/src/blitter/8bpp_base.cpp
+++ b/src/blitter/8bpp_base.cpp
@@ -12,6 +12,7 @@
#include "../stdafx.h"
#include "../gfx_func.h"
#include "8bpp_base.hpp"
+#include "common.hpp"
#include "../safeguards.h"
@@ -35,6 +36,13 @@ void Blitter_8bppBase::SetPixel(void *video, int x, int y, uint8 colour)
*((uint8 *)video + x + y * _screen.pitch) = colour;
}
+void Blitter_8bppBase::DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash)
+{
+ this->DrawLineGeneric(x, y, x2, y2, screen_width, screen_height, width, dash, [=](int x, int y) {
+ *((uint8 *)video + x + y * _screen.pitch) = colour;
+ });
+}
+
void Blitter_8bppBase::DrawRect(void *video, int width, int height, uint8 colour)
{
do {
diff --git a/src/blitter/8bpp_base.hpp b/src/blitter/8bpp_base.hpp
index 2dff78499..8f75dda5d 100644
--- a/src/blitter/8bpp_base.hpp
+++ b/src/blitter/8bpp_base.hpp
@@ -21,6 +21,7 @@ public:
/* virtual */ void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal);
/* virtual */ void *MoveTo(void *video, int x, int y);
/* virtual */ void SetPixel(void *video, int x, int y, uint8 colour);
+ /* virtual */ void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash);
/* virtual */ void DrawRect(void *video, int width, int height, uint8 colour);
/* virtual */ void CopyFromBuffer(void *video, const void *src, int width, int height);
/* virtual */ void CopyToBuffer(const void *video, void *dst, int width, int height);
diff --git a/src/blitter/base.hpp b/src/blitter/base.hpp
index a9403b339..388359441 100644
--- a/src/blitter/base.hpp
+++ b/src/blitter/base.hpp
@@ -122,7 +122,7 @@ public:
* @param width Line width.
* @param dash Length of dashes for dashed lines. 0 means solid line.
*/
- virtual void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash = 0);
+ virtual void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash = 0) = 0;
/**
* Copy from a buffer to the screen.
@@ -203,6 +203,8 @@ public:
virtual void PostResize() { };
virtual ~Blitter() { }
+
+ template <typename SetPixelT> void DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, int screen_height, int width, int dash, SetPixelT set_pixel);
};
#endif /* BLITTER_BASE_HPP */
diff --git a/src/blitter/base.cpp b/src/blitter/common.hpp
index e83df2e71..0e255ca9a 100644
--- a/src/blitter/base.cpp
+++ b/src/blitter/common.hpp
@@ -7,15 +7,16 @@
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
-/** @file base.cpp Implementation of the base for all blitters. */
+/** @file common.hpp Common functionality for all blitter implementations. */
+
+#ifndef BLITTER_COMMON_HPP
+#define BLITTER_COMMON_HPP
-#include "../stdafx.h"
#include "base.hpp"
#include "../core/math_func.hpp"
-#include "../safeguards.h"
-
-void Blitter::DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash)
+template <typename SetPixelT>
+void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, int screen_height, int width, int dash, SetPixelT set_pixel)
{
int dy;
int dx;
@@ -40,7 +41,7 @@ void Blitter::DrawLine(void *video, int x, int y, int x2, int y2, int screen_wid
if (dx == 0 && dy == 0) {
/* The algorithm below cannot handle this special case; make it work at least for line width 1 */
- if (x >= 0 && x < screen_width && y >= 0 && y < screen_height) this->SetPixel(video, x, y, colour);
+ if (x >= 0 && x < screen_width && y >= 0 && y < screen_height) set_pixel(x, y);
return;
}
@@ -83,7 +84,7 @@ void Blitter::DrawLine(void *video, int x, int y, int x2, int y2, int screen_wid
while (x != x2) {
if (dash_count < dash && x >= 0 && x < screen_width) {
for (int y = y_low; y != y_high; y += stepy) {
- if (y >= 0 && y < screen_height) this->SetPixel(video, x, y, colour);
+ if (y >= 0 && y < screen_height) set_pixel(x, y);
}
}
if (frac_low >= 0) {
@@ -118,7 +119,7 @@ void Blitter::DrawLine(void *video, int x, int y, int x2, int y2, int screen_wid
while (y != y2) {
if (dash_count < dash && y >= 0 && y < screen_height) {
for (int x = x_low; x != x_high; x += stepx) {
- if (x >= 0 && x < screen_width) this->SetPixel(video, x, y, colour);
+ if (x >= 0 && x < screen_width) set_pixel(x, y);
}
}
if (frac_low >= 0) {
@@ -136,3 +137,5 @@ void Blitter::DrawLine(void *video, int x, int y, int x2, int y2, int screen_wid
}
}
}
+
+#endif /* BLITTER_COMMON_HPP */