diff options
author | Jonathan G Rennison <j.g.rennison@gmail.com> | 2018-01-16 23:23:52 +0000 |
---|---|---|
committer | PeterN <peter@fuzzle.org> | 2019-01-24 11:12:06 +0000 |
commit | db924a4681f019a6372f5192693af5aede36d080 (patch) | |
tree | 210488cfd3c478b086e353c10826ee834d605d6b /src/blitter | |
parent | ed325ada887f09904b3351020903899a033c6b51 (diff) | |
download | openttd-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.cpp | 19 | ||||
-rw-r--r-- | src/blitter/32bpp_anim.hpp | 1 | ||||
-rw-r--r-- | src/blitter/32bpp_base.cpp | 9 | ||||
-rw-r--r-- | src/blitter/32bpp_base.hpp | 1 | ||||
-rw-r--r-- | src/blitter/8bpp_base.cpp | 8 | ||||
-rw-r--r-- | src/blitter/8bpp_base.hpp | 1 | ||||
-rw-r--r-- | src/blitter/base.hpp | 4 | ||||
-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 */ |