summaryrefslogtreecommitdiff
path: root/src/blitter
diff options
context:
space:
mode:
authorrubidium <rubidium@openttd.org>2014-01-13 18:17:17 +0000
committerrubidium <rubidium@openttd.org>2014-01-13 18:17:17 +0000
commiteb2c2ef877e3f0de0960c9ebc1480af80c45dfaf (patch)
treef7914ff4b26c115dbc69da882153bac943411e5c /src/blitter
parentfdf55a1a484aab3fe5e169574fd3dd5c982b1913 (diff)
downloadopenttd-eb2c2ef877e3f0de0960c9ebc1480af80c45dfaf.tar.xz
(svn r26259) -Codechange: add and maintain some general flags about sprites to prevent unneeded execution of expensive code (MJP)
Diffstat (limited to 'src/blitter')
-rw-r--r--src/blitter/32bpp_sse2.cpp17
-rw-r--r--src/blitter/32bpp_sse2.hpp15
2 files changed, 31 insertions, 1 deletions
diff --git a/src/blitter/32bpp_sse2.cpp b/src/blitter/32bpp_sse2.cpp
index 2f1dc3828..40b3620a2 100644
--- a/src/blitter/32bpp_sse2.cpp
+++ b/src/blitter/32bpp_sse2.cpp
@@ -57,7 +57,10 @@ Sprite *Blitter_32bppSSE_Base::Encode(const SpriteLoader::Sprite *sprite, Alloca
dst_sprite->y_offs = sprite->y_offs;
memcpy(dst_sprite->data, &sd, sizeof(SpriteData));
- /* Copy colours. */
+ /* Copy colours and determine flags. */
+ bool has_remap = false;
+ bool has_anim = false;
+ bool has_translucency = false;
for (ZoomLevel z = zoom_min; z <= zoom_max; z++) {
const SpriteLoader::Sprite *src_sprite = &sprite[z];
const SpriteLoader::CommonPixel *src = (const SpriteLoader::CommonPixel *) src_sprite->data;
@@ -68,8 +71,13 @@ Sprite *Blitter_32bppSSE_Base::Encode(const SpriteLoader::Sprite *sprite, Alloca
for (uint x = src_sprite->width; x != 0; x--) {
if (src->a != 0) {
dst_rgba->a = src->a;
+ if (src->a != 0 && src->a != 255) has_translucency = true;
dst_mv->m = src->m;
if (src->m != 0) {
+ /* Do some accounting for flags. */
+ has_remap = true;
+ if (src->m >= PALETTE_ANIM_START) has_anim = true;
+
/* Get brightest value (or default brightness if it's a black pixel). */
const uint8 rgb_max = max(src->r, max(src->g, src->b));
dst_mv->v = (rgb_max == 0) ? Blitter_32bppBase::DEFAULT_BRIGHTNESS : rgb_max;
@@ -119,6 +127,13 @@ Sprite *Blitter_32bppSSE_Base::Encode(const SpriteLoader::Sprite *sprite, Alloca
}
}
+ /* Store sprite flags. */
+ sd.flags = SF_NONE;
+ if (has_translucency) sd.flags |= SF_TRANSLUCENT;
+ if (!has_remap) sd.flags |= SF_NO_REMAP;
+ if (!has_anim) sd.flags |= SF_NO_ANIM;
+ memcpy(dst_sprite->data, &sd, sizeof(SpriteData));
+
return dst_sprite;
}
diff --git a/src/blitter/32bpp_sse2.hpp b/src/blitter/32bpp_sse2.hpp
index 3caf7ba76..43a5fc400 100644
--- a/src/blitter/32bpp_sse2.hpp
+++ b/src/blitter/32bpp_sse2.hpp
@@ -49,6 +49,18 @@ public:
BT_NONE, ///< No specialisation for either case.
};
+ /** Helper for using specialised functions designed to prevent whenever it's possible things like:
+ * - IO (reading video buffer),
+ * - calculations (alpha blending),
+ * - heavy branching (remap lookups and animation buffer handling).
+ */
+ enum SpriteFlags {
+ SF_NONE = 0,
+ SF_TRANSLUCENT = 1 << 1, ///< The sprite has at least 1 translucent pixel.
+ SF_NO_REMAP = 1 << 2, ///< The sprite has no remappable colour pixel.
+ SF_NO_ANIM = 1 << 3, ///< The sprite has no palette animated pixel.
+ };
+
/** Data stored about a (single) sprite. */
struct SpriteInfo {
uint32 sprite_offset; ///< The offset to the sprite data.
@@ -57,6 +69,7 @@ public:
uint16 sprite_width; ///< The width of the sprite.
};
struct SpriteData {
+ SpriteFlags flags;
SpriteInfo infos[ZOOM_LVL_COUNT];
byte data[]; ///< Data, all zoomlevels.
};
@@ -64,6 +77,8 @@ public:
Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator);
};
+DECLARE_ENUM_AS_BIT_SET(Blitter_32bppSSE_Base::SpriteFlags);
+
/** The SSE2 32 bpp blitter (without palette animation). */
class Blitter_32bppSSE2 : public Blitter_32bppSimple, public Blitter_32bppSSE_Base {
public: