The Battle for Wesnoth  1.19.25+dev
utils_simd.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2025
3  by Durzi/mentos987
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #pragma once
17 
18 #include "game_config.hpp"
20 #include "sdl/surface.hpp"
21 
22 #include <cstdint>
23 #include <algorithm>
24 
25 /**
26  * @file
27  * SIMD-accelerated helper functions for image manipulation.
28  * These functions operate on raw pixel buffers to isolate platform-specific
29  * intrinsics (SSE2, NEON) from the main codebase.
30  */
31 
32 namespace simd {
33 
34  /** Minimum number of pixels required to trigger SIMD optimizations. */
35  constexpr std::size_t SIMD_THRESHOLD = 64;
36 
37  /** Checks if SIMD hardware acceleration is allowed/enabeled. */
38  inline bool is_enabled() {
39  // CLI (Command Line Flag). Example: wesnoth --no-simd
41  return false;
42  }
43 
44  // Env (Environment Variable). Does not exist by default. Initialized once since getenv() is a heavy operation.
45  static const bool env_disables_simd = std::getenv("WESNOTH_NO_SIMD") != nullptr;
46  if(env_disables_simd) {
47  return false;
48  }
49 
50  // The user's saved preference. Set by the SIMD checkbox at advanced options menu in the game.
51  return prefs::get().simd_enabled();
52  }
53 }
54 
55 /**
56 * @brief Modifies the alpha channel of the surface pixels based on the mask.
57 * @param surf The surface to modify.
58 * @param mask The mask surface to read alpha values from.
59 * @param empty Output: set to false if any resulting pixel is non-transparent.
60 * Should be initialised to true by the caller.
61 * @return Number of pixels processed via SIMD (always a multiple of 4),
62 * or 0 if SIMD was unavailable / pixel count was below the threshold.
63 */
64 std::size_t mask_surface_simd(surface& surf, const surface& mask, bool& empty);
65 
66 /**
67 * @brief Applies an alpha modification to the whole surface using SIMD.
68 * @param surf The surface to modify.
69 * @param alpha_mod The 0-255 modifier to multiply the existing alpha by.
70 * @return Number of pixels processed via SIMD, or 0 if SIMD was not used.
71 */
72 std::size_t apply_surface_opacity_simd(surface& surf, uint8_t alpha_mod);
73 
74 /**
75 * @brief Adjusts the color channels of a surface using saturated SIMD arithmetic.
76 * @param surf The surface to modify.
77 * @param r, g, b Amounts to add (positive) or subtract (negative) per channel. Clamped to [-255, 255].
78 * @return Number of pixels processed via SIMD, or 0 if SIMD was not used.
79 */
80 std::size_t adjust_surface_color_simd(surface& surf, int r, int g, int b);
81 
82 /**
83 * @brief Flips each row of pixels (horizontal mirror) using SIMD.
84 * @param surf The surface to modify.
85 * @return Number of columns (per row) processed via SIMD, or 0 if SIMD was not used.
86 */
87 std::size_t flip_image_simd(surface& surf);
double g
Definition: astarsearch.cpp:63
static prefs & get()
bool is_enabled()
Checks if SIMD hardware acceleration is allowed/enabeled.
Definition: utils_simd.hpp:38
constexpr std::size_t SIMD_THRESHOLD
Minimum number of pixels required to trigger SIMD optimizations.
Definition: utils_simd.hpp:35
surface surf
Image.
std::size_t adjust_surface_color_simd(surface &surf, int r, int g, int b)
Adjusts the color channels of a surface using saturated SIMD arithmetic.
Definition: utils_simd.cpp:337
std::size_t flip_image_simd(surface &surf)
Flips each row of pixels (horizontal mirror) using SIMD.
Definition: utils_simd.cpp:354
std::size_t apply_surface_opacity_simd(surface &surf, uint8_t alpha_mod)
Applies an alpha modification to the whole surface using SIMD.
Definition: utils_simd.cpp:320
std::size_t mask_surface_simd(surface &surf, const surface &mask, bool &empty)
Modifies the alpha channel of the surface pixels based on the mask.
Definition: utils_simd.cpp:302
#define b