summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/io/pck_packer.cpp2
-rw-r--r--drivers/gles2/rasterizer_scene_gles2.cpp10
-rw-r--r--drivers/gles2/rasterizer_scene_gles2.h1
-rw-r--r--drivers/gles2/rasterizer_storage_gles2.cpp227
-rw-r--r--drivers/gles2/rasterizer_storage_gles2.h2
-rw-r--r--drivers/gles2/shaders/canvas.glsl20
-rw-r--r--drivers/gles2/shaders/cubemap_filter.glsl26
-rw-r--r--drivers/gles2/shaders/scene.glsl20
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp5
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp10
-rw-r--r--editor/editor_inspector.cpp23
-rw-r--r--editor/editor_sectioned_inspector.cpp2
-rw-r--r--editor/plugins/script_editor_plugin.cpp2
-rw-r--r--editor/plugins/texture_region_editor_plugin.cpp40
-rw-r--r--editor/plugins/texture_region_editor_plugin.h5
-rw-r--r--editor/scene_tree_dock.cpp6
-rw-r--r--main/main.cpp10
-rw-r--r--main/main.h3
-rw-r--r--modules/mono/SCsub3
-rw-r--r--modules/mono/csharp_script.cpp21
-rw-r--r--modules/mono/csharp_script.h11
-rw-r--r--modules/mono/mono_gd/gd_mono.cpp18
-rw-r--r--modules/mono/mono_gd/gd_mono.h4
-rw-r--r--modules/mono/utils/osx_utils.h1
-rw-r--r--platform/osx/os_osx.mm4
-rw-r--r--platform/windows/detect.py8
-rw-r--r--platform/windows/os_windows.cpp21
-rw-r--r--platform/x11/detect.py22
-rw-r--r--scene/2d/cpu_particles_2d.cpp3
-rw-r--r--scene/resources/tile_set.cpp2
-rw-r--r--servers/visual/rasterizer.h1
-rw-r--r--servers/visual/visual_server_scene.cpp164
-rw-r--r--thirdparty/README.md3
-rw-r--r--thirdparty/libtheora/decode.c8
-rw-r--r--thirdparty/libtheora/patches/theora.git-0ae66d565e6bead8604d312bc1a4e9dccf245c88.patch38
-rw-r--r--thirdparty/misc/base64.h4
36 files changed, 606 insertions, 144 deletions
diff --git a/core/io/pck_packer.cpp b/core/io/pck_packer.cpp
index 36bd429bc0..8920bbfb81 100644
--- a/core/io/pck_packer.cpp
+++ b/core/io/pck_packer.cpp
@@ -175,7 +175,7 @@ Error PCKPacker::flush(bool p_verbose) {
printf("\n");
file->close();
- memdelete(buf);
+ memdelete_arr(buf);
return OK;
};
diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp
index e4783e907b..ce2961170a 100644
--- a/drivers/gles2/rasterizer_scene_gles2.cpp
+++ b/drivers/gles2/rasterizer_scene_gles2.cpp
@@ -524,7 +524,11 @@ bool RasterizerSceneGLES2::reflection_probe_instance_begin_render(RID p_instance
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
glBindRenderbuffer(GL_RENDERBUFFER, rpi->depth); //resize depth buffer
+#ifdef JAVASCRIPT_ENABLED
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, size, size);
+#else
glRenderbufferStorage(GL_RENDERBUFFER, _DEPTH_COMPONENT24_OES, size, size);
+#endif
for (int i = 0; i < 6; i++) {
glBindFramebuffer(GL_FRAMEBUFFER, rpi->fbo[i]);
@@ -2873,7 +2877,7 @@ void RasterizerSceneGLES2::render_shadow(RID p_light, RID p_shadow_atlas, int p_
if (light->type == VS::LIGHT_OMNI) {
// cubemap only
- if (light->omni_shadow_mode == VS::LIGHT_OMNI_SHADOW_CUBE) {
+ if (light->omni_shadow_mode == VS::LIGHT_OMNI_SHADOW_CUBE && storage->config.support_write_depth) {
int cubemap_index = shadow_cubemaps.size() - 1;
// find an appropriate cubemap to render to
@@ -2969,7 +2973,7 @@ void RasterizerSceneGLES2::render_shadow(RID p_light, RID p_shadow_atlas, int p_
state.scene_shader.set_conditional(SceneShaderGLES2::RENDER_DEPTH_DUAL_PARABOLOID, false);
// convert cubemap to dual paraboloid if needed
- if (light->type == VS::LIGHT_OMNI && light->omni_shadow_mode == VS::LIGHT_OMNI_SHADOW_CUBE && p_pass == 5) {
+ if (light->type == VS::LIGHT_OMNI && (light->omni_shadow_mode == VS::LIGHT_OMNI_SHADOW_CUBE && storage->config.support_write_depth) && p_pass == 5) {
ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas);
glBindFramebuffer(GL_FRAMEBUFFER, shadow_atlas->fbo);
@@ -3131,7 +3135,7 @@ void RasterizerSceneGLES2::initialize() {
}
// cubemaps for shadows
- {
+ if (!storage->config.support_write_depth) { //not going to be used
int max_shadow_cubemap_sampler_size = 512;
int cube_size = max_shadow_cubemap_sampler_size;
diff --git a/drivers/gles2/rasterizer_scene_gles2.h b/drivers/gles2/rasterizer_scene_gles2.h
index 42ac621e45..0d917f4da2 100644
--- a/drivers/gles2/rasterizer_scene_gles2.h
+++ b/drivers/gles2/rasterizer_scene_gles2.h
@@ -473,6 +473,7 @@ public:
virtual void light_instance_set_transform(RID p_light_instance, const Transform &p_transform);
virtual void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_bias_scale = 1.0);
virtual void light_instance_mark_visible(RID p_light_instance);
+ virtual bool light_instances_can_render_shadow_cube() const { return storage->config.support_write_depth; }
LightInstance **render_light_instances;
int render_directional_lights;
diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp
index 0622a353df..22c05d9d77 100644
--- a/drivers/gles2/rasterizer_storage_gles2.cpp
+++ b/drivers/gles2/rasterizer_storage_gles2.cpp
@@ -1715,8 +1715,196 @@ RID RasterizerStorageGLES2::mesh_create() {
return mesh_owner.make_rid(mesh);
}
+static PoolVector<uint8_t> _unpack_half_floats(const PoolVector<uint8_t> &array, uint32_t &format, int p_vertices) {
+
+ uint32_t p_format = format;
+
+ static int src_size[VS::ARRAY_MAX];
+ static int dst_size[VS::ARRAY_MAX];
+ static int to_convert[VS::ARRAY_MAX];
+
+ int src_stride = 0;
+ int dst_stride = 0;
+
+ for (int i = 0; i < VS::ARRAY_MAX; i++) {
+
+ to_convert[i] = 0;
+ if (!(p_format & (1 << i))) {
+ src_size[i] = 0;
+ dst_size[i] = 0;
+ continue;
+ }
+
+ switch (i) {
+
+ case VS::ARRAY_VERTEX: {
+
+ if (p_format & VS::ARRAY_COMPRESS_VERTEX) {
+
+ if (p_format & VS::ARRAY_FLAG_USE_2D_VERTICES) {
+ src_size[i] = 4;
+ dst_size[i] = 8;
+ to_convert[i] = 2;
+ } else {
+ src_size[i] = 8;
+ dst_size[i] = 12;
+ to_convert[i] = 3;
+ }
+
+ format &= ~VS::ARRAY_COMPRESS_VERTEX;
+ } else {
+
+ if (p_format & VS::ARRAY_FLAG_USE_2D_VERTICES) {
+ src_size[i] = 8;
+ dst_size[i] = 8;
+ } else {
+ src_size[i] = 12;
+ dst_size[i] = 12;
+ }
+ }
+
+ } break;
+ case VS::ARRAY_NORMAL: {
+
+ if (p_format & VS::ARRAY_COMPRESS_NORMAL) {
+ src_size[i] = 4;
+ dst_size[i] = 4;
+ } else {
+ src_size[i] = 12;
+ dst_size[i] = 12;
+ }
+
+ } break;
+ case VS::ARRAY_TANGENT: {
+
+ if (p_format & VS::ARRAY_COMPRESS_TANGENT) {
+ src_size[i] = 4;
+ dst_size[i] = 4;
+ } else {
+ src_size[i] = 16;
+ dst_size[i] = 16;
+ }
+
+ } break;
+ case VS::ARRAY_COLOR: {
+
+ if (p_format & VS::ARRAY_COMPRESS_COLOR) {
+ src_size[i] = 4;
+ dst_size[i] = 4;
+ } else {
+ src_size[i] = 16;
+ dst_size[i] = 16;
+ }
+
+ } break;
+ case VS::ARRAY_TEX_UV: {
+
+ if (p_format & VS::ARRAY_COMPRESS_TEX_UV) {
+ src_size[i] = 4;
+ to_convert[i] = 2;
+ format &= ~VS::ARRAY_COMPRESS_TEX_UV;
+ } else {
+ src_size[i] = 8;
+ }
+
+ dst_size[i] = 8;
+
+ } break;
+ case VS::ARRAY_TEX_UV2: {
+
+ if (p_format & VS::ARRAY_COMPRESS_TEX_UV2) {
+ src_size[i] = 4;
+ to_convert[i] = 2;
+ format &= ~VS::ARRAY_COMPRESS_TEX_UV2;
+ } else {
+ src_size[i] = 8;
+ }
+
+ dst_size[i] = 8;
+
+ } break;
+ case VS::ARRAY_BONES: {
+
+ if (p_format & VS::ARRAY_FLAG_USE_16_BIT_BONES) {
+ src_size[i] = 8;
+ dst_size[i] = 8;
+ } else {
+ src_size[i] = 4;
+ dst_size[i] = 4;
+ }
+
+ } break;
+ case VS::ARRAY_WEIGHTS: {
+
+ if (p_format & VS::ARRAY_COMPRESS_WEIGHTS) {
+ src_size[i] = 8;
+ dst_size[i] = 8;
+ } else {
+ src_size[i] = 16;
+ dst_size[i] = 16;
+ }
+
+ } break;
+ case VS::ARRAY_INDEX: {
+
+ src_size[i] = 0;
+ dst_size[i] = 0;
+
+ } break;
+ }
+
+ src_stride += src_size[i];
+ dst_stride += dst_size[i];
+ }
+
+ PoolVector<uint8_t> ret;
+ ret.resize(p_vertices * dst_stride);
+
+ PoolVector<uint8_t>::Read r = array.read();
+ PoolVector<uint8_t>::Write w = ret.write();
+
+ int src_offset = 0;
+ int dst_offset = 0;
+
+ for (int i = 0; i < VS::ARRAY_MAX; i++) {
+
+ if (src_size[i] == 0) {
+ continue; //no go
+ }
+ const uint8_t *rptr = r.ptr();
+ uint8_t *wptr = w.ptr();
+ if (to_convert[i]) { //converting
+
+ for (int j = 0; j < p_vertices; j++) {
+ const uint16_t *src = (const uint16_t *)&rptr[src_stride * j + src_offset];
+ float *dst = (float *)&wptr[dst_stride * j + dst_offset];
+
+ for (int k = 0; k < to_convert[i]; k++) {
+
+ dst[k] = Math::half_to_float(src[k]);
+ }
+ }
+
+ } else {
+ //just copy
+ for (int j = 0; j < p_vertices; j++) {
+ for (int k = 0; k < src_size[i]; k++) {
+ wptr[dst_stride * j + dst_offset + k] = rptr[src_stride * j + src_offset + k];
+ }
+ }
+ }
+
+ src_offset += src_size[i];
+ dst_offset += dst_size[i];
+ }
+
+ r = PoolVector<uint8_t>::Read();
+ w = PoolVector<uint8_t>::Write();
+
+ return ret;
+}
+
void RasterizerStorageGLES2::mesh_add_surface(RID p_mesh, uint32_t p_format, VS::PrimitiveType p_primitive, const PoolVector<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes, const Vector<AABB> &p_bone_aabbs) {
- PoolVector<uint8_t> array = p_array;
Mesh *mesh = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND(!mesh);
@@ -1735,6 +1923,7 @@ void RasterizerStorageGLES2::mesh_add_surface(RID p_mesh, uint32_t p_format, VS:
Surface::Attrib attribs[VS::ARRAY_MAX];
int stride = 0;
+ bool uses_half_float = false;
for (int i = 0; i < VS::ARRAY_MAX; i++) {
@@ -1763,6 +1952,7 @@ void RasterizerStorageGLES2::mesh_add_surface(RID p_mesh, uint32_t p_format, VS:
if (p_format & VS::ARRAY_COMPRESS_VERTEX) {
attribs[i].type = _GL_HALF_FLOAT_OES;
stride += attribs[i].size * 2;
+ uses_half_float = true;
} else {
attribs[i].type = GL_FLOAT;
stride += attribs[i].size * 4;
@@ -1823,6 +2013,7 @@ void RasterizerStorageGLES2::mesh_add_surface(RID p_mesh, uint32_t p_format, VS:
if (p_format & VS::ARRAY_COMPRESS_TEX_UV) {
attribs[i].type = _GL_HALF_FLOAT_OES;
stride += 4;
+ uses_half_float = true;
} else {
attribs[i].type = GL_FLOAT;
stride += 8;
@@ -1838,6 +2029,7 @@ void RasterizerStorageGLES2::mesh_add_surface(RID p_mesh, uint32_t p_format, VS:
if (p_format & VS::ARRAY_COMPRESS_TEX_UV2) {
attribs[i].type = _GL_HALF_FLOAT_OES;
stride += 4;
+ uses_half_float = true;
} else {
attribs[i].type = GL_FLOAT;
stride += 8;
@@ -1900,6 +2092,7 @@ void RasterizerStorageGLES2::mesh_add_surface(RID p_mesh, uint32_t p_format, VS:
}
//validate sizes
+ PoolVector<uint8_t> array = p_array;
int array_size = stride * p_vertex_count;
int index_array_size = 0;
@@ -1931,6 +2124,15 @@ void RasterizerStorageGLES2::mesh_add_surface(RID p_mesh, uint32_t p_format, VS:
ERR_FAIL_COND(array.size() != array_size);
+ if (!config.support_half_float_vertices && uses_half_float) {
+
+ uint32_t new_format = p_format;
+ PoolVector<uint8_t> unpacked_array = _unpack_half_floats(array, new_format, p_vertex_count);
+
+ mesh_add_surface(p_mesh, new_format, p_primitive, unpacked_array, p_vertex_count, p_index_array, p_index_count, p_aabb, p_blend_shapes, p_bone_aabbs);
+ return; //do not go any further, above function used unpacked stuff will be used instead.
+ }
+
if (p_format & VS::ARRAY_FORMAT_INDEX) {
index_array_size = attribs[VS::ARRAY_INDEX].stride * p_index_count;
@@ -4007,7 +4209,11 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) {
glGenRenderbuffers(1, &rt->depth);
glBindRenderbuffer(GL_RENDERBUFFER, rt->depth);
+#ifdef JAVASCRIPT_ENABLED
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, rt->width, rt->height);
+#else
glRenderbufferStorage(GL_RENDERBUFFER, _DEPTH_COMPONENT24_OES, rt->width, rt->height);
+#endif
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
@@ -4218,7 +4424,11 @@ RID RasterizerStorageGLES2::canvas_light_shadow_buffer_create(int p_width) {
glGenRenderbuffers(1, &cls->depth);
glBindRenderbuffer(GL_RENDERBUFFER, cls->depth);
- glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, cls->size, cls->height);
+#ifdef JAVASCRIPT_ENABLED
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, cls->size, cls->height);
+#else
+ glRenderbufferStorage(GL_RENDERBUFFER, _DEPTH_COMPONENT24_OES, cls->size, cls->height);
+#endif
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, cls->depth);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
@@ -4665,6 +4875,19 @@ void RasterizerStorageGLES2::initialize() {
config.support_32_bits_indices = config.extensions.has("GL_OES_element_index_uint");
#endif
+#ifdef GLES_OVER_GL
+ config.support_write_depth = true;
+#else
+ config.support_write_depth = config.extensions.has("GL_EXT_frag_depth");
+#endif
+
+#ifdef JAVASCRIPT_ENABLED
+ config.support_half_float_vertices = false;
+#else
+ //every other platform, be it mobile or desktop, supports this (even if not in the GLES2 spec).
+ config.support_half_float_vertices = true;
+#endif
+
frame.count = 0;
frame.delta = 0;
frame.current_rt = NULL;
diff --git a/drivers/gles2/rasterizer_storage_gles2.h b/drivers/gles2/rasterizer_storage_gles2.h
index ae14aaa9c0..ed21238db6 100644
--- a/drivers/gles2/rasterizer_storage_gles2.h
+++ b/drivers/gles2/rasterizer_storage_gles2.h
@@ -80,6 +80,8 @@ public:
bool use_rgba_2d_shadows;
bool support_32_bits_indices;
+ bool support_write_depth;
+ bool support_half_float_vertices;
} config;
struct Resources {
diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl
index d483659e4d..45d26e7254 100644
--- a/drivers/gles2/shaders/canvas.glsl
+++ b/drivers/gles2/shaders/canvas.glsl
@@ -215,6 +215,26 @@ VERTEX_SHADER_CODE
/* clang-format off */
[fragment]
+#ifndef USE_GLES_OVER_GL
+
+#ifdef GL_EXT_shader_texture_lod
+#extension GL_EXT_shader_texture_lod : enable
+#define texture2DLod(img, coord, lod) texture2DLodEXT(img, coord, lod)
+#define textureCubeLod(img, coord, lod) textureCubeLodEXT(img, coord, lod)
+#endif
+
+#ifdef GL_ARB_shader_texture_lod
+#extension GL_ARB_shader_texture_lod : enable
+#endif
+
+#if !defined(GL_EXT_shader_texture_lod) && !defined(GL_ARB_shader_texture_lod)
+#define texture2DLod(img, coord, lod) texture2D(img, coord, lod)
+#define textureCubeLod(img, coord, lod) textureCube(img, coord, lod)
+#endif
+
+#endif
+
+
#ifdef USE_GLES_OVER_GL
#define lowp
#define mediump
diff --git a/drivers/gles2/shaders/cubemap_filter.glsl b/drivers/gles2/shaders/cubemap_filter.glsl
index 06274a7698..c9a0fd4ba2 100644
--- a/drivers/gles2/shaders/cubemap_filter.glsl
+++ b/drivers/gles2/shaders/cubemap_filter.glsl
@@ -25,11 +25,23 @@ void main() {
/* clang-format off */
[fragment]
+#ifndef USE_GLES_OVER_GL
+
+#ifdef GL_EXT_shader_texture_lod
+#extension GL_EXT_shader_texture_lod : enable
+#define texture2DLod(img, coord, lod) texture2DLodEXT(img, coord, lod)
+#define textureCubeLod(img, coord, lod) textureCubeLodEXT(img, coord, lod)
+#endif
+
+#ifdef GL_ARB_shader_texture_lod
#extension GL_ARB_shader_texture_lod : enable
+#endif
+
+#if !defined(GL_EXT_shader_texture_lod) && !defined(GL_ARB_shader_texture_lod)
+#define texture2DLod(img, coord, lod) texture2D(img, coord, lod)
+#define textureCubeLod(img, coord, lod) textureCube(img, coord, lod)
+#endif
-#ifndef GL_ARB_shader_texture_lod
-#define texture2DLod(img, coord, lod) texture2D(img, coord)
-#define textureCubeLod(img, coord, lod) textureCube(img, coord)
#endif
#ifdef USE_GLES_OVER_GL
@@ -118,7 +130,13 @@ vec3 texelCoordToVec(vec2 uv, int faceID) {
faceUvVectors[5][2] = vec3(0.0, 0.0, 1.0); // +z face
// out = u * s_faceUv[0] + v * s_faceUv[1] + s_faceUv[2].
- vec3 result = (faceUvVectors[faceID][0] * uv.x) + (faceUvVectors[faceID][1] * uv.y) + faceUvVectors[faceID][2];
+ vec3 result;
+ for (int i = 0; i < 6; i++) {
+ if (i == faceID) {
+ result = (faceUvVectors[i][0] * uv.x) + (faceUvVectors[i][1] * uv.y) + faceUvVectors[i][2];
+ break;
+ }
+ }
return normalize(result);
}
diff --git a/drivers/gles2/shaders/scene.glsl b/drivers/gles2/shaders/scene.glsl
index b2b9458ed2..148b5ae7ef 100644
--- a/drivers/gles2/shaders/scene.glsl
+++ b/drivers/gles2/shaders/scene.glsl
@@ -655,13 +655,27 @@ VERTEX_SHADER_CODE
/* clang-format off */
[fragment]
+
+#ifndef USE_GLES_OVER_GL
+
+#ifdef GL_EXT_shader_texture_lod
+#extension GL_EXT_shader_texture_lod : enable
+#define texture2DLod(img, coord, lod) texture2DLodEXT(img, coord, lod)
+#define textureCubeLod(img, coord, lod) textureCubeLodEXT(img, coord, lod)
+#endif
+
+#ifdef GL_ARB_shader_texture_lod
#extension GL_ARB_shader_texture_lod : enable
+#endif
+
+#if !defined(GL_EXT_shader_texture_lod) && !defined(GL_ARB_shader_texture_lod)
+#define texture2DLod(img, coord, lod) texture2D(img, coord, lod)
+#define textureCubeLod(img, coord, lod) textureCube(img, coord, lod)
+#endif
-#ifndef GL_ARB_shader_texture_lod
-#define texture2DLod(img, coord, lod) texture2D(img, coord)
-#define textureCubeLod(img, coord, lod) textureCube(img, coord)
#endif
+
#ifdef USE_GLES_OVER_GL
#define lowp
#define mediump
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index 1fba8535d8..b831197759 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -1832,6 +1832,7 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) {
storage->info.render.vertices_count += s->index_array_len * amount;
} else
#endif
+
if (s->index_array_len > 0) {
glDrawElementsInstanced(gl_primitive[s->primitive], s->index_array_len, (s->array_len >= (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0, amount);
@@ -3113,7 +3114,7 @@ void RasterizerSceneGLES3::_copy_screen(bool p_invalidate_color, bool p_invalida
GLenum attachments[2] = {
GL_COLOR_ATTACHMENT0,
- GL_DEPTH_STENCIL_ATTACHMENT
+ GL_DEPTH_ATTACHMENT
};
glInvalidateFramebuffer(GL_FRAMEBUFFER, p_invalidate_depth ? 2 : 1, attachments);
@@ -4163,7 +4164,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->buffers.fbo);
glReadBuffer(GL_COLOR_ATTACHMENT0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->fbo);
- glBlitFramebuffer(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, 0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+ glBlitFramebuffer(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, 0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
//bind depth for read
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 24673c8755..4818fd4927 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -6931,7 +6931,12 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) {
glGenTextures(1, &rt->exposure.color);
glBindTexture(GL_TEXTURE_2D, rt->exposure.color);
+#ifdef IPHONE_ENABLED
+ ///@TODO ugly hack to get around iOS not supporting 32bit single channel floating point textures...
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_R16F, 1, 1, 0, GL_RED, GL_FLOAT, NULL);
+#else
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, 1, 1, 0, GL_RED, GL_FLOAT, NULL);
+#endif
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->exposure.color, 0);
status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
@@ -7163,7 +7168,12 @@ RID RasterizerStorageGLES3::canvas_light_shadow_buffer_create(int p_width) {
if (config.use_rgba_2d_shadows) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, cls->size, cls->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
} else {
+#ifdef IPHONE_ENABLED
+ ///@TODO ugly hack to get around iOS not supporting 32bit single channel floating point textures...
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_R16F, cls->size, cls->height, 0, GL_RED, GL_FLOAT, NULL);
+#else
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, cls->size, cls->height, 0, GL_RED, GL_FLOAT, NULL);
+#endif
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp
index 0e5fd3a999..e660bb2daf 100644
--- a/editor/editor_inspector.cpp
+++ b/editor/editor_inspector.cpp
@@ -1366,7 +1366,28 @@ void EditorInspector::update_tree() {
//to update properly if all is refreshed
StringName current_selected = property_selected;
- int current_focusable = property_focusable;
+ int current_focusable = -1;
+
+ if (property_focusable != -1) {
+ //check focusable is really focusable
+ bool restore_focus = false;
+ Control *focused = get_focus_owner();
+ if (focused) {
+ Node *parent = focused->get_parent();
+ while (parent) {
+ EditorInspector *inspector = Object::cast_to<EditorInspector>(parent);
+ if (inspector) {
+ restore_focus = inspector == this; //may be owned by another inspector
+ break; //exit after the first inspector is found, since there may be nested ones
+ }
+ parent = parent->get_parent();
+ }
+ }
+
+ if (restore_focus) {
+ current_focusable = property_focusable;
+ }
+ }
_clear();
diff --git a/editor/editor_sectioned_inspector.cpp b/editor/editor_sectioned_inspector.cpp
index a2883690da..acc7637c0b 100644
--- a/editor/editor_sectioned_inspector.cpp
+++ b/editor/editor_sectioned_inspector.cpp
@@ -241,7 +241,7 @@ void SectionedInspector::update_category_list() {
int sp = pi.name.find("/");
if (sp == -1)
- pi.name = "Global/" + pi.name;
+ pi.name = "global/" + pi.name;
Vector<String> sectionarr = pi.name.split("/");
String metasection;
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index 182738cf14..9e65d9de10 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -301,7 +301,7 @@ void ScriptEditor::_goto_script_line2(int p_line) {
void ScriptEditor::_goto_script_line(REF p_script, int p_line) {
Ref<Script> script = Object::cast_to<Script>(*p_script);
- if (!script.is_null() && script->has_source_code()) {
+ if (script.is_valid() && (script->has_source_code() || script->get_path().is_resource_file())) {
if (edit(p_script, p_line, 0)) {
editor->push_item(p_script.ptr());
diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp
index 6bd0309d17..3eeb871380 100644
--- a/editor/plugins/texture_region_editor_plugin.cpp
+++ b/editor/plugins/texture_region_editor_plugin.cpp
@@ -51,6 +51,8 @@ void TextureRegionEditor::_region_draw() {
Ref<Texture> base_tex = NULL;
if (node_sprite)
base_tex = node_sprite->get_texture();
+ else if (node_sprite_3d)
+ base_tex = node_sprite_3d->get_texture();
else if (node_ninepatch)
base_tex = node_ninepatch->get_texture();
else if (obj_styleBox.is_valid())
@@ -285,6 +287,8 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) {
Rect2 r;
if (node_sprite)
r = node_sprite->get_region_rect();
+ else if (node_sprite_3d)
+ r = node_sprite_3d->get_region_rect();
else if (node_ninepatch)
r = node_ninepatch->get_region_rect();
else if (obj_styleBox.is_valid())
@@ -298,6 +302,9 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) {
if (node_sprite) {
undo_redo->add_do_method(node_sprite, "set_region_rect", rect);
undo_redo->add_undo_method(node_sprite, "set_region_rect", node_sprite->get_region_rect());
+ } else if (node_sprite_3d) {
+ undo_redo->add_do_method(node_sprite_3d, "set_region_rect", rect);
+ undo_redo->add_undo_method(node_sprite_3d, "set_region_rect", node_sprite_3d->get_region_rect());
} else if (node_ninepatch) {
undo_redo->add_do_method(node_ninepatch, "set_region_rect", rect);
undo_redo->add_undo_method(node_ninepatch, "set_region_rect", node_ninepatch->get_region_rect());
@@ -325,6 +332,8 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) {
drag = true;
if (node_sprite)
rect_prev = node_sprite->get_region_rect();
+ else if (node_sprite_3d)
+ rect_prev = node_sprite_3d->get_region_rect();
else if (node_ninepatch)
rect_prev = node_ninepatch->get_region_rect();
else if (obj_styleBox.is_valid())
@@ -363,6 +372,9 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) {
if (node_sprite) {
undo_redo->add_do_method(node_sprite, "set_region_rect", node_sprite->get_region_rect());
undo_redo->add_undo_method(node_sprite, "set_region_rect", rect_prev);
+ } else if (node_sprite_3d) {
+ undo_redo->add_do_method(node_sprite_3d, "set_region_rect", node_sprite_3d->get_region_rect());
+ undo_redo->add_undo_method(node_sprite_3d, "set_region_rect", rect_prev);
} else if (atlas_tex.is_valid()) {
undo_redo->add_do_method(atlas_tex.ptr(), "set_region", atlas_tex->get_region());
undo_redo->add_undo_method(atlas_tex.ptr(), "set_region", rect_prev);
@@ -590,6 +602,8 @@ void TextureRegionEditor::_zoom_out() {
void TextureRegionEditor::apply_rect(const Rect2 &p_rect) {
if (node_sprite)
node_sprite->set_region_rect(p_rect);
+ else if (node_sprite_3d)
+ node_sprite_3d->set_region_rect(p_rect);
else if (node_ninepatch)
node_ninepatch->set_region_rect(p_rect);
else if (obj_styleBox.is_valid())
@@ -601,6 +615,8 @@ void TextureRegionEditor::apply_rect(const Rect2 &p_rect) {
void TextureRegionEditor::_update_rect() {
if (node_sprite)
rect = node_sprite->get_region_rect();
+ else if (node_sprite_3d)
+ rect = node_sprite_3d->get_region_rect();
else if (node_ninepatch)
rect = node_ninepatch->get_region_rect();
else if (obj_styleBox.is_valid())
@@ -616,6 +632,8 @@ void TextureRegionEditor::_update_autoslice() {
Ref<Texture> texture = NULL;
if (node_sprite)
texture = node_sprite->get_texture();
+ else if (node_sprite_3d)
+ texture = node_sprite_3d->get_texture();
else if (node_ninepatch)
texture = node_ninepatch->get_texture();
else if (obj_styleBox.is_valid())
@@ -702,9 +720,10 @@ void TextureRegionEditor::_notification(int p_what) {
}
void TextureRegionEditor::_node_removed(Object *p_obj) {
- if (p_obj == node_sprite || p_obj == node_ninepatch || p_obj == obj_styleBox.ptr() || p_obj == atlas_tex.ptr()) {
- node_ninepatch = NULL;
+ if (p_obj == node_sprite || p_obj == node_sprite_3d || p_obj == node_ninepatch || p_obj == obj_styleBox.ptr() || p_obj == atlas_tex.ptr()) {
node_sprite = NULL;
+ node_sprite_3d = NULL;
+ node_ninepatch = NULL;
obj_styleBox = Ref<StyleBox>(NULL);
atlas_tex = Ref<AtlasTexture>(NULL);
hide();
@@ -743,6 +762,10 @@ bool TextureRegionEditor::is_ninepatch() {
return node_ninepatch != NULL;
}
+Sprite3D *TextureRegionEditor::get_sprite_3d() {
+ return node_sprite_3d;
+}
+
Sprite *TextureRegionEditor::get_sprite() {
return node_sprite;
}
@@ -750,6 +773,8 @@ Sprite *TextureRegionEditor::get_sprite() {
void TextureRegionEditor::edit(Object *p_obj) {
if (node_sprite)
node_sprite->remove_change_receptor(this);
+ if (node_sprite_3d)
+ node_sprite_3d->remove_change_receptor(this);
if (node_ninepatch)
node_ninepatch->remove_change_receptor(this);
if (obj_styleBox.is_valid())
@@ -758,6 +783,7 @@ void TextureRegionEditor::edit(Object *p_obj) {
atlas_tex->remove_change_receptor(this);
if (p_obj) {
node_sprite = Object::cast_to<Sprite>(p_obj);
+ node_sprite_3d = Object::cast_to<Sprite3D>(p_obj);
node_ninepatch = Object::cast_to<NinePatchRect>(p_obj);
if (Object::cast_to<StyleBoxTexture>(p_obj))
obj_styleBox = Ref<StyleBoxTexture>(Object::cast_to<StyleBoxTexture>(p_obj));
@@ -767,12 +793,13 @@ void TextureRegionEditor::edit(Object *p_obj) {
_edit_region();
} else {
node_sprite = NULL;
+ node_sprite_3d = NULL;
node_ninepatch = NULL;
obj_styleBox = Ref<StyleBoxTexture>(NULL);
atlas_tex = Ref<AtlasTexture>(NULL);
}
edit_draw->update();
- if (node_sprite && !node_sprite->is_region()) {
+ if ((node_sprite && !node_sprite->is_region()) || (node_sprite_3d && !node_sprite_3d->is_region())) {
set_process(true);
}
if (!p_obj) {
@@ -792,6 +819,8 @@ void TextureRegionEditor::_edit_region() {
Ref<Texture> texture = NULL;
if (node_sprite)
texture = node_sprite->get_texture();
+ else if (node_sprite_3d)
+ texture = node_sprite_3d->get_texture();
else if (node_ninepatch)
texture = node_ninepatch->get_texture();
else if (obj_styleBox.is_valid())
@@ -834,6 +863,7 @@ Vector2 TextureRegionEditor::snap_point(Vector2 p_target) const {
TextureRegionEditor::TextureRegionEditor(EditorNode *p_editor) {
node_sprite = NULL;
+ node_sprite_3d = NULL;
node_ninepatch = NULL;
obj_styleBox = Ref<StyleBoxTexture>(NULL);
atlas_tex = Ref<AtlasTexture>(NULL);
@@ -976,13 +1006,13 @@ void TextureRegionEditorPlugin::edit(Object *p_object) {
}
bool TextureRegionEditorPlugin::handles(Object *p_object) const {
- return p_object->is_class("Sprite") || p_object->is_class("NinePatchRect") || p_object->is_class("StyleBoxTexture") || p_object->is_class("AtlasTexture");
+ return p_object->is_class("Sprite") || p_object->is_class("Sprite3D") || p_object->is_class("NinePatchRect") || p_object->is_class("StyleBoxTexture") || p_object->is_class("AtlasTexture");
}
void TextureRegionEditorPlugin::make_visible(bool p_visible) {
if (p_visible) {
texture_region_button->show();
- if (region_editor->is_stylebox() || region_editor->is_atlas_texture() || region_editor->is_ninepatch() || (region_editor->get_sprite() && region_editor->get_sprite()->is_region()) || texture_region_button->is_pressed()) {
+ if (region_editor->is_stylebox() || region_editor->is_atlas_texture() || region_editor->is_ninepatch() || (region_editor->get_sprite() && region_editor->get_sprite()->is_region()) || (region_editor->get_sprite_3d() && region_editor->get_sprite_3d()->is_region()) || texture_region_button->is_pressed()) {
editor->make_bottom_panel_item_visible(region_editor);
}
} else {
diff --git a/editor/plugins/texture_region_editor_plugin.h b/editor/plugins/texture_region_editor_plugin.h
index e4d7971160..19eaef9bc3 100644
--- a/editor/plugins/texture_region_editor_plugin.h
+++ b/editor/plugins/texture_region_editor_plugin.h
@@ -35,6 +35,7 @@
#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "scene/2d/sprite.h"
+#include "scene/3d/sprite_3d.h"
#include "scene/gui/nine_patch_rect.h"
#include "scene/resources/style_box.h"
#include "scene/resources/texture.h"
@@ -83,8 +84,9 @@ class TextureRegionEditor : public VBoxContainer {
Vector2 snap_step;
Vector2 snap_separation;
- NinePatchRect *node_ninepatch;
Sprite *node_sprite;
+ Sprite3D *node_sprite_3d;
+ NinePatchRect *node_ninepatch;
Ref<StyleBoxTexture> obj_styleBox;
Ref<AtlasTexture> atlas_tex;
@@ -132,6 +134,7 @@ public:
bool is_stylebox();
bool is_atlas_texture();
bool is_ninepatch();
+ Sprite3D *get_sprite_3d();
Sprite *get_sprite();
void edit(Object *p_obj);
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index be1c4a36bd..738d747956 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -565,6 +565,12 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
//check that from node to root, all owners are right
+ if (root->get_scene_inherited_state().is_valid()) {
+ accept->set_text(TTR("Can't reparent nodes in inherited scenes, order of nodes can't change."));
+ accept->popup_centered_minsize();
+ return;
+ }
+
if (node->get_owner() != root) {
accept->set_text(TTR("Node must belong to the edited scene to become root."));
accept->popup_centered_minsize();
diff --git a/main/main.cpp b/main/main.cpp
index cbf30af38c..b94130002d 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -1789,6 +1789,10 @@ uint64_t Main::target_ticks = 0;
uint32_t Main::frames = 0;
uint32_t Main::frame = 0;
bool Main::force_redraw_requested = false;
+bool Main::iterating = false;
+bool Main::is_iterating() {
+ return iterating;
+}
// For performance metrics
static uint64_t physics_process_max = 0;
@@ -1796,6 +1800,10 @@ static uint64_t idle_process_max = 0;
bool Main::iteration() {
+ ERR_FAIL_COND_V(iterating, false);
+
+ iterating = true;
+
uint64_t ticks = OS::get_singleton()->get_ticks_usec();
Engine::get_singleton()->_frame_ticks = ticks;
main_timer_sync.set_cpu_ticks_usec(ticks);
@@ -1923,6 +1931,8 @@ bool Main::iteration() {
frames = 0;
}
+ iterating = false;
+
if (fixed_fps != -1)
return exit;
diff --git a/main/main.h b/main/main.h
index 01fc259a8a..1bdce7d17f 100644
--- a/main/main.h
+++ b/main/main.h
@@ -47,6 +47,7 @@ class Main {
static uint32_t frames;
static uint32_t frame;
static bool force_redraw_requested;
+ static bool iterating;
public:
static bool is_project_manager();
@@ -58,6 +59,8 @@ public:
static bool iteration();
static void force_redraw();
+ static bool is_iterating();
+
static void cleanup();
};
diff --git a/modules/mono/SCsub b/modules/mono/SCsub
index e1f5e2ef28..706949154e 100644
--- a/modules/mono/SCsub
+++ b/modules/mono/SCsub
@@ -88,6 +88,9 @@ vars.Update(env_mono)
if env_mono['mono_glue']:
env_mono.Append(CPPDEFINES=['MONO_GLUE_ENABLED'])
+if env_mono['tools'] or env_mono['target'] != 'release':
+ env_mono.Append(CPPDEFINES=['GD_MONO_HOT_RELOAD'])
+
# Configure TLS checks
import tls_configure
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp
index 02220ab52f..0b21ba3347 100644
--- a/modules/mono/csharp_script.cpp
+++ b/modules/mono/csharp_script.cpp
@@ -607,7 +607,7 @@ struct CSharpScriptDepSort {
void CSharpLanguage::reload_all_scripts() {
-#ifdef DEBUG_ENABLED
+#ifdef GD_MONO_HOT_RELOAD
if (is_assembly_reloading_needed()) {
reload_assemblies(false);
}
@@ -618,15 +618,20 @@ void CSharpLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_soft
(void)p_script; // UNUSED
+ CRASH_COND(!Engine::get_singleton()->is_editor_hint());
+
#ifdef TOOLS_ENABLED
MonoReloadNode::get_singleton()->restart_reload_timer();
+#endif
+
+#ifdef GD_MONO_HOT_RELOAD
if (is_assembly_reloading_needed()) {
reload_assemblies(p_soft_reload);
}
#endif
}
-#ifdef TOOLS_ENABLED
+#ifdef GD_MONO_HOT_RELOAD
bool CSharpLanguage::is_assembly_reloading_needed() {
if (!gdmono->is_runtime_initialized())
@@ -658,11 +663,13 @@ bool CSharpLanguage::is_assembly_reloading_needed() {
return false; // No assembly to load
}
+#ifdef TOOLS_ENABLED
if (!gdmono->get_core_api_assembly() && gdmono->metadata_is_api_assembly_invalidated(APIAssembly::API_CORE))
return false; // The core API assembly to load is invalidated
if (!gdmono->get_editor_api_assembly() && gdmono->metadata_is_api_assembly_invalidated(APIAssembly::API_EDITOR))
return false; // The editor API assembly to load is invalidated
+#endif
return true;
}
@@ -760,9 +767,11 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
PlaceHolderScriptInstance *placeholder = scr->placeholder_instance_create(obj);
obj->set_script_instance(placeholder);
+#ifdef TOOLS_ENABLED
// Even though build didn't fail, this tells the placeholder to keep properties and
// it allows using property_set_fallback for restoring the state without a valid script.
scr->placeholder_fallback_enabled = true;
+#endif
// Restore Variant properties state, it will be kept by the placeholder until the next script reloading
for (List<Pair<StringName, Variant> >::Element *G = scr->pending_reload_state[obj_id].properties.front(); G; G = G->next()) {
@@ -778,13 +787,14 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
for (List<Ref<CSharpScript> >::Element *E = to_reload.front(); E; E = E->next()) {
Ref<CSharpScript> scr = E->get();
+#ifdef TOOLS_ENABLED
scr->exports_invalidated = true;
+#endif
scr->signals_invalidated = true;
scr->reload(p_soft_reload);
scr->update_exports();
{
-#ifdef DEBUG_ENABLED
for (Set<ObjectID>::Element *F = scr->pending_reload_instances.front(); F; F = F->next()) {
ObjectID obj_id = F->get();
Object *obj = ObjectDB::get_instance(obj_id);
@@ -843,17 +853,18 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
scr->pending_reload_state.erase(obj_id);
}
-#endif
scr->pending_reload_instances.clear();
}
}
+#ifdef TOOLS_ENABLED
// FIXME: Hack to refresh editor in order to display new properties and signals. See if there is a better alternative.
if (Engine::get_singleton()->is_editor_hint()) {
EditorNode::get_singleton()->get_inspector()->update_tree();
NodeDock::singleton->update_lists();
}
+#endif
}
#endif
@@ -2810,9 +2821,11 @@ Error ResourceFormatSaverCSharpScript::save(const String &p_path, const RES &p_r
file->close();
memdelete(file);
+#ifdef TOOLS_ENABLED
if (ScriptServer::is_reload_scripts_on_save_enabled()) {
CSharpLanguage::get_singleton()->reload_tool_script(p_resource, false);
}
+#endif
return OK;
}
diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h
index e554e1f41f..8a09be79a6 100644
--- a/modules/mono/csharp_script.h
+++ b/modules/mono/csharp_script.h
@@ -82,10 +82,7 @@ class CSharpScript : public Script {
Set<Object *> instances;
-#ifdef DEBUG_ENABLED
- Set<ObjectID> pending_reload_instances;
-#endif
-
+#ifdef GD_MONO_HOT_RELOAD
struct StateBackup {
// TODO
// Replace with buffer containing the serialized state of managed scripts.
@@ -93,8 +90,8 @@ class CSharpScript : public Script {
List<Pair<StringName, Variant> > properties;
};
-#ifdef TOOLS_ENABLED
- Map<ObjectID, CSharpScript::StateBackup> pending_reload_state;
+ Set<ObjectID> pending_reload_instances;
+ Map<ObjectID, StateBackup> pending_reload_state;
#endif
String source;
@@ -313,7 +310,7 @@ public:
bool debug_break(const String &p_error, bool p_allow_continue = true);
bool debug_break_parse(const String &p_file, int p_line, const String &p_error);
-#ifdef TOOLS_ENABLED
+#ifdef GD_MONO_HOT_RELOAD
bool is_assembly_reloading_needed();
void reload_assemblies(bool p_soft_reload);
#endif
diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp
index 42a6fe1ef8..900caefe1c 100644
--- a/modules/mono/mono_gd/gd_mono.cpp
+++ b/modules/mono/mono_gd/gd_mono.cpp
@@ -731,7 +731,9 @@ Error GDMono::_unload_scripts_domain() {
#endif
core_api_assembly_out_of_sync = false;
+#ifdef TOOLS_ENABLED
editor_api_assembly_out_of_sync = false;
+#endif
MonoDomain *domain = scripts_domain;
scripts_domain = NULL;
@@ -764,7 +766,7 @@ Error GDMono::_load_tools_domain() {
}
#endif
-#ifdef TOOLS_ENABLED
+#ifdef GD_MONO_HOT_RELOAD
Error GDMono::reload_scripts_domain() {
ERR_FAIL_COND_V(!runtime_initialized, ERR_BUG);
@@ -785,8 +787,12 @@ Error GDMono::reload_scripts_domain() {
#ifdef MONO_GLUE_ENABLED
if (!_load_api_assemblies()) {
- if ((core_api_assembly && (core_api_assembly_out_of_sync || !GDMonoUtils::mono_cache.godot_api_cache_updated)) ||
- (editor_api_assembly && editor_api_assembly_out_of_sync)) {
+ if ((core_api_assembly && (core_api_assembly_out_of_sync || !GDMonoUtils::mono_cache.godot_api_cache_updated))
+#ifdef TOOLS_ENABLED
+ || (editor_api_assembly && editor_api_assembly_out_of_sync)
+#endif
+ ) {
+#ifdef TOOLS_ENABLED
// The assembly was successfully loaded, but the full api could not be cached.
// This is most likely an outdated assembly loaded because of an invalid version in the
// metadata, so we invalidate the version in the metadata and unload the script domain.
@@ -810,6 +816,10 @@ Error GDMono::reload_scripts_domain() {
}
return ERR_CANT_RESOLVE;
+#else
+ ERR_PRINT("The loaded API assembly is invalid");
+ CRASH_NOW();
+#endif
} else {
return ERR_CANT_OPEN;
}
@@ -924,7 +934,9 @@ GDMono::GDMono() {
#endif
core_api_assembly_out_of_sync = false;
+#ifdef TOOLS_ENABLED
editor_api_assembly_out_of_sync = false;
+#endif
corlib_assembly = NULL;
core_api_assembly = NULL;
diff --git a/modules/mono/mono_gd/gd_mono.h b/modules/mono/mono_gd/gd_mono.h
index 6a00b287b0..13de3061b3 100644
--- a/modules/mono/mono_gd/gd_mono.h
+++ b/modules/mono/mono_gd/gd_mono.h
@@ -95,7 +95,9 @@ class GDMono {
#endif
bool core_api_assembly_out_of_sync;
+#ifdef TOOLS_ENABLED
bool editor_api_assembly_out_of_sync;
+#endif
GDMonoAssembly *corlib_assembly;
GDMonoAssembly *core_api_assembly;
@@ -193,7 +195,7 @@ public:
GDMonoClass *get_class(MonoClass *p_raw_class);
-#ifdef TOOLS_ENABLED
+#ifdef GD_MONO_HOT_RELOAD
Error reload_scripts_domain();
#endif
diff --git a/modules/mono/utils/osx_utils.h b/modules/mono/utils/osx_utils.h
index 918642f7b2..cc72233058 100644
--- a/modules/mono/utils/osx_utils.h
+++ b/modules/mono/utils/osx_utils.h
@@ -31,6 +31,7 @@
#include "core/ustring.h"
#ifndef OSX_UTILS_H
+#define OSX_UTILS_H
#ifdef OSX_ENABLED
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index ddd98ab88c..760858b2e5 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -304,7 +304,9 @@ static Vector2 get_mouse_pos(NSPoint locationInWindow, CGFloat backingScaleFacto
if (OS_OSX::singleton->main_loop) {
Main::force_redraw();
//Event retrieval blocks until resize is over. Call Main::iteration() directly.
- Main::iteration();
+ if (!Main::is_iterating()) { //avoid cyclic loop
+ Main::iteration();
+ }
}
/*
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index e14db9a201..0662bc2edc 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -208,8 +208,8 @@ def configure_msvc(env, manual_msvc_config):
'RTAUDIO_ENABLED', 'WASAPI_ENABLED',
'WINMIDI_ENABLED', 'TYPED_METHOD_BIND',
'WIN32', 'MSVC',
- 'WINVER=$target_win_version',
- '_WIN32_WINNT=$target_win_version'])
+ 'WINVER=%s' % env["target_win_version"],
+ '_WIN32_WINNT=%s' % env["target_win_version"]])
env.AppendUnique(CPPDEFINES=['NOMINMAX']) # disable bogus min/max WinDef.h macros
if env["bits"] == "64":
env.AppendUnique(CPPDEFINES=['_WIN64'])
@@ -218,7 +218,7 @@ def configure_msvc(env, manual_msvc_config):
LIBS = ['winmm', 'opengl32', 'dsound', 'kernel32', 'ole32', 'oleaut32',
'user32', 'gdi32', 'IPHLPAPI', 'Shlwapi', 'wsock32', 'Ws2_32',
- 'shell32', 'advapi32', 'dinput8', 'dxguid', 'imm32', 'bcrypt']
+ 'shell32', 'advapi32', 'dinput8', 'dxguid', 'imm32', 'bcrypt','Avrt']
env.Append(LINKFLAGS=[p + env["LIBSUFFIX"] for p in LIBS])
if manual_msvc_config:
@@ -329,7 +329,7 @@ def configure_mingw(env):
env.Append(CCFLAGS=['-DRTAUDIO_ENABLED'])
env.Append(CCFLAGS=['-DWASAPI_ENABLED'])
env.Append(CCFLAGS=['-DWINVER=%s' % env['target_win_version'], '-D_WIN32_WINNT=%s' % env['target_win_version']])
- env.Append(LIBS=['mingw32', 'opengl32', 'dsound', 'ole32', 'd3d9', 'winmm', 'gdi32', 'iphlpapi', 'shlwapi', 'wsock32', 'ws2_32', 'kernel32', 'oleaut32', 'dinput8', 'dxguid', 'ksuser', 'imm32', 'bcrypt'])
+ env.Append(LIBS=['mingw32', 'opengl32', 'dsound', 'ole32', 'd3d9', 'winmm', 'gdi32', 'iphlpapi', 'shlwapi', 'wsock32', 'ws2_32', 'kernel32', 'oleaut32', 'dinput8', 'dxguid', 'ksuser', 'imm32', 'bcrypt','avrt'])
env.Append(CPPFLAGS=['-DMINGW_ENABLED'])
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index 3b41f1b901..5cba34ac62 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -50,6 +50,7 @@
#include "servers/visual/visual_server_raster.h"
#include "servers/visual/visual_server_wrap_mt.h"
#include "windows_terminal_logger.h"
+#include <avrt.h>
#include <process.h>
#include <regstr.h>
@@ -783,7 +784,9 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
case WM_TIMER: {
if (wParam == move_timer_id) {
process_key_events();
- Main::iteration();
+ if (!Main::is_iterating()) {
+ Main::iteration();
+ }
}
} break;
@@ -1371,6 +1374,19 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
set_ime_active(false);
+ if (!OS::get_singleton()->is_in_low_processor_usage_mode()) {
+ //SetPriorityClass(GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS);
+ SetPriorityClass(GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS);
+ DWORD index = 0;
+ HANDLE handle = AvSetMmThreadCharacteristics("Games", &index);
+ if (handle)
+ AvSetMmThreadPriority(handle, AVRT_PRIORITY_CRITICAL);
+
+ // This is needed to make sure that background work does not starve the main thread.
+ // This is only setting priority of this thread, not the whole process.
+ SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
+ }
+
return OK;
}
@@ -2319,6 +2335,9 @@ void OS_Windows::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shap
iconinfo.hbmMask = hAndMask;
iconinfo.hbmColor = hXorMask;
+ if (cursors[p_shape])
+ DestroyIcon(cursors[p_shape]);
+
cursors[p_shape] = CreateIconIndirect(&iconinfo);
if (p_shape == cursor_shape) {
diff --git a/platform/x11/detect.py b/platform/x11/detect.py
index 415e8ceaa6..72139538b7 100644
--- a/platform/x11/detect.py
+++ b/platform/x11/detect.py
@@ -61,8 +61,9 @@ def get_opts():
return [
BoolVariable('use_llvm', 'Use the LLVM compiler', False),
BoolVariable('use_static_cpp', 'Link libgcc and libstdc++ statically for better portability', False),
- BoolVariable('use_sanitizer', 'Use LLVM compiler address sanitizer', False),
- BoolVariable('use_leak_sanitizer', 'Use LLVM compiler memory leaks sanitizer (implies use_sanitizer)', False),
+ BoolVariable('use_ubsan', 'Use LLVM/GCC compiler undefined behavior sanitizer (UBSAN)', False),
+ BoolVariable('use_asan', 'Use LLVM/GCC compiler address sanitizer (ASAN))', False),
+ BoolVariable('use_lsan', 'Use LLVM/GCC compiler leak sanitizer (LSAN))', False),
BoolVariable('pulseaudio', 'Detect & use pulseaudio', True),
BoolVariable('udev', 'Use udev for gamepad connection callbacks', False),
EnumVariable('debug_symbols', 'Add debugging symbols to release builds', 'yes', ('yes', 'no', 'full')),
@@ -131,12 +132,19 @@ def configure(env):
env.Append(CPPFLAGS=['-DTYPED_METHOD_BIND'])
env.extra_suffix = ".llvm" + env.extra_suffix
- # leak sanitizer requires (address) sanitizer
- if env['use_sanitizer'] or env['use_leak_sanitizer']:
- env.Append(CCFLAGS=['-fsanitize=address', '-fno-omit-frame-pointer'])
- env.Append(LINKFLAGS=['-fsanitize=address'])
+
+ if env['use_ubsan'] or env['use_asan'] or env['use_lsan']:
env.extra_suffix += "s"
- if env['use_leak_sanitizer']:
+
+ if env['use_ubsan']:
+ env.Append(CCFLAGS=['-fsanitize=undefined'])
+ env.Append(LINKFLAGS=['-fsanitize=undefined'])
+
+ if env['use_asan']:
+ env.Append(CCFLAGS=['-fsanitize=address'])
+ env.Append(LINKFLAGS=['-fsanitize=address'])
+
+ if env['use_lsan']:
env.Append(CCFLAGS=['-fsanitize=leak'])
env.Append(LINKFLAGS=['-fsanitize=leak'])
diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp
index 36b900bf82..21feb6e226 100644
--- a/scene/2d/cpu_particles_2d.cpp
+++ b/scene/2d/cpu_particles_2d.cpp
@@ -840,7 +840,7 @@ void CPUParticles2D::_particles_process(float p_delta) {
if (flags[FLAG_ALIGN_Y_TO_VELOCITY]) {
if (p.velocity.length() > 0.0) {
- p.transform.elements[0] = p.velocity.normalized();
+ p.transform.elements[1] = p.velocity.normalized();
p.transform.elements[0] = p.transform.elements[1].tangent();
}
@@ -1378,6 +1378,7 @@ CPUParticles2D::CPUParticles2D() {
set_param(PARAM_INITIAL_LINEAR_VELOCITY, 1);
//set_param(PARAM_ORBIT_VELOCITY, 0);
set_param(PARAM_LINEAR_ACCEL, 0);
+ set_param(PARAM_ANGULAR_VELOCITY, 0);
set_param(PARAM_RADIAL_ACCEL, 0);
set_param(PARAM_TANGENTIAL_ACCEL, 0);
set_param(PARAM_DAMPING, 0);
diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp
index 38a5f9714e..5a2e7245a2 100644
--- a/scene/resources/tile_set.cpp
+++ b/scene/resources/tile_set.cpp
@@ -908,7 +908,7 @@ void TileSet::_tile_set_shapes(int p_id, const Array &p_shapes) {
if (d.has("one_way_margin") && d["one_way_margin"].is_num())
s.one_way_collision_margin = d["one_way_margin"];
else
- s.one_way_collision = 1.0;
+ s.one_way_collision_margin = 1.0;
if (d.has("autotile_coord") && d["autotile_coord"].get_type() == Variant::VECTOR2)
s.autotile_coord = d["autotile_coord"];
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h
index 394592ec64..6f8a30070a 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -141,6 +141,7 @@ public:
virtual void light_instance_set_transform(RID p_light_instance, const Transform &p_transform) = 0;
virtual void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_bias_scale = 1.0) = 0;
virtual void light_instance_mark_visible(RID p_light_instance) = 0;
+ virtual bool light_instances_can_render_shadow_cube() const { return true; }
virtual RID reflection_atlas_create() = 0;
virtual void reflection_atlas_set_size(RID p_ref_atlas, int p_size) = 0;
diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp
index 53e8d6a030..23ad2ec1ec 100644
--- a/servers/visual/visual_server_scene.cpp
+++ b/servers/visual/visual_server_scene.cpp
@@ -1535,106 +1535,102 @@ bool VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
VS::LightOmniShadowMode shadow_mode = VSG::storage->light_omni_get_shadow_mode(p_instance->base);
- switch (shadow_mode) {
- case VS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID: {
+ if (shadow_mode == VS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID || !VSG::scene_render->light_instances_can_render_shadow_cube()) {
- for (int i = 0; i < 2; i++) {
+ for (int i = 0; i < 2; i++) {
- //using this one ensures that raster deferred will have it
+ //using this one ensures that raster deferred will have it
- float radius = VSG::storage->light_get_param(p_instance->base, VS::LIGHT_PARAM_RANGE);
-
- float z = i == 0 ? -1 : 1;
- Vector<Plane> planes;
- planes.resize(5);
- planes.write[0] = light_transform.xform(Plane(Vector3(0, 0, z), radius));
- planes.write[1] = light_transform.xform(Plane(Vector3(1, 0, z).normalized(), radius));
- planes.write[2] = light_transform.xform(Plane(Vector3(-1, 0, z).normalized(), radius));
- planes.write[3] = light_transform.xform(Plane(Vector3(0, 1, z).normalized(), radius));
- planes.write[4] = light_transform.xform(Plane(Vector3(0, -1, z).normalized(), radius));
-
- int cull_count = p_scenario->octree.cull_convex(planes, instance_shadow_cull_result, MAX_INSTANCE_CULL, VS::INSTANCE_GEOMETRY_MASK);
- Plane near_plane(light_transform.origin, light_transform.basis.get_axis(2) * z);
-
- for (int j = 0; j < cull_count; j++) {
-
- Instance *instance = instance_shadow_cull_result[j];
- if (!instance->visible || !((1 << instance->base_type) & VS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) {
- cull_count--;
- SWAP(instance_shadow_cull_result[j], instance_shadow_cull_result[cull_count]);
- j--;
- } else {
- if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
- animated_material_found = true;
- }
+ float radius = VSG::storage->light_get_param(p_instance->base, VS::LIGHT_PARAM_RANGE);
- instance->depth = near_plane.distance_to(instance->transform.origin);
- instance->depth_layer = 0;
+ float z = i == 0 ? -1 : 1;
+ Vector<Plane> planes;
+ planes.resize(5);
+ planes.write[0] = light_transform.xform(Plane(Vector3(0, 0, z), radius));
+ planes.write[1] = light_transform.xform(Plane(Vector3(1, 0, z).normalized(), radius));
+ planes.write[2] = light_transform.xform(Plane(Vector3(-1, 0, z).normalized(), radius));
+ planes.write[3] = light_transform.xform(Plane(Vector3(0, 1, z).normalized(), radius));
+ planes.write[4] = light_transform.xform(Plane(Vector3(0, -1, z).normalized(), radius));
+
+ int cull_count = p_scenario->octree.cull_convex(planes, instance_shadow_cull_result, MAX_INSTANCE_CULL, VS::INSTANCE_GEOMETRY_MASK);
+ Plane near_plane(light_transform.origin, light_transform.basis.get_axis(2) * z);
+
+ for (int j = 0; j < cull_count; j++) {
+
+ Instance *instance = instance_shadow_cull_result[j];
+ if (!instance->visible || !((1 << instance->base_type) & VS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) {
+ cull_count--;
+ SWAP(instance_shadow_cull_result[j], instance_shadow_cull_result[cull_count]);
+ j--;
+ } else {
+ if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
+ animated_material_found = true;
}
- }
- VSG::scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, i);
- VSG::scene_render->render_shadow(light->instance, p_shadow_atlas, i, (RasterizerScene::InstanceBase **)instance_shadow_cull_result, cull_count);
+ instance->depth = near_plane.distance_to(instance->transform.origin);
+ instance->depth_layer = 0;
+ }
}
- } break;
- case VS::LIGHT_OMNI_SHADOW_CUBE: {
-
- float radius = VSG::storage->light_get_param(p_instance->base, VS::LIGHT_PARAM_RANGE);
- CameraMatrix cm;
- cm.set_perspective(90, 1, 0.01, radius);
-
- for (int i = 0; i < 6; i++) {
- //using this one ensures that raster deferred will have it
-
- static const Vector3 view_normals[6] = {
- Vector3(-1, 0, 0),
- Vector3(+1, 0, 0),
- Vector3(0, -1, 0),
- Vector3(0, +1, 0),
- Vector3(0, 0, -1),
- Vector3(0, 0, +1)
- };
- static const Vector3 view_up[6] = {
- Vector3(0, -1, 0),
- Vector3(0, -1, 0),
- Vector3(0, 0, -1),
- Vector3(0, 0, +1),
- Vector3(0, -1, 0),
- Vector3(0, -1, 0)
- };
-
- Transform xform = light_transform * Transform().looking_at(view_normals[i], view_up[i]);
-
- Vector<Plane> planes = cm.get_projection_planes(xform);
+ VSG::scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, i);
+ VSG::scene_render->render_shadow(light->instance, p_shadow_atlas, i, (RasterizerScene::InstanceBase **)instance_shadow_cull_result, cull_count);
+ }
+ } else { //shadow cube
- int cull_count = p_scenario->octree.cull_convex(planes, instance_shadow_cull_result, MAX_INSTANCE_CULL, VS::INSTANCE_GEOMETRY_MASK);
+ float radius = VSG::storage->light_get_param(p_instance->base, VS::LIGHT_PARAM_RANGE);
+ CameraMatrix cm;
+ cm.set_perspective(90, 1, 0.01, radius);
- Plane near_plane(xform.origin, -xform.basis.get_axis(2));
- for (int j = 0; j < cull_count; j++) {
+ for (int i = 0; i < 6; i++) {
- Instance *instance = instance_shadow_cull_result[j];
- if (!instance->visible || !((1 << instance->base_type) & VS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) {
- cull_count--;
- SWAP(instance_shadow_cull_result[j], instance_shadow_cull_result[cull_count]);
- j--;
- } else {
- if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
- animated_material_found = true;
- }
- instance->depth = near_plane.distance_to(instance->transform.origin);
- instance->depth_layer = 0;
+ //using this one ensures that raster deferred will have it
+
+ static const Vector3 view_normals[6] = {
+ Vector3(-1, 0, 0),
+ Vector3(+1, 0, 0),
+ Vector3(0, -1, 0),
+ Vector3(0, +1, 0),
+ Vector3(0, 0, -1),
+ Vector3(0, 0, +1)
+ };
+ static const Vector3 view_up[6] = {
+ Vector3(0, -1, 0),
+ Vector3(0, -1, 0),
+ Vector3(0, 0, -1),
+ Vector3(0, 0, +1),
+ Vector3(0, -1, 0),
+ Vector3(0, -1, 0)
+ };
+
+ Transform xform = light_transform * Transform().looking_at(view_normals[i], view_up[i]);
+
+ Vector<Plane> planes = cm.get_projection_planes(xform);
+
+ int cull_count = p_scenario->octree.cull_convex(planes, instance_shadow_cull_result, MAX_INSTANCE_CULL, VS::INSTANCE_GEOMETRY_MASK);
+
+ Plane near_plane(xform.origin, -xform.basis.get_axis(2));
+ for (int j = 0; j < cull_count; j++) {
+
+ Instance *instance = instance_shadow_cull_result[j];
+ if (!instance->visible || !((1 << instance->base_type) & VS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) {
+ cull_count--;
+ SWAP(instance_shadow_cull_result[j], instance_shadow_cull_result[cull_count]);
+ j--;
+ } else {
+ if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
+ animated_material_found = true;
}
+ instance->depth = near_plane.distance_to(instance->transform.origin);
+ instance->depth_layer = 0;
}
-
- VSG::scene_render->light_instance_set_shadow_transform(light->instance, cm, xform, radius, 0, i);
- VSG::scene_render->render_shadow(light->instance, p_shadow_atlas, i, (RasterizerScene::InstanceBase **)instance_shadow_cull_result, cull_count);
}
- //restore the regular DP matrix
- VSG::scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, 0);
+ VSG::scene_render->light_instance_set_shadow_transform(light->instance, cm, xform, radius, 0, i);
+ VSG::scene_render->render_shadow(light->instance, p_shadow_atlas, i, (RasterizerScene::InstanceBase **)instance_shadow_cull_result, cull_count);
+ }
- } break;
+ //restore the regular DP matrix
+ VSG::scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, 0);
}
} break;
diff --git a/thirdparty/README.md b/thirdparty/README.md
index 186f183ea2..738835c70a 100644
--- a/thirdparty/README.md
+++ b/thirdparty/README.md
@@ -202,6 +202,9 @@ Files extracted from upstream source:
- all .h files in include/theora/ as theora/
- COPYING and LICENSE
+Upstream patches included in the `patches` directory have been applied
+on top of the 1.1.1 source (not included in any stable release yet).
+
## libvorbis
diff --git a/thirdparty/libtheora/decode.c b/thirdparty/libtheora/decode.c
index 7be66463d8..bde967b794 100644
--- a/thirdparty/libtheora/decode.c
+++ b/thirdparty/libtheora/decode.c
@@ -397,10 +397,10 @@ static int oc_dec_init(oc_dec_ctx *_dec,const th_info *_info,
int qsum;
qsum=0;
for(qti=0;qti<2;qti++)for(pli=0;pli<3;pli++){
- qsum+=_dec->state.dequant_tables[qti][pli][qi][12]+
- _dec->state.dequant_tables[qti][pli][qi][17]+
- _dec->state.dequant_tables[qti][pli][qi][18]+
- _dec->state.dequant_tables[qti][pli][qi][24]<<(pli==0);
+ qsum+=_dec->state.dequant_tables[qi][pli][qti][12]+
+ _dec->state.dequant_tables[qi][pli][qti][17]+
+ _dec->state.dequant_tables[qi][pli][qti][18]+
+ _dec->state.dequant_tables[qi][pli][qti][24]<<(pli==0);
}
_dec->pp_sharp_mod[qi]=-(qsum>>11);
}
diff --git a/thirdparty/libtheora/patches/theora.git-0ae66d565e6bead8604d312bc1a4e9dccf245c88.patch b/thirdparty/libtheora/patches/theora.git-0ae66d565e6bead8604d312bc1a4e9dccf245c88.patch
new file mode 100644
index 0000000000..1b9c8e20be
--- /dev/null
+++ b/thirdparty/libtheora/patches/theora.git-0ae66d565e6bead8604d312bc1a4e9dccf245c88.patch
@@ -0,0 +1,38 @@
+From 0ae66d565e6bead8604d312bc1a4e9dccf245c88 Mon Sep 17 00:00:00 2001
+From: Tim Terriberry <tterribe@xiph.org>
+Date: Tue, 8 May 2012 02:51:57 +0000
+Subject: [PATCH] Fix pp_sharp_mod calculation.
+
+This was broken when the dequant_tables indexing changed in commit
+ r16102, but it only affected post-processing quality, so we never
+ noticed.
+With gcc 4.8.0, this can now trigger a segfault during decoder
+ initialization.
+
+svn path=/trunk/theora/; revision=18268
+---
+ decode.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/decode.c b/decode.c
+index b803505..9f2516a 100644
+--- a/decode.c
++++ b/decode.c
+@@ -400,10 +400,10 @@ static int oc_dec_init(oc_dec_ctx *_dec,const th_info *_info,
+ int qsum;
+ qsum=0;
+ for(qti=0;qti<2;qti++)for(pli=0;pli<3;pli++){
+- qsum+=_dec->state.dequant_tables[qti][pli][qi][12]+
+- _dec->state.dequant_tables[qti][pli][qi][17]+
+- _dec->state.dequant_tables[qti][pli][qi][18]+
+- _dec->state.dequant_tables[qti][pli][qi][24]<<(pli==0);
++ qsum+=_dec->state.dequant_tables[qi][pli][qti][12]+
++ _dec->state.dequant_tables[qi][pli][qti][17]+
++ _dec->state.dequant_tables[qi][pli][qti][18]+
++ _dec->state.dequant_tables[qi][pli][qti][24]<<(pli==0);
+ }
+ _dec->pp_sharp_mod[qi]=-(qsum>>11);
+ }
+--
+2.11.0
+
diff --git a/thirdparty/misc/base64.h b/thirdparty/misc/base64.h
index 4c300382c1..ffcd0af973 100644
--- a/thirdparty/misc/base64.h
+++ b/thirdparty/misc/base64.h
@@ -11,8 +11,8 @@
extern "C" {
-uint32_t base64_encode(char *to, char *from, uint32_t len);
-uint32_t base64_decode(char *to, char *from, uint32_t len);
+long base64_encode(char *to, char *from, unsigned int len);
+long base64_decode(char *to, char *from, unsigned int len);
};
#endif /* BASE64_H */