Add closest_power_of_2 func and implement mix_rate/latency on OS X
This commit is contained in:
parent
33c1d25517
commit
eab850524e
@ -676,8 +676,8 @@ void Image::resize_to_po2(bool p_square) {
|
|||||||
ERR_FAIL();
|
ERR_FAIL();
|
||||||
}
|
}
|
||||||
|
|
||||||
int w = nearest_power_of_2(width);
|
int w = next_power_of_2(width);
|
||||||
int h = nearest_power_of_2(height);
|
int h = next_power_of_2(height);
|
||||||
|
|
||||||
if (w == width && h == height) {
|
if (w == width && h == height) {
|
||||||
|
|
||||||
@ -1060,7 +1060,7 @@ Error Image::generate_mipmaps() {
|
|||||||
|
|
||||||
PoolVector<uint8_t>::Write wp = data.write();
|
PoolVector<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;
|
||||||
|
@ -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) \
|
#define WRITE_FIT(m_bytes) \
|
||||||
{ \
|
{ \
|
||||||
if (write_pos + (m_bytes) > write_max) { \
|
if (write_pos + (m_bytes) > write_max) { \
|
||||||
write_max = write_pos + (m_bytes); \
|
write_max = write_pos + (m_bytes); \
|
||||||
} \
|
} \
|
||||||
if (write_max > write_buffer_size) { \
|
if (write_max > write_buffer_size) { \
|
||||||
write_buffer_size = nearest_power_of_2(write_max); \
|
write_buffer_size = next_power_of_2(write_max); \
|
||||||
buffer.resize(write_buffer_size); \
|
buffer.resize(write_buffer_size); \
|
||||||
write_ptr = buffer.ptr(); \
|
write_ptr = buffer.ptr(); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
Error FileAccessCompressed::open_after_magic(FileAccess *p_base) {
|
Error FileAccessCompressed::open_after_magic(FileAccess *p_base) {
|
||||||
|
@ -265,12 +265,12 @@ 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));
|
||||||
input_buffer.resize(nearest_power_of_2(p_max_size + 4));
|
input_buffer.resize(next_power_of_2(p_max_size + 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PacketPeerStream::set_output_buffer_max_size(int p_max_size) {
|
void PacketPeerStream::set_output_buffer_max_size(int p_max_size) {
|
||||||
|
|
||||||
output_buffer.resize(nearest_power_of_2(p_max_size + 4));
|
output_buffer.resize(next_power_of_2(p_max_size + 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
PacketPeerStream::PacketPeerStream() {
|
PacketPeerStream::PacketPeerStream() {
|
||||||
|
@ -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++) {
|
||||||
|
|
||||||
real_t h = nearest_power_of_2(results[i].max_h);
|
real_t h = next_power_of_2(results[i].max_h);
|
||||||
real_t w = nearest_power_of_2(results[i].max_w);
|
real_t w = next_power_of_2(results[i].max_w);
|
||||||
real_t aspect = h > w ? h / w : w / h;
|
real_t aspect = h > w ? h / w : w / h;
|
||||||
if (aspect < best_aspect) {
|
if (aspect < best_aspect) {
|
||||||
best = i;
|
best = i;
|
||||||
|
@ -162,9 +162,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;
|
||||||
@ -176,6 +176,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);
|
||||||
|
|
||||||
|
@ -71,7 +71,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));
|
return next_power_of_2(p_elements * sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
_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 o;
|
size_t o;
|
||||||
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;
|
||||||
*out = nearest_power_of_2(o);
|
*out = next_power_of_2(o);
|
||||||
if (_add_overflow(o, static_cast<size_t>(32), &p)) return false; //no longer allocated here
|
if (_add_overflow(o, static_cast<size_t>(32), &p)) return false; //no longer allocated here
|
||||||
return true;
|
return true;
|
||||||
#else
|
#else
|
||||||
|
@ -87,7 +87,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);
|
||||||
|
@ -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_width = next_power_of_2(p_width);
|
||||||
int po2_height = nearest_power_of_2(p_height);
|
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
|
||||||
@ -3998,7 +3998,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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ void RasterizerSceneGLES3::shadow_atlas_set_size(RID p_atlas, int p_size) {
|
|||||||
ERR_FAIL_COND(!shadow_atlas);
|
ERR_FAIL_COND(!shadow_atlas);
|
||||||
ERR_FAIL_COND(p_size < 0);
|
ERR_FAIL_COND(p_size < 0);
|
||||||
|
|
||||||
p_size = nearest_power_of_2(p_size);
|
p_size = next_power_of_2(p_size);
|
||||||
|
|
||||||
if (p_size == shadow_atlas->size)
|
if (p_size == shadow_atlas->size)
|
||||||
return;
|
return;
|
||||||
@ -185,7 +185,7 @@ void RasterizerSceneGLES3::shadow_atlas_set_quadrant_subdivision(RID p_atlas, in
|
|||||||
ERR_FAIL_INDEX(p_quadrant, 4);
|
ERR_FAIL_INDEX(p_quadrant, 4);
|
||||||
ERR_FAIL_INDEX(p_subdivision, 16384);
|
ERR_FAIL_INDEX(p_subdivision, 16384);
|
||||||
|
|
||||||
uint32_t subdiv = nearest_power_of_2(p_subdivision);
|
uint32_t subdiv = next_power_of_2(p_subdivision);
|
||||||
if (subdiv & 0xaaaaaaaa) { //sqrt(subdiv) must be integer
|
if (subdiv & 0xaaaaaaaa) { //sqrt(subdiv) must be integer
|
||||||
subdiv <<= 1;
|
subdiv <<= 1;
|
||||||
}
|
}
|
||||||
@ -310,7 +310,7 @@ bool RasterizerSceneGLES3::shadow_atlas_update_light(RID p_atlas, RID p_light_in
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t quad_size = shadow_atlas->size >> 1;
|
uint32_t quad_size = shadow_atlas->size >> 1;
|
||||||
int desired_fit = MIN(quad_size / shadow_atlas->smallest_subdiv, nearest_power_of_2(quad_size * p_coverage));
|
int desired_fit = MIN(quad_size / shadow_atlas->smallest_subdiv, next_power_of_2(quad_size * p_coverage));
|
||||||
|
|
||||||
int valid_quadrants[4];
|
int valid_quadrants[4];
|
||||||
int valid_quadrant_count = 0;
|
int valid_quadrant_count = 0;
|
||||||
@ -479,7 +479,7 @@ void RasterizerSceneGLES3::reflection_atlas_set_size(RID p_ref_atlas, int p_size
|
|||||||
ReflectionAtlas *reflection_atlas = reflection_atlas_owner.getornull(p_ref_atlas);
|
ReflectionAtlas *reflection_atlas = reflection_atlas_owner.getornull(p_ref_atlas);
|
||||||
ERR_FAIL_COND(!reflection_atlas);
|
ERR_FAIL_COND(!reflection_atlas);
|
||||||
|
|
||||||
int size = nearest_power_of_2(p_size);
|
int size = next_power_of_2(p_size);
|
||||||
|
|
||||||
if (size == reflection_atlas->size)
|
if (size == reflection_atlas->size)
|
||||||
return;
|
return;
|
||||||
@ -554,7 +554,7 @@ void RasterizerSceneGLES3::reflection_atlas_set_subdivision(RID p_ref_atlas, int
|
|||||||
ReflectionAtlas *reflection_atlas = reflection_atlas_owner.getornull(p_ref_atlas);
|
ReflectionAtlas *reflection_atlas = reflection_atlas_owner.getornull(p_ref_atlas);
|
||||||
ERR_FAIL_COND(!reflection_atlas);
|
ERR_FAIL_COND(!reflection_atlas);
|
||||||
|
|
||||||
uint32_t subdiv = nearest_power_of_2(p_subdiv);
|
uint32_t subdiv = next_power_of_2(p_subdiv);
|
||||||
if (subdiv & 0xaaaaaaaa) { //sqrt(subdiv) must be integer
|
if (subdiv & 0xaaaaaaaa) { //sqrt(subdiv) must be integer
|
||||||
subdiv <<= 1;
|
subdiv <<= 1;
|
||||||
}
|
}
|
||||||
@ -4757,7 +4757,7 @@ void RasterizerSceneGLES3::initialize() {
|
|||||||
{
|
{
|
||||||
//directional light shadow
|
//directional light shadow
|
||||||
directional_shadow.light_count = 0;
|
directional_shadow.light_count = 0;
|
||||||
directional_shadow.size = nearest_power_of_2(GLOBAL_GET("rendering/quality/directional_shadow/size"));
|
directional_shadow.size = next_power_of_2(GLOBAL_GET("rendering/quality/directional_shadow/size"));
|
||||||
glGenFramebuffers(1, &directional_shadow.fbo);
|
glGenFramebuffers(1, &directional_shadow.fbo);
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, directional_shadow.fbo);
|
glBindFramebuffer(GL_FRAMEBUFFER, directional_shadow.fbo);
|
||||||
glGenTextures(1, &directional_shadow.depth);
|
glGenTextures(1, &directional_shadow.depth);
|
||||||
|
@ -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
|
||||||
|
@ -118,7 +118,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));
|
||||||
|
@ -50,7 +50,7 @@ Error AudioDriverXAudio2::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++) {
|
||||||
|
@ -1536,8 +1536,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.x=next_power_of_2(res_size.x);
|
||||||
res_size.y=nearest_power_of_2(res_size.y);
|
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_RGBA8);
|
Image atlas(res_size.x,res_size.y,0,Image::FORMAT_RGBA8);
|
||||||
|
@ -1280,8 +1280,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_w=next_power_of_2(dst_size.width);
|
||||||
atlas_h=nearest_power_of_2(dst_size.height);
|
atlas_h=next_power_of_2(dst_size.height);
|
||||||
}
|
}
|
||||||
Image atlas;
|
Image atlas;
|
||||||
atlas.create(atlas_w,atlas_h,0,alpha?Image::FORMAT_RGBA8:Image::FORMAT_RGB8);
|
atlas.create(atlas_w,atlas_h,0,alpha?Image::FORMAT_RGBA8:Image::FORMAT_RGB8);
|
||||||
|
@ -1460,7 +1460,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;
|
||||||
@ -1558,7 +1558,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));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -118,7 +118,7 @@ static void _compress_etc(Image *p_img, float p_lossy_quality, bool force_etc1_f
|
|||||||
}
|
}
|
||||||
|
|
||||||
int imgw = p_img->get_width(), imgh = p_img->get_height();
|
int imgw = p_img->get_width(), imgh = p_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);
|
||||||
|
|
||||||
Image::Format etc_format = force_etc1_format ? Image::FORMAT_ETC : _get_etc2_mode(detected_channels);
|
Image::Format etc_format = force_etc1_format ? Image::FORMAT_ETC : _get_etc2_mode(detected_channels);
|
||||||
|
|
||||||
|
@ -446,7 +446,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);
|
||||||
|
@ -915,7 +915,7 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
|
|||||||
|
|
||||||
VALIDATE_ARG_NUM(0);
|
VALIDATE_ARG_NUM(0);
|
||||||
int64_t num = *p_inputs[0];
|
int64_t num = *p_inputs[0];
|
||||||
*r_return = nearest_power_of_2(num);
|
*r_return = next_power_of_2(num);
|
||||||
} break;
|
} break;
|
||||||
case VisualScriptBuiltinFunc::OBJ_WEAKREF: {
|
case VisualScriptBuiltinFunc::OBJ_WEAKREF: {
|
||||||
|
|
||||||
|
@ -81,7 +81,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 = next_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));
|
||||||
}
|
}
|
||||||
|
@ -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 = next_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;
|
||||||
|
@ -30,6 +30,10 @@
|
|||||||
#ifdef OSX_ENABLED
|
#ifdef OSX_ENABLED
|
||||||
|
|
||||||
#include "audio_driver_osx.h"
|
#include "audio_driver_osx.h"
|
||||||
|
#include "core/project_settings.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() {
|
||||||
AudioStreamBasicDescription strdesc;
|
|
||||||
strdesc.mFormatID = kAudioFormatLinearPCM;
|
|
||||||
strdesc.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
|
|
||||||
strdesc.mChannelsPerFrame = channels;
|
|
||||||
strdesc.mSampleRate = 44100;
|
|
||||||
strdesc.mFramesPerPacket = 1;
|
|
||||||
strdesc.mBitsPerChannel = 16;
|
|
||||||
strdesc.mBytesPerFrame = strdesc.mBitsPerChannel * strdesc.mChannelsPerFrame / 8;
|
|
||||||
strdesc.mBytesPerPacket = strdesc.mBytesPerFrame * strdesc.mFramesPerPacket;
|
|
||||||
|
|
||||||
OSStatus result;
|
|
||||||
AURenderCallbackStruct callback;
|
|
||||||
AudioComponentDescription desc;
|
AudioComponentDescription desc;
|
||||||
AudioComponent comp = NULL;
|
|
||||||
const AudioUnitElement output_bus = 0;
|
|
||||||
const AudioUnitElement bus = output_bus;
|
|
||||||
const AudioUnitScope scope = kAudioUnitScope_Input;
|
|
||||||
|
|
||||||
zeromem(&desc, sizeof(desc));
|
zeromem(&desc, sizeof(desc));
|
||||||
desc.componentType = kAudioUnitType_Output;
|
desc.componentType = kAudioUnitType_Output;
|
||||||
desc.componentSubType = kAudioUnitSubType_HALOutput;
|
desc.componentSubType = kAudioUnitSubType_HALOutput;
|
||||||
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
|
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
|
||||||
|
|
||||||
comp = AudioComponentFindNext(NULL, &desc);
|
AudioComponent comp = AudioComponentFindNext(NULL, &desc);
|
||||||
ERR_FAIL_COND_V(comp == NULL, FAILED);
|
ERR_FAIL_COND_V(comp == NULL, FAILED);
|
||||||
|
|
||||||
result = AudioComponentInstanceNew(comp, &audio_unit);
|
OSStatus result = AudioComponentInstanceNew(comp, &audio_unit);
|
||||||
ERR_FAIL_COND_V(result != noErr, FAILED);
|
ERR_FAIL_COND_V(result != noErr, FAILED);
|
||||||
|
|
||||||
result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_StreamFormat, scope, bus, &strdesc, sizeof(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);
|
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.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
|
||||||
|
strdesc.mChannelsPerFrame = channels;
|
||||||
|
strdesc.mSampleRate = mix_rate;
|
||||||
|
strdesc.mFramesPerPacket = 1;
|
||||||
|
strdesc.mBitsPerChannel = 16;
|
||||||
|
strdesc.mBytesPerFrame = strdesc.mBitsPerChannel * strdesc.mChannelsPerFrame / 8;
|
||||||
|
strdesc.mBytesPerPacket = strdesc.mBytesPerFrame * strdesc.mFramesPerPacket;
|
||||||
|
|
||||||
|
result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, kOutputBus, &strdesc, sizeof(strdesc));
|
||||||
|
ERR_FAIL_COND_V(result != noErr, FAILED);
|
||||||
|
|
||||||
|
int latency = GLOBAL_DEF("audio/output_latency", 25);
|
||||||
|
unsigned int buffer_size = closest_power_of_2(latency * mix_rate / 1000);
|
||||||
|
|
||||||
|
if (OS::get_singleton()->is_stdout_verbose()) {
|
||||||
|
print_line("audio buffer size: " + itos(buffer_size) + " calculated latency: " + itos(buffer_size * 1000 / mix_rate));
|
||||||
|
}
|
||||||
|
|
||||||
|
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(){};
|
||||||
|
@ -44,10 +44,12 @@ class AudioDriverOSX : public AudioDriver {
|
|||||||
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,
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -289,7 +289,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);
|
||||||
|
|
||||||
|
@ -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 = next_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);
|
||||||
|
|
||||||
|
@ -1001,11 +1001,11 @@ void VisualServerCanvas::canvas_light_set_shadow_buffer_size(RID p_light, int p_
|
|||||||
RasterizerCanvas::Light *clight = canvas_light_owner.get(p_light);
|
RasterizerCanvas::Light *clight = canvas_light_owner.get(p_light);
|
||||||
ERR_FAIL_COND(!clight);
|
ERR_FAIL_COND(!clight);
|
||||||
|
|
||||||
int new_size = nearest_power_of_2(p_size);
|
int new_size = next_power_of_2(p_size);
|
||||||
if (new_size == clight->shadow_buffer_size)
|
if (new_size == clight->shadow_buffer_size)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
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()) {
|
||||||
VSG::storage->free(clight->shadow_buffer);
|
VSG::storage->free(clight->shadow_buffer);
|
||||||
|
@ -4376,7 +4376,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()) {
|
||||||
|
Loading…
Reference in New Issue
Block a user