OpenTTD Source 20241224-master-gee860a5c8e
32bpp_anim_sse2.cpp
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * 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/>.
6 */
7
10#ifdef WITH_SSE
11
12#include "../stdafx.h"
13#include "../video/video_driver.hpp"
14#include "32bpp_anim_sse2.hpp"
15#include "32bpp_sse_func.hpp"
16
17#include "../safeguards.h"
18
20static FBlitter_32bppSSE2_Anim iFBlitter_32bppSSE2_Anim;
21
22GNU_TARGET("sse2")
23void Blitter_32bppSSE2_Anim::PaletteAnimate(const Palette &palette)
24{
25 assert(!_screen_disable_anim);
26
27 this->palette = palette;
28 /* If first_dirty is 0, it is for 8bpp indication to send the new
29 * palette. However, only the animation colours might possibly change.
30 * Especially when going between toyland and non-toyland. */
31 assert(this->palette.first_dirty == PALETTE_ANIM_START || this->palette.first_dirty == 0);
32
33 const uint16_t *anim = this->anim_buf;
34 Colour *dst = (Colour *)_screen.dst_ptr;
35
36 bool screen_dirty = false;
37
38 /* Let's walk the anim buffer and try to find the pixels */
39 const int width = this->anim_buf_width;
40 const int screen_pitch = _screen.pitch;
41 const int anim_pitch = this->anim_buf_pitch;
42 __m128i anim_cmp = _mm_set1_epi16(PALETTE_ANIM_START - 1);
43 __m128i brightness_cmp = _mm_set1_epi16(Blitter_32bppBase::DEFAULT_BRIGHTNESS);
44 __m128i colour_mask = _mm_set1_epi16(0xFF);
45 for (int y = this->anim_buf_height; y != 0 ; y--) {
46 Colour *next_dst_ln = dst + screen_pitch;
47 const uint16_t *next_anim_ln = anim + anim_pitch;
48 int x = width;
49 while (x > 0) {
50 __m128i data = _mm_load_si128((const __m128i *) anim);
51
52 /* low bytes only, shifted into high positions */
53 __m128i colour_data = _mm_and_si128(data, colour_mask);
54
55 /* test if any colour >= PALETTE_ANIM_START */
56 int colour_cmp_result = _mm_movemask_epi8(_mm_cmpgt_epi16(colour_data, anim_cmp));
57 if (colour_cmp_result) {
58 /* test if any brightness is unexpected */
59 if (x < 8 || colour_cmp_result != 0xFFFF ||
60 _mm_movemask_epi8(_mm_cmpeq_epi16(_mm_srli_epi16(data, 8), brightness_cmp)) != 0xFFFF) {
61 /* slow path: < 8 pixels left or unexpected brightnesses */
62 for (int z = std::min<int>(x, 8); z != 0 ; z--) {
63 int value = _mm_extract_epi16(data, 0);
64 uint8_t colour = GB(value, 0, 8);
65 if (colour >= PALETTE_ANIM_START) {
66 /* Update this pixel */
67 *dst = AdjustBrightneSSE(LookupColourInPalette(colour), GB(value, 8, 8));
68 screen_dirty = true;
69 }
70 data = _mm_srli_si128(data, 2);
71 dst++;
72 }
73 } else {
74 /* medium path: 8 pixels to animate all of expected brightnesses */
75 for (int z = 0; z < 8; z++) {
76 *dst = LookupColourInPalette(_mm_extract_epi16(colour_data, 0));
77 colour_data = _mm_srli_si128(colour_data, 2);
78 dst++;
79 }
80 screen_dirty = true;
81 }
82 } else {
83 /* fast path, no animation */
84 dst += 8;
85 }
86 anim += 8;
87 x -= 8;
88 }
89 dst = next_dst_ln;
90 anim = next_anim_ln;
91 }
92
93 if (screen_dirty) {
94 /* Make sure the backend redraws the whole screen */
95 VideoDriver::GetInstance()->MakeDirty(0, 0, _screen.width, _screen.height);
96 }
97}
98
99#endif /* WITH_SSE */
Functions related to SSE 32 bpp blitter.
debug_inline static constexpr uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
virtual void MakeDirty(int left, int top, int width, int height)=0
Mark a particular area dirty.
static VideoDriver * GetInstance()
Get the currently active instance of the video driver.
bool _screen_disable_anim
Disable palette animation (important for 32bpp-anim blitter during giant screenshot)
Definition gfx.cpp:46
static constexpr uint8_t PALETTE_ANIM_START
Index in the _palettes array from which all animations are taking places (table/palettes....
Definition gfx_type.h:294
Information about the currently used palette.
Definition gfx_type.h:328
Structure to access the alpha, red, green, and blue channels from a 32 bit number.
Definition gfx_type.h:165