Codechange: make 32bpp blitter enumerations scoped

This commit is contained in:
Rubidium
2026-06-26 15:50:46 +02:00
committed by rubidium42
parent 42fe1133ad
commit cc92e3d421
4 changed files with 63 additions and 49 deletions
+37 -25
View File
@@ -43,7 +43,7 @@ inline void Blitter_32bppSSE4_Anim::Draw(const BlitterParams *bp, ZoomLevel zoom
const MapValue *src_mv_line = (const MapValue *) &sd->data[si->mv_offset] + bp->skip_top * si->sprite_width;
const Colour *src_rgba_line = (const Colour *) ((const uint8_t *) &sd->data[si->sprite_offset] + bp->skip_top * si->sprite_line_size);
if (read_mode != RM_WITH_MARGIN) {
if (read_mode != ReadMode::WithMargin) {
src_rgba_line += bp->skip_left;
src_mv_line += bp->skip_left;
}
@@ -61,8 +61,8 @@ inline void Blitter_32bppSSE4_Anim::Draw(const BlitterParams *bp, ZoomLevel zoom
if (mode != BlitterMode::Transparent) src_mv = src_mv_line;
uint16_t *anim = anim_line;
if (read_mode == RM_WITH_MARGIN) {
assert(bt_last == BT_NONE); // or you must ensure block type is preserved
if (read_mode == ReadMode::WithMargin) {
assert(bt_last == BlockType::None); // or you must ensure block type is preserved
anim += src_rgba_line[0].data;
src += src_rgba_line[0].data;
dst += src_rgba_line[0].data;
@@ -155,7 +155,7 @@ bmno_full_transparency:
dst += 2;
}
if ((bt_last == BT_NONE && effective_width & 1) || bt_last == BT_ODD) {
if ((bt_last == BlockType::None && effective_width & 1) || bt_last == BlockType::Odd) {
if (src->a == 0) {
/* Complete transparency. */
} else if (src->a == 255) {
@@ -266,7 +266,7 @@ bmcr_full_transparency:
anim += 2;
}
if ((bt_last == BT_NONE && effective_width & 1) || bt_last == BT_ODD) {
if ((bt_last == BlockType::None && effective_width & 1) || bt_last == BlockType::Odd) {
/* In case the m-channel is zero, do not remap this pixel in any way. */
__m128i srcABCD;
if (src->a == 0) break;
@@ -309,7 +309,7 @@ bmcr_alpha_blend_single:
if (src[-1].a) anim[-1] = 0;
}
if ((bt_last == BT_NONE && bp->width & 1) || bt_last == BT_ODD) {
if ((bt_last == BlockType::None && bp->width & 1) || bt_last == BlockType::Odd) {
__m128i srcABCD = _mm_cvtsi32_si128(src->data);
__m128i dstABCD = _mm_cvtsi32_si128(dst->data);
dst->data = _mm_cvtsi128_si32(DarkenTwoPixels(srcABCD, dstABCD, a_cm, tr_nom_base));
@@ -373,6 +373,25 @@ next_line:
}
}
/**
* Draws a sprite to a (screen) buffer. It is templated to allow faster operation.
*
* @tparam mode blitter mode
* @param bp further blitting parameters
* @param zoom zoom level at which we are drawing
* @param animated Whether the sprite is animated.
*/
template <BlitterMode mode, Blitter_32bppSSE_Base::ReadMode read_mode, Blitter_32bppSSE_Base::BlockType bt_last, bool translucent>
inline void Blitter_32bppSSE4_Anim::Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom, bool animated)
{
if (animated) {
this->Draw<mode, read_mode, bt_last, translucent, true>(bp, zoom);
} else {
this->Draw<mode, read_mode, bt_last, translucent, false>(bp, zoom);
}
}
/**
* Draws a sprite to a (screen) buffer. Calls adequate templated function.
*
@@ -394,25 +413,20 @@ void Blitter_32bppSSE4_Anim::Draw(Blitter::BlitterParams *bp, BlitterMode mode,
bm_normal:
if (bp->skip_left != 0 || bp->width <= MARGIN_NORMAL_THRESHOLD) {
const BlockType bt_last = (BlockType) (bp->width & 1);
if (bt_last == BT_EVEN) {
if (sprite_flags.Test(SpriteFlag::NoAnim)) Draw<BlitterMode::Normal, RM_WITH_SKIP, BT_EVEN, true, false>(bp, zoom);
else Draw<BlitterMode::Normal, RM_WITH_SKIP, BT_EVEN, true, true>(bp, zoom);
if (bt_last == BlockType::Even) {
Draw<BlitterMode::Normal, ReadMode::WithSkip, BlockType::Even, true>(bp, zoom, !sprite_flags.Test(SpriteFlag::NoAnim));
} else {
if (sprite_flags.Test(SpriteFlag::NoAnim)) Draw<BlitterMode::Normal, RM_WITH_SKIP, BT_ODD, true, false>(bp, zoom);
else Draw<BlitterMode::Normal, RM_WITH_SKIP, BT_ODD, true, true>(bp, zoom);
Draw<BlitterMode::Normal, ReadMode::WithSkip, BlockType::Odd, true>(bp, zoom, !sprite_flags.Test(SpriteFlag::NoAnim));
}
} else {
#ifdef POINTER_IS_64BIT
if (sprite_flags.Test(SpriteFlag::Translucent)) {
if (sprite_flags.Test(SpriteFlag::NoAnim)) Draw<BlitterMode::Normal, RM_WITH_MARGIN, BT_NONE, true, false>(bp, zoom);
else Draw<BlitterMode::Normal, RM_WITH_MARGIN, BT_NONE, true, true>(bp, zoom);
Draw<BlitterMode::Normal, ReadMode::WithMargin, BlockType::None, true>(bp, zoom, !sprite_flags.Test(SpriteFlag::NoAnim));
} else {
if (sprite_flags.Test(SpriteFlag::NoAnim)) Draw<BlitterMode::Normal, RM_WITH_MARGIN, BT_NONE, false, false>(bp, zoom);
else Draw<BlitterMode::Normal, RM_WITH_MARGIN, BT_NONE, false, true>(bp, zoom);
Draw<BlitterMode::Normal, ReadMode::WithMargin, BlockType::None, false>(bp, zoom, !sprite_flags.Test(SpriteFlag::NoAnim));
}
#else
if (sprite_flags.Test(SpriteFlag::NoAnim)) Draw<BlitterMode::Normal, RM_WITH_MARGIN, BT_NONE, true, false>(bp, zoom);
else Draw<BlitterMode::Normal, RM_WITH_MARGIN, BT_NONE, true, true>(bp, zoom);
Draw<BlitterMode::Normal, ReadMode::WithMargin, BlockType::None, true>(bp, zoom, !sprite_flags.Test(SpriteFlag::NoAnim));
#endif
}
break;
@@ -420,17 +434,15 @@ bm_normal:
case BlitterMode::ColourRemap:
if (sprite_flags.Test(SpriteFlag::NoRemap)) goto bm_normal;
if (bp->skip_left != 0 || bp->width <= MARGIN_REMAP_THRESHOLD) {
if (sprite_flags.Test(SpriteFlag::NoAnim)) Draw<BlitterMode::ColourRemap, RM_WITH_SKIP, BT_NONE, true, false>(bp, zoom);
else Draw<BlitterMode::ColourRemap, RM_WITH_SKIP, BT_NONE, true, true>(bp, zoom);
Draw<BlitterMode::ColourRemap, ReadMode::WithSkip, BlockType::None, true>(bp, zoom, !sprite_flags.Test(SpriteFlag::NoAnim));
} else {
if (sprite_flags.Test(SpriteFlag::NoAnim)) Draw<BlitterMode::ColourRemap, RM_WITH_MARGIN, BT_NONE, true, false>(bp, zoom);
else Draw<BlitterMode::ColourRemap, RM_WITH_MARGIN, BT_NONE, true, true>(bp, zoom);
Draw<BlitterMode::ColourRemap, ReadMode::WithMargin, BlockType::None, true>(bp, zoom, !sprite_flags.Test(SpriteFlag::NoAnim));
}
break;
case BlitterMode::Transparent: Draw<BlitterMode::Transparent, RM_NONE, BT_NONE, true, true>(bp, zoom); return;
case BlitterMode::TransparentRemap: Draw<BlitterMode::TransparentRemap, RM_NONE, BT_NONE, true, true>(bp, zoom); return;
case BlitterMode::CrashRemap: Draw<BlitterMode::CrashRemap, RM_NONE, BT_NONE, true, true>(bp, zoom); return;
case BlitterMode::BlackRemap: Draw<BlitterMode::BlackRemap, RM_NONE, BT_NONE, true, true>(bp, zoom); return;
case BlitterMode::Transparent: Draw<BlitterMode::Transparent, ReadMode::None, BlockType::None, true, true>(bp, zoom); return;
case BlitterMode::TransparentRemap: Draw<BlitterMode::TransparentRemap, ReadMode::None, BlockType::None, true, true>(bp, zoom); return;
case BlitterMode::CrashRemap: Draw<BlitterMode::CrashRemap, ReadMode::None, BlockType::None, true, true>(bp, zoom); return;
case BlitterMode::BlackRemap: Draw<BlitterMode::BlackRemap, ReadMode::None, BlockType::None, true, true>(bp, zoom); return;
}
}
+2
View File
@@ -38,6 +38,8 @@ private:
public:
template <BlitterMode mode, Blitter_32bppSSE_Base::ReadMode read_mode, Blitter_32bppSSE_Base::BlockType bt_last, bool translucent, bool animated>
void Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom);
template <BlitterMode mode, Blitter_32bppSSE_Base::ReadMode read_mode, Blitter_32bppSSE_Base::BlockType bt_last, bool translucent>
void Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom, bool animated);
void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override;
Sprite *Encode(SpriteType sprite_type, const SpriteLoader::SpriteCollection &sprite, SpriteAllocator &allocator) override
+8 -8
View File
@@ -39,17 +39,17 @@ public:
static_assert(sizeof(MapValue) == 2);
/** Helper for creating specialised functions for specific optimisations. */
enum ReadMode : uint8_t {
RM_WITH_SKIP, ///< Use normal code for skipping empty pixels.
RM_WITH_MARGIN, ///< Use cached number of empty pixels at begin and end of line to reduce work.
RM_NONE, ///< No specialisation.
enum class ReadMode : uint8_t {
WithSkip, ///< Use normal code for skipping empty pixels.
WithMargin, ///< Use cached number of empty pixels at begin and end of line to reduce work.
None, ///< No specialisation.
};
/** Helper for creating specialised functions for the case where the sprite width is odd or even. */
enum BlockType : uint8_t {
BT_EVEN, ///< An even number of pixels in the width; no need for a special case for the last pixel.
BT_ODD, ///< An odd number of pixels in the width; special case for the last pixel.
BT_NONE, ///< No specialisation for either case.
enum class BlockType : uint8_t {
Even, ///< An even number of pixels in the width; no need for a special case for the last pixel.
Odd, ///< An odd number of pixels in the width; special case for the last pixel.
None, ///< No specialisation for either case.
};
/** Helper for using specialised functions designed to prevent whenever it's possible things like:
+16 -16
View File
@@ -231,7 +231,7 @@ inline void Blitter_32bppSSE4::Draw(const Blitter::BlitterParams *bp, ZoomLevel
const MapValue *src_mv_line = (const MapValue *) &sd->data[si->mv_offset] + bp->skip_top * si->sprite_width;
const Colour *src_rgba_line = (const Colour *) ((const uint8_t *) &sd->data[si->sprite_offset] + bp->skip_top * si->sprite_line_size);
if (read_mode != RM_WITH_MARGIN) {
if (read_mode != ReadMode::WithMargin) {
src_rgba_line += bp->skip_left;
src_mv_line += bp->skip_left;
}
@@ -261,8 +261,8 @@ inline void Blitter_32bppSSE4::Draw(const Blitter::BlitterParams *bp, ZoomLevel
const Colour *src = src_rgba_line + META_LENGTH;
if (mode == BlitterMode::ColourRemap || mode == BlitterMode::CrashRemap) src_mv = src_mv_line;
if (read_mode == RM_WITH_MARGIN) {
assert(bt_last == BT_NONE); // or you must ensure block type is preserved
if (read_mode == ReadMode::WithMargin) {
assert(bt_last == BlockType::None); // or you must ensure block type is preserved
src += src_rgba_line[0].data;
dst += src_rgba_line[0].data;
if (mode == BlitterMode::ColourRemap || mode == BlitterMode::CrashRemap) src_mv += src_rgba_line[0].data;
@@ -293,7 +293,7 @@ inline void Blitter_32bppSSE4::Draw(const Blitter::BlitterParams *bp, ZoomLevel
dst += 2;
}
if ((bt_last == BT_NONE && effective_width & 1) || bt_last == BT_ODD) {
if ((bt_last == BlockType::None && effective_width & 1) || bt_last == BlockType::Odd) {
__m128i srcABCD = _mm_cvtsi32_si128(src->data);
__m128i dstABCD = _mm_cvtsi32_si128(dst->data);
dst->data = _mm_cvtsi128_si32(AlphaBlendTwoPixels(srcABCD, dstABCD, ALPHA_BLEND_PARAM_1, ALPHA_BLEND_PARAM_2, ALPHA_BLEND_PARAM_3));
@@ -347,7 +347,7 @@ inline void Blitter_32bppSSE4::Draw(const Blitter::BlitterParams *bp, ZoomLevel
src_mv += 2;
}
if ((bt_last == BT_NONE && effective_width & 1) || bt_last == BT_ODD) {
if ((bt_last == BlockType::None && effective_width & 1) || bt_last == BlockType::Odd) {
#else
for (uint x = (uint) effective_width; x > 0; x--) {
#endif
@@ -392,7 +392,7 @@ bmcr_alpha_blend_single:
dst += 2;
}
if ((bt_last == BT_NONE && bp->width & 1) || bt_last == BT_ODD) {
if ((bt_last == BlockType::None && bp->width & 1) || bt_last == BlockType::Odd) {
__m128i srcABCD = _mm_cvtsi32_si128(src->data);
__m128i dstABCD = _mm_cvtsi32_si128(dst->data);
dst->data = _mm_cvtsi128_si32(DarkenTwoPixels(srcABCD, dstABCD, DARKEN_PARAM_1, DARKEN_PARAM_2));
@@ -468,14 +468,14 @@ void Blitter_32bppSSE4::Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomL
bm_normal:
const BlockType bt_last = (BlockType) (bp->width & 1);
switch (bt_last) {
default: Draw<BlitterMode::Normal, RM_WITH_SKIP, BT_EVEN, true>(bp, zoom); return;
case BT_ODD: Draw<BlitterMode::Normal, RM_WITH_SKIP, BT_ODD, true>(bp, zoom); return;
default: Draw<BlitterMode::Normal, ReadMode::WithSkip, BlockType::Even, true>(bp, zoom); return;
case BlockType::Odd: Draw<BlitterMode::Normal, ReadMode::WithSkip, BlockType::Odd, true>(bp, zoom); return;
}
} else {
if (((const Blitter_32bppSSE_Base::SpriteData *) bp->sprite)->flags.Test(SpriteFlag::Translucent)) {
Draw<BlitterMode::Normal, RM_WITH_MARGIN, BT_NONE, true>(bp, zoom);
Draw<BlitterMode::Normal, ReadMode::WithMargin, BlockType::None, true>(bp, zoom);
} else {
Draw<BlitterMode::Normal, RM_WITH_MARGIN, BT_NONE, false>(bp, zoom);
Draw<BlitterMode::Normal, ReadMode::WithMargin, BlockType::None, false>(bp, zoom);
}
return;
}
@@ -484,14 +484,14 @@ bm_normal:
case BlitterMode::ColourRemap:
if (((const Blitter_32bppSSE_Base::SpriteData *) bp->sprite)->flags.Test(SpriteFlag::NoRemap)) goto bm_normal;
if (bp->skip_left != 0 || bp->width <= MARGIN_REMAP_THRESHOLD) {
Draw<BlitterMode::ColourRemap, RM_WITH_SKIP, BT_NONE, true>(bp, zoom); return;
Draw<BlitterMode::ColourRemap, ReadMode::WithSkip, BlockType::None, true>(bp, zoom); return;
} else {
Draw<BlitterMode::ColourRemap, RM_WITH_MARGIN, BT_NONE, true>(bp, zoom); return;
Draw<BlitterMode::ColourRemap, ReadMode::WithMargin, BlockType::None, true>(bp, zoom); return;
}
case BlitterMode::Transparent: Draw<BlitterMode::Transparent, RM_NONE, BT_NONE, true>(bp, zoom); return;
case BlitterMode::TransparentRemap: Draw<BlitterMode::TransparentRemap, RM_NONE, BT_NONE, true>(bp, zoom); return;
case BlitterMode::CrashRemap: Draw<BlitterMode::CrashRemap, RM_NONE, BT_NONE, true>(bp, zoom); return;
case BlitterMode::BlackRemap: Draw<BlitterMode::BlackRemap, RM_NONE, BT_NONE, true>(bp, zoom); return;
case BlitterMode::Transparent: Draw<BlitterMode::Transparent, ReadMode::None, BlockType::None, true>(bp, zoom); return;
case BlitterMode::TransparentRemap: Draw<BlitterMode::TransparentRemap, ReadMode::None, BlockType::None, true>(bp, zoom); return;
case BlitterMode::CrashRemap: Draw<BlitterMode::CrashRemap, ReadMode::None, BlockType::None, true>(bp, zoom); return;
case BlitterMode::BlackRemap: Draw<BlitterMode::BlackRemap, ReadMode::None, BlockType::None, true>(bp, zoom); return;
}
}
#endif /* FULL_ANIMATION */