Explorar el Código

Merge pull request #10419 from marcelofg55/2.1

Add closest_power_of_2 func and implement mix_rate/latency on OS X
Rémi Verschelde hace 8 años
padre
commit
e5102a99b9

+ 3 - 3
core/image.cpp

@@ -581,8 +581,8 @@ void Image::resize_to_po2(bool p_square) {
 		ERR_FAIL();
 		ERR_FAIL();
 	}
 	}
 
 
-	int w = nearest_power_of_2(width);
-	int h = nearest_power_of_2(height);
+	int w = next_power_of_2(width);
+	int h = next_power_of_2(height);
 
 
 	if (w == width && h == height) {
 	if (w == width && h == height) {
 
 
@@ -968,7 +968,7 @@ Error Image::generate_mipmaps(int p_mipmaps, bool p_keep_existing) {
 
 
 	DVector<uint8_t>::Write wp = data.write();
 	DVector<uint8_t>::Write wp = data.write();
 
 
-	if (nearest_power_of_2(width) == uint32_t(width) && nearest_power_of_2(height) == uint32_t(height)) {
+	if (next_power_of_2(width) == uint32_t(width) && next_power_of_2(height) == uint32_t(height)) {
 		//use fast code for powers of 2
 		//use fast code for powers of 2
 		int prev_ofs = 0;
 		int prev_ofs = 0;
 		int prev_h = height;
 		int prev_h = height;

+ 10 - 10
core/io/file_access_compressed.cpp

@@ -43,16 +43,16 @@ void FileAccessCompressed::configure(const String &p_magic, Compression::Mode p_
 	block_size = p_block_size;
 	block_size = p_block_size;
 }
 }
 
 
-#define WRITE_FIT(m_bytes)                                     \
-	{                                                          \
-		if (write_pos + (m_bytes) > write_max) {               \
-			write_max = write_pos + (m_bytes);                 \
-		}                                                      \
-		if (write_max > write_buffer_size) {                   \
-			write_buffer_size = nearest_power_of_2(write_max); \
-			buffer.resize(write_buffer_size);                  \
-			write_ptr = buffer.ptr();                          \
-		}                                                      \
+#define WRITE_FIT(m_bytes)                                  \
+	{                                                       \
+		if (write_pos + (m_bytes) > write_max) {            \
+			write_max = write_pos + (m_bytes);              \
+		}                                                   \
+		if (write_max > write_buffer_size) {                \
+			write_buffer_size = next_power_of_2(write_max); \
+			buffer.resize(write_buffer_size);               \
+			write_ptr = buffer.ptr();                       \
+		}                                                   \
 	}
 	}
 
 
 Error FileAccessCompressed::open_after_magic(FileAccess *p_base) {
 Error FileAccessCompressed::open_after_magic(FileAccess *p_base) {

+ 1 - 1
core/io/packet_peer.cpp

@@ -249,7 +249,7 @@ void PacketPeerStream::set_input_buffer_max_size(int p_max_size) {
 	ERR_EXPLAIN("Buffer in use, resizing would cause loss of data");
 	ERR_EXPLAIN("Buffer in use, resizing would cause loss of data");
 	ERR_FAIL_COND(ring_buffer.data_left());
 	ERR_FAIL_COND(ring_buffer.data_left());
 	ring_buffer.resize(nearest_shift(p_max_size + 4));
 	ring_buffer.resize(nearest_shift(p_max_size + 4));
-	temp_buffer.resize(nearest_power_of_2(p_max_size + 4));
+	temp_buffer.resize(next_power_of_2(p_max_size + 4));
 }
 }
 
 
 PacketPeerStream::PacketPeerStream() {
 PacketPeerStream::PacketPeerStream() {

+ 2 - 2
core/math/geometry.cpp

@@ -1076,8 +1076,8 @@ void Geometry::make_atlas(const Vector<Size2i> &p_rects, Vector<Point2i> &r_resu
 
 
 	for (int i = 0; i < results.size(); i++) {
 	for (int i = 0; i < results.size(); i++) {
 
 
-		float h = nearest_power_of_2(results[i].max_h);
-		float w = nearest_power_of_2(results[i].max_w);
+		float h = next_power_of_2(results[i].max_h);
+		float w = next_power_of_2(results[i].max_w);
 		float aspect = h > w ? h / w : w / h;
 		float aspect = h > w ? h / w : w / h;
 		if (aspect < best_aspect) {
 		if (aspect < best_aspect) {
 			best = i;
 			best = i;

+ 19 - 2
core/typedefs.h

@@ -166,9 +166,9 @@ inline void __swap_tmpl(T &x, T &y) {
 #define _add_overflow __builtin_add_overflow
 #define _add_overflow __builtin_add_overflow
 #endif
 #endif
 
 
-/** Function to find the nearest (bigger) power of 2 to an integer */
+/** Function to find the next power of 2 to an integer */
 
 
-static _FORCE_INLINE_ unsigned int nearest_power_of_2(unsigned int x) {
+static _FORCE_INLINE_ unsigned int next_power_of_2(unsigned int x) {
 
 
 	--x;
 	--x;
 	x |= x >> 1;
 	x |= x >> 1;
@@ -180,6 +180,23 @@ static _FORCE_INLINE_ unsigned int nearest_power_of_2(unsigned int x) {
 	return ++x;
 	return ++x;
 }
 }
 
 
+static _FORCE_INLINE_ unsigned int previous_power_of_2(unsigned int x) {
+
+	x |= x >> 1;
+	x |= x >> 2;
+	x |= x >> 4;
+	x |= x >> 8;
+	x |= x >> 16;
+	return x - (x >> 1);
+}
+
+static _FORCE_INLINE_ unsigned int closest_power_of_2(unsigned int x) {
+
+	unsigned int nx = next_power_of_2(x);
+	unsigned int px = previous_power_of_2(x);
+	return (nx - x) > (x - px) ? px : nx;
+}
+
 // We need this definition inside the function below.
 // We need this definition inside the function below.
 static inline int get_shift_from_power_of_2(unsigned int p_pixel);
 static inline int get_shift_from_power_of_2(unsigned int p_pixel);
 
 

+ 2 - 2
core/vector.h

@@ -70,7 +70,7 @@ class Vector {
 
 
 	_FORCE_INLINE_ size_t _get_alloc_size(size_t p_elements) const {
 	_FORCE_INLINE_ size_t _get_alloc_size(size_t p_elements) const {
 		//return nearest_power_of_2_templated(p_elements*sizeof(T)+sizeof(SafeRefCount)+sizeof(int));
 		//return nearest_power_of_2_templated(p_elements*sizeof(T)+sizeof(SafeRefCount)+sizeof(int));
-		return nearest_power_of_2(p_elements * sizeof(T) + sizeof(SafeRefCount) + sizeof(int));
+		return next_power_of_2(p_elements * sizeof(T) + sizeof(SafeRefCount) + sizeof(int));
 	}
 	}
 
 
 	_FORCE_INLINE_ bool _get_alloc_size_checked(size_t p_elements, size_t *out) const {
 	_FORCE_INLINE_ bool _get_alloc_size_checked(size_t p_elements, size_t *out) const {
@@ -79,7 +79,7 @@ class Vector {
 		size_t p;
 		size_t p;
 		if (_mul_overflow(p_elements, sizeof(T), &o)) return false;
 		if (_mul_overflow(p_elements, sizeof(T), &o)) return false;
 		if (_add_overflow(o, sizeof(SafeRefCount) + sizeof(int), &p)) return false;
 		if (_add_overflow(o, sizeof(SafeRefCount) + sizeof(int), &p)) return false;
-		*out = nearest_power_of_2(p);
+		*out = next_power_of_2(p);
 		return true;
 		return true;
 #else
 #else
 		// Speed is more important than correctness here, do the operations unchecked
 		// Speed is more important than correctness here, do the operations unchecked

+ 1 - 1
drivers/alsa/audio_driver_alsa.cpp

@@ -86,7 +86,7 @@ Error AudioDriverALSA::init() {
 	CHECK_FAIL(status < 0);
 	CHECK_FAIL(status < 0);
 
 
 	int latency = GLOBAL_DEF("audio/output_latency", 25);
 	int latency = GLOBAL_DEF("audio/output_latency", 25);
-	buffer_size = nearest_power_of_2(latency * mix_rate / 1000);
+	buffer_size = closest_power_of_2(latency * mix_rate / 1000);
 
 
 	// set buffer size from project settings
 	// set buffer size from project settings
 	status = snd_pcm_hw_params_set_buffer_size_near(pcm_handle, hwparams, &buffer_size);
 	status = snd_pcm_hw_params_set_buffer_size_near(pcm_handle, hwparams, &buffer_size);

+ 9 - 9
drivers/gles2/rasterizer_gles2.cpp

@@ -857,8 +857,8 @@ void RasterizerGLES2::texture_allocate(RID p_texture, int p_width, int p_height,
 	GLenum internal_format;
 	GLenum internal_format;
 	bool compressed;
 	bool compressed;
 
 
-	int po2_width = nearest_power_of_2(p_width);
-	int po2_height = nearest_power_of_2(p_height);
+	int po2_width = next_power_of_2(p_width);
+	int po2_height = next_power_of_2(p_height);
 
 
 	if (p_flags & VS::TEXTURE_FLAG_VIDEO_SURFACE) {
 	if (p_flags & VS::TEXTURE_FLAG_VIDEO_SURFACE) {
 		p_flags &= ~VS::TEXTURE_FLAG_MIPMAPS; // no mipies for video
 		p_flags &= ~VS::TEXTURE_FLAG_MIPMAPS; // no mipies for video
@@ -977,7 +977,7 @@ void RasterizerGLES2::texture_set_data(RID p_texture, const Image &p_image, VS::
 		glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // raw Filtering
 		glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // raw Filtering
 	}
 	}
 
 
-	bool force_clamp_to_edge = !(texture->flags & VS::TEXTURE_FLAG_MIPMAPS && !texture->ignore_mipmaps) && (nearest_power_of_2(texture->alloc_height) != texture->alloc_height || nearest_power_of_2(texture->alloc_width) != texture->alloc_width);
+	bool force_clamp_to_edge = !(texture->flags & VS::TEXTURE_FLAG_MIPMAPS && !texture->ignore_mipmaps) && (next_power_of_2(texture->alloc_height) != texture->alloc_height || next_power_of_2(texture->alloc_width) != texture->alloc_width);
 
 
 	if (!force_clamp_to_edge && (texture->flags & VS::TEXTURE_FLAG_REPEAT || texture->flags & VS::TEXTURE_FLAG_MIRRORED_REPEAT) && texture->target != GL_TEXTURE_CUBE_MAP) {
 	if (!force_clamp_to_edge && (texture->flags & VS::TEXTURE_FLAG_REPEAT || texture->flags & VS::TEXTURE_FLAG_MIRRORED_REPEAT) && texture->target != GL_TEXTURE_CUBE_MAP) {
 
 
@@ -1234,7 +1234,7 @@ void RasterizerGLES2::texture_set_flags(RID p_texture, uint32_t p_flags) {
 	uint32_t cube = texture->flags & VS::TEXTURE_FLAG_CUBEMAP;
 	uint32_t cube = texture->flags & VS::TEXTURE_FLAG_CUBEMAP;
 	texture->flags = p_flags | cube; // can't remove a cube from being a cube
 	texture->flags = p_flags | cube; // can't remove a cube from being a cube
 
 
-	bool force_clamp_to_edge = !(p_flags & VS::TEXTURE_FLAG_MIPMAPS && !texture->ignore_mipmaps) && (nearest_power_of_2(texture->alloc_height) != texture->alloc_height || nearest_power_of_2(texture->alloc_width) != texture->alloc_width);
+	bool force_clamp_to_edge = !(p_flags & VS::TEXTURE_FLAG_MIPMAPS && !texture->ignore_mipmaps) && (next_power_of_2(texture->alloc_height) != texture->alloc_height || next_power_of_2(texture->alloc_width) != texture->alloc_width);
 
 
 	if (!force_clamp_to_edge && (texture->flags & VS::TEXTURE_FLAG_REPEAT || texture->flags & VS::TEXTURE_FLAG_MIRRORED_REPEAT) && texture->target != GL_TEXTURE_CUBE_MAP) {
 	if (!force_clamp_to_edge && (texture->flags & VS::TEXTURE_FLAG_REPEAT || texture->flags & VS::TEXTURE_FLAG_MIRRORED_REPEAT) && texture->target != GL_TEXTURE_CUBE_MAP) {
 
 
@@ -2701,7 +2701,7 @@ void RasterizerGLES2::multimesh_set_instance_count(RID p_multimesh, int p_count)
 
 
 	if (use_texture_instancing) {
 	if (use_texture_instancing) {
 
 
-		if (nearest_power_of_2(p_count) != nearest_power_of_2(multimesh->elements.size())) {
+		if (next_power_of_2(p_count) != next_power_of_2(multimesh->elements.size())) {
 			if (multimesh->tex_id) {
 			if (multimesh->tex_id) {
 				glDeleteTextures(1, &multimesh->tex_id);
 				glDeleteTextures(1, &multimesh->tex_id);
 				multimesh->tex_id = 0;
 				multimesh->tex_id = 0;
@@ -2709,7 +2709,7 @@ void RasterizerGLES2::multimesh_set_instance_count(RID p_multimesh, int p_count)
 
 
 			if (p_count) {
 			if (p_count) {
 
 
-				uint32_t po2 = nearest_power_of_2(p_count);
+				uint32_t po2 = next_power_of_2(p_count);
 				if (po2 & 0xAAAAAAAA) {
 				if (po2 & 0xAAAAAAAA) {
 					//half width
 					//half width
 
 
@@ -3333,7 +3333,7 @@ void RasterizerGLES2::skeleton_resize(RID p_skeleton, int p_bones) {
 	};
 	};
 	if (use_hw_skeleton_xform) {
 	if (use_hw_skeleton_xform) {
 
 
-		if (nearest_power_of_2(p_bones) != nearest_power_of_2(skeleton->bones.size())) {
+		if (next_power_of_2(p_bones) != next_power_of_2(skeleton->bones.size())) {
 			if (skeleton->tex_id) {
 			if (skeleton->tex_id) {
 				glDeleteTextures(1, &skeleton->tex_id);
 				glDeleteTextures(1, &skeleton->tex_id);
 				skeleton->tex_id = 0;
 				skeleton->tex_id = 0;
@@ -3344,7 +3344,7 @@ void RasterizerGLES2::skeleton_resize(RID p_skeleton, int p_bones) {
 				glGenTextures(1, &skeleton->tex_id);
 				glGenTextures(1, &skeleton->tex_id);
 				glActiveTexture(GL_TEXTURE0);
 				glActiveTexture(GL_TEXTURE0);
 				glBindTexture(GL_TEXTURE_2D, skeleton->tex_id);
 				glBindTexture(GL_TEXTURE_2D, skeleton->tex_id);
-				int ps = nearest_power_of_2(p_bones * 3);
+				int ps = next_power_of_2(p_bones * 3);
 #ifdef GLEW_ENABLED
 #ifdef GLEW_ENABLED
 				glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, ps, 1, 0, GL_RGBA, GL_FLOAT, skel_default.ptr());
 				glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, ps, 1, 0, GL_RGBA, GL_FLOAT, skel_default.ptr());
 #else
 #else
@@ -4001,7 +4001,7 @@ void RasterizerGLES2::begin_frame() {
 
 
 		glActiveTexture(GL_TEXTURE0);
 		glActiveTexture(GL_TEXTURE0);
 		glBindTexture(GL_TEXTURE_2D, s->tex_id);
 		glBindTexture(GL_TEXTURE_2D, s->tex_id);
-		glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, nearest_power_of_2(s->bones.size() * 3), 1, GL_RGBA, GL_FLOAT, sk_float);
+		glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, next_power_of_2(s->bones.size() * 3), 1, GL_RGBA, GL_FLOAT, sk_float);
 		_skeleton_dirty_list.remove(_skeleton_dirty_list.first());
 		_skeleton_dirty_list.remove(_skeleton_dirty_list.first());
 	}
 	}
 
 

+ 1 - 1
drivers/pulseaudio/audio_driver_pulseaudio.cpp

@@ -54,7 +54,7 @@ Error AudioDriverPulseAudio::init() {
 	spec.rate = mix_rate;
 	spec.rate = mix_rate;
 
 
 	int latency = GLOBAL_DEF("audio/output_latency", 25);
 	int latency = GLOBAL_DEF("audio/output_latency", 25);
-	buffer_size = nearest_power_of_2(latency * mix_rate / 1000);
+	buffer_size = closest_power_of_2(latency * mix_rate / 1000);
 
 
 	pa_buffer_attr attr;
 	pa_buffer_attr attr;
 	// set to appropriate buffer size from global settings
 	// set to appropriate buffer size from global settings

+ 1 - 1
drivers/rtaudio/audio_driver_rtaudio.cpp

@@ -115,7 +115,7 @@ Error AudioDriverRtAudio::init() {
 
 
 	int latency = GLOBAL_DEF("audio/output_latency", 25);
 	int latency = GLOBAL_DEF("audio/output_latency", 25);
 	// calculate desired buffer_size, taking the desired numberOfBuffers into account (latency depends on numberOfBuffers*buffer_size)
 	// calculate desired buffer_size, taking the desired numberOfBuffers into account (latency depends on numberOfBuffers*buffer_size)
-	unsigned int buffer_size = nearest_power_of_2(latency * mix_rate / 1000 / target_number_of_buffers);
+	unsigned int buffer_size = closest_power_of_2(latency * mix_rate / 1000 / target_number_of_buffers);
 
 
 	if (OS::get_singleton()->is_stdout_verbose()) {
 	if (OS::get_singleton()->is_stdout_verbose()) {
 		print_line("audio buffer size: " + itos(buffer_size));
 		print_line("audio buffer size: " + itos(buffer_size));

+ 2 - 2
editor/io_plugins/editor_font_import_plugin.cpp

@@ -1460,8 +1460,8 @@ Ref<BitmapFont> EditorFontImportPlugin::generate_font(const Ref<ResourceImportMe
 	Vector<Point2i> res;
 	Vector<Point2i> res;
 	Size2i res_size;
 	Size2i res_size;
 	EditorAtlas::fit(sizes, res, res_size);
 	EditorAtlas::fit(sizes, res, res_size);
-	res_size.x = nearest_power_of_2(res_size.x);
-	res_size.y = nearest_power_of_2(res_size.y);
+	res_size.x = next_power_of_2(res_size.x);
+	res_size.y = next_power_of_2(res_size.y);
 	print_line("Atlas size: " + res_size);
 	print_line("Atlas size: " + res_size);
 
 
 	Image atlas(res_size.x, res_size.y, 0, Image::FORMAT_RGBA);
 	Image atlas(res_size.x, res_size.y, 0, Image::FORMAT_RGBA);

+ 2 - 2
editor/io_plugins/editor_texture_import_plugin.cpp

@@ -1185,8 +1185,8 @@ Error EditorTextureImportPlugin::import2(const String &p_path, const Ref<Resourc
 		int atlas_w = dst_size.width;
 		int atlas_w = dst_size.width;
 		int atlas_h = dst_size.height;
 		int atlas_h = dst_size.height;
 		if (blit_to_po2) {
 		if (blit_to_po2) {
-			atlas_w = nearest_power_of_2(dst_size.width);
-			atlas_h = nearest_power_of_2(dst_size.height);
+			atlas_w = next_power_of_2(dst_size.width);
+			atlas_h = next_power_of_2(dst_size.height);
 		}
 		}
 		Image atlas;
 		Image atlas;
 		atlas.create(atlas_w, atlas_h, 0, alpha ? Image::FORMAT_RGBA : Image::FORMAT_RGB);
 		atlas.create(atlas_w, atlas_h, 0, alpha ? Image::FORMAT_RGBA : Image::FORMAT_RGB);

+ 2 - 2
editor/plugins/baked_light_baker.cpp

@@ -1333,7 +1333,7 @@ void BakedLightBaker::_make_octree_texture() {
 		} else {
 		} else {
 
 
 			baked_light_texture_w = otex_w;
 			baked_light_texture_w = otex_w;
-			baked_light_texture_h = nearest_power_of_2(row);
+			baked_light_texture_h = next_power_of_2(row);
 			print_line("w: " + itos(otex_w));
 			print_line("w: " + itos(otex_w));
 			print_line("h: " + itos(row));
 			print_line("h: " + itos(row));
 			break;
 			break;
@@ -1419,7 +1419,7 @@ void BakedLightBaker::_make_octree_texture() {
 		}
 		}
 	}
 	}
 
 
-	baked_octree_texture_h = nearest_power_of_2(baked_octree_texture_h);
+	baked_octree_texture_h = next_power_of_2(baked_octree_texture_h);
 	print_line("RESULT! " + itos(baked_octree_texture_w) + "," + itos(baked_octree_texture_h));
 	print_line("RESULT! " + itos(baked_octree_texture_w) + "," + itos(baked_octree_texture_h));
 }
 }
 
 

+ 1 - 1
modules/etc1/image_etc.cpp

@@ -99,7 +99,7 @@ static void _compress_etc(Image *p_img) {
 
 
 	int imgw = img.get_width(), imgh = img.get_height();
 	int imgw = img.get_width(), imgh = img.get_height();
 
 
-	ERR_FAIL_COND(nearest_power_of_2(imgw) != imgw || nearest_power_of_2(imgh) != imgh);
+	ERR_FAIL_COND(next_power_of_2(imgw) != imgw || next_power_of_2(imgh) != imgh);
 
 
 	if (img.get_format() != Image::FORMAT_RGB)
 	if (img.get_format() != Image::FORMAT_RGB)
 		img.convert(Image::FORMAT_RGB);
 		img.convert(Image::FORMAT_RGB);

+ 1 - 1
modules/gdscript/gd_functions.cpp

@@ -440,7 +440,7 @@ void GDFunctions::call(Function p_func, const Variant **p_args, int p_arg_count,
 			VALIDATE_ARG_COUNT(1);
 			VALIDATE_ARG_COUNT(1);
 			VALIDATE_ARG_NUM(0);
 			VALIDATE_ARG_NUM(0);
 			int64_t num = *p_args[0];
 			int64_t num = *p_args[0];
-			r_ret = nearest_power_of_2(num);
+			r_ret = next_power_of_2(num);
 		} break;
 		} break;
 		case OBJ_WEAKREF: {
 		case OBJ_WEAKREF: {
 			VALIDATE_ARG_COUNT(1);
 			VALIDATE_ARG_COUNT(1);

+ 2 - 2
modules/squish/image_compress_squish.cpp

@@ -89,8 +89,8 @@ void image_compress_squish(Image *p_image) {
 		ERR_FAIL_COND(!w || w % 4 != 0);
 		ERR_FAIL_COND(!w || w % 4 != 0);
 		ERR_FAIL_COND(!h || h % 4 != 0);
 		ERR_FAIL_COND(!h || h % 4 != 0);
 	} else {
 	} else {
-		ERR_FAIL_COND(!w || w != nearest_power_of_2(w));
-		ERR_FAIL_COND(!h || h != nearest_power_of_2(h));
+		ERR_FAIL_COND(!w || w != next_power_of_2(w));
+		ERR_FAIL_COND(!h || h != next_power_of_2(h));
 	};
 	};
 
 
 	if (p_image->get_format() >= Image::FORMAT_BC1)
 	if (p_image->get_format() >= Image::FORMAT_BC1)

+ 1 - 1
platform/android/audio_driver_jandroid.cpp

@@ -79,7 +79,7 @@ Error AudioDriverAndroid::init() {
 
 
 	int latency = GLOBAL_DEF("audio/output_latency", 25);
 	int latency = GLOBAL_DEF("audio/output_latency", 25);
 	latency = 50;
 	latency = 50;
-	unsigned int buffer_size = nearest_power_of_2(latency * mix_rate / 1000);
+	unsigned int buffer_size = closest_power_of_2(latency * mix_rate / 1000);
 	if (OS::get_singleton()->is_stdout_verbose()) {
 	if (OS::get_singleton()->is_stdout_verbose()) {
 		print_line("audio buffer size: " + itos(buffer_size));
 		print_line("audio buffer size: " + itos(buffer_size));
 	}
 	}

+ 1 - 1
platform/haiku/audio_driver_media_kit.cpp

@@ -43,7 +43,7 @@ Error AudioDriverMediaKit::init() {
 	channels = 2;
 	channels = 2;
 
 
 	int latency = GLOBAL_DEF("audio/output_latency", 25);
 	int latency = GLOBAL_DEF("audio/output_latency", 25);
-	buffer_size = nearest_power_of_2(latency * mix_rate / 1000);
+	buffer_size = closest_power_of_2(latency * mix_rate / 1000);
 	samples_in = memnew_arr(int32_t, buffer_size * channels);
 	samples_in = memnew_arr(int32_t, buffer_size * channels);
 
 
 	media_raw_audio_format format;
 	media_raw_audio_format format;

+ 66 - 36
platform/osx/audio_driver_osx.cpp

@@ -30,6 +30,10 @@
 #ifdef OSX_ENABLED
 #ifdef OSX_ENABLED
 
 
 #include "audio_driver_osx.h"
 #include "audio_driver_osx.h"
+#include "globals.h"
+#include "os/os.h"
+
+#define kOutputBus 0
 
 
 static OSStatus outputDeviceAddressCB(AudioObjectID inObjectID, UInt32 inNumberAddresses, const AudioObjectPropertyAddress *inAddresses, void *__nullable inClientData) {
 static OSStatus outputDeviceAddressCB(AudioObjectID inObjectID, UInt32 inNumberAddresses, const AudioObjectPropertyAddress *inAddresses, void *__nullable inClientData) {
 	AudioDriverOSX *driver = (AudioDriverOSX *)inClientData;
 	AudioDriverOSX *driver = (AudioDriverOSX *)inClientData;
@@ -40,42 +44,69 @@ static OSStatus outputDeviceAddressCB(AudioObjectID inObjectID, UInt32 inNumberA
 }
 }
 
 
 Error AudioDriverOSX::initDevice() {
 Error AudioDriverOSX::initDevice() {
+	AudioComponentDescription desc;
+	zeromem(&desc, sizeof(desc));
+	desc.componentType = kAudioUnitType_Output;
+	desc.componentSubType = kAudioUnitSubType_HALOutput;
+	desc.componentManufacturer = kAudioUnitManufacturer_Apple;
+
+	AudioComponent comp = AudioComponentFindNext(NULL, &desc);
+	ERR_FAIL_COND_V(comp == NULL, FAILED);
+
+	OSStatus result = AudioComponentInstanceNew(comp, &audio_unit);
+	ERR_FAIL_COND_V(result != noErr, FAILED);
+
 	AudioStreamBasicDescription strdesc;
 	AudioStreamBasicDescription strdesc;
+
+	// TODO: Implement this
+	/*zeromem(&strdesc, sizeof(strdesc));
+	UInt32 size = sizeof(strdesc);
+	result = AudioUnitGetProperty(audio_unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, kOutputBus, &strdesc, &size);
+	ERR_FAIL_COND_V(result != noErr, FAILED);
+
+	switch (strdesc.mChannelsPerFrame) {
+		case 2: // Stereo
+		case 6: // Surround 5.1
+		case 8: // Surround 7.1
+			channels = strdesc.mChannelsPerFrame;
+			break;
+
+		default:
+			// Unknown number of channels, default to stereo
+			channels = 2;
+			break;
+	}*/
+
+	mix_rate = GLOBAL_DEF("audio/mix_rate", 44100);
+
+	zeromem(&strdesc, sizeof(strdesc));
 	strdesc.mFormatID = kAudioFormatLinearPCM;
 	strdesc.mFormatID = kAudioFormatLinearPCM;
 	strdesc.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
 	strdesc.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
 	strdesc.mChannelsPerFrame = channels;
 	strdesc.mChannelsPerFrame = channels;
-	strdesc.mSampleRate = 44100;
+	strdesc.mSampleRate = mix_rate;
 	strdesc.mFramesPerPacket = 1;
 	strdesc.mFramesPerPacket = 1;
 	strdesc.mBitsPerChannel = 16;
 	strdesc.mBitsPerChannel = 16;
 	strdesc.mBytesPerFrame = strdesc.mBitsPerChannel * strdesc.mChannelsPerFrame / 8;
 	strdesc.mBytesPerFrame = strdesc.mBitsPerChannel * strdesc.mChannelsPerFrame / 8;
 	strdesc.mBytesPerPacket = strdesc.mBytesPerFrame * strdesc.mFramesPerPacket;
 	strdesc.mBytesPerPacket = strdesc.mBytesPerFrame * strdesc.mFramesPerPacket;
 
 
-	OSStatus result;
-	AURenderCallbackStruct callback;
-	AudioComponentDescription desc;
-	AudioComponent comp = NULL;
-	const AudioUnitElement output_bus = 0;
-	const AudioUnitElement bus = output_bus;
-	const AudioUnitScope scope = kAudioUnitScope_Input;
-
-	zeromem(&desc, sizeof(desc));
-	desc.componentType = kAudioUnitType_Output;
-	desc.componentSubType = kAudioUnitSubType_HALOutput;
-	desc.componentManufacturer = kAudioUnitManufacturer_Apple;
+	result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, kOutputBus, &strdesc, sizeof(strdesc));
+	ERR_FAIL_COND_V(result != noErr, FAILED);
 
 
-	comp = AudioComponentFindNext(NULL, &desc);
-	ERR_FAIL_COND_V(comp == NULL, FAILED);
+	int latency = GLOBAL_DEF("audio/output_latency", 25);
+	unsigned int buffer_size = closest_power_of_2(latency * mix_rate / 1000);
 
 
-	result = AudioComponentInstanceNew(comp, &audio_unit);
-	ERR_FAIL_COND_V(result != noErr, FAILED);
+	if (OS::get_singleton()->is_stdout_verbose()) {
+		print_line("audio buffer size: " + itos(buffer_size) + " calculated latency: " + itos(buffer_size * 1000 / mix_rate));
+	}
 
 
-	result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_StreamFormat, scope, bus, &strdesc, sizeof(strdesc));
-	ERR_FAIL_COND_V(result != noErr, FAILED);
+	samples_in.resize(buffer_size);
+	buffer_frames = buffer_size / channels;
 
 
+	AURenderCallbackStruct callback;
 	zeromem(&callback, sizeof(AURenderCallbackStruct));
 	zeromem(&callback, sizeof(AURenderCallbackStruct));
 	callback.inputProc = &AudioDriverOSX::output_callback;
 	callback.inputProc = &AudioDriverOSX::output_callback;
 	callback.inputProcRefCon = this;
 	callback.inputProcRefCon = this;
-	result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_SetRenderCallback, scope, bus, &callback, sizeof(callback));
+	result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, kOutputBus, &callback, sizeof(callback));
 	ERR_FAIL_COND_V(result != noErr, FAILED);
 	ERR_FAIL_COND_V(result != noErr, FAILED);
 
 
 	result = AudioUnitInitialize(audio_unit);
 	result = AudioUnitInitialize(audio_unit);
@@ -114,15 +145,10 @@ Error AudioDriverOSX::init() {
 	result = AudioObjectAddPropertyListener(kAudioObjectSystemObject, &outputDeviceAddress, &outputDeviceAddressCB, this);
 	result = AudioObjectAddPropertyListener(kAudioObjectSystemObject, &outputDeviceAddress, &outputDeviceAddressCB, this);
 	ERR_FAIL_COND_V(result != noErr, FAILED);
 	ERR_FAIL_COND_V(result != noErr, FAILED);
 
 
-	const int samples = 1024;
-	samples_in = memnew_arr(int32_t, samples); // whatever
-	buffer_frames = samples / channels;
-
 	return initDevice();
 	return initDevice();
 };
 };
 
 
 Error AudioDriverOSX::reopen() {
 Error AudioDriverOSX::reopen() {
-	Error err;
 	bool restart = false;
 	bool restart = false;
 
 
 	lock();
 	lock();
@@ -131,7 +157,7 @@ Error AudioDriverOSX::reopen() {
 		restart = true;
 		restart = true;
 	}
 	}
 
 
-	err = finishDevice();
+	Error err = finishDevice();
 	if (err != OK) {
 	if (err != OK) {
 		ERR_PRINT("finishDevice failed");
 		ERR_PRINT("finishDevice failed");
 		unlock();
 		unlock();
@@ -179,7 +205,7 @@ OSStatus AudioDriverOSX::output_callback(void *inRefCon,
 		while (frames_left) {
 		while (frames_left) {
 
 
 			int frames = MIN(frames_left, ad->buffer_frames);
 			int frames = MIN(frames_left, ad->buffer_frames);
-			ad->audio_server_process(frames, ad->samples_in);
+			ad->audio_server_process(frames, ad->samples_in.ptr());
 
 
 			for (int j = 0; j < frames * ad->channels; j++) {
 			for (int j = 0; j < frames * ad->channels; j++) {
 
 
@@ -232,29 +258,33 @@ bool AudioDriverOSX::try_lock() {
 }
 }
 
 
 void AudioDriverOSX::finish() {
 void AudioDriverOSX::finish() {
-	OSStatus result;
-
 	finishDevice();
 	finishDevice();
 
 
-	result = AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &outputDeviceAddress, &outputDeviceAddressCB, this);
+	OSStatus result = AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &outputDeviceAddress, &outputDeviceAddressCB, this);
 	if (result != noErr) {
 	if (result != noErr) {
 		ERR_PRINT("AudioObjectRemovePropertyListener failed");
 		ERR_PRINT("AudioObjectRemovePropertyListener failed");
 	}
 	}
 
 
+	AURenderCallbackStruct callback;
+	zeromem(&callback, sizeof(AURenderCallbackStruct));
+	result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, kOutputBus, &callback, sizeof(callback));
+	if (result != noErr) {
+		ERR_PRINT("AudioUnitSetProperty failed");
+	}
+
 	if (mutex) {
 	if (mutex) {
 		memdelete(mutex);
 		memdelete(mutex);
 		mutex = NULL;
 		mutex = NULL;
 	}
 	}
-
-	if (samples_in) {
-		memdelete_arr(samples_in);
-		samples_in = NULL;
-	}
 };
 };
 
 
 AudioDriverOSX::AudioDriverOSX() {
 AudioDriverOSX::AudioDriverOSX() {
+	active = false;
 	mutex = NULL;
 	mutex = NULL;
-	samples_in = NULL;
+
+	mix_rate = 44100;
+	channels = 2;
+	samples_in.clear();
 };
 };
 
 
 AudioDriverOSX::~AudioDriverOSX(){};
 AudioDriverOSX::~AudioDriverOSX(){};

+ 3 - 1
platform/osx/audio_driver_osx.h

@@ -44,10 +44,12 @@ class AudioDriverOSX : public AudioDriverSW {
 	bool active;
 	bool active;
 	Mutex *mutex;
 	Mutex *mutex;
 
 
+	int mix_rate;
 	int channels;
 	int channels;
-	int32_t *samples_in;
 	int buffer_frames;
 	int buffer_frames;
 
 
+	Vector<int32_t> samples_in;
+
 	static OSStatus output_callback(void *inRefCon,
 	static OSStatus output_callback(void *inRefCon,
 			AudioUnitRenderActionFlags *ioActionFlags,
 			AudioUnitRenderActionFlags *ioActionFlags,
 			const AudioTimeStamp *inTimeStamp,
 			const AudioTimeStamp *inTimeStamp,

+ 1 - 1
platform/winrt/audio_driver_winrt.cpp

@@ -54,7 +54,7 @@ Error AudioDriverWinRT::init() {
 	channels = 2;
 	channels = 2;
 
 
 	int latency = GLOBAL_DEF("audio/output_latency", 25);
 	int latency = GLOBAL_DEF("audio/output_latency", 25);
-	buffer_size = nearest_power_of_2(latency * mix_rate / 1000);
+	buffer_size = closest_power_of_2(latency * mix_rate / 1000);
 
 
 	samples_in = memnew_arr(int32_t, buffer_size * channels);
 	samples_in = memnew_arr(int32_t, buffer_size * channels);
 	for (int i = 0; i < AUDIO_BUFFERS; i++) {
 	for (int i = 0; i < AUDIO_BUFFERS; i++) {

+ 1 - 1
scene/resources/dynamic_font.cpp

@@ -524,7 +524,7 @@ void DynamicFontAtSize::_update_char(CharType p_char) {
 		if (mh > texsize)
 		if (mh > texsize)
 			texsize = mh; //special case, adapt to it?
 			texsize = mh; //special case, adapt to it?
 
 
-		texsize = nearest_power_of_2(texsize);
+		texsize = next_power_of_2(texsize);
 
 
 		texsize = MIN(texsize, 4096);
 		texsize = MIN(texsize, 4096);
 
 

+ 1 - 1
scene/resources/dynamic_font_stb.cpp

@@ -260,7 +260,7 @@ void DynamicFontAtSize::_update_char(CharType p_char) {
 		if (mh > texsize)
 		if (mh > texsize)
 			texsize = mh; //special case, adapt to it?
 			texsize = mh; //special case, adapt to it?
 
 
-		texsize = nearest_power_of_2(texsize);
+		texsize = next_power_of_2(texsize);
 
 
 		texsize = MIN(texsize, 4096);
 		texsize = MIN(texsize, 4096);
 
 

+ 1 - 1
servers/audio/audio_driver_dummy.cpp

@@ -45,7 +45,7 @@ Error AudioDriverDummy::init() {
 	channels = 2;
 	channels = 2;
 
 
 	int latency = GLOBAL_DEF("audio/output_latency", 25);
 	int latency = GLOBAL_DEF("audio/output_latency", 25);
-	buffer_size = nearest_power_of_2(latency * mix_rate / 1000);
+	buffer_size = closest_power_of_2(latency * mix_rate / 1000);
 
 
 	samples_in = memnew_arr(int32_t, buffer_size * channels);
 	samples_in = memnew_arr(int32_t, buffer_size * channels);
 
 

+ 1 - 1
servers/visual/visual_server_raster.cpp

@@ -3847,7 +3847,7 @@ void VisualServerRaster::canvas_light_set_shadow_buffer_size(RID p_light, int p_
 
 
 	ERR_FAIL_COND(p_size < 32 || p_size > 16384);
 	ERR_FAIL_COND(p_size < 32 || p_size > 16384);
 
 
-	clight->shadow_buffer_size = nearest_power_of_2(p_size);
+	clight->shadow_buffer_size = next_power_of_2(p_size);
 
 
 	if (clight->shadow_buffer.is_valid()) {
 	if (clight->shadow_buffer.is_valid()) {
 		rasterizer->free(clight->shadow_buffer);
 		rasterizer->free(clight->shadow_buffer);