diff options
Diffstat (limited to 'src/blitter/32bpp_sse2.cpp')
-rw-r--r-- | src/blitter/32bpp_sse2.cpp | 158 |
1 files changed, 1 insertions, 157 deletions
diff --git a/src/blitter/32bpp_sse2.cpp b/src/blitter/32bpp_sse2.cpp index 49fb28c35..2f1dc3828 100644 --- a/src/blitter/32bpp_sse2.cpp +++ b/src/blitter/32bpp_sse2.cpp @@ -15,167 +15,11 @@ #include "../zoom_func.h" #include "../settings_type.h" #include "32bpp_sse2.hpp" +#include "32bpp_sse_func.hpp" /** Instantiation of the SSE2 32bpp blitter factory. */ static FBlitter_32bppSSE2 iFBlitter_32bppSSE2; -/** - * 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 <BlitterMode mode, Blitter_32bppSSE2::ReadMode read_mode, Blitter_32bppSSE2::BlockType bt_last> -inline void Blitter_32bppSSE2::Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom) -{ - const byte *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 clear_hi = CLEAR_HIGH_BYTE_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, clear_hi, clear_hi)); - 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, clear_hi, clear_hi)); - } - break; - - case BM_COLOUR_REMAP: - for (uint x = (uint) effective_width; x != 0; x--) { - /* 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, clear_hi, clear_hi); - } - dst->data = _mm_cvtsi128_si32(srcABCD); - } - src_mv++; - dst++; - src++; - } - 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, tr_nom_base, 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, tr_nom_base, 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_32bppSSE2::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<BM_NORMAL, RM_WITH_SKIP, BT_EVEN>(bp, zoom); return; - case BT_ODD: Draw<BM_NORMAL, RM_WITH_SKIP, BT_ODD>(bp, zoom); return; - default: NOT_REACHED(); - } - } else { - Draw<BM_NORMAL, RM_WITH_MARGIN, BT_NONE>(bp, zoom); return; - } - break; - } - case BM_COLOUR_REMAP: - if (bp->skip_left != 0 || bp->width <= MARGIN_REMAP_THRESHOLD) { - Draw<BM_COLOUR_REMAP, RM_WITH_SKIP, BT_NONE>(bp, zoom); return; - } else { - Draw<BM_COLOUR_REMAP, RM_WITH_MARGIN, BT_NONE>(bp, zoom); return; - } - case BM_TRANSPARENT: Draw<BM_TRANSPARENT, RM_NONE, BT_NONE>(bp, zoom); return; - default: NOT_REACHED(); - } -} - Sprite *Blitter_32bppSSE_Base::Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator) { /* First uint32 of a line = the number of transparent pixels from the left. |