diff --git a/core/io/file_access.cpp b/core/io/file_access.cpp index caae8ee026..aa4651a2c3 100644 --- a/core/io/file_access.cpp +++ b/core/io/file_access.cpp @@ -425,7 +425,7 @@ class CharBuffer { int64_t written = 0; bool grow() { - if (vector.resize(next_power_of_2((uint64_t)1 + (uint64_t)written)) != OK) { + if (vector.resize(Math::next_power_of_2((uint64_t)1 + (uint64_t)written)) != OK) { return false; } diff --git a/core/io/file_access_compressed.cpp b/core/io/file_access_compressed.cpp index 8062d97b7a..7b020e142d 100644 --- a/core/io/file_access_compressed.cpp +++ b/core/io/file_access_compressed.cpp @@ -320,7 +320,7 @@ bool FileAccessCompressed::store_buffer(const uint8_t *p_src, uint64_t p_length) write_max = write_pos + (p_length); } if (write_max > write_buffer_size) { - write_buffer_size = next_power_of_2(write_max); + write_buffer_size = Math::next_power_of_2(write_max); ERR_FAIL_COND_V(buffer.resize(write_buffer_size) != OK, false); write_ptr = buffer.ptrw(); } diff --git a/core/io/image.cpp b/core/io/image.cpp index 827cbaf20d..75dea84fd4 100644 --- a/core/io/image.cpp +++ b/core/io/image.cpp @@ -1231,14 +1231,14 @@ static void _overlay(const uint8_t *__restrict p_src, uint8_t *__restrict p_dst, } bool Image::is_size_po2() const { - return is_power_of_2(width) && is_power_of_2(height); + return Math::is_power_of_2(width) && Math::is_power_of_2(height); } void Image::resize_to_po2(bool p_square, Interpolation p_interpolation) { ERR_FAIL_COND_MSG(is_compressed(), "Cannot resize in compressed image formats."); - int w = next_power_of_2((uint32_t)width); - int h = next_power_of_2((uint32_t)height); + int w = Math::next_power_of_2((uint32_t)width); + int h = Math::next_power_of_2((uint32_t)height); if (p_square) { w = h = MAX(w, h); } diff --git a/core/io/packet_peer.cpp b/core/io/packet_peer.cpp index 8c09fbc9ed..418c90b22c 100644 --- a/core/io/packet_peer.cpp +++ b/core/io/packet_peer.cpp @@ -38,7 +38,7 @@ void PacketPeer::set_encode_buffer_max_size(int p_max_size) { ERR_FAIL_COND_MSG(p_max_size < 1024, "Max encode buffer must be at least 1024 bytes"); ERR_FAIL_COND_MSG(p_max_size > 256 * 1024 * 1024, "Max encode buffer cannot exceed 256 MiB"); - encode_buffer_max_size = next_power_of_2((uint32_t)p_max_size); + encode_buffer_max_size = Math::next_power_of_2((uint32_t)p_max_size); encode_buffer.clear(); } @@ -103,7 +103,7 @@ Error PacketPeer::put_var(const Variant &p_packet, bool p_full_objects) { if (unlikely(encode_buffer.size() < len)) { encode_buffer.resize(0); // Avoid realloc - encode_buffer.resize(next_power_of_2((uint32_t)len)); + encode_buffer.resize(Math::next_power_of_2((uint32_t)len)); } uint8_t *w = encode_buffer.ptrw(); @@ -301,8 +301,8 @@ void PacketPeerStream::set_input_buffer_max_size(int p_max_size) { ERR_FAIL_COND_MSG(p_max_size < 0, "Max size of input buffer size cannot be smaller than 0."); // WARNING: May lose packets. ERR_FAIL_COND_MSG(ring_buffer.data_left(), "Buffer in use, resizing would cause loss of data."); - ring_buffer.resize(nearest_shift(next_power_of_2((uint32_t)p_max_size + (uint32_t)4)) - 1); - input_buffer.resize(next_power_of_2((uint32_t)p_max_size + (uint32_t)4)); + ring_buffer.resize(Math::nearest_shift(Math::next_power_of_2((uint32_t)p_max_size + (uint32_t)4)) - 1); + input_buffer.resize(Math::next_power_of_2((uint32_t)p_max_size + (uint32_t)4)); } int PacketPeerStream::get_input_buffer_max_size() const { @@ -310,7 +310,7 @@ int PacketPeerStream::get_input_buffer_max_size() const { } void PacketPeerStream::set_output_buffer_max_size(int p_max_size) { - output_buffer.resize(next_power_of_2((uint32_t)p_max_size + (uint32_t)4)); + output_buffer.resize(Math::next_power_of_2((uint32_t)p_max_size + (uint32_t)4)); } int PacketPeerStream::get_output_buffer_max_size() const { diff --git a/core/io/packet_peer_udp.cpp b/core/io/packet_peer_udp.cpp index 478c2d76ba..f1338ac063 100644 --- a/core/io/packet_peer_udp.cpp +++ b/core/io/packet_peer_udp.cpp @@ -201,7 +201,7 @@ Error PacketPeerUDP::bind(int p_port, const IPAddress &p_bind_address, int p_rec _sock->close(); return err; } - rb.resize(nearest_shift((uint32_t)p_recv_buffer_size)); + rb.resize(Math::nearest_shift((uint32_t)p_recv_buffer_size)); return OK; } diff --git a/core/io/stream_peer_gzip.cpp b/core/io/stream_peer_gzip.cpp index bfd6b7bd65..907e3eed67 100644 --- a/core/io/stream_peer_gzip.cpp +++ b/core/io/stream_peer_gzip.cpp @@ -76,7 +76,7 @@ Error StreamPeerGZIP::_start(bool p_compress, bool p_is_deflate, int buffer_size ERR_FAIL_COND_V_MSG(buffer_size <= 0, ERR_INVALID_PARAMETER, "Invalid buffer size. It should be a positive integer."); clear(); compressing = p_compress; - rb.resize(nearest_shift(uint32_t(buffer_size - 1))); + rb.resize(Math::nearest_shift(uint32_t(buffer_size - 1))); buffer.resize(1024); // Create ctx. diff --git a/core/math/geometry_2d.cpp b/core/math/geometry_2d.cpp index f6d0ed74ee..7b6a3a1828 100644 --- a/core/math/geometry_2d.cpp +++ b/core/math/geometry_2d.cpp @@ -30,6 +30,8 @@ #include "geometry_2d.h" +#include "core/math/math_funcs_binary.h" + GODOT_GCC_WARNING_PUSH_AND_IGNORE("-Walloc-zero") #include "thirdparty/clipper2/include/clipper2/clipper.h" GODOT_GCC_WARNING_POP @@ -227,8 +229,8 @@ void Geometry2D::make_atlas(const Vector &p_rects, Vector &r_re real_t best_aspect = 1e20; for (int i = 0; i < results.size(); i++) { - real_t h = next_power_of_2((uint32_t)results[i].max_h); - real_t w = next_power_of_2((uint32_t)results[i].max_w); + real_t h = Math::next_power_of_2((uint32_t)results[i].max_h); + real_t w = Math::next_power_of_2((uint32_t)results[i].max_w); real_t aspect = h > w ? h / w : w / h; if (aspect < best_aspect) { best = i; diff --git a/core/math/math_funcs_binary.h b/core/math/math_funcs_binary.h new file mode 100644 index 0000000000..2e9a13853a --- /dev/null +++ b/core/math/math_funcs_binary.h @@ -0,0 +1,188 @@ +/**************************************************************************/ +/* math_funcs_binary.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#pragma once + +#include "core/typedefs.h" + +namespace Math { + +/* Functions to handle powers of 2 and shifting. */ + +// Returns `true` if a positive integer is a power of 2, `false` otherwise. +template +inline bool is_power_of_2(const T x) { + return x && ((x & (x - 1)) == 0); +} + +// Function to find the next power of 2 to an integer. +constexpr uint64_t next_power_of_2(uint64_t p_number) { + if (p_number == 0) { + return 0; + } + + --p_number; + p_number |= p_number >> 1; + p_number |= p_number >> 2; + p_number |= p_number >> 4; + p_number |= p_number >> 8; + p_number |= p_number >> 16; + p_number |= p_number >> 32; + + return ++p_number; +} + +constexpr uint32_t next_power_of_2(uint32_t p_number) { + if (p_number == 0) { + return 0; + } + + --p_number; + p_number |= p_number >> 1; + p_number |= p_number >> 2; + p_number |= p_number >> 4; + p_number |= p_number >> 8; + p_number |= p_number >> 16; + + return ++p_number; +} + +// Function to find the previous power of 2 to an integer. +constexpr uint64_t previous_power_of_2(uint64_t p_number) { + p_number |= p_number >> 1; + p_number |= p_number >> 2; + p_number |= p_number >> 4; + p_number |= p_number >> 8; + p_number |= p_number >> 16; + p_number |= p_number >> 32; + return p_number - (p_number >> 1); +} + +constexpr uint32_t previous_power_of_2(uint32_t p_number) { + p_number |= p_number >> 1; + p_number |= p_number >> 2; + p_number |= p_number >> 4; + p_number |= p_number >> 8; + p_number |= p_number >> 16; + return p_number - (p_number >> 1); +} + +// Function to find the closest power of 2 to an integer. +constexpr uint64_t closest_power_of_2(uint64_t p_number) { + uint64_t nx = next_power_of_2(p_number); + uint64_t px = previous_power_of_2(p_number); + return (nx - p_number) > (p_number - px) ? px : nx; +} + +constexpr uint32_t closest_power_of_2(uint32_t p_number) { + uint32_t nx = next_power_of_2(p_number); + uint32_t px = previous_power_of_2(p_number); + return (nx - p_number) > (p_number - px) ? px : nx; +} + +// Get a shift value from a power of 2. +constexpr int32_t get_shift_from_power_of_2(uint64_t p_bits) { + for (uint64_t i = 0; i < (uint64_t)64; i++) { + if (p_bits == (uint64_t)((uint64_t)1 << i)) { + return i; + } + } + + return -1; +} + +constexpr int32_t get_shift_from_power_of_2(uint32_t p_bits) { + for (uint32_t i = 0; i < (uint32_t)32; i++) { + if (p_bits == (uint32_t)((uint32_t)1 << i)) { + return i; + } + } + + return -1; +} + +template +_FORCE_INLINE_ T nearest_power_of_2_templated(T p_number) { + --p_number; + + // The number of operations on x is the base two logarithm + // of the number of bits in the type. Add three to account + // for sizeof(T) being in bytes. + constexpr size_t shift_steps = get_shift_from_power_of_2((uint64_t)sizeof(T)) + 3; + + // If the compiler is smart, it unrolls this loop. + // If it's dumb, this is a bit slow. + for (size_t i = 0; i < shift_steps; i++) { + p_number |= p_number >> (1 << i); + } + + return ++p_number; +} + +// Function to find the nearest (bigger) power of 2 to an integer. +constexpr uint64_t nearest_shift(uint64_t p_number) { + uint64_t i = 63; + do { + i--; + if (p_number & ((uint64_t)1 << i)) { + return i + (uint64_t)1; + } + } while (i != 0); + + return 0; +} + +constexpr uint32_t nearest_shift(uint32_t p_number) { + uint32_t i = 31; + do { + i--; + if (p_number & ((uint32_t)1 << i)) { + return i + (uint32_t)1; + } + } while (i != 0); + + return 0; +} + +// constexpr function to find the floored log2 of a number +template +constexpr T floor_log2(T x) { + return x < 2 ? x : 1 + floor_log2(x >> 1); +} + +// Get the number of bits needed to represent the number. +// IE, if you pass in 8, you will get 4. +// If you want to know how many bits are needed to store 8 values however, pass in (8 - 1). +template +constexpr T get_num_bits(T x) { + return floor_log2(x); +} + +} //namespace Math diff --git a/core/object/object.cpp b/core/object/object.cpp index 582e62468b..802c2e8bb6 100644 --- a/core/object/object.cpp +++ b/core/object/object.cpp @@ -2258,8 +2258,8 @@ void *Object::get_instance_binding(void *p_token, const GDExtensionInstanceBindi } } if (unlikely(!binding && p_callbacks)) { - uint32_t current_size = next_power_of_2(_instance_binding_count); - uint32_t new_size = next_power_of_2(_instance_binding_count + 1); + uint32_t current_size = Math::next_power_of_2(_instance_binding_count); + uint32_t new_size = Math::next_power_of_2(_instance_binding_count + 1); if (current_size == 0 || new_size > current_size) { _instance_bindings = (InstanceBinding *)memrealloc(_instance_bindings, new_size * sizeof(InstanceBinding)); diff --git a/core/os/memory.cpp b/core/os/memory.cpp index 71d68058da..7e5ce92b55 100644 --- a/core/os/memory.cpp +++ b/core/os/memory.cpp @@ -30,6 +30,7 @@ #include "memory.h" +#include "core/math/math_funcs_binary.h" #include "core/profiling/profiling.h" #include "core/templates/safe_refcount.h" @@ -63,7 +64,7 @@ static SafeNumeric _max_mem_usage; #endif void *Memory::alloc_aligned_static(size_t p_bytes, size_t p_alignment) { - DEV_ASSERT(is_power_of_2(p_alignment)); + DEV_ASSERT(Math::is_power_of_2(p_alignment)); void *p1, *p2; if ((p1 = (void *)malloc(p_bytes + p_alignment - 1 + sizeof(uint32_t))) == nullptr) { diff --git a/core/string/string_buffer.h b/core/string/string_buffer.h index e707a3ad48..0ba13c4f84 100644 --- a/core/string/string_buffer.h +++ b/core/string/string_buffer.h @@ -126,7 +126,7 @@ StringBuffer &StringBuffer::reserve(int p_ } bool need_copy = string_length > 0 && buffer.is_empty(); - buffer.resize_uninitialized(next_power_of_2((uint32_t)p_size)); + buffer.resize_uninitialized(Math::next_power_of_2((uint32_t)p_size)); if (need_copy) { memcpy(buffer.ptrw(), short_buffer, string_length * sizeof(char32_t)); } diff --git a/core/templates/a_hash_map.h b/core/templates/a_hash_map.h index 18c4f40e09..e8c0b0cf0e 100644 --- a/core/templates/a_hash_map.h +++ b/core/templates/a_hash_map.h @@ -30,6 +30,7 @@ #pragma once +#include "core/math/math_funcs_binary.h" #include "core/os/memory.h" #include "core/string/print_string.h" #include "core/templates/hashfuncs.h" @@ -210,7 +211,7 @@ private: uint32_t real_old_capacity = _capacity_mask + 1; // Capacity can't be 0 and must be 2^n - 1. _capacity_mask = MAX(4u, p_new_capacity); - uint32_t real_capacity = next_power_of_2(_capacity_mask); + uint32_t real_capacity = Math::next_power_of_2(_capacity_mask); _capacity_mask = real_capacity - 1; Metadata *old_map_data = _metadata; @@ -412,7 +413,7 @@ public: void reserve(uint32_t p_new_capacity) { if (_elements == nullptr) { _capacity_mask = MAX(4u, p_new_capacity); - _capacity_mask = next_power_of_2(_capacity_mask) - 1; + _capacity_mask = Math::next_power_of_2(_capacity_mask) - 1; return; // Unallocated yet. } if (p_new_capacity <= get_capacity()) { @@ -690,7 +691,7 @@ public: AHashMap(uint32_t p_initial_capacity) { // Capacity can't be 0 and must be 2^n - 1. _capacity_mask = MAX(4u, p_initial_capacity); - _capacity_mask = next_power_of_2(_capacity_mask) - 1; + _capacity_mask = Math::next_power_of_2(_capacity_mask) - 1; } AHashMap() : _capacity_mask(INITIAL_CAPACITY - 1) { diff --git a/core/templates/paged_allocator.h b/core/templates/paged_allocator.h index 697dc1e9d8..cbf0467089 100644 --- a/core/templates/paged_allocator.h +++ b/core/templates/paged_allocator.h @@ -31,6 +31,7 @@ #pragma once #include "core/core_globals.h" +#include "core/math/math_funcs_binary.h" #include "core/os/memory.h" #include "core/os/spin_lock.h" #include "core/string/ustring.h" @@ -145,9 +146,9 @@ public: } ERR_FAIL_COND(page_pool != nullptr); // Safety check. ERR_FAIL_COND(p_page_size == 0); - page_size = nearest_power_of_2_templated(p_page_size); + page_size = Math::nearest_power_of_2_templated(p_page_size); page_mask = page_size - 1; - page_shift = get_shift_from_power_of_2(page_size); + page_shift = Math::get_shift_from_power_of_2(page_size); if constexpr (thread_safe) { spin_lock.unlock(); } diff --git a/core/templates/paged_array.h b/core/templates/paged_array.h index 060c5a58c7..fff19312b5 100644 --- a/core/templates/paged_array.h +++ b/core/templates/paged_array.h @@ -30,6 +30,7 @@ #pragma once +#include "core/math/math_funcs_binary.h" #include "core/os/memory.h" #include "core/os/spin_lock.h" #include "core/typedefs.h" @@ -88,7 +89,7 @@ public: } uint32_t get_page_size_shift() const { - return get_shift_from_power_of_2(page_size); + return Math::get_shift_from_power_of_2(page_size); } uint32_t get_page_size_mask() const { @@ -116,7 +117,7 @@ public: void configure(uint32_t p_page_size) { ERR_FAIL_COND(page_pool != nullptr); // Safety check. ERR_FAIL_COND(p_page_size == 0); - page_size = nearest_power_of_2_templated(p_page_size); + page_size = Math::nearest_power_of_2_templated(p_page_size); } PagedArrayPool(uint32_t p_page_size = 4096) { // power of 2 recommended because of alignment with OS page sizes. Even if element is bigger, its still a multiple and get rounded amount of pages diff --git a/core/typedefs.h b/core/typedefs.h index c3264861e8..4171fa7fdc 100644 --- a/core/typedefs.h +++ b/core/typedefs.h @@ -140,167 +140,16 @@ constexpr auto CLAMP(const T m_a, const T2 m_min, const T3 m_max) { return m_a < m_min ? m_min : (m_a > m_max ? m_max : m_a); } -// Generic swap template. -#ifndef SWAP -#define SWAP(m_x, m_y) std::swap((m_x), (m_y)) -#endif // SWAP - // Like std::size, but without requiring any additional includes. template constexpr size_t std_size(const T (&)[SIZE]) { return SIZE; } -/* Functions to handle powers of 2 and shifting. */ - -// Returns `true` if a positive integer is a power of 2, `false` otherwise. -template -inline bool is_power_of_2(const T x) { - return x && ((x & (x - 1)) == 0); -} - -// Function to find the next power of 2 to an integer. -constexpr uint64_t next_power_of_2(uint64_t p_number) { - if (p_number == 0) { - return 0; - } - - --p_number; - p_number |= p_number >> 1; - p_number |= p_number >> 2; - p_number |= p_number >> 4; - p_number |= p_number >> 8; - p_number |= p_number >> 16; - p_number |= p_number >> 32; - - return ++p_number; -} - -constexpr uint32_t next_power_of_2(uint32_t p_number) { - if (p_number == 0) { - return 0; - } - - --p_number; - p_number |= p_number >> 1; - p_number |= p_number >> 2; - p_number |= p_number >> 4; - p_number |= p_number >> 8; - p_number |= p_number >> 16; - - return ++p_number; -} - -// Function to find the previous power of 2 to an integer. -constexpr uint64_t previous_power_of_2(uint64_t p_number) { - p_number |= p_number >> 1; - p_number |= p_number >> 2; - p_number |= p_number >> 4; - p_number |= p_number >> 8; - p_number |= p_number >> 16; - p_number |= p_number >> 32; - return p_number - (p_number >> 1); -} - -constexpr uint32_t previous_power_of_2(uint32_t p_number) { - p_number |= p_number >> 1; - p_number |= p_number >> 2; - p_number |= p_number >> 4; - p_number |= p_number >> 8; - p_number |= p_number >> 16; - return p_number - (p_number >> 1); -} - -// Function to find the closest power of 2 to an integer. -constexpr uint64_t closest_power_of_2(uint64_t p_number) { - uint64_t nx = next_power_of_2(p_number); - uint64_t px = previous_power_of_2(p_number); - return (nx - p_number) > (p_number - px) ? px : nx; -} - -constexpr uint32_t closest_power_of_2(uint32_t p_number) { - uint32_t nx = next_power_of_2(p_number); - uint32_t px = previous_power_of_2(p_number); - return (nx - p_number) > (p_number - px) ? px : nx; -} - -// Get a shift value from a power of 2. -constexpr int32_t get_shift_from_power_of_2(uint64_t p_bits) { - for (uint64_t i = 0; i < (uint64_t)64; i++) { - if (p_bits == (uint64_t)((uint64_t)1 << i)) { - return i; - } - } - - return -1; -} - -constexpr int32_t get_shift_from_power_of_2(uint32_t p_bits) { - for (uint32_t i = 0; i < (uint32_t)32; i++) { - if (p_bits == (uint32_t)((uint32_t)1 << i)) { - return i; - } - } - - return -1; -} - -template -static _FORCE_INLINE_ T nearest_power_of_2_templated(T p_number) { - --p_number; - - // The number of operations on x is the base two logarithm - // of the number of bits in the type. Add three to account - // for sizeof(T) being in bytes. - constexpr size_t shift_steps = get_shift_from_power_of_2((uint64_t)sizeof(T)) + 3; - - // If the compiler is smart, it unrolls this loop. - // If it's dumb, this is a bit slow. - for (size_t i = 0; i < shift_steps; i++) { - p_number |= p_number >> (1 << i); - } - - return ++p_number; -} - -// Function to find the nearest (bigger) power of 2 to an integer. -constexpr uint64_t nearest_shift(uint64_t p_number) { - uint64_t i = 63; - do { - i--; - if (p_number & ((uint64_t)1 << i)) { - return i + (uint64_t)1; - } - } while (i != 0); - - return 0; -} - -constexpr uint32_t nearest_shift(uint32_t p_number) { - uint32_t i = 31; - do { - i--; - if (p_number & ((uint32_t)1 << i)) { - return i + (uint32_t)1; - } - } while (i != 0); - - return 0; -} - -// constexpr function to find the floored log2 of a number -template -constexpr T floor_log2(T x) { - return x < 2 ? x : 1 + floor_log2(x >> 1); -} - -// Get the number of bits needed to represent the number. -// IE, if you pass in 8, you will get 4. -// If you want to know how many bits are needed to store 8 values however, pass in (8 - 1). -template -constexpr T get_num_bits(T x) { - return floor_log2(x); -} +// Generic swap template. +#ifndef SWAP +#define SWAP(m_x, m_y) std::swap((m_x), (m_y)) +#endif // SWAP // Swap 16, 32 and 64 bits value for endianness. #if defined(__GNUC__) diff --git a/core/variant/variant_utility.cpp b/core/variant/variant_utility.cpp index 1c5b02cdd8..29893fccab 100644 --- a/core/variant/variant_utility.cpp +++ b/core/variant/variant_utility.cpp @@ -769,7 +769,7 @@ int64_t VariantUtilityFunctions::clampi(int64_t x, int64_t min, int64_t max) { } int64_t VariantUtilityFunctions::nearest_po2(int64_t x) { - return nearest_power_of_2_templated(uint64_t(x)); + return Math::nearest_power_of_2_templated(uint64_t(x)); } // Random diff --git a/drivers/alsa/audio_driver_alsa.cpp b/drivers/alsa/audio_driver_alsa.cpp index 126d47f8ca..16417a1cd9 100644 --- a/drivers/alsa/audio_driver_alsa.cpp +++ b/drivers/alsa/audio_driver_alsa.cpp @@ -112,7 +112,7 @@ Error AudioDriverALSA::init_output_device() { // Ref: https://www.alsa-project.org/main/index.php/FramesPeriods unsigned int periods = 2; int latency = Engine::get_singleton()->get_audio_output_latency(); - buffer_frames = closest_power_of_2(latency * mix_rate / 1000); + buffer_frames = Math::closest_power_of_2(latency * mix_rate / 1000); buffer_size = buffer_frames * periods; period_size = buffer_frames; diff --git a/drivers/coreaudio/audio_driver_coreaudio.mm b/drivers/coreaudio/audio_driver_coreaudio.mm index d9e0240ac7..7e5fef0cf3 100644 --- a/drivers/coreaudio/audio_driver_coreaudio.mm +++ b/drivers/coreaudio/audio_driver_coreaudio.mm @@ -155,7 +155,7 @@ Error AudioDriverCoreAudio::init() { uint32_t latency = Engine::get_singleton()->get_audio_output_latency(); // Sample rate is independent of channels (ref: https://stackoverflow.com/questions/11048825/audio-sample-frequency-rely-on-channels) - buffer_frames = closest_power_of_2(latency * (uint32_t)mix_rate / (uint32_t)1000); + buffer_frames = Math::closest_power_of_2(latency * (uint32_t)mix_rate / (uint32_t)1000); #ifdef MACOS_ENABLED result = AudioUnitSetProperty(audio_unit, kAudioDevicePropertyBufferFrameSize, kAudioUnitScope_Global, kOutputBus, &buffer_frames, sizeof(UInt32)); @@ -461,7 +461,7 @@ Error AudioDriverCoreAudio::init_input_device() { uint32_t latency = Engine::get_singleton()->get_audio_output_latency(); // Sample rate is independent of channels (ref: https://stackoverflow.com/questions/11048825/audio-sample-frequency-rely-on-channels) - capture_buffer_frames = closest_power_of_2(latency * (uint32_t)capture_mix_rate / (uint32_t)1000); + capture_buffer_frames = Math::closest_power_of_2(latency * (uint32_t)capture_mix_rate / (uint32_t)1000); buffer_size = capture_buffer_frames * capture_channels; diff --git a/drivers/d3d12/rendering_device_driver_d3d12.cpp b/drivers/d3d12/rendering_device_driver_d3d12.cpp index 66a624221c..3eead5350e 100644 --- a/drivers/d3d12/rendering_device_driver_d3d12.cpp +++ b/drivers/d3d12/rendering_device_driver_d3d12.cpp @@ -1119,7 +1119,7 @@ uint32_t RenderingDeviceDriverD3D12::_find_max_common_supported_sample_count(Vec msql.SampleCount = (UINT)samples; HRESULT res = device->CheckFeatureSupport(D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS, &msql, sizeof(msql)); if (SUCCEEDED(res) && msql.NumQualityLevels) { - int bit = get_shift_from_power_of_2((uint32_t)samples); + int bit = Math::get_shift_from_power_of_2((uint32_t)samples); ERR_FAIL_COND_V(bit == -1, 1); mask |= (uint32_t)(1 << bit); } @@ -1131,7 +1131,7 @@ uint32_t RenderingDeviceDriverD3D12::_find_max_common_supported_sample_count(Vec if (common == UINT32_MAX) { return 1; } else { - return ((uint32_t)1 << nearest_shift(common)); + return ((uint32_t)1 << Math::nearest_shift(common)); } } diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index 816b313116..8da68e6eee 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -2161,7 +2161,7 @@ void RasterizerCanvasGLES3::occluder_polygon_set_cull_mode(RID p_occluder, RS::C void RasterizerCanvasGLES3::set_shadow_texture_size(int p_size) { GLES3::Config *config = GLES3::Config::get_singleton(); - p_size = nearest_power_of_2_templated(p_size); + p_size = Math::nearest_power_of_2_templated(p_size); if (p_size > config->max_texture_size) { p_size = config->max_texture_size; diff --git a/drivers/gles3/storage/light_storage.cpp b/drivers/gles3/storage/light_storage.cpp index 7d53392f7f..df8b43f879 100644 --- a/drivers/gles3/storage/light_storage.cpp +++ b/drivers/gles3/storage/light_storage.cpp @@ -1285,7 +1285,7 @@ void LightStorage::shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(p_atlas); ERR_FAIL_NULL(shadow_atlas); ERR_FAIL_COND(p_size < 0); - p_size = next_power_of_2((uint32_t)p_size); + p_size = Math::next_power_of_2((uint32_t)p_size); if (p_size == shadow_atlas->size && p_16_bits == shadow_atlas->use_16_bits) { return; @@ -1332,7 +1332,7 @@ void LightStorage::shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quad ERR_FAIL_INDEX(p_quadrant, 4); ERR_FAIL_INDEX(p_subdivision, 16384); - uint32_t subdiv = next_power_of_2((uint32_t)p_subdivision); + uint32_t subdiv = Math::next_power_of_2((uint32_t)p_subdivision); if (subdiv & 0xaaaaaaaa) { // sqrt(subdiv) must be integer. subdiv <<= 1; } @@ -1406,7 +1406,7 @@ bool LightStorage::shadow_atlas_update_light(RID p_atlas, RID p_light_instance, } uint32_t quad_size = shadow_atlas->size >> 1; - int desired_fit = MIN(quad_size / shadow_atlas->smallest_subdiv, next_power_of_2(uint32_t(quad_size * p_coverage))); + int desired_fit = MIN(quad_size / shadow_atlas->smallest_subdiv, Math::next_power_of_2(uint32_t(quad_size * p_coverage))); int valid_quadrants[4]; int valid_quadrant_count = 0; @@ -1675,7 +1675,7 @@ void LightStorage::update_directional_shadow_atlas() { } void LightStorage::directional_shadow_atlas_set_size(int p_size, bool p_16_bits) { - p_size = nearest_power_of_2_templated(p_size); + p_size = Math::nearest_power_of_2_templated(p_size); if (directional_shadow.size == p_size && directional_shadow.use_16_bits == p_16_bits) { return; diff --git a/drivers/gles3/storage/texture_storage.cpp b/drivers/gles3/storage/texture_storage.cpp index 2c36f53e9f..eb86613d29 100644 --- a/drivers/gles3/storage/texture_storage.cpp +++ b/drivers/gles3/storage/texture_storage.cpp @@ -2356,7 +2356,7 @@ void TextureStorage::update_texture_atlas() { si.pixel_size = Size2i(src_tex->width, src_tex->height); if (base_size < (uint32_t)si.size.width) { - base_size = nearest_power_of_2_templated(si.size.width); + base_size = Math::nearest_power_of_2_templated(si.size.width); } si.texture = E.key; @@ -2426,7 +2426,7 @@ void TextureStorage::update_texture_atlas() { } texture_atlas.size.width = base_size * border; - texture_atlas.size.height = nearest_power_of_2_templated(atlas_height * border); + texture_atlas.size.height = Math::nearest_power_of_2_templated(atlas_height * border); for (int i = 0; i < item_count; i++) { TextureAtlas::Texture *t = texture_atlas.textures.getptr(items[i].texture); @@ -3598,7 +3598,7 @@ void TextureStorage::render_target_sdf_process(RID p_render_target) { // Process - int stride = nearest_power_of_2_templated(MAX(size.width, size.height) / 2); + int stride = Math::nearest_power_of_2_templated(MAX(size.width, size.height) / 2); variant = CanvasSdfShaderGLES3::MODE_PROCESS; success = sdf_shader.shader.version_bind_shader(sdf_shader.shader_version, variant); diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.cpp b/drivers/pulseaudio/audio_driver_pulseaudio.cpp index 8bc88495d3..5a94fb01b0 100644 --- a/drivers/pulseaudio/audio_driver_pulseaudio.cpp +++ b/drivers/pulseaudio/audio_driver_pulseaudio.cpp @@ -222,7 +222,7 @@ Error AudioDriverPulseAudio::init_output_device() { } int tmp_latency = Engine::get_singleton()->get_audio_output_latency(); - buffer_frames = closest_power_of_2(tmp_latency * mix_rate / 1000); + buffer_frames = Math::closest_power_of_2(tmp_latency * mix_rate / 1000); pa_buffer_size = buffer_frames * pa_map.channels; print_verbose("PulseAudio: detected " + itos(pa_map.channels) + " output channels"); @@ -727,7 +727,7 @@ Error AudioDriverPulseAudio::init_input_device() { spec.rate = mix_rate; int input_latency = 30; - int input_buffer_frames = closest_power_of_2(input_latency * mix_rate / 1000); + int input_buffer_frames = Math::closest_power_of_2(input_latency * mix_rate / 1000); int input_buffer_size = input_buffer_frames * spec.channels; pa_buffer_attr attr = {}; diff --git a/drivers/xaudio2/audio_driver_xaudio2.cpp b/drivers/xaudio2/audio_driver_xaudio2.cpp index 0c2fdb64df..1db5491f4e 100644 --- a/drivers/xaudio2/audio_driver_xaudio2.cpp +++ b/drivers/xaudio2/audio_driver_xaudio2.cpp @@ -46,7 +46,7 @@ Error AudioDriverXAudio2::init() { channels = 2; int latency = Engine::get_singleton()->get_audio_output_latency(); - buffer_size = closest_power_of_2(latency * mix_rate / 1000); + buffer_size = Math::closest_power_of_2(latency * mix_rate / 1000); samples_in = memnew_arr(int32_t, size_t(buffer_size) * channels); for (int i = 0; i < AUDIO_BUFFERS; i++) { diff --git a/editor/import/editor_atlas_packer.cpp b/editor/import/editor_atlas_packer.cpp index 94de4d1d23..fb6f2a0da8 100644 --- a/editor/import/editor_atlas_packer.cpp +++ b/editor/import/editor_atlas_packer.cpp @@ -171,8 +171,8 @@ void EditorAtlasPacker::chart_pack(Vector &charts, int &r_width, int &r_h bitmaps.sort(); - int atlas_max_width = nearest_power_of_2_templated(p_atlas_max_size) / divide_by; - int atlas_w = nearest_power_of_2_templated(max_w); + int atlas_max_width = Math::nearest_power_of_2_templated(p_atlas_max_size) / divide_by; + int atlas_w = Math::nearest_power_of_2_templated(max_w); int atlas_h; while (true) { atlas_h = 0; diff --git a/editor/scene/texture/texture_3d_editor_plugin.cpp b/editor/scene/texture/texture_3d_editor_plugin.cpp index 174f643ba7..da34d90db2 100644 --- a/editor/scene/texture/texture_3d_editor_plugin.cpp +++ b/editor/scene/texture/texture_3d_editor_plugin.cpp @@ -187,7 +187,7 @@ void Texture3DEditor::_update_gui() { } const uint32_t components_mask = Image::get_format_component_mask(format); - if (is_power_of_2(components_mask)) { + if (Math::is_power_of_2(components_mask)) { // Only one channel available, no point in showing a channel selector. channel_selector->hide(); } else { diff --git a/editor/scene/texture/texture_editor_plugin.cpp b/editor/scene/texture/texture_editor_plugin.cpp index 65f6aa5e37..d8f96942ed 100644 --- a/editor/scene/texture/texture_editor_plugin.cpp +++ b/editor/scene/texture/texture_editor_plugin.cpp @@ -278,7 +278,7 @@ TexturePreview::TexturePreview(Ref p_texture, bool p_show_metadata) { const uint32_t components_mask = format != Image::FORMAT_MAX ? Image::get_format_component_mask(format) : 0xf; // Add color channel selector at the bottom left if more than 1 channel is available. - if (p_show_metadata && !is_power_of_2(components_mask)) { + if (p_show_metadata && !Math::is_power_of_2(components_mask)) { channel_selector = memnew(ColorChannelSelector); channel_selector->connect("selected_channels_changed", callable_mp(this, &TexturePreview::on_selected_channels_changed)); channel_selector->set_h_size_flags(Control::SIZE_SHRINK_BEGIN); diff --git a/editor/scene/texture/texture_layered_editor_plugin.cpp b/editor/scene/texture/texture_layered_editor_plugin.cpp index d0749b381b..cd6ea2a079 100644 --- a/editor/scene/texture/texture_layered_editor_plugin.cpp +++ b/editor/scene/texture/texture_layered_editor_plugin.cpp @@ -241,7 +241,7 @@ void TextureLayeredEditor::_update_gui() { info->set_text(texture_info); const uint32_t components_mask = Image::get_format_component_mask(format); - if (is_power_of_2(components_mask)) { + if (Math::is_power_of_2(components_mask)) { // Only one channel available, no point in showing a channel selector. channel_selector->hide(); } else { diff --git a/modules/lightmapper_rd/lightmapper_rd.cpp b/modules/lightmapper_rd/lightmapper_rd.cpp index 9fc119a2f4..7a065e7a64 100644 --- a/modules/lightmapper_rd/lightmapper_rd.cpp +++ b/modules/lightmapper_rd/lightmapper_rd.cpp @@ -226,7 +226,7 @@ void LightmapperRD::_sort_triangle_clusters(uint32_t p_cluster_size, uint32_t p_ break; } - uint32_t left_cluster_count = next_power_of_2(p_count / 2); + uint32_t left_cluster_count = Math::next_power_of_2(p_count / 2); left_cluster_count = MAX(left_cluster_count, p_cluster_size); left_cluster_count = MIN(left_cluster_count, p_count); _sort_triangle_clusters(p_cluster_size, p_cluster_index, p_index_start, left_cluster_count, p_triangle_sort, p_cluster_aabb); @@ -257,8 +257,8 @@ Lightmapper::BakeError LightmapperRD::_blit_meshes_into_atlas(int p_max_texture_ atlas_size = atlas_size.max(s + Size2i(2, 2).maxi(p_denoiser_range) * p_supersampling_factor); } - int max = nearest_power_of_2_templated(atlas_size.width); - max = MAX(max, nearest_power_of_2_templated(atlas_size.height)); + int max = Math::nearest_power_of_2_templated(atlas_size.width); + max = MAX(max, Math::nearest_power_of_2_templated(atlas_size.height)); if (max > p_max_texture_size) { return BAKE_ERROR_TEXTURE_EXCEEDS_MAX_SIZE; @@ -1016,7 +1016,7 @@ LightmapperRD::BakeError LightmapperRD::_denoise(RenderingDevice *p_rd, Refsize.x * 0.125, 256); - texsize = next_power_of_2((uint32_t)texsize); + texsize = Math::next_power_of_2((uint32_t)texsize); if (p_msdf) { texsize = MIN(texsize, 2048); } else { texsize = MIN(texsize, 1024); } if (mw > texsize) { // Special case, adapt to it? - texsize = next_power_of_2((uint32_t)mw); + texsize = Math::next_power_of_2((uint32_t)mw); } if (mh > texsize) { // Special case, adapt to it? - texsize = next_power_of_2((uint32_t)mh); + texsize = Math::next_power_of_2((uint32_t)mh); } ShelfPackTexture tex = ShelfPackTexture(texsize, texsize); diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp index 230c459e48..aa2c807996 100644 --- a/modules/text_server_fb/text_server_fb.cpp +++ b/modules/text_server_fb/text_server_fb.cpp @@ -287,7 +287,7 @@ _FORCE_INLINE_ TextServerFallback::FontTexturePosition TextServerFallback::find_ // Could not find texture to fit, create one. int texsize = MAX(p_data->size.x * 0.125, 256); - texsize = next_power_of_2((uint32_t)texsize); + texsize = Math::next_power_of_2((uint32_t)texsize); if (p_msdf) { texsize = MIN(texsize, 2048); @@ -295,10 +295,10 @@ _FORCE_INLINE_ TextServerFallback::FontTexturePosition TextServerFallback::find_ texsize = MIN(texsize, 1024); } if (mw > texsize) { // Special case, adapt to it? - texsize = next_power_of_2((uint32_t)mw); + texsize = Math::next_power_of_2((uint32_t)mw); } if (mh > texsize) { // Special case, adapt to it? - texsize = next_power_of_2((uint32_t)mh); + texsize = Math::next_power_of_2((uint32_t)mh); } ShelfPackTexture tex = ShelfPackTexture(texsize, texsize); diff --git a/modules/webrtc/webrtc_data_channel.cpp b/modules/webrtc/webrtc_data_channel.cpp index 687e9b5f40..ac1c4a4997 100644 --- a/modules/webrtc/webrtc_data_channel.cpp +++ b/modules/webrtc/webrtc_data_channel.cpp @@ -61,7 +61,7 @@ void WebRTCDataChannel::_bind_methods() { } WebRTCDataChannel::WebRTCDataChannel() { - _in_buffer_shift = nearest_shift(uint32_t((int)GLOBAL_GET("network/limits/webrtc/max_channel_in_buffer_kb") - 1)) + (uint32_t)10; + _in_buffer_shift = Math::nearest_shift(uint32_t((int)GLOBAL_GET("network/limits/webrtc/max_channel_in_buffer_kb") - 1)) + (uint32_t)10; } WebRTCDataChannel::~WebRTCDataChannel() { diff --git a/modules/websocket/emws_peer.cpp b/modules/websocket/emws_peer.cpp index 56cae55b36..9a6e6581f4 100644 --- a/modules/websocket/emws_peer.cpp +++ b/modules/websocket/emws_peer.cpp @@ -106,7 +106,7 @@ Error EMWSPeer::connect_to_url(const String &p_url, const Ref &p_tls if (peer_sock == -1) { return FAILED; } - in_buffer.resize(nearest_shift((uint32_t)inbound_buffer_size), max_queued_packets); + in_buffer.resize(Math::nearest_shift((uint32_t)inbound_buffer_size), max_queued_packets); packet_buffer.resize(inbound_buffer_size); ready_state = STATE_CONNECTING; return OK; diff --git a/modules/websocket/wsl_peer.cpp b/modules/websocket/wsl_peer.cpp index b9369f5b47..65d0313938 100644 --- a/modules/websocket/wsl_peer.cpp +++ b/modules/websocket/wsl_peer.cpp @@ -297,7 +297,7 @@ Error WSLPeer::_do_server_handshake() { wslay_event_context_server_init(&wsl_ctx, &_wsl_callbacks, this); wslay_event_config_set_no_buffering(wsl_ctx, 1); wslay_event_config_set_max_recv_msg_length(wsl_ctx, inbound_buffer_size); - in_buffer.resize(nearest_shift((uint32_t)inbound_buffer_size), max_queued_packets); + in_buffer.resize(Math::nearest_shift((uint32_t)inbound_buffer_size), max_queued_packets); packet_buffer.resize(inbound_buffer_size); ready_state = STATE_OPEN; } @@ -406,7 +406,7 @@ void WSLPeer::_do_client_handshake() { wslay_event_context_client_init(&wsl_ctx, &_wsl_callbacks, this); wslay_event_config_set_no_buffering(wsl_ctx, 1); wslay_event_config_set_max_recv_msg_length(wsl_ctx, inbound_buffer_size); - in_buffer.resize(nearest_shift((uint32_t)inbound_buffer_size), max_queued_packets); + in_buffer.resize(Math::nearest_shift((uint32_t)inbound_buffer_size), max_queued_packets); packet_buffer.resize(inbound_buffer_size); ready_state = STATE_OPEN; break; diff --git a/platform/web/audio_driver_web.cpp b/platform/web/audio_driver_web.cpp index fbb3971a77..253fe231d9 100644 --- a/platform/web/audio_driver_web.cpp +++ b/platform/web/audio_driver_web.cpp @@ -129,7 +129,7 @@ Error AudioDriverWeb::init() { } mix_rate = audio_context.mix_rate; channel_count = audio_context.channel_count; - buffer_length = closest_power_of_2(uint32_t(latency * mix_rate / 1000)); + buffer_length = Math::closest_power_of_2(uint32_t(latency * mix_rate / 1000)); Error err = create(buffer_length, channel_count); if (err != OK) { return err; diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index 896b82783d..a81371e669 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -4578,7 +4578,7 @@ struct AnimationCompressionDataState { return 1; } } - return nearest_shift((uint32_t)p_delta); + return Math::nearest_shift((uint32_t)p_delta); } void _compute_max_shifts(uint32_t p_from, uint32_t p_to, uint32_t *max_shifts, uint32_t &max_frame_delta_shift) const { @@ -4589,7 +4589,7 @@ struct AnimationCompressionDataState { for (uint32_t i = p_from + 1; i <= p_to; i++) { int32_t frame_delta = temp_packets[i].frame - temp_packets[i - 1].frame; - max_frame_delta_shift = MAX(max_frame_delta_shift, nearest_shift((uint32_t)frame_delta)); + max_frame_delta_shift = MAX(max_frame_delta_shift, Math::nearest_shift((uint32_t)frame_delta)); for (uint32_t j = 0; j < components; j++) { int32_t diff = _compute_delta16_signed(temp_packets[i - 1].data[j], temp_packets[i].data[j]); uint32_t shift = _compute_shift_bits_signed(diff); diff --git a/scene/resources/material.h b/scene/resources/material.h index 901e057c00..a6ccd3ad1b 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -357,27 +357,27 @@ public: private: struct MaterialKey { // enum values - uint64_t texture_filter : get_num_bits(TEXTURE_FILTER_MAX - 1); - uint64_t detail_uv : get_num_bits(DETAIL_UV_MAX - 1); - uint64_t transparency : get_num_bits(TRANSPARENCY_MAX - 1); - uint64_t alpha_antialiasing_mode : get_num_bits(ALPHA_ANTIALIASING_MAX - 1); - uint64_t shading_mode : get_num_bits(SHADING_MODE_MAX - 1); - uint64_t blend_mode : get_num_bits(BLEND_MODE_MAX - 1); - uint64_t depth_draw_mode : get_num_bits(DEPTH_DRAW_MAX - 1); - uint64_t depth_test : get_num_bits(DEPTH_TEST_MAX - 1); - uint64_t cull_mode : get_num_bits(CULL_MAX - 1); - uint64_t diffuse_mode : get_num_bits(DIFFUSE_MAX - 1); - uint64_t specular_mode : get_num_bits(SPECULAR_MAX - 1); - uint64_t billboard_mode : get_num_bits(BILLBOARD_MAX - 1); - uint64_t detail_blend_mode : get_num_bits(BLEND_MODE_MAX - 1); - uint64_t roughness_channel : get_num_bits(TEXTURE_CHANNEL_MAX - 1); - uint64_t emission_op : get_num_bits(EMISSION_OP_MAX - 1); - uint64_t distance_fade : get_num_bits(DISTANCE_FADE_MAX - 1); + uint64_t texture_filter : Math::get_num_bits(TEXTURE_FILTER_MAX - 1); + uint64_t detail_uv : Math::get_num_bits(DETAIL_UV_MAX - 1); + uint64_t transparency : Math::get_num_bits(TRANSPARENCY_MAX - 1); + uint64_t alpha_antialiasing_mode : Math::get_num_bits(ALPHA_ANTIALIASING_MAX - 1); + uint64_t shading_mode : Math::get_num_bits(SHADING_MODE_MAX - 1); + uint64_t blend_mode : Math::get_num_bits(BLEND_MODE_MAX - 1); + uint64_t depth_draw_mode : Math::get_num_bits(DEPTH_DRAW_MAX - 1); + uint64_t depth_test : Math::get_num_bits(DEPTH_TEST_MAX - 1); + uint64_t cull_mode : Math::get_num_bits(CULL_MAX - 1); + uint64_t diffuse_mode : Math::get_num_bits(DIFFUSE_MAX - 1); + uint64_t specular_mode : Math::get_num_bits(SPECULAR_MAX - 1); + uint64_t billboard_mode : Math::get_num_bits(BILLBOARD_MAX - 1); + uint64_t detail_blend_mode : Math::get_num_bits(BLEND_MODE_MAX - 1); + uint64_t roughness_channel : Math::get_num_bits(TEXTURE_CHANNEL_MAX - 1); + uint64_t emission_op : Math::get_num_bits(EMISSION_OP_MAX - 1); + uint64_t distance_fade : Math::get_num_bits(DISTANCE_FADE_MAX - 1); // stencil - uint64_t stencil_mode : get_num_bits(STENCIL_MODE_MAX - 1); + uint64_t stencil_mode : Math::get_num_bits(STENCIL_MODE_MAX - 1); uint64_t stencil_flags : STENCIL_FLAG_NUM_BITS; - uint64_t stencil_compare : get_num_bits(STENCIL_COMPARE_MAX - 1); + uint64_t stencil_compare : Math::get_num_bits(STENCIL_COMPARE_MAX - 1); uint64_t stencil_reference : 8; // booleans diff --git a/servers/audio/audio_rb_resampler.cpp b/servers/audio/audio_rb_resampler.cpp index 86369b64f1..bd50e34bfe 100644 --- a/servers/audio/audio_rb_resampler.cpp +++ b/servers/audio/audio_rb_resampler.cpp @@ -31,6 +31,7 @@ #include "audio_rb_resampler.h" #include "core/math/audio_frame.h" +#include "core/math/math_funcs_binary.h" #include "core/os/memory.h" int AudioRBResampler::get_channel_count() const { @@ -178,7 +179,7 @@ int AudioRBResampler::get_num_of_ready_frames() { Error AudioRBResampler::setup(int p_channels, int p_src_mix_rate, int p_target_mix_rate, int p_buffer_msec, int p_minbuff_needed) { ERR_FAIL_COND_V(p_channels != 1 && p_channels != 2 && p_channels != 4 && p_channels != 6 && p_channels != 8, ERR_INVALID_PARAMETER); - int desired_rb_bits = nearest_shift((uint32_t)MAX((p_buffer_msec / 1000.0) * p_src_mix_rate, p_minbuff_needed)); + int desired_rb_bits = Math::nearest_shift((uint32_t)MAX((p_buffer_msec / 1000.0) * p_src_mix_rate, p_minbuff_needed)); bool recreate = !rb; diff --git a/servers/audio/effects/audio_effect_capture.cpp b/servers/audio/effects/audio_effect_capture.cpp index ecc0bd9383..4246084c5c 100644 --- a/servers/audio/effects/audio_effect_capture.cpp +++ b/servers/audio/effects/audio_effect_capture.cpp @@ -79,7 +79,7 @@ Ref AudioEffectCapture::instantiate() { if (!buffer_initialized) { float target_buffer_size = AudioServer::get_singleton()->get_mix_rate() * buffer_length_seconds; ERR_FAIL_COND_V(target_buffer_size <= 0 || target_buffer_size >= (1 << 27), Ref()); - buffer.resize(nearest_shift((uint32_t)target_buffer_size)); + buffer.resize(Math::nearest_shift((uint32_t)target_buffer_size)); buffer_initialized = true; } diff --git a/servers/audio/effects/audio_stream_generator.cpp b/servers/audio/effects/audio_stream_generator.cpp index 08ec27c84b..aa33b8f372 100644 --- a/servers/audio/effects/audio_stream_generator.cpp +++ b/servers/audio/effects/audio_stream_generator.cpp @@ -71,7 +71,7 @@ Ref AudioStreamGenerator::instantiate_playback() { playback.instantiate(); playback->generator = this; uint32_t target_buffer_size = _get_target_rate() * buffer_len; - playback->buffer.resize(nearest_shift(target_buffer_size)); + playback->buffer.resize(Math::nearest_shift(target_buffer_size)); playback->buffer.clear(); return playback; } diff --git a/servers/rendering/renderer_rd/cluster_builder_rd.cpp b/servers/rendering/renderer_rd/cluster_builder_rd.cpp index 65be409491..afc2d6a68b 100644 --- a/servers/rendering/renderer_rd/cluster_builder_rd.cpp +++ b/servers/rendering/renderer_rd/cluster_builder_rd.cpp @@ -501,7 +501,7 @@ void ClusterBuilderRD::bake_cluster() { RendererRD::MaterialStorage::store_camera(adjusted_projection, state.projection); state.inv_z_far = 1.0 / z_far; - state.screen_to_clusters_shift = get_shift_from_power_of_2(cluster_size); + state.screen_to_clusters_shift = Math::get_shift_from_power_of_2(cluster_size); state.screen_to_clusters_shift -= divisor; //screen is smaller, shift one less state.cluster_screen_width = cluster_screen_size.x; @@ -600,7 +600,7 @@ void ClusterBuilderRD::debug(ElementType p_element) { push_constant.screen_size[1] = screen_size.y; push_constant.cluster_screen_size[0] = cluster_screen_size.x; push_constant.cluster_screen_size[1] = cluster_screen_size.y; - push_constant.cluster_shift = get_shift_from_power_of_2(cluster_size); + push_constant.cluster_shift = Math::get_shift_from_power_of_2(cluster_size); push_constant.cluster_type = p_element; push_constant.orthogonal = camera_orthogonal; push_constant.z_far = z_far; diff --git a/servers/rendering/renderer_rd/environment/fog.cpp b/servers/rendering/renderer_rd/environment/fog.cpp index a4d68d0951..2663609bde 100644 --- a/servers/rendering/renderer_rd/environment/fog.cpp +++ b/servers/rendering/renderer_rd/environment/fog.cpp @@ -1127,7 +1127,7 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P { uint32_t cluster_size = p_settings.cluster_builder->get_cluster_size(); - params.cluster_shift = get_shift_from_power_of_2(cluster_size); + params.cluster_shift = Math::get_shift_from_power_of_2(cluster_size); uint32_t cluster_screen_width = Math::division_round_up((uint32_t)p_settings.rb_size.x, cluster_size); uint32_t cluster_screen_height = Math::division_round_up((uint32_t)p_settings.rb_size.y, cluster_size); diff --git a/servers/rendering/renderer_rd/environment/gi.cpp b/servers/rendering/renderer_rd/environment/gi.cpp index 7dc9615e68..e5991691ed 100644 --- a/servers/rendering/renderer_rd/environment/gi.cpp +++ b/servers/rendering/renderer_rd/environment/gi.cpp @@ -484,7 +484,7 @@ void GI::SDFGI::create(RID p_env, const Vector3 &p_world_position, uint32_t p_re RD::TextureFormat tf_aniso1 = tf_sdf; tf_aniso1.format = RD::DATA_FORMAT_R8G8_UNORM; - int passes = nearest_shift(cascade_size) - 1; + int passes = Math::nearest_shift(cascade_size) - 1; //store lightprobe SH RD::TextureFormat tf_probes; @@ -2659,7 +2659,7 @@ void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vectorcluster_size); + scene_state.ubo.cluster_shift = Math::get_shift_from_power_of_2(p_render_data->cluster_size); scene_state.ubo.max_cluster_element_count_div_32 = p_render_data->cluster_max_elements / 32; { uint32_t cluster_screen_width = Math::division_round_up((uint32_t)p_screen_size.width, p_render_data->cluster_size); @@ -789,7 +789,7 @@ void RenderForwardClustered::SceneState::grow_instance_buffer(RenderListType p_r if (p_req_element_count > 0) { if (instance_buffer[p_render_list].get_size(0u) < p_req_element_count * sizeof(SceneState::InstanceData)) { instance_buffer[p_render_list].uninit(); - uint32_t new_size = nearest_power_of_2_templated(MAX(uint64_t(INSTANCE_DATA_BUFFER_MIN_SIZE), p_req_element_count)); + uint32_t new_size = Math::nearest_power_of_2_templated(MAX(uint64_t(INSTANCE_DATA_BUFFER_MIN_SIZE), p_req_element_count)); instance_buffer[p_render_list].set_storage_size(0u, new_size * sizeof(SceneState::InstanceData)); curr_gpu_ptr[p_render_list] = nullptr; } diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp index 90af8a9fcb..54c0fc2cb4 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -1960,7 +1960,7 @@ void RenderForwardMobile::SceneState::grow_instance_buffer(RenderListType p_rend if (p_req_element_count > 0) { if (instance_buffer[p_render_list].get_size(0u) < p_req_element_count * sizeof(SceneState::InstanceData)) { instance_buffer[p_render_list].uninit(); - uint32_t new_size = nearest_power_of_2_templated(MAX(uint64_t(INSTANCE_DATA_BUFFER_MIN_SIZE), p_req_element_count)); + uint32_t new_size = Math::nearest_power_of_2_templated(MAX(uint64_t(INSTANCE_DATA_BUFFER_MIN_SIZE), p_req_element_count)); instance_buffer[p_render_list].set_storage_size(0u, new_size * sizeof(SceneState::InstanceData)); curr_gpu_ptr[p_render_list] = nullptr; } diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index 25a588ed8a..4a962c03b5 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -1002,7 +1002,7 @@ void RendererCanvasRenderRD::_update_occluder_buffer(uint32_t p_size) { if (p_size > state.shadow_occluder_buffer_size) { needs_update = true; - state.shadow_occluder_buffer_size = next_power_of_2(p_size); + state.shadow_occluder_buffer_size = Math::next_power_of_2(p_size); if (state.shadow_occluder_buffer.is_valid()) { RD::get_singleton()->free_rid(state.shadow_occluder_buffer); } @@ -2146,7 +2146,7 @@ bool RendererCanvasRenderRD::free(RID p_rid) { } void RendererCanvasRenderRD::set_shadow_texture_size(int p_size) { - p_size = MAX(1, nearest_power_of_2_templated(p_size)); + p_size = MAX(1, Math::nearest_power_of_2_templated(p_size)); if (p_size == state.shadow_texture_size) { return; } diff --git a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp index e59d7a237c..57a411f807 100644 --- a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp @@ -2157,7 +2157,7 @@ void LightStorage::shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(p_atlas); ERR_FAIL_NULL(shadow_atlas); ERR_FAIL_COND(p_size < 0); - p_size = next_power_of_2((uint32_t)p_size); + p_size = Math::next_power_of_2((uint32_t)p_size); if (p_size == shadow_atlas->size && p_16_bits == shadow_atlas->use_16_bits) { return; @@ -2194,7 +2194,7 @@ void LightStorage::shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quad ERR_FAIL_INDEX(p_quadrant, 4); ERR_FAIL_INDEX(p_subdivision, 16384); - uint32_t subdiv = next_power_of_2((uint32_t)p_subdivision); + uint32_t subdiv = Math::next_power_of_2((uint32_t)p_subdivision); if (subdiv & 0xaaaaaaaa) { //sqrt(subdiv) must be integer subdiv <<= 1; } @@ -2389,7 +2389,7 @@ bool LightStorage::shadow_atlas_update_light(RID p_atlas, RID p_light_instance, } uint32_t quad_size = shadow_atlas->size >> 1; - int desired_fit = MIN(quad_size / shadow_atlas->smallest_subdiv, next_power_of_2(uint32_t(quad_size * p_coverage))); + int desired_fit = MIN(quad_size / shadow_atlas->smallest_subdiv, Math::next_power_of_2(uint32_t(quad_size * p_coverage))); int valid_quadrants[4]; int valid_quadrant_count = 0; @@ -2554,7 +2554,7 @@ void LightStorage::update_directional_shadow_atlas() { } } void LightStorage::directional_shadow_atlas_set_size(int p_size, bool p_16_bits) { - p_size = nearest_power_of_2_templated(p_size); + p_size = Math::nearest_power_of_2_templated(p_size); if (directional_shadow.size == p_size && directional_shadow.use_16_bits == p_16_bits) { return; diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp index a60815a690..83f07b8e29 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp @@ -3431,7 +3431,7 @@ void TextureStorage::update_decal_atlas() { si.pixel_size = Size2i(src_tex->width, src_tex->height); if (base_size < (uint32_t)si.size.width) { - base_size = nearest_power_of_2_templated(si.size.width); + base_size = Math::nearest_power_of_2_templated(si.size.width); } si.texture = E.key; @@ -3501,7 +3501,7 @@ void TextureStorage::update_decal_atlas() { } decal_atlas.size.width = base_size * border; - decal_atlas.size.height = nearest_power_of_2_templated(atlas_height * border); + decal_atlas.size.height = Math::nearest_power_of_2_templated(atlas_height * border); for (int i = 0; i < item_count; i++) { DecalAtlas::Texture *t = decal_atlas.textures.getptr(items[i].texture); @@ -4678,7 +4678,7 @@ void TextureStorage::render_target_sdf_process(RID p_render_target) { /* Process */ - int stride = nearest_power_of_2_templated(MAX(push_constant.size[0], push_constant.size[1]) / 2); + int stride = Math::nearest_power_of_2_templated(MAX(push_constant.size[0], push_constant.size[1]) / 2); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, rt_sdf.pipelines[RenderTargetSDF::SHADER_PROCESS]); diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp index a841defead..9d79ec31bf 100644 --- a/servers/rendering/rendering_device.cpp +++ b/servers/rendering/rendering_device.cpp @@ -6540,7 +6540,7 @@ RenderingDevice::TransferWorker *RenderingDevice::_acquire_transfer_worker(uint3 driver->buffer_free(transfer_worker->staging_buffer); } - uint32_t new_staging_buffer_size = next_power_of_2(expected_buffer_size); + uint32_t new_staging_buffer_size = Math::next_power_of_2(expected_buffer_size); transfer_worker->staging_buffer_size_allocated = new_staging_buffer_size; transfer_worker->staging_buffer = driver->buffer_create(new_staging_buffer_size, RDD::BUFFER_USAGE_TRANSFER_FROM_BIT, RDD::MEMORY_ALLOCATION_TYPE_CPU, frames_drawn); } @@ -7807,10 +7807,10 @@ Error RenderingDevice::initialize(RenderingContextDriver *p_context, DisplayServ download_staging_buffers.max_size = upload_staging_buffers.max_size; texture_upload_region_size_px = GLOBAL_GET("rendering/rendering_device/staging_buffer/texture_upload_region_size_px"); - texture_upload_region_size_px = nearest_power_of_2_templated(texture_upload_region_size_px); + texture_upload_region_size_px = Math::nearest_power_of_2_templated(texture_upload_region_size_px); texture_download_region_size_px = GLOBAL_GET("rendering/rendering_device/staging_buffer/texture_download_region_size_px"); - texture_download_region_size_px = nearest_power_of_2_templated(texture_download_region_size_px); + texture_download_region_size_px = Math::nearest_power_of_2_templated(texture_download_region_size_px); // Ensure current staging block is valid and at least one per frame exists. upload_staging_buffers.current = 0; diff --git a/tests/core/math/test_math_funcs.h b/tests/core/math/test_math_funcs.h index f75bb7db61..98ce3bf076 100644 --- a/tests/core/math/test_math_funcs.h +++ b/tests/core/math/test_math_funcs.h @@ -58,35 +58,35 @@ TEST_CASE("[Math] C++ macros") { } TEST_CASE("[Math] Power of two functions") { - CHECK(next_power_of_2((uint32_t)0) == 0); - CHECK(next_power_of_2((uint32_t)1) == 1); - CHECK(next_power_of_2((uint32_t)16) == 16); - CHECK(next_power_of_2((uint32_t)17) == 32); - CHECK(next_power_of_2((uint32_t)65535) == 65536); + CHECK(Math::next_power_of_2((uint32_t)0) == 0); + CHECK(Math::next_power_of_2((uint32_t)1) == 1); + CHECK(Math::next_power_of_2((uint32_t)16) == 16); + CHECK(Math::next_power_of_2((uint32_t)17) == 32); + CHECK(Math::next_power_of_2((uint32_t)65535) == 65536); - CHECK(previous_power_of_2((uint32_t)0) == 0); - CHECK(previous_power_of_2((uint32_t)1) == 1); - CHECK(previous_power_of_2((uint32_t)16) == 16); - CHECK(previous_power_of_2((uint32_t)17) == 16); - CHECK(previous_power_of_2((uint32_t)65535) == 32768); + CHECK(Math::previous_power_of_2((uint32_t)0) == 0); + CHECK(Math::previous_power_of_2((uint32_t)1) == 1); + CHECK(Math::previous_power_of_2((uint32_t)16) == 16); + CHECK(Math::previous_power_of_2((uint32_t)17) == 16); + CHECK(Math::previous_power_of_2((uint32_t)65535) == 32768); - CHECK(closest_power_of_2((uint32_t)0) == 0); - CHECK(closest_power_of_2((uint32_t)1) == 1); - CHECK(closest_power_of_2((uint32_t)16) == 16); - CHECK(closest_power_of_2((uint32_t)17) == 16); - CHECK(closest_power_of_2((uint32_t)65535) == 65536); + CHECK(Math::closest_power_of_2((uint32_t)0) == 0); + CHECK(Math::closest_power_of_2((uint32_t)1) == 1); + CHECK(Math::closest_power_of_2((uint32_t)16) == 16); + CHECK(Math::closest_power_of_2((uint32_t)17) == 16); + CHECK(Math::closest_power_of_2((uint32_t)65535) == 65536); - CHECK(get_shift_from_power_of_2((uint32_t)0) == -1); - CHECK(get_shift_from_power_of_2((uint32_t)1) == 0); - CHECK(get_shift_from_power_of_2((uint32_t)16) == 4); - CHECK(get_shift_from_power_of_2((uint32_t)17) == -1); - CHECK(get_shift_from_power_of_2((uint32_t)65535) == -1); + CHECK(Math::get_shift_from_power_of_2((uint32_t)0) == -1); + CHECK(Math::get_shift_from_power_of_2((uint32_t)1) == 0); + CHECK(Math::get_shift_from_power_of_2((uint32_t)16) == 4); + CHECK(Math::get_shift_from_power_of_2((uint32_t)17) == -1); + CHECK(Math::get_shift_from_power_of_2((uint32_t)65535) == -1); - CHECK(nearest_shift((uint32_t)0) == 0); - CHECK(nearest_shift((uint32_t)1) == 1); - CHECK(nearest_shift((uint32_t)16) == 5); - CHECK(nearest_shift((uint32_t)17) == 5); - CHECK(nearest_shift((uint32_t)65535) == 16); + CHECK(Math::nearest_shift((uint32_t)0) == 0); + CHECK(Math::nearest_shift((uint32_t)1) == 1); + CHECK(Math::nearest_shift((uint32_t)16) == 5); + CHECK(Math::nearest_shift((uint32_t)17) == 5); + CHECK(Math::nearest_shift((uint32_t)65535) == 16); } TEST_CASE_TEMPLATE("[Math] abs", T, int, float, double) {