diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/coreaudio/audio_driver_coreaudio.cpp | 8 | ||||
-rw-r--r-- | drivers/coremidi/midi_driver_coremidi.cpp | 2 | ||||
-rw-r--r-- | drivers/gles2/rasterizer_canvas_gles2.cpp | 46 | ||||
-rw-r--r-- | drivers/gles2/rasterizer_scene_gles2.cpp | 6 | ||||
-rw-r--r-- | drivers/gles2/rasterizer_storage_gles2.cpp | 59 | ||||
-rw-r--r-- | drivers/gles2/rasterizer_storage_gles2.h | 2 | ||||
-rw-r--r-- | drivers/gles2/shaders/scene.glsl | 3 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_canvas_gles3.cpp | 6 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.cpp | 6 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.h | 2 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_storage_gles3.cpp | 74 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_storage_gles3.h | 6 | ||||
-rw-r--r-- | drivers/gles3/shaders/canvas.glsl | 26 | ||||
-rw-r--r-- | drivers/unix/file_access_unix.cpp | 27 | ||||
-rw-r--r-- | drivers/unix/net_socket_posix.cpp | 6 | ||||
-rw-r--r-- | drivers/unix/os_unix.cpp | 2 | ||||
-rw-r--r-- | drivers/unix/semaphore_posix.cpp | 2 | ||||
-rw-r--r-- | drivers/unix/semaphore_posix.h | 2 | ||||
-rw-r--r-- | drivers/wasapi/audio_driver_wasapi.cpp | 2 |
19 files changed, 183 insertions, 104 deletions
diff --git a/drivers/coreaudio/audio_driver_coreaudio.cpp b/drivers/coreaudio/audio_driver_coreaudio.cpp index 3b06c47244..9081fccd3a 100644 --- a/drivers/coreaudio/audio_driver_coreaudio.cpp +++ b/drivers/coreaudio/audio_driver_coreaudio.cpp @@ -186,15 +186,15 @@ OSStatus AudioDriverCoreAudio::output_callback(void *inRefCon, for (unsigned int i = 0; i < ioData->mNumberBuffers; i++) { AudioBuffer *abuf = &ioData->mBuffers[i]; - int frames_left = inNumberFrames; + unsigned int frames_left = inNumberFrames; int16_t *out = (int16_t *)abuf->mData; while (frames_left) { - int frames = MIN(frames_left, ad->buffer_frames); + unsigned int frames = MIN(frames_left, ad->buffer_frames); ad->audio_server_process(frames, ad->samples_in.ptrw()); - for (int j = 0; j < frames * ad->channels; j++) { + for (unsigned int j = 0; j < frames * ad->channels; j++) { out[j] = ad->samples_in[j] >> 16; } @@ -231,7 +231,7 @@ OSStatus AudioDriverCoreAudio::input_callback(void *inRefCon, OSStatus result = AudioUnitRender(ad->input_unit, ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, &bufferList); if (result == noErr) { - for (int i = 0; i < inNumberFrames * ad->capture_channels; i++) { + for (unsigned int i = 0; i < inNumberFrames * ad->capture_channels; i++) { int32_t sample = ad->input_buf[i] << 16; ad->capture_buffer_write(sample); diff --git a/drivers/coremidi/midi_driver_coremidi.cpp b/drivers/coremidi/midi_driver_coremidi.cpp index 7a92ac0702..28665b5190 100644 --- a/drivers/coremidi/midi_driver_coremidi.cpp +++ b/drivers/coremidi/midi_driver_coremidi.cpp @@ -39,7 +39,7 @@ void MIDIDriverCoreMidi::read(const MIDIPacketList *packet_list, void *read_proc_ref_con, void *src_conn_ref_con) { MIDIPacket *packet = const_cast<MIDIPacket *>(packet_list->packet); - for (int i = 0; i < packet_list->numPackets; i++) { + for (UInt32 i = 0; i < packet_list->numPackets; i++) { receive_input_packet(packet->timeStamp, packet->data, packet->length); packet = MIDIPacketNext(packet); } diff --git a/drivers/gles2/rasterizer_canvas_gles2.cpp b/drivers/gles2/rasterizer_canvas_gles2.cpp index 6be48a4c58..16e5e92abd 100644 --- a/drivers/gles2/rasterizer_canvas_gles2.cpp +++ b/drivers/gles2/rasterizer_canvas_gles2.cpp @@ -494,8 +494,10 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur if (line->width <= 1) { Vector2 verts[2] = { - Vector2(line->from.x, line->from.y), - Vector2(line->to.x, line->to.y) + // Offset the line slightly to make sure we always draw the pixel at the from coordinate. + // Without this, corners of rectangles might be missing a pixel. (See diamond exit rule and #32657) + Vector2(Math::floor(line->from.x) + 0.5, Math::floor(line->from.y) + 0.5), + Vector2(Math::floor(line->to.x) + 0.5, Math::floor(line->to.y) + 0.5) }; #ifdef GLES_OVER_GL @@ -761,6 +763,14 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur source.size.y = tex->height; } + float screen_scale = 1.0; + + if (source.size.x != 0 && source.size.y != 0) { + + screen_scale = MIN(np->rect.size.x / source.size.x, np->rect.size.y / source.size.y); + screen_scale = MIN(1.0, screen_scale); + } + // prepare vertex buffer // this buffer contains [ POS POS UV UV ] * @@ -777,13 +787,13 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur buffer[(0 * 4 * 4) + 2] = source.position.x * texpixel_size.x; buffer[(0 * 4 * 4) + 3] = source.position.y * texpixel_size.y; - buffer[(0 * 4 * 4) + 4] = np->rect.position.x + np->margin[MARGIN_LEFT]; + buffer[(0 * 4 * 4) + 4] = np->rect.position.x + np->margin[MARGIN_LEFT] * screen_scale; buffer[(0 * 4 * 4) + 5] = np->rect.position.y; buffer[(0 * 4 * 4) + 6] = (source.position.x + np->margin[MARGIN_LEFT]) * texpixel_size.x; buffer[(0 * 4 * 4) + 7] = source.position.y * texpixel_size.y; - buffer[(0 * 4 * 4) + 8] = np->rect.position.x + np->rect.size.x - np->margin[MARGIN_RIGHT]; + buffer[(0 * 4 * 4) + 8] = np->rect.position.x + np->rect.size.x - np->margin[MARGIN_RIGHT] * screen_scale; buffer[(0 * 4 * 4) + 9] = np->rect.position.y; buffer[(0 * 4 * 4) + 10] = (source.position.x + source.size.x - np->margin[MARGIN_RIGHT]) * texpixel_size.x; @@ -798,25 +808,25 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur // second row buffer[(1 * 4 * 4) + 0] = np->rect.position.x; - buffer[(1 * 4 * 4) + 1] = np->rect.position.y + np->margin[MARGIN_TOP]; + buffer[(1 * 4 * 4) + 1] = np->rect.position.y + np->margin[MARGIN_TOP] * screen_scale; buffer[(1 * 4 * 4) + 2] = source.position.x * texpixel_size.x; buffer[(1 * 4 * 4) + 3] = (source.position.y + np->margin[MARGIN_TOP]) * texpixel_size.y; - buffer[(1 * 4 * 4) + 4] = np->rect.position.x + np->margin[MARGIN_LEFT]; - buffer[(1 * 4 * 4) + 5] = np->rect.position.y + np->margin[MARGIN_TOP]; + buffer[(1 * 4 * 4) + 4] = np->rect.position.x + np->margin[MARGIN_LEFT] * screen_scale; + buffer[(1 * 4 * 4) + 5] = np->rect.position.y + np->margin[MARGIN_TOP] * screen_scale; buffer[(1 * 4 * 4) + 6] = (source.position.x + np->margin[MARGIN_LEFT]) * texpixel_size.x; buffer[(1 * 4 * 4) + 7] = (source.position.y + np->margin[MARGIN_TOP]) * texpixel_size.y; - buffer[(1 * 4 * 4) + 8] = np->rect.position.x + np->rect.size.x - np->margin[MARGIN_RIGHT]; - buffer[(1 * 4 * 4) + 9] = np->rect.position.y + np->margin[MARGIN_TOP]; + buffer[(1 * 4 * 4) + 8] = np->rect.position.x + np->rect.size.x - np->margin[MARGIN_RIGHT] * screen_scale; + buffer[(1 * 4 * 4) + 9] = np->rect.position.y + np->margin[MARGIN_TOP] * screen_scale; buffer[(1 * 4 * 4) + 10] = (source.position.x + source.size.x - np->margin[MARGIN_RIGHT]) * texpixel_size.x; buffer[(1 * 4 * 4) + 11] = (source.position.y + np->margin[MARGIN_TOP]) * texpixel_size.y; buffer[(1 * 4 * 4) + 12] = np->rect.position.x + np->rect.size.x; - buffer[(1 * 4 * 4) + 13] = np->rect.position.y + np->margin[MARGIN_TOP]; + buffer[(1 * 4 * 4) + 13] = np->rect.position.y + np->margin[MARGIN_TOP] * screen_scale; buffer[(1 * 4 * 4) + 14] = (source.position.x + source.size.x) * texpixel_size.x; buffer[(1 * 4 * 4) + 15] = (source.position.y + np->margin[MARGIN_TOP]) * texpixel_size.y; @@ -824,25 +834,25 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur // third row buffer[(2 * 4 * 4) + 0] = np->rect.position.x; - buffer[(2 * 4 * 4) + 1] = np->rect.position.y + np->rect.size.y - np->margin[MARGIN_BOTTOM]; + buffer[(2 * 4 * 4) + 1] = np->rect.position.y + np->rect.size.y - np->margin[MARGIN_BOTTOM] * screen_scale; buffer[(2 * 4 * 4) + 2] = source.position.x * texpixel_size.x; buffer[(2 * 4 * 4) + 3] = (source.position.y + source.size.y - np->margin[MARGIN_BOTTOM]) * texpixel_size.y; - buffer[(2 * 4 * 4) + 4] = np->rect.position.x + np->margin[MARGIN_LEFT]; - buffer[(2 * 4 * 4) + 5] = np->rect.position.y + np->rect.size.y - np->margin[MARGIN_BOTTOM]; + buffer[(2 * 4 * 4) + 4] = np->rect.position.x + np->margin[MARGIN_LEFT] * screen_scale; + buffer[(2 * 4 * 4) + 5] = np->rect.position.y + np->rect.size.y - np->margin[MARGIN_BOTTOM] * screen_scale; buffer[(2 * 4 * 4) + 6] = (source.position.x + np->margin[MARGIN_LEFT]) * texpixel_size.x; buffer[(2 * 4 * 4) + 7] = (source.position.y + source.size.y - np->margin[MARGIN_BOTTOM]) * texpixel_size.y; - buffer[(2 * 4 * 4) + 8] = np->rect.position.x + np->rect.size.x - np->margin[MARGIN_RIGHT]; - buffer[(2 * 4 * 4) + 9] = np->rect.position.y + np->rect.size.y - np->margin[MARGIN_BOTTOM]; + buffer[(2 * 4 * 4) + 8] = np->rect.position.x + np->rect.size.x - np->margin[MARGIN_RIGHT] * screen_scale; + buffer[(2 * 4 * 4) + 9] = np->rect.position.y + np->rect.size.y - np->margin[MARGIN_BOTTOM] * screen_scale; buffer[(2 * 4 * 4) + 10] = (source.position.x + source.size.x - np->margin[MARGIN_RIGHT]) * texpixel_size.x; buffer[(2 * 4 * 4) + 11] = (source.position.y + source.size.y - np->margin[MARGIN_BOTTOM]) * texpixel_size.y; buffer[(2 * 4 * 4) + 12] = np->rect.position.x + np->rect.size.x; - buffer[(2 * 4 * 4) + 13] = np->rect.position.y + np->rect.size.y - np->margin[MARGIN_BOTTOM]; + buffer[(2 * 4 * 4) + 13] = np->rect.position.y + np->rect.size.y - np->margin[MARGIN_BOTTOM] * screen_scale; buffer[(2 * 4 * 4) + 14] = (source.position.x + source.size.x) * texpixel_size.x; buffer[(2 * 4 * 4) + 15] = (source.position.y + source.size.y - np->margin[MARGIN_BOTTOM]) * texpixel_size.y; @@ -855,13 +865,13 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur buffer[(3 * 4 * 4) + 2] = source.position.x * texpixel_size.x; buffer[(3 * 4 * 4) + 3] = (source.position.y + source.size.y) * texpixel_size.y; - buffer[(3 * 4 * 4) + 4] = np->rect.position.x + np->margin[MARGIN_LEFT]; + buffer[(3 * 4 * 4) + 4] = np->rect.position.x + np->margin[MARGIN_LEFT] * screen_scale; buffer[(3 * 4 * 4) + 5] = np->rect.position.y + np->rect.size.y; buffer[(3 * 4 * 4) + 6] = (source.position.x + np->margin[MARGIN_LEFT]) * texpixel_size.x; buffer[(3 * 4 * 4) + 7] = (source.position.y + source.size.y) * texpixel_size.y; - buffer[(3 * 4 * 4) + 8] = np->rect.position.x + np->rect.size.x - np->margin[MARGIN_RIGHT]; + buffer[(3 * 4 * 4) + 8] = np->rect.position.x + np->rect.size.x - np->margin[MARGIN_RIGHT] * screen_scale; buffer[(3 * 4 * 4) + 9] = np->rect.position.y + np->rect.size.y; buffer[(3 * 4 * 4) + 10] = (source.position.x + source.size.x - np->margin[MARGIN_RIGHT]) * texpixel_size.x; diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp index 088ce3d198..f712219a64 100644 --- a/drivers/gles2/rasterizer_scene_gles2.cpp +++ b/drivers/gles2/rasterizer_scene_gles2.cpp @@ -131,7 +131,7 @@ void RasterizerSceneGLES2::shadow_atlas_set_size(RID p_atlas, int p_size) { //maximum compatibility, renderbuffer and RGBA shadow glGenRenderbuffers(1, &shadow_atlas->depth); - glBindRenderbuffer(GL_RENDERBUFFER, directional_shadow.depth); + glBindRenderbuffer(GL_RENDERBUFFER, shadow_atlas->depth); glRenderbufferStorage(GL_RENDERBUFFER, storage->config.depth_internalformat, shadow_atlas->size, shadow_atlas->size); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, shadow_atlas->depth); @@ -3769,6 +3769,10 @@ void RasterizerSceneGLES2::render_shadow(RID p_light, RID p_shadow_atlas, int p_ glEnable(GL_SCISSOR_TEST); glClearDepth(1.0f); glClear(GL_DEPTH_BUFFER_BIT); + if (storage->config.use_rgba_3d_shadows) { + glClearColor(1.0, 1.0, 1.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + } glDisable(GL_SCISSOR_TEST); if (light->reverse_cull) { diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp index 451d6adaa9..b55b623632 100644 --- a/drivers/gles2/rasterizer_storage_gles2.cpp +++ b/drivers/gles2/rasterizer_storage_gles2.cpp @@ -114,7 +114,7 @@ void RasterizerStorageGLES2::bind_quad_array() const { glEnableVertexAttribArray(VS::ARRAY_TEX_UV); } -Ref<Image> RasterizerStorageGLES2::_get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, uint32_t p_flags, Image::Format &r_real_format, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_compressed, bool p_will_need_resize) const { +Ref<Image> RasterizerStorageGLES2::_get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, uint32_t p_flags, Image::Format &r_real_format, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_compressed, bool p_force_decompress) const { r_gl_format = 0; Ref<Image> image = p_image; @@ -261,7 +261,7 @@ Ref<Image> RasterizerStorageGLES2::_get_gl_image_and_format(const Ref<Image> &p_ } break; case Image::FORMAT_DXT1: { - if (config.s3tc_supported && !p_will_need_resize) { + if (config.s3tc_supported) { r_gl_internal_format = _EXT_COMPRESSED_RGBA_S3TC_DXT1_EXT; r_gl_format = GL_RGBA; r_gl_type = GL_UNSIGNED_BYTE; @@ -273,7 +273,7 @@ Ref<Image> RasterizerStorageGLES2::_get_gl_image_and_format(const Ref<Image> &p_ } break; case Image::FORMAT_DXT3: { - if (config.s3tc_supported && !p_will_need_resize) { + if (config.s3tc_supported) { r_gl_internal_format = _EXT_COMPRESSED_RGBA_S3TC_DXT3_EXT; r_gl_format = GL_RGBA; r_gl_type = GL_UNSIGNED_BYTE; @@ -285,7 +285,7 @@ Ref<Image> RasterizerStorageGLES2::_get_gl_image_and_format(const Ref<Image> &p_ } break; case Image::FORMAT_DXT5: { - if (config.s3tc_supported && !p_will_need_resize) { + if (config.s3tc_supported) { r_gl_internal_format = _EXT_COMPRESSED_RGBA_S3TC_DXT5_EXT; r_gl_format = GL_RGBA; r_gl_type = GL_UNSIGNED_BYTE; @@ -424,7 +424,7 @@ Ref<Image> RasterizerStorageGLES2::_get_gl_image_and_format(const Ref<Image> &p_ } break; case Image::FORMAT_ETC: { - if (config.etc1_supported && !p_will_need_resize) { + if (config.etc1_supported) { r_gl_internal_format = _EXT_ETC1_RGB8_OES; r_gl_format = GL_RGBA; r_gl_type = GL_UNSIGNED_BYTE; @@ -467,7 +467,7 @@ Ref<Image> RasterizerStorageGLES2::_get_gl_image_and_format(const Ref<Image> &p_ } } - if (need_decompress) { + if (need_decompress || p_force_decompress) { if (!image.is_null()) { @@ -638,7 +638,7 @@ void RasterizerStorageGLES2::texture_set_data(RID p_texture, const Ref<Image> &p if (texture->resize_to_po2) { if (p_image->is_compressed()) { - ERR_PRINTS("Texture '" + texture->path + "' was required to be a power of 2 (because it uses either mipmaps or repeat), so it was decompressed. This will hurt performance and memory usage."); + ERR_PRINTS("Texture '" + texture->path + "' is required to be a power of 2 because it uses either mipmaps or repeat, so it was decompressed. This will hurt performance and memory usage."); } if (img == p_image) { @@ -659,12 +659,13 @@ void RasterizerStorageGLES2::texture_set_data(RID p_texture, const Ref<Image> &p img->resize(texture->alloc_width, texture->alloc_height, Image::INTERPOLATE_BILINEAR); } - }; + } GLenum blit_target = (texture->target == GL_TEXTURE_CUBE_MAP) ? _cube_side_enum[p_layer] : GL_TEXTURE_2D; texture->data_size = img->get_data().size(); PoolVector<uint8_t>::Read read = img->get_data().read(); + ERR_FAIL_COND(!read.ptr()); glActiveTexture(GL_TEXTURE0); glBindTexture(texture->target, texture->tex_id); @@ -718,7 +719,7 @@ void RasterizerStorageGLES2::texture_set_data(RID p_texture, const Ref<Image> &p int size, ofs; img->get_mipmap_offset_and_size(i, ofs, size); - if (texture->compressed) { + if (compressed) { glPixelStorei(GL_UNPACK_ALIGNMENT, 4); int bw = w; @@ -3236,12 +3237,14 @@ Color RasterizerStorageGLES2::multimesh_instance_get_custom_data(RID p_multimesh void RasterizerStorageGLES2::multimesh_set_as_bulk_array(RID p_multimesh, const PoolVector<float> &p_array) { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND(!multimesh); + ERR_FAIL_COND(!multimesh->data.ptr()); int dsize = multimesh->data.size(); ERR_FAIL_COND(dsize != p_array.size()); PoolVector<float>::Read r = p_array.read(); + ERR_FAIL_COND(!r.ptr()); copymem(multimesh->data.ptrw(), r.ptr(), dsize * sizeof(float)); multimesh->dirty_data = true; @@ -4733,21 +4736,39 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glFramebufferTexture2DMultisample(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->color, 0, msaa); + glFramebufferTexture2DMultisample(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->multisample_color, 0, msaa); #endif GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) { + // Delete allocated resources and default to no MSAA + WARN_PRINT_ONCE("Cannot allocate back framebuffer for MSAA"); printf("err status: %x\n", status); - _render_target_clear(rt); - ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE); + config.multisample_supported = false; + rt->multisample_active = false; + + glDeleteFramebuffers(1, &rt->multisample_fbo); + rt->multisample_fbo = 0; + + glDeleteRenderbuffers(1, &rt->multisample_depth); + rt->multisample_depth = 0; +#ifdef ANDROID_ENABLED + glDeleteTextures(1, &rt->multisample_color); +#else + glDeleteRenderbuffers(1, &rt->multisample_color); +#endif + rt->multisample_color = 0; } glBindRenderbuffer(GL_RENDERBUFFER, 0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); +#ifdef ANDROID_ENABLED + glBindTexture(GL_TEXTURE_2D, 0); +#endif } else -#endif +#endif // JAVASCRIPT_ENABLED { rt->multisample_active = false; } @@ -4983,10 +5004,10 @@ void RasterizerStorageGLES2::_render_target_clear(RenderTarget *rt) { glDeleteRenderbuffers(1, &rt->multisample_depth); rt->multisample_depth = 0; -#ifdef GLES_OVER_GL - glDeleteRenderbuffers(1, &rt->multisample_color); -#else +#ifdef ANDROID_ENABLED glDeleteTextures(1, &rt->multisample_color); +#else + glDeleteRenderbuffers(1, &rt->multisample_color); #endif rt->multisample_color = 0; } @@ -5732,7 +5753,7 @@ void RasterizerStorageGLES2::initialize() { config.float_texture_supported = config.extensions.has("GL_ARB_texture_float") || config.extensions.has("GL_OES_texture_float"); config.s3tc_supported = config.extensions.has("GL_EXT_texture_compression_s3tc") || config.extensions.has("WEBGL_compressed_texture_s3tc"); config.etc1_supported = config.extensions.has("GL_OES_compressed_ETC1_RGB8_texture") || config.extensions.has("WEBGL_compressed_texture_etc1"); - config.pvrtc_supported = config.extensions.has("IMG_texture_compression_pvrtc"); + config.pvrtc_supported = config.extensions.has("IMG_texture_compression_pvrtc") || config.extensions.has("WEBGL_compressed_texture_pvrtc"); config.support_npot_repeat_mipmap = config.extensions.has("GL_OES_texture_npot"); #endif @@ -5771,7 +5792,7 @@ void RasterizerStorageGLES2::initialize() { config.support_depth_cubemaps = true; #else config.use_rgba_2d_shadows = !(config.float_texture_supported && config.extensions.has("GL_EXT_texture_rg")); - config.support_depth_texture = config.extensions.has("GL_OES_depth_texture"); + config.support_depth_texture = config.extensions.has("GL_OES_depth_texture") || config.extensions.has("WEBGL_depth_texture"); config.use_rgba_3d_shadows = !config.support_depth_texture; config.support_depth_cubemaps = config.extensions.has("GL_OES_depth_texture_cube_map"); #endif @@ -5798,7 +5819,7 @@ void RasterizerStorageGLES2::initialize() { #endif config.rgtc_supported = config.extensions.has("GL_EXT_texture_compression_rgtc") || config.extensions.has("GL_ARB_texture_compression_rgtc") || config.extensions.has("EXT_texture_compression_rgtc"); - config.bptc_supported = config.extensions.has("GL_ARB_texture_compression_bptc"); + config.bptc_supported = config.extensions.has("GL_ARB_texture_compression_bptc") || config.extensions.has("EXT_texture_compression_bptc"); //determine formats for depth textures (or renderbuffers) if (config.support_depth_texture) { diff --git a/drivers/gles2/rasterizer_storage_gles2.h b/drivers/gles2/rasterizer_storage_gles2.h index 2e78910614..27f06074ed 100644 --- a/drivers/gles2/rasterizer_storage_gles2.h +++ b/drivers/gles2/rasterizer_storage_gles2.h @@ -337,7 +337,7 @@ public: mutable RID_Owner<Texture> texture_owner; - Ref<Image> _get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, uint32_t p_flags, Image::Format &r_real_format, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_compressed, bool p_will_need_resize) const; + Ref<Image> _get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, uint32_t p_flags, Image::Format &r_real_format, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_compressed, bool p_force_decompress) const; virtual RID texture_create(); virtual void texture_allocate(RID p_texture, int p_width, int p_height, int p_depth_3d, Image::Format p_format, VS::TextureType p_type, uint32_t p_flags = VS::TEXTURE_FLAGS_DEFAULT); diff --git a/drivers/gles2/shaders/scene.glsl b/drivers/gles2/shaders/scene.glsl index 57c2d886b3..e36e776881 100644 --- a/drivers/gles2/shaders/scene.glsl +++ b/drivers/gles2/shaders/scene.glsl @@ -729,9 +729,6 @@ uniform highp vec2 viewport_size; uniform vec2 screen_pixel_size; #endif -// I think supporting this in GLES2 is difficult -// uniform highp sampler2D depth_buffer; - #if defined(SCREEN_TEXTURE_USED) uniform highp sampler2D screen_texture; //texunit:-4 #endif diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index edffe852a2..e09ba755ea 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -548,8 +548,10 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur if (line->width <= 1) { Vector2 verts[2] = { - Vector2(line->from.x, line->from.y), - Vector2(line->to.x, line->to.y) + // Offset the line slightly to make sure we always draw the pixel at the from coordinate. + // Without this, corners of rectangles might be missing a pixel. (See diamond exit rule and #32657) + Vector2(Math::floor(line->from.x) + 0.5, Math::floor(line->from.y) + 0.5), + Vector2(Math::floor(line->to.x) + 0.5, Math::floor(line->to.y) + 0.5) }; #ifdef GLES_OVER_GL diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 35f414cf09..519fdf2b3b 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -1093,7 +1093,7 @@ void RasterizerSceneGLES3::gi_probe_instance_set_bounds(RID p_probe, const Vecto //////////////////////////// //////////////////////////// -bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material *p_material, bool p_alpha_pass) { +bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material *p_material, bool p_depth_pass, bool p_alpha_pass) { /* this is handled outside if (p_material->shader->spatial.cull_mode == RasterizerStorageGLES3::Shader::Spatial::CULL_MODE_DISABLED) { @@ -1121,7 +1121,7 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material *p_m if (state.current_depth_draw != p_material->shader->spatial.depth_draw_mode) { switch (p_material->shader->spatial.depth_draw_mode) { case RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS: { - glDepthMask(GL_TRUE); + glDepthMask(p_depth_pass); // If some transparent objects write to depth, we need to re-copy depth texture when we need it if (p_alpha_pass && !state.used_depth_prepass) { state.prepared_depth_texture = false; @@ -2241,7 +2241,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_ storage->info.render.material_switch_count++; - rebind = _setup_material(material, p_alpha_pass); + rebind = _setup_material(material, use_opaque_prepass, p_alpha_pass); if (rebind) { storage->info.render.shader_rebind_count++; diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h index 3d09adcfeb..e6d2449653 100644 --- a/drivers/gles3/rasterizer_scene_gles3.h +++ b/drivers/gles3/rasterizer_scene_gles3.h @@ -832,7 +832,7 @@ public: _FORCE_INLINE_ void _set_cull(bool p_front, bool p_disabled, bool p_reverse_cull); - _FORCE_INLINE_ bool _setup_material(RasterizerStorageGLES3::Material *p_material, bool p_alpha_pass); + _FORCE_INLINE_ bool _setup_material(RasterizerStorageGLES3::Material *p_material, bool p_depth_pass, bool p_alpha_pass); _FORCE_INLINE_ void _setup_geometry(RenderList::Element *e, const Transform &p_view_transform); _FORCE_INLINE_ void _render_geometry(RenderList::Element *e); _FORCE_INLINE_ void _setup_light(RenderList::Element *e, const Transform &p_view_transform); diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index 95be67a5b7..f94020b918 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -135,13 +135,13 @@ void glTexStorage2DCustom(GLenum target, GLsizei levels, GLenum internalformat, GLuint RasterizerStorageGLES3::system_fbo = 0; -Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, uint32_t p_flags, Image::Format &r_real_format, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_compressed, bool &srgb) const { +Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, uint32_t p_flags, Image::Format &r_real_format, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_compressed, bool &r_srgb, bool p_force_decompress) const { r_compressed = false; r_gl_format = 0; r_real_format = p_format; Ref<Image> image = p_image; - srgb = false; + r_srgb = false; bool need_decompress = false; @@ -188,7 +188,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_ r_gl_internal_format = (config.srgb_decode_supported || (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) ? GL_SRGB8 : GL_RGB8; r_gl_format = GL_RGB; r_gl_type = GL_UNSIGNED_BYTE; - srgb = true; + r_srgb = true; } break; case Image::FORMAT_RGBA8: { @@ -196,7 +196,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_ r_gl_format = GL_RGBA; r_gl_internal_format = (config.srgb_decode_supported || (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) ? GL_SRGB8_ALPHA8 : GL_RGBA8; r_gl_type = GL_UNSIGNED_BYTE; - srgb = true; + r_srgb = true; } break; case Image::FORMAT_RGBA4444: { @@ -278,7 +278,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_ r_gl_format = GL_RGBA; r_gl_type = GL_UNSIGNED_BYTE; r_compressed = true; - srgb = true; + r_srgb = true; } else { @@ -294,7 +294,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_ r_gl_format = GL_RGBA; r_gl_type = GL_UNSIGNED_BYTE; r_compressed = true; - srgb = true; + r_srgb = true; } else { @@ -310,7 +310,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_ r_gl_format = GL_RGBA; r_gl_type = GL_UNSIGNED_BYTE; r_compressed = true; - srgb = true; + r_srgb = true; } else { @@ -355,7 +355,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_ r_gl_format = GL_RGBA; r_gl_type = GL_UNSIGNED_BYTE; r_compressed = true; - srgb = true; + r_srgb = true; } else { @@ -395,7 +395,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_ r_gl_format = GL_RGBA; r_gl_type = GL_UNSIGNED_BYTE; r_compressed = true; - srgb = true; + r_srgb = true; } else { @@ -410,7 +410,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_ r_gl_format = GL_RGBA; r_gl_type = GL_UNSIGNED_BYTE; r_compressed = true; - srgb = true; + r_srgb = true; } else { @@ -426,7 +426,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_ r_gl_format = GL_RGBA; r_gl_type = GL_UNSIGNED_BYTE; r_compressed = true; - srgb = true; + r_srgb = true; } else { @@ -442,7 +442,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_ r_gl_format = GL_RGBA; r_gl_type = GL_UNSIGNED_BYTE; r_compressed = true; - srgb = true; + r_srgb = true; } else { @@ -527,7 +527,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_ r_gl_format = GL_RGB; r_gl_type = GL_UNSIGNED_BYTE; r_compressed = true; - srgb = true; + r_srgb = true; } else { @@ -542,7 +542,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_ r_gl_format = GL_RGBA; r_gl_type = GL_UNSIGNED_BYTE; r_compressed = true; - srgb = true; + r_srgb = true; } else { @@ -557,7 +557,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_ r_gl_format = GL_RGBA; r_gl_type = GL_UNSIGNED_BYTE; r_compressed = true; - srgb = true; + r_srgb = true; } else { @@ -570,7 +570,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_ } } - if (need_decompress) { + if (need_decompress || p_force_decompress) { if (!image.is_null()) { image = image->duplicate(); @@ -584,7 +584,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_ r_gl_type = GL_UNSIGNED_BYTE; r_compressed = false; r_real_format = Image::FORMAT_RGBA8; - srgb = true; + r_srgb = true; return image; } @@ -677,8 +677,22 @@ void RasterizerStorageGLES3::texture_allocate(RID p_texture, int p_width, int p_ } break; } + texture->is_npot_repeat_mipmap = false; +#ifdef JAVASCRIPT_ENABLED + // WebGL 2.0 on browsers does not seem to properly support compressed non power-of-two (NPOT) + // textures with repeat/mipmaps, even though NPOT textures should be supported as per the spec. + // Force decompressing them to work it around on WebGL 2.0 at a performance cost (GH-33058). + int po2_width = next_power_of_2(p_width); + int po2_height = next_power_of_2(p_height); + bool is_po2 = p_width == po2_width && p_height == po2_height; + + if (!is_po2 && (p_flags & VS::TEXTURE_FLAG_REPEAT || p_flags & VS::TEXTURE_FLAG_MIPMAPS)) { + texture->is_npot_repeat_mipmap = true; + } +#endif // JAVASCRIPT_ENABLED + Image::Format real_format; - _get_gl_image_and_format(Ref<Image>(), texture->format, texture->flags, real_format, format, internal_format, type, compressed, srgb); + _get_gl_image_and_format(Ref<Image>(), texture->format, texture->flags, real_format, format, internal_format, type, compressed, srgb, texture->is_npot_repeat_mipmap); texture->alloc_width = texture->width; texture->alloc_height = texture->height; @@ -753,13 +767,9 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Ref<Image> &p if (config.keep_original_textures && !(texture->flags & VS::TEXTURE_FLAG_USED_FOR_STREAMING)) { texture->images.write[p_layer] = p_image; } -#ifndef GLES_OVER_GL - if (p_image->is_compressed() && p_image->has_mipmaps() && !p_image->is_size_po2()) { - ERR_PRINTS("Texuture '" + texture->path + "' is compressed, has mipmaps but is not of powerf-of-2 size. This does not work on OpenGL ES 3.0."); - } -#endif + Image::Format real_format; - Ref<Image> img = _get_gl_image_and_format(p_image, p_image->get_format(), texture->flags, real_format, format, internal_format, type, compressed, srgb); + Ref<Image> img = _get_gl_image_and_format(p_image, p_image->get_format(), texture->flags, real_format, format, internal_format, type, compressed, srgb, texture->is_npot_repeat_mipmap); if (config.shrink_textures_x2 && (p_image->has_mipmaps() || !p_image->is_compressed()) && !(texture->flags & VS::TEXTURE_FLAG_USED_FOR_STREAMING)) { @@ -795,6 +805,7 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Ref<Image> &p texture->data_size = img->get_data().size(); PoolVector<uint8_t>::Read read = img->get_data().read(); + ERR_FAIL_COND(!read.ptr()); glActiveTexture(GL_TEXTURE0); glBindTexture(texture->target, texture->tex_id); @@ -992,7 +1003,7 @@ void RasterizerStorageGLES3::texture_set_data_partial(RID p_texture, const Ref<I } Image::Format real_format; - Ref<Image> img = _get_gl_image_and_format(p_sub_img, p_sub_img->get_format(), texture->flags, real_format, format, internal_format, type, compressed, srgb); + Ref<Image> img = _get_gl_image_and_format(p_sub_img, p_sub_img->get_format(), texture->flags, real_format, format, internal_format, type, compressed, srgb, texture->is_npot_repeat_mipmap); GLenum blit_target = GL_TEXTURE_2D; @@ -1091,7 +1102,8 @@ Ref<Image> RasterizerStorageGLES3::texture_get_data(RID p_texture, int p_layer) gl_internal_format, gl_type, compressed, - srgb); + srgb, + texture->is_npot_repeat_mipmap); PoolVector<uint8_t> data; @@ -1197,7 +1209,7 @@ Ref<Image> RasterizerStorageGLES3::texture_get_data(RID p_texture, int p_layer) GLenum gl_type; bool compressed; bool srgb; - _get_gl_image_and_format(Ref<Image>(), texture->format, texture->flags, real_format, gl_format, gl_internal_format, gl_type, compressed, srgb); + _get_gl_image_and_format(Ref<Image>(), texture->format, texture->flags, real_format, gl_format, gl_internal_format, gl_type, compressed, srgb, false); PoolVector<uint8_t> data; @@ -1267,7 +1279,7 @@ Ref<Image> RasterizerStorageGLES3::texture_get_data(RID p_texture, int p_layer) GLenum gl_type; bool compressed; bool srgb; - _get_gl_image_and_format(Ref<Image>(), texture->format, texture->flags, real_format, gl_format, gl_internal_format, gl_type, compressed, srgb); + _get_gl_image_and_format(Ref<Image>(), texture->format, texture->flags, real_format, gl_format, gl_internal_format, gl_type, compressed, srgb, texture->is_npot_repeat_mipmap); PoolVector<uint8_t> data; @@ -4718,6 +4730,7 @@ void RasterizerStorageGLES3::multimesh_set_as_bulk_array(RID p_multimesh, const MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); ERR_FAIL_COND(!multimesh); + ERR_FAIL_COND(!multimesh->data.ptr()); int dsize = multimesh->data.size(); @@ -4854,15 +4867,16 @@ RID RasterizerStorageGLES3::immediate_create() { return immediate_owner.make_rid(im); } -void RasterizerStorageGLES3::immediate_begin(RID p_immediate, VS::PrimitiveType p_rimitive, RID p_texture) { +void RasterizerStorageGLES3::immediate_begin(RID p_immediate, VS::PrimitiveType p_primitive, RID p_texture) { + ERR_FAIL_INDEX(p_primitive, (int)VS::PRIMITIVE_MAX); Immediate *im = immediate_owner.get(p_immediate); ERR_FAIL_COND(!im); ERR_FAIL_COND(im->building); Immediate::Chunk ic; ic.texture = p_texture; - ic.primitive = p_rimitive; + ic.primitive = p_primitive; im->chunks.push_back(ic); im->mask = 0; im->building = true; diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h index 84632308b4..3b1021d0e1 100644 --- a/drivers/gles3/rasterizer_storage_gles3.h +++ b/drivers/gles3/rasterizer_storage_gles3.h @@ -266,6 +266,8 @@ public: int mipmaps; + bool is_npot_repeat_mipmap; + bool active; GLuint tex_id; @@ -342,7 +344,7 @@ public: mutable RID_Owner<Texture> texture_owner; - Ref<Image> _get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, uint32_t p_flags, Image::Format &r_real_format, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_compressed, bool &srgb) const; + Ref<Image> _get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, uint32_t p_flags, Image::Format &r_real_format, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_compressed, bool &r_srgb, bool p_force_decompress) const; virtual RID texture_create(); virtual void texture_allocate(RID p_texture, int p_width, int p_height, int p_depth_3d, Image::Format p_format, VS::TextureType p_type, uint32_t p_flags = VS::TEXTURE_FLAGS_DEFAULT); @@ -869,7 +871,7 @@ public: mutable RID_Owner<Immediate> immediate_owner; virtual RID immediate_create(); - virtual void immediate_begin(RID p_immediate, VS::PrimitiveType p_rimitive, RID p_texture = RID()); + virtual void immediate_begin(RID p_immediate, VS::PrimitiveType p_primitive, RID p_texture = RID()); virtual void immediate_vertex(RID p_immediate, const Vector3 &p_vertex); virtual void immediate_normal(RID p_immediate, const Vector3 &p_normal); virtual void immediate_tangent(RID p_immediate, const Plane &p_tangent); diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl index e83f53d648..7255b0425c 100644 --- a/drivers/gles3/shaders/canvas.glsl +++ b/drivers/gles3/shaders/canvas.glsl @@ -380,14 +380,16 @@ uniform bool np_draw_center; // left top right bottom in pixel coordinates uniform vec4 np_margins; -float map_ninepatch_axis(float pixel, float draw_size, float tex_pixel_size, float margin_begin, float margin_end, int np_repeat, inout int draw_center) { +float map_ninepatch_axis(float pixel, float draw_size, float tex_pixel_size, float margin_begin, float margin_end, float s_ratio, int np_repeat, inout int draw_center) { float tex_size = 1.0 / tex_pixel_size; - if (pixel < margin_begin) { - return pixel * tex_pixel_size; - } else if (pixel >= draw_size - margin_end) { - return (tex_size - (draw_size - pixel)) * tex_pixel_size; + float screen_margin_begin = margin_begin / s_ratio; + float screen_margin_end = margin_end / s_ratio; + if (pixel < screen_margin_begin) { + return pixel * s_ratio * tex_pixel_size; + } else if (pixel >= draw_size - screen_margin_end) { + return (tex_size - (draw_size - pixel) * s_ratio) * tex_pixel_size; } else { if (!np_draw_center) { draw_center--; @@ -395,22 +397,22 @@ float map_ninepatch_axis(float pixel, float draw_size, float tex_pixel_size, flo if (np_repeat == 0) { //stretch //convert to ratio - float ratio = (pixel - margin_begin) / (draw_size - margin_begin - margin_end); + float ratio = (pixel - screen_margin_begin) / (draw_size - screen_margin_begin - screen_margin_end); //scale to source texture return (margin_begin + ratio * (tex_size - margin_begin - margin_end)) * tex_pixel_size; } else if (np_repeat == 1) { //tile //convert to ratio - float ofs = mod((pixel - margin_begin), tex_size - margin_begin - margin_end); + float ofs = mod((pixel - screen_margin_begin), tex_size - margin_begin - margin_end); //scale to source texture return (margin_begin + ofs) * tex_pixel_size; } else if (np_repeat == 2) { //tile fit //convert to ratio - float src_area = draw_size - margin_begin - margin_end; + float src_area = draw_size - screen_margin_begin - screen_margin_end; float dst_area = tex_size - margin_begin - margin_end; float scale = max(1.0, floor(src_area / max(dst_area, 0.0000001) + 0.5)); //convert to ratio - float ratio = (pixel - margin_begin) / src_area; + float ratio = (pixel - screen_margin_begin) / src_area; ratio = mod(ratio * scale, 1.0); return (margin_begin + ratio * dst_area) * tex_pixel_size; } @@ -432,9 +434,11 @@ void main() { #ifdef USE_NINEPATCH int draw_center = 2; + float s_ratio = max((1.0 / color_texpixel_size.x) / abs(dst_rect.z), (1.0 / color_texpixel_size.y) / abs(dst_rect.w)); + s_ratio = max(1.0, s_ratio); uv = vec2( - map_ninepatch_axis(pixel_size_interp.x, abs(dst_rect.z), color_texpixel_size.x, np_margins.x, np_margins.z, np_repeat_h, draw_center), - map_ninepatch_axis(pixel_size_interp.y, abs(dst_rect.w), color_texpixel_size.y, np_margins.y, np_margins.w, np_repeat_v, draw_center)); + map_ninepatch_axis(pixel_size_interp.x, abs(dst_rect.z), color_texpixel_size.x, np_margins.x, np_margins.z, s_ratio, np_repeat_h, draw_center), + map_ninepatch_axis(pixel_size_interp.y, abs(dst_rect.w), color_texpixel_size.y, np_margins.y, np_margins.w, s_ratio, np_repeat_v, draw_center)); if (draw_center == 0) { color.a = 0.0; diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp index 8be1d5d8f3..99425d5002 100644 --- a/drivers/unix/file_access_unix.cpp +++ b/drivers/unix/file_access_unix.cpp @@ -56,6 +56,12 @@ #define S_ISREG(m) ((m)&S_IFREG) #endif +#ifndef NO_FCNTL +#include <fcntl.h> +#else +#include <sys/ioctl.h> +#endif + void FileAccessUnix::check_errors() const { ERR_FAIL_COND_MSG(!f, "File must be opened before use."); @@ -123,11 +129,24 @@ Error FileAccessUnix::_open(const String &p_path, int p_mode_flags) { } break; } return last_error; - } else { - last_error = OK; - flags = p_mode_flags; - return OK; } + + // Set close on exec to avoid leaking it to subprocesses. + int fd = fileno(f); + + if (fd != -1) { +#if defined(NO_FCNTL) + unsigned long par = 0; + ioctl(fd, FIOCLEX, &par); +#else + int opts = fcntl(fd, F_GETFD); + fcntl(fd, F_SETFD, opts | FD_CLOEXEC); +#endif + } + + last_error = OK; + flags = p_mode_flags; + return OK; } void FileAccessUnix::close() { diff --git a/drivers/unix/net_socket_posix.cpp b/drivers/unix/net_socket_posix.cpp index da46b393c6..5f99a40c79 100644 --- a/drivers/unix/net_socket_posix.cpp +++ b/drivers/unix/net_socket_posix.cpp @@ -70,6 +70,7 @@ #define SOCK_CBUF(x) x #define SOCK_IOCTL ioctl #define SOCK_CLOSE ::close +#define SOCK_CONNECT(p_sock, p_addr, p_addr_len) ::connect(p_sock, p_addr, p_addr_len) /* Windows */ #elif defined(WINDOWS_ENABLED) @@ -83,6 +84,9 @@ #define SOCK_CBUF(x) (const char *)(x) #define SOCK_IOCTL ioctlsocket #define SOCK_CLOSE closesocket +// connect is broken on windows under certain conditions, reasons unknown: +// See https://github.com/godotengine/webrtc-native/issues/6 +#define SOCK_CONNECT(p_sock, p_addr, p_addr_len) ::WSAConnect(p_sock, p_addr, p_addr_len, NULL, NULL, NULL, NULL) // Workaround missing flag in MinGW #if defined(__MINGW32__) && !defined(SIO_UDP_NETRESET) @@ -409,7 +413,7 @@ Error NetSocketPosix::connect_to_host(IP_Address p_host, uint16_t p_port) { struct sockaddr_storage addr; size_t addr_size = _set_addr_storage(&addr, p_host, p_port, _ip_type); - if (::connect(_sock, (struct sockaddr *)&addr, addr_size) != 0) { + if (SOCK_CONNECT(_sock, (struct sockaddr *)&addr, addr_size) != 0) { NetError err = _get_socket_error(); diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp index b3d98a0648..25dee6aedb 100644 --- a/drivers/unix/os_unix.cpp +++ b/drivers/unix/os_unix.cpp @@ -126,7 +126,9 @@ void OS_Unix::initialize_core() { RWLockDummy::make_default(); #else ThreadPosix::make_default(); +#if !defined(OSX_ENABLED) && !defined(IPHONE_ENABLED) SemaphorePosix::make_default(); +#endif MutexPosix::make_default(); RWLockPosix::make_default(); #endif diff --git a/drivers/unix/semaphore_posix.cpp b/drivers/unix/semaphore_posix.cpp index 5aa51d77d1..fc2d5b0dfe 100644 --- a/drivers/unix/semaphore_posix.cpp +++ b/drivers/unix/semaphore_posix.cpp @@ -30,7 +30,7 @@ #include "semaphore_posix.h" -#if defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED) +#if (defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED)) && !defined(OSX_ENABLED) && !defined(IPHONE_ENABLED) #include "core/os/memory.h" #include <errno.h> diff --git a/drivers/unix/semaphore_posix.h b/drivers/unix/semaphore_posix.h index 83e75c9a82..8aff01fc27 100644 --- a/drivers/unix/semaphore_posix.h +++ b/drivers/unix/semaphore_posix.h @@ -33,7 +33,7 @@ #include "core/os/semaphore.h" -#if defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED) +#if (defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED)) && !defined(OSX_ENABLED) && !defined(IPHONE_ENABLED) #include <semaphore.h> diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp index adc3cc8d65..336d5c5814 100644 --- a/drivers/wasapi/audio_driver_wasapi.cpp +++ b/drivers/wasapi/audio_driver_wasapi.cpp @@ -76,7 +76,7 @@ public: CMMNotificationClient() : _cRef(1), _pEnumerator(NULL) {} - ~CMMNotificationClient() { + virtual ~CMMNotificationClient() { if ((_pEnumerator) != NULL) { (_pEnumerator)->Release(); (_pEnumerator) = NULL; |