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.
pull/78/head
Jonathan G Rennison 7 years ago committed by PeterN
parent ed325ada88
commit db924a4681

@ -1201,8 +1201,8 @@
<ClInclude Include="..\src\blitter\8bpp_optimized.hpp" />
<ClCompile Include="..\src\blitter\8bpp_simple.cpp" />
<ClInclude Include="..\src\blitter\8bpp_simple.hpp" />
<ClCompile Include="..\src\blitter\base.cpp" />
<ClInclude Include="..\src\blitter\base.hpp" />
<ClInclude Include="..\src\blitter\common.hpp" />
<ClInclude Include="..\src\blitter\factory.hpp" />
<ClCompile Include="..\src\blitter\null.cpp" />
<ClInclude Include="..\src\blitter\null.hpp" />

@ -2691,12 +2691,12 @@
<ClInclude Include="..\src\blitter\8bpp_simple.hpp">
<Filter>Blitters</Filter>
</ClInclude>
<ClCompile Include="..\src\blitter\base.cpp">
<Filter>Blitters</Filter>
</ClCompile>
<ClInclude Include="..\src\blitter\base.hpp">
<Filter>Blitters</Filter>
</ClInclude>
<ClInclude Include="..\src\blitter\common.hpp">
<Filter>Blitters</Filter>
</ClInclude>
<ClInclude Include="..\src\blitter\factory.hpp">
<Filter>Blitters</Filter>
</ClInclude>

@ -1201,8 +1201,8 @@
<ClInclude Include="..\src\blitter\8bpp_optimized.hpp" />
<ClCompile Include="..\src\blitter\8bpp_simple.cpp" />
<ClInclude Include="..\src\blitter\8bpp_simple.hpp" />
<ClCompile Include="..\src\blitter\base.cpp" />
<ClInclude Include="..\src\blitter\base.hpp" />
<ClInclude Include="..\src\blitter\common.hpp" />
<ClInclude Include="..\src\blitter\factory.hpp" />
<ClCompile Include="..\src\blitter\null.cpp" />
<ClInclude Include="..\src\blitter\null.hpp" />

@ -2691,12 +2691,12 @@
<ClInclude Include="..\src\blitter\8bpp_simple.hpp">
<Filter>Blitters</Filter>
</ClInclude>
<ClCompile Include="..\src\blitter\base.cpp">
<Filter>Blitters</Filter>
</ClCompile>
<ClInclude Include="..\src\blitter\base.hpp">
<Filter>Blitters</Filter>
</ClInclude>
<ClInclude Include="..\src\blitter\common.hpp">
<Filter>Blitters</Filter>
</ClInclude>
<ClInclude Include="..\src\blitter\factory.hpp">
<Filter>Blitters</Filter>
</ClInclude>

@ -948,8 +948,8 @@ blitter/8bpp_optimized.hpp
blitter/8bpp_simple.cpp
blitter/8bpp_simple.hpp
#end
blitter/base.cpp
blitter/base.hpp
blitter/common.hpp
blitter/factory.hpp
blitter/null.cpp
blitter/null.hpp

@ -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) {

@ -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);

@ -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);

@ -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);

@ -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 {

@ -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);

@ -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 */

@ -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 */
Loading…
Cancel
Save