From fdf55a1a484aab3fe5e169574fd3dd5c982b1913 Mon Sep 17 00:00:00 2001 From: rubidium Date: Mon, 13 Jan 2014 18:12:33 +0000 Subject: (svn r26258) -Codechange: deduplicate Draw methods (MJP) --- src/blitter/32bpp_ssse3.cpp | 201 +------------------------------------------- 1 file changed, 1 insertion(+), 200 deletions(-) (limited to 'src/blitter/32bpp_ssse3.cpp') diff --git a/src/blitter/32bpp_ssse3.cpp b/src/blitter/32bpp_ssse3.cpp index 3c42d359c..33d49648e 100644 --- a/src/blitter/32bpp_ssse3.cpp +++ b/src/blitter/32bpp_ssse3.cpp @@ -15,208 +15,9 @@ #include "../zoom_func.h" #include "../settings_type.h" #include "32bpp_ssse3.hpp" +#include "32bpp_sse_func.hpp" /** Instantiation of the SSSE3 32bpp blitter factory. */ static FBlitter_32bppSSSE3 iFBlitter_32bppSSSE3; -/** - * 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 - */ -IGNORE_UNINITIALIZED_WARNING_START -template -inline void Blitter_32bppSSSE3::Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom) -{ - const byte * const remap = bp->remap; - Colour *dst_line = (Colour *) bp->dst + bp->top * bp->pitch + bp->left; - int effective_width = bp->width; - - /* Find where to start reading in the source sprite. */ - const SpriteData * const sd = (const SpriteData *) bp->sprite; - const SpriteInfo * const si = &sd->infos[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 byte *) &sd->data[si->sprite_offset] + bp->skip_top * si->sprite_line_size); - - if (read_mode != RM_WITH_MARGIN) { - src_rgba_line += bp->skip_left; - src_mv_line += bp->skip_left; - } - const MapValue *src_mv = src_mv_line; - - /* Load these variables into register before loop. */ - const __m128i a_cm = ALPHA_CONTROL_MASK; - const __m128i pack_low_cm = PACK_LOW_CONTROL_MASK; - const __m128i tr_nom_base = TRANSPARENT_NOM_BASE; - - for (int y = bp->height; y != 0; y--) { - Colour *dst = dst_line; - const Colour *src = src_rgba_line + META_LENGTH; - if (mode == BM_COLOUR_REMAP) src_mv = src_mv_line; - - if (read_mode == RM_WITH_MARGIN) { - assert(bt_last == BT_NONE); // or you must ensure block type is preserved - src += src_rgba_line[0].data; - dst += src_rgba_line[0].data; - if (mode == BM_COLOUR_REMAP) src_mv += src_rgba_line[0].data; - const int width_diff = si->sprite_width - bp->width; - effective_width = bp->width - (int) src_rgba_line[0].data; - const int delta_diff = (int) src_rgba_line[1].data - width_diff; - const int new_width = effective_width - delta_diff; - effective_width = delta_diff > 0 ? new_width : effective_width; - if (effective_width <= 0) goto next_line; - } - - switch (mode) { - default: - for (uint x = (uint) effective_width / 2; x > 0; x--) { - __m128i srcABCD = _mm_loadl_epi64((const __m128i*) src); - __m128i dstABCD = _mm_loadl_epi64((__m128i*) dst); - _mm_storel_epi64((__m128i*) dst, AlphaBlendTwoPixels(srcABCD, dstABCD, a_cm, pack_low_cm)); - src += 2; - dst += 2; - } - - if ((bt_last == BT_NONE && effective_width & 1) || bt_last == BT_ODD) { - __m128i srcABCD = _mm_cvtsi32_si128(src->data); - __m128i dstABCD = _mm_cvtsi32_si128(dst->data); - dst->data = _mm_cvtsi128_si32(AlphaBlendTwoPixels(srcABCD, dstABCD, a_cm, pack_low_cm)); - } - break; - - case BM_COLOUR_REMAP: - for (uint x = (uint) effective_width / 2; x > 0; x--) { - __m128i srcABCD = _mm_loadl_epi64((const __m128i*) src); - __m128i dstABCD = _mm_loadl_epi64((__m128i*) dst); - uint32 mvX2 = *((uint32 *) const_cast(src_mv)); - - /* Remap colours. */ - if (mvX2 & 0x00FF00FF) { - #define CMOV_REMAP(m_colour, m_src, m_m) \ - /* Written so the compiler uses CMOV. */ \ - Colour m_colour = 0; \ - { \ - const Colour srcm = (Colour) (m_src); \ - const uint m = (byte) (m_m); \ - const uint r = remap[m]; \ - const Colour cmap = (this->LookupColourInPalette(r).data & 0x00FFFFFF) | (srcm.data & 0xFF000000); \ - m_colour = r == 0 ? m_colour : cmap; \ - m_colour = m != 0 ? m_colour : srcm; \ - } -#ifdef _SQ64 - uint64 srcs = _mm_cvtsi128_si64(srcABCD); - uint64 remapped_src = 0; - CMOV_REMAP(c0, srcs, mvX2); - remapped_src = c0.data; - CMOV_REMAP(c1, srcs >> 32, mvX2 >> 16); - remapped_src |= (uint64) c1.data << 32; - srcABCD = _mm_cvtsi64_si128(remapped_src); -#else - Colour remapped_src[2]; - CMOV_REMAP(c0, _mm_cvtsi128_si32(srcABCD), mvX2); - remapped_src[0] = c0.data; - CMOV_REMAP(c1, src[1], mvX2 >> 16); - remapped_src[1] = c1.data; - srcABCD = _mm_loadl_epi64((__m128i*) &remapped_src); -#endif - - if ((mvX2 & 0xFF00FF00) != 0x80008000) srcABCD = AdjustBrightnessOfTwoPixels(srcABCD, mvX2); - } - - /* Blend colours. */ - _mm_storel_epi64((__m128i *) dst, AlphaBlendTwoPixels(srcABCD, dstABCD, a_cm, pack_low_cm)); - dst += 2; - src += 2; - src_mv += 2; - } - - if ((bt_last == BT_NONE && effective_width & 1) || bt_last == BT_ODD) { - /* In case the m-channel is zero, do not remap this pixel in any way. */ - __m128i srcABCD; - if (src_mv->m) { - const uint r = remap[src_mv->m]; - if (r != 0) { - Colour remapped_colour = AdjustBrightneSSE(this->LookupColourInPalette(r), src_mv->v); - if (src->a == 255) { - *dst = remapped_colour; - } else { - remapped_colour.a = src->a; - srcABCD = _mm_cvtsi32_si128(remapped_colour.data); - goto bmcr_alpha_blend_single; - } - } - } else { - srcABCD = _mm_cvtsi32_si128(src->data); - if (src->a < 255) { -bmcr_alpha_blend_single: - __m128i dstABCD = _mm_cvtsi32_si128(dst->data); - srcABCD = AlphaBlendTwoPixels(srcABCD, dstABCD, a_cm, pack_low_cm); - } - dst->data = _mm_cvtsi128_si32(srcABCD); - } - } - break; - - case BM_TRANSPARENT: - /* Make the current colour a bit more black, so it looks like this image is transparent. */ - for (uint x = (uint) bp->width / 2; x > 0; x--) { - __m128i srcABCD = _mm_loadl_epi64((const __m128i*) src); - __m128i dstABCD = _mm_loadl_epi64((__m128i*) dst); - _mm_storel_epi64((__m128i *) dst, DarkenTwoPixels(srcABCD, dstABCD, a_cm, tr_nom_base)); - src += 2; - dst += 2; - } - - if ((bt_last == BT_NONE && bp->width & 1) || bt_last == BT_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)); - } - break; - } - -next_line: - if (mode == BM_COLOUR_REMAP) src_mv_line += si->sprite_width; - src_rgba_line = (const Colour*) ((const byte*) src_rgba_line + si->sprite_line_size); - dst_line += bp->pitch; - } -} -IGNORE_UNINITIALIZED_WARNING_STOP - -/** - * Draws a sprite to a (screen) buffer. Calls adequate templated function. - * - * @param bp further blitting parameters - * @param mode blitter mode - * @param zoom zoom level at which we are drawing - */ -void Blitter_32bppSSSE3::Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) -{ - switch (mode) { - case BM_NORMAL: { - if (bp->skip_left != 0 || bp->width <= MARGIN_NORMAL_THRESHOLD) { - const BlockType bt_last = (BlockType) (bp->width & 1); - switch (bt_last) { - case BT_EVEN: Draw(bp, zoom); return; - case BT_ODD: Draw(bp, zoom); return; - default: NOT_REACHED(); - } - } else { - Draw(bp, zoom); return; - } - break; - } - case BM_COLOUR_REMAP: - if (bp->skip_left != 0 || bp->width <= MARGIN_REMAP_THRESHOLD) { - Draw(bp, zoom); return; - } else { - Draw(bp, zoom); return; - } - case BM_TRANSPARENT: Draw(bp, zoom); return; - default: NOT_REACHED(); - } -} - #endif /* WITH_SSE */ -- cgit v1.2.3-54-g00ecf