summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/alsa/SCsub3
-rw-r--r--drivers/alsa/asound-so_wrap.c96
-rw-r--r--drivers/alsa/asound-so_wrap.h40
-rw-r--r--drivers/alsa/audio_driver_alsa.cpp57
-rw-r--r--drivers/alsa/audio_driver_alsa.h40
-rw-r--r--drivers/alsamidi/midi_driver_alsamidi.h5
-rw-r--r--drivers/coreaudio/audio_driver_coreaudio.cpp76
-rw-r--r--drivers/coreaudio/audio_driver_coreaudio.h50
-rw-r--r--drivers/gles3/environment/fog.cpp2
-rw-r--r--drivers/gles3/environment/fog.h2
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp194
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.h18
-rw-r--r--drivers/gles3/rasterizer_gles3.cpp12
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp49
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.h3
-rw-r--r--drivers/gles3/shader_gles3.cpp2
-rw-r--r--drivers/gles3/shaders/canvas.glsl20
-rw-r--r--drivers/gles3/shaders/canvas_uniforms_inc.glsl3
-rw-r--r--drivers/gles3/shaders/scene.glsl23
-rw-r--r--drivers/gles3/shaders/skeleton.glsl17
-rw-r--r--drivers/gles3/shaders/sky.glsl38
-rw-r--r--drivers/gles3/shaders/stdlib_inc.glsl14
-rw-r--r--drivers/gles3/storage/config.cpp4
-rw-r--r--drivers/gles3/storage/config.h3
-rw-r--r--drivers/gles3/storage/light_storage.cpp11
-rw-r--r--drivers/gles3/storage/light_storage.h14
-rw-r--r--drivers/gles3/storage/material_storage.cpp29
-rw-r--r--drivers/gles3/storage/mesh_storage.cpp37
-rw-r--r--drivers/gles3/storage/mesh_storage.h2
-rw-r--r--drivers/gles3/storage/texture_storage.cpp86
-rw-r--r--drivers/gles3/storage/texture_storage.h40
-rw-r--r--drivers/gles3/storage/utilities.cpp3
-rw-r--r--drivers/pulseaudio/SCsub3
-rw-r--r--drivers/pulseaudio/audio_driver_pulseaudio.cpp155
-rw-r--r--drivers/pulseaudio/audio_driver_pulseaudio.h59
-rw-r--r--drivers/pulseaudio/pulse-so_wrap.c152
-rw-r--r--drivers/pulseaudio/pulse-so_wrap.h110
-rw-r--r--drivers/unix/dir_access_unix.cpp4
-rw-r--r--drivers/unix/file_access_unix.cpp4
-rw-r--r--drivers/unix/file_access_unix.h2
-rw-r--r--drivers/unix/os_unix.cpp19
-rw-r--r--drivers/unix/os_unix.h4
-rw-r--r--drivers/vulkan/rendering_device_vulkan.cpp141
-rw-r--r--drivers/vulkan/rendering_device_vulkan.h4
-rw-r--r--drivers/vulkan/vulkan_context.cpp161
-rw-r--r--drivers/vulkan/vulkan_context.h1
-rw-r--r--drivers/wasapi/audio_driver_wasapi.cpp172
-rw-r--r--drivers/wasapi/audio_driver_wasapi.h59
-rw-r--r--drivers/windows/file_access_windows.cpp50
-rw-r--r--drivers/windows/file_access_windows.h8
-rw-r--r--drivers/xaudio2/audio_driver_xaudio2.cpp4
-rw-r--r--drivers/xaudio2/audio_driver_xaudio2.h23
52 files changed, 1190 insertions, 938 deletions
diff --git a/drivers/alsa/SCsub b/drivers/alsa/SCsub
index 1d76bb18c4..f17acb0f91 100644
--- a/drivers/alsa/SCsub
+++ b/drivers/alsa/SCsub
@@ -3,6 +3,7 @@
Import("env")
if "alsa" in env and env["alsa"]:
- env.add_source_files(env.drivers_sources, "asound-so_wrap.c")
+ if env["use_sowrap"]:
+ env.add_source_files(env.drivers_sources, "asound-so_wrap.c")
env.add_source_files(env.drivers_sources, "*.cpp")
diff --git a/drivers/alsa/asound-so_wrap.c b/drivers/alsa/asound-so_wrap.c
index 65624bcb70..ffe24d4313 100644
--- a/drivers/alsa/asound-so_wrap.c
+++ b/drivers/alsa/asound-so_wrap.c
@@ -1,12 +1,11 @@
// This file is generated. Do not edit!
// see https://github.com/hpvb/dynload-wrapper for details
-// generated by /home/hp/Projects/godot/pulse/generate-wrapper.py 0.3 on 2021-02-22 19:22:12
-// flags: /home/hp/Projects/godot/pulse/generate-wrapper.py --include /usr/include/alsa/asoundlib.h --sys-include <alsa/asoundlib.h> --soname libasound.so.2 --init-name asound --omit-prefix snd_pcm_sw_params_set_tstamp_type --omit-prefix snd_pcm_status_get_audio_htstamp_report --omit-prefix snd_pcm_sw_params_get_tstamp_type --omit-prefix snd_pcm_status_set_audio_htstamp_config --output-header asound-so_wrap.h --output-implementation asound-so_wrap.c
+// generated by generate-wrapper.py 0.3 on 2023-01-12 10:26:13
+// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/alsa/asoundlib.h --sys-include "thirdparty/linuxbsd_headers/alsa/asoundlib.h" --soname libasound.so.2 --init-name asound --omit-prefix snd_pcm_sw_params_set_tstamp_type --omit-prefix snd_pcm_status_get_audio_htstamp_report --omit-prefix snd_pcm_sw_params_get_tstamp_type --omit-prefix snd_pcm_status_set_audio_htstamp_config --output-header ./drivers/alsa/asound-so_wrap.h --output-implementation ./drivers/alsa/asound-so_wrap.c
//
#include <stdint.h>
#define snd_asoundlib_version snd_asoundlib_version_dylibloader_orig_asound
-#define snd_dlpath snd_dlpath_dylibloader_orig_asound
#define snd_dlopen snd_dlopen_dylibloader_orig_asound
#define snd_dlsym snd_dlsym_dylibloader_orig_asound
#define snd_dlclose snd_dlclose_dylibloader_orig_asound
@@ -40,7 +39,6 @@
#define snd_strerror snd_strerror_dylibloader_orig_asound
#define snd_lib_error_set_handler snd_lib_error_set_handler_dylibloader_orig_asound
#define snd_lib_error_set_local snd_lib_error_set_local_dylibloader_orig_asound
-#define snd_config_topdir snd_config_topdir_dylibloader_orig_asound
#define snd_config_top snd_config_top_dylibloader_orig_asound
#define snd_config_load snd_config_load_dylibloader_orig_asound
#define snd_config_load_override snd_config_load_override_dylibloader_orig_asound
@@ -58,9 +56,6 @@
#define snd_config_expand snd_config_expand_dylibloader_orig_asound
#define snd_config_evaluate snd_config_evaluate_dylibloader_orig_asound
#define snd_config_add snd_config_add_dylibloader_orig_asound
-#define snd_config_add_before snd_config_add_before_dylibloader_orig_asound
-#define snd_config_add_after snd_config_add_after_dylibloader_orig_asound
-#define snd_config_remove snd_config_remove_dylibloader_orig_asound
#define snd_config_delete snd_config_delete_dylibloader_orig_asound
#define snd_config_delete_compound_members snd_config_delete_compound_members_dylibloader_orig_asound
#define snd_config_copy snd_config_copy_dylibloader_orig_asound
@@ -78,7 +73,6 @@
#define snd_config_imake_safe_string snd_config_imake_safe_string_dylibloader_orig_asound
#define snd_config_imake_pointer snd_config_imake_pointer_dylibloader_orig_asound
#define snd_config_get_type snd_config_get_type_dylibloader_orig_asound
-#define snd_config_is_array snd_config_is_array_dylibloader_orig_asound
#define snd_config_set_id snd_config_set_id_dylibloader_orig_asound
#define snd_config_set_integer snd_config_set_integer_dylibloader_orig_asound
#define snd_config_set_integer64 snd_config_set_integer64_dylibloader_orig_asound
@@ -423,7 +417,6 @@
#define snd_pcm_areas_silence snd_pcm_areas_silence_dylibloader_orig_asound
#define snd_pcm_area_copy snd_pcm_area_copy_dylibloader_orig_asound
#define snd_pcm_areas_copy snd_pcm_areas_copy_dylibloader_orig_asound
-#define snd_pcm_areas_copy_wrap snd_pcm_areas_copy_wrap_dylibloader_orig_asound
#define snd_pcm_hook_get_pcm snd_pcm_hook_get_pcm_dylibloader_orig_asound
#define snd_pcm_hook_get_private snd_pcm_hook_get_private_dylibloader_orig_asound
#define snd_pcm_hook_set_private snd_pcm_hook_set_private_dylibloader_orig_asound
@@ -1015,7 +1008,6 @@
#define snd_mixer_selem_id_get_index snd_mixer_selem_id_get_index_dylibloader_orig_asound
#define snd_mixer_selem_id_set_name snd_mixer_selem_id_set_name_dylibloader_orig_asound
#define snd_mixer_selem_id_set_index snd_mixer_selem_id_set_index_dylibloader_orig_asound
-#define snd_mixer_selem_id_parse snd_mixer_selem_id_parse_dylibloader_orig_asound
#define snd_seq_open snd_seq_open_dylibloader_orig_asound
#define snd_seq_open_lconf snd_seq_open_lconf_dylibloader_orig_asound
#define snd_seq_name snd_seq_name_dylibloader_orig_asound
@@ -1284,9 +1276,8 @@
#define snd_midi_event_encode snd_midi_event_encode_dylibloader_orig_asound
#define snd_midi_event_encode_byte snd_midi_event_encode_byte_dylibloader_orig_asound
#define snd_midi_event_decode snd_midi_event_decode_dylibloader_orig_asound
-#include <alsa/asoundlib.h>
+#include "thirdparty/linuxbsd_headers/alsa/asoundlib.h"
#undef snd_asoundlib_version
-#undef snd_dlpath
#undef snd_dlopen
#undef snd_dlsym
#undef snd_dlclose
@@ -1320,7 +1311,6 @@
#undef snd_strerror
#undef snd_lib_error_set_handler
#undef snd_lib_error_set_local
-#undef snd_config_topdir
#undef snd_config_top
#undef snd_config_load
#undef snd_config_load_override
@@ -1338,9 +1328,6 @@
#undef snd_config_expand
#undef snd_config_evaluate
#undef snd_config_add
-#undef snd_config_add_before
-#undef snd_config_add_after
-#undef snd_config_remove
#undef snd_config_delete
#undef snd_config_delete_compound_members
#undef snd_config_copy
@@ -1358,7 +1345,6 @@
#undef snd_config_imake_safe_string
#undef snd_config_imake_pointer
#undef snd_config_get_type
-#undef snd_config_is_array
#undef snd_config_set_id
#undef snd_config_set_integer
#undef snd_config_set_integer64
@@ -1703,7 +1689,6 @@
#undef snd_pcm_areas_silence
#undef snd_pcm_area_copy
#undef snd_pcm_areas_copy
-#undef snd_pcm_areas_copy_wrap
#undef snd_pcm_hook_get_pcm
#undef snd_pcm_hook_get_private
#undef snd_pcm_hook_set_private
@@ -2295,7 +2280,6 @@
#undef snd_mixer_selem_id_get_index
#undef snd_mixer_selem_id_set_name
#undef snd_mixer_selem_id_set_index
-#undef snd_mixer_selem_id_parse
#undef snd_seq_open
#undef snd_seq_open_lconf
#undef snd_seq_name
@@ -2567,8 +2551,7 @@
#include <dlfcn.h>
#include <stdio.h>
const char* (*snd_asoundlib_version_dylibloader_wrapper_asound)( void);
-int (*snd_dlpath_dylibloader_wrapper_asound)( char*, size_t,const char*);
-void* (*snd_dlopen_dylibloader_wrapper_asound)(const char*, int, char*, size_t);
+void* (*snd_dlopen_dylibloader_wrapper_asound)(const char*, int);
void* (*snd_dlsym_dylibloader_wrapper_asound)( void*,const char*,const char*);
int (*snd_dlclose_dylibloader_wrapper_asound)( void*);
int (*snd_async_add_handler_dylibloader_wrapper_asound)( snd_async_handler_t**, int, snd_async_callback_t, void*);
@@ -2601,7 +2584,6 @@ int (*snd_output_flush_dylibloader_wrapper_asound)( snd_output_t*);
const char* (*snd_strerror_dylibloader_wrapper_asound)( int);
int (*snd_lib_error_set_handler_dylibloader_wrapper_asound)( snd_lib_error_handler_t);
snd_local_error_handler_t (*snd_lib_error_set_local_dylibloader_wrapper_asound)( snd_local_error_handler_t);
-const char* (*snd_config_topdir_dylibloader_wrapper_asound)( void);
int (*snd_config_top_dylibloader_wrapper_asound)( snd_config_t**);
int (*snd_config_load_dylibloader_wrapper_asound)( snd_config_t*, snd_input_t*);
int (*snd_config_load_override_dylibloader_wrapper_asound)( snd_config_t*, snd_input_t*);
@@ -2619,9 +2601,6 @@ int (*snd_config_search_definition_dylibloader_wrapper_asound)( snd_config_t*,co
int (*snd_config_expand_dylibloader_wrapper_asound)( snd_config_t*, snd_config_t*,const char*, snd_config_t*, snd_config_t**);
int (*snd_config_evaluate_dylibloader_wrapper_asound)( snd_config_t*, snd_config_t*, snd_config_t*, snd_config_t**);
int (*snd_config_add_dylibloader_wrapper_asound)( snd_config_t*, snd_config_t*);
-int (*snd_config_add_before_dylibloader_wrapper_asound)( snd_config_t*, snd_config_t*);
-int (*snd_config_add_after_dylibloader_wrapper_asound)( snd_config_t*, snd_config_t*);
-int (*snd_config_remove_dylibloader_wrapper_asound)( snd_config_t*);
int (*snd_config_delete_dylibloader_wrapper_asound)( snd_config_t*);
int (*snd_config_delete_compound_members_dylibloader_wrapper_asound)(const snd_config_t*);
int (*snd_config_copy_dylibloader_wrapper_asound)( snd_config_t**, snd_config_t*);
@@ -2639,7 +2618,6 @@ int (*snd_config_imake_string_dylibloader_wrapper_asound)( snd_config_t**,const
int (*snd_config_imake_safe_string_dylibloader_wrapper_asound)( snd_config_t**,const char*,const char*);
int (*snd_config_imake_pointer_dylibloader_wrapper_asound)( snd_config_t**,const char*,const void*);
snd_config_type_t (*snd_config_get_type_dylibloader_wrapper_asound)(const snd_config_t*);
-int (*snd_config_is_array_dylibloader_wrapper_asound)(const snd_config_t*);
int (*snd_config_set_id_dylibloader_wrapper_asound)( snd_config_t*,const char*);
int (*snd_config_set_integer_dylibloader_wrapper_asound)( snd_config_t*, long);
int (*snd_config_set_integer64_dylibloader_wrapper_asound)( snd_config_t*, long long);
@@ -2984,7 +2962,6 @@ int (*snd_pcm_area_silence_dylibloader_wrapper_asound)(const snd_pcm_channel_are
int (*snd_pcm_areas_silence_dylibloader_wrapper_asound)(const snd_pcm_channel_area_t*, snd_pcm_uframes_t, unsigned int, snd_pcm_uframes_t, snd_pcm_format_t);
int (*snd_pcm_area_copy_dylibloader_wrapper_asound)(const snd_pcm_channel_area_t*, snd_pcm_uframes_t,const snd_pcm_channel_area_t*, snd_pcm_uframes_t, unsigned int, snd_pcm_format_t);
int (*snd_pcm_areas_copy_dylibloader_wrapper_asound)(const snd_pcm_channel_area_t*, snd_pcm_uframes_t,const snd_pcm_channel_area_t*, snd_pcm_uframes_t, unsigned int, snd_pcm_uframes_t, snd_pcm_format_t);
-int (*snd_pcm_areas_copy_wrap_dylibloader_wrapper_asound)(const snd_pcm_channel_area_t*, snd_pcm_uframes_t,const snd_pcm_uframes_t,const snd_pcm_channel_area_t*, snd_pcm_uframes_t,const snd_pcm_uframes_t,const unsigned int, snd_pcm_uframes_t,const snd_pcm_format_t);
snd_pcm_t* (*snd_pcm_hook_get_pcm_dylibloader_wrapper_asound)( snd_pcm_hook_t*);
void* (*snd_pcm_hook_get_private_dylibloader_wrapper_asound)( snd_pcm_hook_t*);
void (*snd_pcm_hook_set_private_dylibloader_wrapper_asound)( snd_pcm_hook_t*, void*);
@@ -3576,7 +3553,6 @@ const char* (*snd_mixer_selem_id_get_name_dylibloader_wrapper_asound)(const snd_
unsigned int (*snd_mixer_selem_id_get_index_dylibloader_wrapper_asound)(const snd_mixer_selem_id_t*);
void (*snd_mixer_selem_id_set_name_dylibloader_wrapper_asound)( snd_mixer_selem_id_t*,const char*);
void (*snd_mixer_selem_id_set_index_dylibloader_wrapper_asound)( snd_mixer_selem_id_t*, unsigned int);
-int (*snd_mixer_selem_id_parse_dylibloader_wrapper_asound)( snd_mixer_selem_id_t*,const char*);
int (*snd_seq_open_dylibloader_wrapper_asound)( snd_seq_t**,const char*, int, int);
int (*snd_seq_open_lconf_dylibloader_wrapper_asound)( snd_seq_t**,const char*, int, int, snd_config_t*);
const char* (*snd_seq_name_dylibloader_wrapper_asound)( snd_seq_t*);
@@ -3864,14 +3840,6 @@ int initialize_asound(int verbose) {
fprintf(stderr, "%s\n", error);
}
}
-// snd_dlpath
- *(void **) (&snd_dlpath_dylibloader_wrapper_asound) = dlsym(handle, "snd_dlpath");
- if (verbose) {
- error = dlerror();
- if (error != NULL) {
- fprintf(stderr, "%s\n", error);
- }
- }
// snd_dlopen
*(void **) (&snd_dlopen_dylibloader_wrapper_asound) = dlsym(handle, "snd_dlopen");
if (verbose) {
@@ -4136,14 +4104,6 @@ int initialize_asound(int verbose) {
fprintf(stderr, "%s\n", error);
}
}
-// snd_config_topdir
- *(void **) (&snd_config_topdir_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_topdir");
- if (verbose) {
- error = dlerror();
- if (error != NULL) {
- fprintf(stderr, "%s\n", error);
- }
- }
// snd_config_top
*(void **) (&snd_config_top_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_top");
if (verbose) {
@@ -4280,30 +4240,6 @@ int initialize_asound(int verbose) {
fprintf(stderr, "%s\n", error);
}
}
-// snd_config_add_before
- *(void **) (&snd_config_add_before_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_add_before");
- if (verbose) {
- error = dlerror();
- if (error != NULL) {
- fprintf(stderr, "%s\n", error);
- }
- }
-// snd_config_add_after
- *(void **) (&snd_config_add_after_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_add_after");
- if (verbose) {
- error = dlerror();
- if (error != NULL) {
- fprintf(stderr, "%s\n", error);
- }
- }
-// snd_config_remove
- *(void **) (&snd_config_remove_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_remove");
- if (verbose) {
- error = dlerror();
- if (error != NULL) {
- fprintf(stderr, "%s\n", error);
- }
- }
// snd_config_delete
*(void **) (&snd_config_delete_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_delete");
if (verbose) {
@@ -4440,14 +4376,6 @@ int initialize_asound(int verbose) {
fprintf(stderr, "%s\n", error);
}
}
-// snd_config_is_array
- *(void **) (&snd_config_is_array_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_is_array");
- if (verbose) {
- error = dlerror();
- if (error != NULL) {
- fprintf(stderr, "%s\n", error);
- }
- }
// snd_config_set_id
*(void **) (&snd_config_set_id_dylibloader_wrapper_asound) = dlsym(handle, "snd_config_set_id");
if (verbose) {
@@ -7200,14 +7128,6 @@ int initialize_asound(int verbose) {
fprintf(stderr, "%s\n", error);
}
}
-// snd_pcm_areas_copy_wrap
- *(void **) (&snd_pcm_areas_copy_wrap_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_areas_copy_wrap");
- if (verbose) {
- error = dlerror();
- if (error != NULL) {
- fprintf(stderr, "%s\n", error);
- }
- }
// snd_pcm_hook_get_pcm
*(void **) (&snd_pcm_hook_get_pcm_dylibloader_wrapper_asound) = dlsym(handle, "snd_pcm_hook_get_pcm");
if (verbose) {
@@ -11936,14 +11856,6 @@ int initialize_asound(int verbose) {
fprintf(stderr, "%s\n", error);
}
}
-// snd_mixer_selem_id_parse
- *(void **) (&snd_mixer_selem_id_parse_dylibloader_wrapper_asound) = dlsym(handle, "snd_mixer_selem_id_parse");
- if (verbose) {
- error = dlerror();
- if (error != NULL) {
- fprintf(stderr, "%s\n", error);
- }
- }
// snd_seq_open
*(void **) (&snd_seq_open_dylibloader_wrapper_asound) = dlsym(handle, "snd_seq_open");
if (verbose) {
diff --git a/drivers/alsa/asound-so_wrap.h b/drivers/alsa/asound-so_wrap.h
index 5332d74152..8d12d15ba8 100644
--- a/drivers/alsa/asound-so_wrap.h
+++ b/drivers/alsa/asound-so_wrap.h
@@ -2,13 +2,12 @@
#define DYLIBLOAD_WRAPPER_ASOUND
// This file is generated. Do not edit!
// see https://github.com/hpvb/dynload-wrapper for details
-// generated by /home/hp/Projects/godot/pulse/generate-wrapper.py 0.3 on 2021-02-22 19:22:12
-// flags: /home/hp/Projects/godot/pulse/generate-wrapper.py --include /usr/include/alsa/asoundlib.h --sys-include <alsa/asoundlib.h> --soname libasound.so.2 --init-name asound --omit-prefix snd_pcm_sw_params_set_tstamp_type --omit-prefix snd_pcm_status_get_audio_htstamp_report --omit-prefix snd_pcm_sw_params_get_tstamp_type --omit-prefix snd_pcm_status_set_audio_htstamp_config --output-header asound-so_wrap.h --output-implementation asound-so_wrap.c
+// generated by generate-wrapper.py 0.3 on 2023-01-12 10:26:13
+// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/alsa/asoundlib.h --sys-include "thirdparty/linuxbsd_headers/alsa/asoundlib.h" --soname libasound.so.2 --init-name asound --omit-prefix snd_pcm_sw_params_set_tstamp_type --omit-prefix snd_pcm_status_get_audio_htstamp_report --omit-prefix snd_pcm_sw_params_get_tstamp_type --omit-prefix snd_pcm_status_set_audio_htstamp_config --output-header ./drivers/alsa/asound-so_wrap.h --output-implementation ./drivers/alsa/asound-so_wrap.c
//
#include <stdint.h>
#define snd_asoundlib_version snd_asoundlib_version_dylibloader_orig_asound
-#define snd_dlpath snd_dlpath_dylibloader_orig_asound
#define snd_dlopen snd_dlopen_dylibloader_orig_asound
#define snd_dlsym snd_dlsym_dylibloader_orig_asound
#define snd_dlclose snd_dlclose_dylibloader_orig_asound
@@ -42,7 +41,6 @@
#define snd_strerror snd_strerror_dylibloader_orig_asound
#define snd_lib_error_set_handler snd_lib_error_set_handler_dylibloader_orig_asound
#define snd_lib_error_set_local snd_lib_error_set_local_dylibloader_orig_asound
-#define snd_config_topdir snd_config_topdir_dylibloader_orig_asound
#define snd_config_top snd_config_top_dylibloader_orig_asound
#define snd_config_load snd_config_load_dylibloader_orig_asound
#define snd_config_load_override snd_config_load_override_dylibloader_orig_asound
@@ -60,9 +58,6 @@
#define snd_config_expand snd_config_expand_dylibloader_orig_asound
#define snd_config_evaluate snd_config_evaluate_dylibloader_orig_asound
#define snd_config_add snd_config_add_dylibloader_orig_asound
-#define snd_config_add_before snd_config_add_before_dylibloader_orig_asound
-#define snd_config_add_after snd_config_add_after_dylibloader_orig_asound
-#define snd_config_remove snd_config_remove_dylibloader_orig_asound
#define snd_config_delete snd_config_delete_dylibloader_orig_asound
#define snd_config_delete_compound_members snd_config_delete_compound_members_dylibloader_orig_asound
#define snd_config_copy snd_config_copy_dylibloader_orig_asound
@@ -80,7 +75,6 @@
#define snd_config_imake_safe_string snd_config_imake_safe_string_dylibloader_orig_asound
#define snd_config_imake_pointer snd_config_imake_pointer_dylibloader_orig_asound
#define snd_config_get_type snd_config_get_type_dylibloader_orig_asound
-#define snd_config_is_array snd_config_is_array_dylibloader_orig_asound
#define snd_config_set_id snd_config_set_id_dylibloader_orig_asound
#define snd_config_set_integer snd_config_set_integer_dylibloader_orig_asound
#define snd_config_set_integer64 snd_config_set_integer64_dylibloader_orig_asound
@@ -425,7 +419,6 @@
#define snd_pcm_areas_silence snd_pcm_areas_silence_dylibloader_orig_asound
#define snd_pcm_area_copy snd_pcm_area_copy_dylibloader_orig_asound
#define snd_pcm_areas_copy snd_pcm_areas_copy_dylibloader_orig_asound
-#define snd_pcm_areas_copy_wrap snd_pcm_areas_copy_wrap_dylibloader_orig_asound
#define snd_pcm_hook_get_pcm snd_pcm_hook_get_pcm_dylibloader_orig_asound
#define snd_pcm_hook_get_private snd_pcm_hook_get_private_dylibloader_orig_asound
#define snd_pcm_hook_set_private snd_pcm_hook_set_private_dylibloader_orig_asound
@@ -1017,7 +1010,6 @@
#define snd_mixer_selem_id_get_index snd_mixer_selem_id_get_index_dylibloader_orig_asound
#define snd_mixer_selem_id_set_name snd_mixer_selem_id_set_name_dylibloader_orig_asound
#define snd_mixer_selem_id_set_index snd_mixer_selem_id_set_index_dylibloader_orig_asound
-#define snd_mixer_selem_id_parse snd_mixer_selem_id_parse_dylibloader_orig_asound
#define snd_seq_open snd_seq_open_dylibloader_orig_asound
#define snd_seq_open_lconf snd_seq_open_lconf_dylibloader_orig_asound
#define snd_seq_name snd_seq_name_dylibloader_orig_asound
@@ -1286,9 +1278,8 @@
#define snd_midi_event_encode snd_midi_event_encode_dylibloader_orig_asound
#define snd_midi_event_encode_byte snd_midi_event_encode_byte_dylibloader_orig_asound
#define snd_midi_event_decode snd_midi_event_decode_dylibloader_orig_asound
-#include <alsa/asoundlib.h>
+#include "thirdparty/linuxbsd_headers/alsa/asoundlib.h"
#undef snd_asoundlib_version
-#undef snd_dlpath
#undef snd_dlopen
#undef snd_dlsym
#undef snd_dlclose
@@ -1322,7 +1313,6 @@
#undef snd_strerror
#undef snd_lib_error_set_handler
#undef snd_lib_error_set_local
-#undef snd_config_topdir
#undef snd_config_top
#undef snd_config_load
#undef snd_config_load_override
@@ -1340,9 +1330,6 @@
#undef snd_config_expand
#undef snd_config_evaluate
#undef snd_config_add
-#undef snd_config_add_before
-#undef snd_config_add_after
-#undef snd_config_remove
#undef snd_config_delete
#undef snd_config_delete_compound_members
#undef snd_config_copy
@@ -1360,7 +1347,6 @@
#undef snd_config_imake_safe_string
#undef snd_config_imake_pointer
#undef snd_config_get_type
-#undef snd_config_is_array
#undef snd_config_set_id
#undef snd_config_set_integer
#undef snd_config_set_integer64
@@ -1705,7 +1691,6 @@
#undef snd_pcm_areas_silence
#undef snd_pcm_area_copy
#undef snd_pcm_areas_copy
-#undef snd_pcm_areas_copy_wrap
#undef snd_pcm_hook_get_pcm
#undef snd_pcm_hook_get_private
#undef snd_pcm_hook_set_private
@@ -2297,7 +2282,6 @@
#undef snd_mixer_selem_id_get_index
#undef snd_mixer_selem_id_set_name
#undef snd_mixer_selem_id_set_index
-#undef snd_mixer_selem_id_parse
#undef snd_seq_open
#undef snd_seq_open_lconf
#undef snd_seq_name
@@ -2570,7 +2554,6 @@
extern "C" {
#endif
#define snd_asoundlib_version snd_asoundlib_version_dylibloader_wrapper_asound
-#define snd_dlpath snd_dlpath_dylibloader_wrapper_asound
#define snd_dlopen snd_dlopen_dylibloader_wrapper_asound
#define snd_dlsym snd_dlsym_dylibloader_wrapper_asound
#define snd_dlclose snd_dlclose_dylibloader_wrapper_asound
@@ -2604,7 +2587,6 @@ extern "C" {
#define snd_strerror snd_strerror_dylibloader_wrapper_asound
#define snd_lib_error_set_handler snd_lib_error_set_handler_dylibloader_wrapper_asound
#define snd_lib_error_set_local snd_lib_error_set_local_dylibloader_wrapper_asound
-#define snd_config_topdir snd_config_topdir_dylibloader_wrapper_asound
#define snd_config_top snd_config_top_dylibloader_wrapper_asound
#define snd_config_load snd_config_load_dylibloader_wrapper_asound
#define snd_config_load_override snd_config_load_override_dylibloader_wrapper_asound
@@ -2622,9 +2604,6 @@ extern "C" {
#define snd_config_expand snd_config_expand_dylibloader_wrapper_asound
#define snd_config_evaluate snd_config_evaluate_dylibloader_wrapper_asound
#define snd_config_add snd_config_add_dylibloader_wrapper_asound
-#define snd_config_add_before snd_config_add_before_dylibloader_wrapper_asound
-#define snd_config_add_after snd_config_add_after_dylibloader_wrapper_asound
-#define snd_config_remove snd_config_remove_dylibloader_wrapper_asound
#define snd_config_delete snd_config_delete_dylibloader_wrapper_asound
#define snd_config_delete_compound_members snd_config_delete_compound_members_dylibloader_wrapper_asound
#define snd_config_copy snd_config_copy_dylibloader_wrapper_asound
@@ -2642,7 +2621,6 @@ extern "C" {
#define snd_config_imake_safe_string snd_config_imake_safe_string_dylibloader_wrapper_asound
#define snd_config_imake_pointer snd_config_imake_pointer_dylibloader_wrapper_asound
#define snd_config_get_type snd_config_get_type_dylibloader_wrapper_asound
-#define snd_config_is_array snd_config_is_array_dylibloader_wrapper_asound
#define snd_config_set_id snd_config_set_id_dylibloader_wrapper_asound
#define snd_config_set_integer snd_config_set_integer_dylibloader_wrapper_asound
#define snd_config_set_integer64 snd_config_set_integer64_dylibloader_wrapper_asound
@@ -2987,7 +2965,6 @@ extern "C" {
#define snd_pcm_areas_silence snd_pcm_areas_silence_dylibloader_wrapper_asound
#define snd_pcm_area_copy snd_pcm_area_copy_dylibloader_wrapper_asound
#define snd_pcm_areas_copy snd_pcm_areas_copy_dylibloader_wrapper_asound
-#define snd_pcm_areas_copy_wrap snd_pcm_areas_copy_wrap_dylibloader_wrapper_asound
#define snd_pcm_hook_get_pcm snd_pcm_hook_get_pcm_dylibloader_wrapper_asound
#define snd_pcm_hook_get_private snd_pcm_hook_get_private_dylibloader_wrapper_asound
#define snd_pcm_hook_set_private snd_pcm_hook_set_private_dylibloader_wrapper_asound
@@ -3579,7 +3556,6 @@ extern "C" {
#define snd_mixer_selem_id_get_index snd_mixer_selem_id_get_index_dylibloader_wrapper_asound
#define snd_mixer_selem_id_set_name snd_mixer_selem_id_set_name_dylibloader_wrapper_asound
#define snd_mixer_selem_id_set_index snd_mixer_selem_id_set_index_dylibloader_wrapper_asound
-#define snd_mixer_selem_id_parse snd_mixer_selem_id_parse_dylibloader_wrapper_asound
#define snd_seq_open snd_seq_open_dylibloader_wrapper_asound
#define snd_seq_open_lconf snd_seq_open_lconf_dylibloader_wrapper_asound
#define snd_seq_name snd_seq_name_dylibloader_wrapper_asound
@@ -3849,8 +3825,7 @@ extern "C" {
#define snd_midi_event_encode_byte snd_midi_event_encode_byte_dylibloader_wrapper_asound
#define snd_midi_event_decode snd_midi_event_decode_dylibloader_wrapper_asound
extern const char* (*snd_asoundlib_version_dylibloader_wrapper_asound)( void);
-extern int (*snd_dlpath_dylibloader_wrapper_asound)( char*, size_t,const char*);
-extern void* (*snd_dlopen_dylibloader_wrapper_asound)(const char*, int, char*, size_t);
+extern void* (*snd_dlopen_dylibloader_wrapper_asound)(const char*, int);
extern void* (*snd_dlsym_dylibloader_wrapper_asound)( void*,const char*,const char*);
extern int (*snd_dlclose_dylibloader_wrapper_asound)( void*);
extern int (*snd_async_add_handler_dylibloader_wrapper_asound)( snd_async_handler_t**, int, snd_async_callback_t, void*);
@@ -3883,7 +3858,6 @@ extern int (*snd_output_flush_dylibloader_wrapper_asound)( snd_output_t*);
extern const char* (*snd_strerror_dylibloader_wrapper_asound)( int);
extern int (*snd_lib_error_set_handler_dylibloader_wrapper_asound)( snd_lib_error_handler_t);
extern snd_local_error_handler_t (*snd_lib_error_set_local_dylibloader_wrapper_asound)( snd_local_error_handler_t);
-extern const char* (*snd_config_topdir_dylibloader_wrapper_asound)( void);
extern int (*snd_config_top_dylibloader_wrapper_asound)( snd_config_t**);
extern int (*snd_config_load_dylibloader_wrapper_asound)( snd_config_t*, snd_input_t*);
extern int (*snd_config_load_override_dylibloader_wrapper_asound)( snd_config_t*, snd_input_t*);
@@ -3901,9 +3875,6 @@ extern int (*snd_config_search_definition_dylibloader_wrapper_asound)( snd_confi
extern int (*snd_config_expand_dylibloader_wrapper_asound)( snd_config_t*, snd_config_t*,const char*, snd_config_t*, snd_config_t**);
extern int (*snd_config_evaluate_dylibloader_wrapper_asound)( snd_config_t*, snd_config_t*, snd_config_t*, snd_config_t**);
extern int (*snd_config_add_dylibloader_wrapper_asound)( snd_config_t*, snd_config_t*);
-extern int (*snd_config_add_before_dylibloader_wrapper_asound)( snd_config_t*, snd_config_t*);
-extern int (*snd_config_add_after_dylibloader_wrapper_asound)( snd_config_t*, snd_config_t*);
-extern int (*snd_config_remove_dylibloader_wrapper_asound)( snd_config_t*);
extern int (*snd_config_delete_dylibloader_wrapper_asound)( snd_config_t*);
extern int (*snd_config_delete_compound_members_dylibloader_wrapper_asound)(const snd_config_t*);
extern int (*snd_config_copy_dylibloader_wrapper_asound)( snd_config_t**, snd_config_t*);
@@ -3921,7 +3892,6 @@ extern int (*snd_config_imake_string_dylibloader_wrapper_asound)( snd_config_t**
extern int (*snd_config_imake_safe_string_dylibloader_wrapper_asound)( snd_config_t**,const char*,const char*);
extern int (*snd_config_imake_pointer_dylibloader_wrapper_asound)( snd_config_t**,const char*,const void*);
extern snd_config_type_t (*snd_config_get_type_dylibloader_wrapper_asound)(const snd_config_t*);
-extern int (*snd_config_is_array_dylibloader_wrapper_asound)(const snd_config_t*);
extern int (*snd_config_set_id_dylibloader_wrapper_asound)( snd_config_t*,const char*);
extern int (*snd_config_set_integer_dylibloader_wrapper_asound)( snd_config_t*, long);
extern int (*snd_config_set_integer64_dylibloader_wrapper_asound)( snd_config_t*, long long);
@@ -4266,7 +4236,6 @@ extern int (*snd_pcm_area_silence_dylibloader_wrapper_asound)(const snd_pcm_chan
extern int (*snd_pcm_areas_silence_dylibloader_wrapper_asound)(const snd_pcm_channel_area_t*, snd_pcm_uframes_t, unsigned int, snd_pcm_uframes_t, snd_pcm_format_t);
extern int (*snd_pcm_area_copy_dylibloader_wrapper_asound)(const snd_pcm_channel_area_t*, snd_pcm_uframes_t,const snd_pcm_channel_area_t*, snd_pcm_uframes_t, unsigned int, snd_pcm_format_t);
extern int (*snd_pcm_areas_copy_dylibloader_wrapper_asound)(const snd_pcm_channel_area_t*, snd_pcm_uframes_t,const snd_pcm_channel_area_t*, snd_pcm_uframes_t, unsigned int, snd_pcm_uframes_t, snd_pcm_format_t);
-extern int (*snd_pcm_areas_copy_wrap_dylibloader_wrapper_asound)(const snd_pcm_channel_area_t*, snd_pcm_uframes_t,const snd_pcm_uframes_t,const snd_pcm_channel_area_t*, snd_pcm_uframes_t,const snd_pcm_uframes_t,const unsigned int, snd_pcm_uframes_t,const snd_pcm_format_t);
extern snd_pcm_t* (*snd_pcm_hook_get_pcm_dylibloader_wrapper_asound)( snd_pcm_hook_t*);
extern void* (*snd_pcm_hook_get_private_dylibloader_wrapper_asound)( snd_pcm_hook_t*);
extern void (*snd_pcm_hook_set_private_dylibloader_wrapper_asound)( snd_pcm_hook_t*, void*);
@@ -4858,7 +4827,6 @@ extern const char* (*snd_mixer_selem_id_get_name_dylibloader_wrapper_asound)(con
extern unsigned int (*snd_mixer_selem_id_get_index_dylibloader_wrapper_asound)(const snd_mixer_selem_id_t*);
extern void (*snd_mixer_selem_id_set_name_dylibloader_wrapper_asound)( snd_mixer_selem_id_t*,const char*);
extern void (*snd_mixer_selem_id_set_index_dylibloader_wrapper_asound)( snd_mixer_selem_id_t*, unsigned int);
-extern int (*snd_mixer_selem_id_parse_dylibloader_wrapper_asound)( snd_mixer_selem_id_t*,const char*);
extern int (*snd_seq_open_dylibloader_wrapper_asound)( snd_seq_t**,const char*, int, int);
extern int (*snd_seq_open_lconf_dylibloader_wrapper_asound)( snd_seq_t**,const char*, int, int, snd_config_t*);
extern const char* (*snd_seq_name_dylibloader_wrapper_asound)( snd_seq_t*);
diff --git a/drivers/alsa/audio_driver_alsa.cpp b/drivers/alsa/audio_driver_alsa.cpp
index 09e4f48204..689f76389b 100644
--- a/drivers/alsa/audio_driver_alsa.cpp
+++ b/drivers/alsa/audio_driver_alsa.cpp
@@ -37,23 +37,23 @@
#include <errno.h>
-#ifdef PULSEAUDIO_ENABLED
+#if defined(PULSEAUDIO_ENABLED) && defined(SOWRAP_ENABLED)
extern "C" {
extern int initialize_pulse(int verbose);
}
#endif
-Error AudioDriverALSA::init_device() {
+Error AudioDriverALSA::init_output_device() {
mix_rate = GLOBAL_GET("audio/driver/mix_rate");
speaker_mode = SPEAKER_MODE_STEREO;
channels = 2;
- // If there is a specified device check that it is really present
- if (device_name != "Default") {
- PackedStringArray list = get_device_list();
- if (list.find(device_name) == -1) {
- device_name = "Default";
- new_device = "Default";
+ // If there is a specified output device check that it is really present
+ if (output_device_name != "Default") {
+ PackedStringArray list = get_output_device_list();
+ if (list.find(output_device_name) == -1) {
+ output_device_name = "Default";
+ new_output_device = "Default";
}
}
@@ -75,10 +75,10 @@ Error AudioDriverALSA::init_device() {
//6 chans - "plug:surround51"
//4 chans - "plug:surround40";
- if (device_name == "Default") {
+ if (output_device_name == "Default") {
status = snd_pcm_open(&pcm_handle, "default", SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
} else {
- String device = device_name;
+ String device = output_device_name;
int pos = device.find(";");
if (pos != -1) {
device = device.substr(0, pos);
@@ -153,6 +153,7 @@ Error AudioDriverALSA::init_device() {
}
Error AudioDriverALSA::init() {
+#ifdef SOWRAP_ENABLED
#ifdef DEBUG_ENABLED
int dylibloader_verbose = 1;
#else
@@ -167,11 +168,11 @@ Error AudioDriverALSA::init() {
if (initialize_asound(dylibloader_verbose)) {
return ERR_CANT_OPEN;
}
-
+#endif
active.clear();
exit_thread.clear();
- Error err = init_device();
+ Error err = init_output_device();
if (err == OK) {
thread.start(AudioDriverALSA::thread_func, this);
}
@@ -227,18 +228,18 @@ void AudioDriverALSA::thread_func(void *p_udata) {
}
}
- // User selected a new device, finish the current one so we'll init the new device
- if (ad->device_name != ad->new_device) {
- ad->device_name = ad->new_device;
- ad->finish_device();
+ // User selected a new output device, finish the current one so we'll init the new device.
+ if (ad->output_device_name != ad->new_output_device) {
+ ad->output_device_name = ad->new_output_device;
+ ad->finish_output_device();
- Error err = ad->init_device();
+ Error err = ad->init_output_device();
if (err != OK) {
- ERR_PRINT("ALSA: init_device error");
- ad->device_name = "Default";
- ad->new_device = "Default";
+ ERR_PRINT("ALSA: init_output_device error");
+ ad->output_device_name = "Default";
+ ad->new_output_device = "Default";
- err = ad->init_device();
+ err = ad->init_output_device();
if (err != OK) {
ad->active.clear();
ad->exit_thread.set();
@@ -263,7 +264,7 @@ AudioDriver::SpeakerMode AudioDriverALSA::get_speaker_mode() const {
return speaker_mode;
}
-PackedStringArray AudioDriverALSA::get_device_list() {
+PackedStringArray AudioDriverALSA::get_output_device_list() {
PackedStringArray list;
list.push_back("Default");
@@ -298,13 +299,13 @@ PackedStringArray AudioDriverALSA::get_device_list() {
return list;
}
-String AudioDriverALSA::get_device() {
- return device_name;
+String AudioDriverALSA::get_output_device() {
+ return output_device_name;
}
-void AudioDriverALSA::set_device(String device) {
+void AudioDriverALSA::set_output_device(const String &p_name) {
lock();
- new_device = device;
+ new_output_device = p_name;
unlock();
}
@@ -316,7 +317,7 @@ void AudioDriverALSA::unlock() {
mutex.unlock();
}
-void AudioDriverALSA::finish_device() {
+void AudioDriverALSA::finish_output_device() {
if (pcm_handle) {
snd_pcm_close(pcm_handle);
pcm_handle = nullptr;
@@ -327,7 +328,7 @@ void AudioDriverALSA::finish() {
exit_thread.set();
thread.wait_to_finish();
- finish_device();
+ finish_output_device();
}
#endif // ALSA_ENABLED
diff --git a/drivers/alsa/audio_driver_alsa.h b/drivers/alsa/audio_driver_alsa.h
index 6e9cf4dba9..b62d7188dd 100644
--- a/drivers/alsa/audio_driver_alsa.h
+++ b/drivers/alsa/audio_driver_alsa.h
@@ -38,7 +38,11 @@
#include "core/templates/safe_refcount.h"
#include "servers/audio_server.h"
+#ifdef SOWRAP_ENABLED
#include "asound-so_wrap.h"
+#else
+#include <alsa/asoundlib.h>
+#endif
class AudioDriverALSA : public AudioDriver {
Thread thread;
@@ -46,14 +50,14 @@ class AudioDriverALSA : public AudioDriver {
snd_pcm_t *pcm_handle = nullptr;
- String device_name = "Default";
- String new_device = "Default";
+ String output_device_name = "Default";
+ String new_output_device = "Default";
Vector<int32_t> samples_in;
Vector<int16_t> samples_out;
- Error init_device();
- void finish_device();
+ Error init_output_device();
+ void finish_output_device();
static void thread_func(void *p_udata);
@@ -69,20 +73,22 @@ class AudioDriverALSA : public AudioDriver {
SafeFlag exit_thread;
public:
- const char *get_name() const {
+ virtual const char *get_name() const override {
return "ALSA";
- };
-
- virtual Error init();
- virtual void start();
- virtual int get_mix_rate() const;
- virtual SpeakerMode get_speaker_mode() const;
- virtual PackedStringArray get_device_list();
- virtual String get_device();
- virtual void set_device(String device);
- virtual void lock();
- virtual void unlock();
- virtual void finish();
+ }
+
+ virtual Error init() override;
+ virtual void start() override;
+ virtual int get_mix_rate() const override;
+ virtual SpeakerMode get_speaker_mode() const override;
+
+ virtual void lock() override;
+ virtual void unlock() override;
+ virtual void finish() override;
+
+ virtual PackedStringArray get_output_device_list() override;
+ virtual String get_output_device() override;
+ virtual void set_output_device(const String &p_name) override;
AudioDriverALSA() {}
~AudioDriverALSA() {}
diff --git a/drivers/alsamidi/midi_driver_alsamidi.h b/drivers/alsamidi/midi_driver_alsamidi.h
index 3c6300411c..80cc96310f 100644
--- a/drivers/alsamidi/midi_driver_alsamidi.h
+++ b/drivers/alsamidi/midi_driver_alsamidi.h
@@ -39,7 +39,12 @@
#include "core/templates/safe_refcount.h"
#include "core/templates/vector.h"
+#ifdef SOWRAP_ENABLED
#include "../alsa/asound-so_wrap.h"
+#else
+#include <alsa/asoundlib.h>
+#endif
+
#include <stdio.h>
class MIDIDriverALSAMidi : public MIDIDriver {
diff --git a/drivers/coreaudio/audio_driver_coreaudio.cpp b/drivers/coreaudio/audio_driver_coreaudio.cpp
index 966a09c6c2..2c959bb07b 100644
--- a/drivers/coreaudio/audio_driver_coreaudio.cpp
+++ b/drivers/coreaudio/audio_driver_coreaudio.cpp
@@ -44,10 +44,10 @@ OSStatus AudioDriverCoreAudio::input_device_address_cb(AudioObjectID inObjectID,
void *inClientData) {
AudioDriverCoreAudio *driver = static_cast<AudioDriverCoreAudio *>(inClientData);
- // If our selected device is the Default call set_device to update the
+ // If our selected input device is the Default, call set_input_device to update the
// kAudioOutputUnitProperty_CurrentDevice property
- if (driver->capture_device_name == "Default") {
- driver->capture_set_device("Default");
+ if (driver->input_device_name == "Default") {
+ driver->set_input_device("Default");
}
return noErr;
@@ -58,10 +58,10 @@ OSStatus AudioDriverCoreAudio::output_device_address_cb(AudioObjectID inObjectID
void *inClientData) {
AudioDriverCoreAudio *driver = static_cast<AudioDriverCoreAudio *>(inClientData);
- // If our selected device is the Default call set_device to update the
+ // If our selected output device is the Default call set_output_device to update the
// kAudioOutputUnitProperty_CurrentDevice property
- if (driver->device_name == "Default") {
- driver->set_device("Default");
+ if (driver->output_device_name == "Default") {
+ driver->set_output_device("Default");
}
return noErr;
@@ -158,7 +158,7 @@ Error AudioDriverCoreAudio::init() {
ERR_FAIL_COND_V(result != noErr, FAILED);
if (GLOBAL_GET("audio/driver/enable_input")) {
- return capture_init();
+ return init_input_device();
}
return OK;
}
@@ -283,11 +283,11 @@ void AudioDriverCoreAudio::unlock() {
}
bool AudioDriverCoreAudio::try_lock() {
- return mutex.try_lock() == OK;
+ return mutex.try_lock();
}
void AudioDriverCoreAudio::finish() {
- capture_finish();
+ finish_input_device();
if (audio_unit) {
OSStatus result;
@@ -337,7 +337,7 @@ void AudioDriverCoreAudio::finish() {
}
}
-Error AudioDriverCoreAudio::capture_init() {
+Error AudioDriverCoreAudio::init_input_device() {
AudioComponentDescription desc;
memset(&desc, 0, sizeof(desc));
desc.componentType = kAudioUnitType_Output;
@@ -433,7 +433,7 @@ Error AudioDriverCoreAudio::capture_init() {
return OK;
}
-void AudioDriverCoreAudio::capture_finish() {
+void AudioDriverCoreAudio::finish_input_device() {
if (input_unit) {
lock();
@@ -471,7 +471,7 @@ void AudioDriverCoreAudio::capture_finish() {
}
}
-Error AudioDriverCoreAudio::capture_start() {
+Error AudioDriverCoreAudio::input_start() {
input_buffer_init(buffer_frames);
OSStatus result = AudioOutputUnitStart(input_unit);
@@ -482,7 +482,7 @@ Error AudioDriverCoreAudio::capture_start() {
return OK;
}
-Error AudioDriverCoreAudio::capture_stop() {
+Error AudioDriverCoreAudio::input_stop() {
if (input_unit) {
OSStatus result = AudioOutputUnitStop(input_unit);
if (result != noErr) {
@@ -495,7 +495,7 @@ Error AudioDriverCoreAudio::capture_stop() {
#ifdef MACOS_ENABLED
-PackedStringArray AudioDriverCoreAudio::_get_device_list(bool capture) {
+PackedStringArray AudioDriverCoreAudio::_get_device_list(bool input) {
PackedStringArray list;
list.push_back("Default");
@@ -514,7 +514,7 @@ PackedStringArray AudioDriverCoreAudio::_get_device_list(bool capture) {
UInt32 deviceCount = size / sizeof(AudioDeviceID);
for (UInt32 i = 0; i < deviceCount; i++) {
- prop.mScope = capture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput;
+ prop.mScope = input ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput;
prop.mSelector = kAudioDevicePropertyStreamConfiguration;
AudioObjectGetPropertyDataSize(audioDevices[i], &prop, 0, nullptr, &size);
@@ -555,10 +555,10 @@ PackedStringArray AudioDriverCoreAudio::_get_device_list(bool capture) {
return list;
}
-void AudioDriverCoreAudio::_set_device(const String &device, bool capture) {
+void AudioDriverCoreAudio::_set_device(const String &output_device, bool input) {
AudioDeviceID deviceId;
bool found = false;
- if (device != "Default") {
+ if (output_device != "Default") {
AudioObjectPropertyAddress prop;
prop.mSelector = kAudioHardwarePropertyDevices;
@@ -573,7 +573,7 @@ void AudioDriverCoreAudio::_set_device(const String &device, bool capture) {
UInt32 deviceCount = size / sizeof(AudioDeviceID);
for (UInt32 i = 0; i < deviceCount && !found; i++) {
- prop.mScope = capture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput;
+ prop.mScope = input ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput;
prop.mSelector = kAudioDevicePropertyStreamConfiguration;
AudioObjectGetPropertyDataSize(audioDevices[i], &prop, 0, nullptr, &size);
@@ -602,7 +602,7 @@ void AudioDriverCoreAudio::_set_device(const String &device, bool capture) {
ERR_FAIL_NULL_MSG(buffer, "Out of memory.");
if (CFStringGetCString(cfname, buffer, maxSize, kCFStringEncodingUTF8)) {
String name = String::utf8(buffer) + " (" + itos(audioDevices[i]) + ")";
- if (name == device) {
+ if (name == output_device) {
deviceId = audioDevices[i];
found = true;
}
@@ -618,7 +618,7 @@ void AudioDriverCoreAudio::_set_device(const String &device, bool capture) {
if (!found) {
// If we haven't found the desired device get the system default one
UInt32 size = sizeof(AudioDeviceID);
- UInt32 elem = capture ? kAudioHardwarePropertyDefaultInputDevice : kAudioHardwarePropertyDefaultOutputDevice;
+ UInt32 elem = input ? kAudioHardwarePropertyDefaultInputDevice : kAudioHardwarePropertyDefaultOutputDevice;
AudioObjectPropertyAddress property = { elem, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster };
OSStatus result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &property, 0, nullptr, &size, &deviceId);
@@ -628,45 +628,45 @@ void AudioDriverCoreAudio::_set_device(const String &device, bool capture) {
}
if (found) {
- OSStatus result = AudioUnitSetProperty(capture ? input_unit : audio_unit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &deviceId, sizeof(AudioDeviceID));
+ OSStatus result = AudioUnitSetProperty(input ? input_unit : audio_unit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &deviceId, sizeof(AudioDeviceID));
ERR_FAIL_COND(result != noErr);
- if (capture) {
- // Reset audio input to keep synchronisation.
+ if (input) {
+ // Reset audio input to keep synchronization.
input_position = 0;
input_size = 0;
}
}
}
-PackedStringArray AudioDriverCoreAudio::get_device_list() {
+PackedStringArray AudioDriverCoreAudio::get_output_device_list() {
return _get_device_list();
}
-String AudioDriverCoreAudio::get_device() {
- return device_name;
+String AudioDriverCoreAudio::get_output_device() {
+ return output_device_name;
}
-void AudioDriverCoreAudio::set_device(String device) {
- device_name = device;
+void AudioDriverCoreAudio::set_output_device(const String &p_name) {
+ output_device_name = p_name;
if (active) {
- _set_device(device_name);
+ _set_device(output_device_name);
}
}
-void AudioDriverCoreAudio::capture_set_device(const String &p_name) {
- capture_device_name = p_name;
- if (active) {
- _set_device(capture_device_name, true);
- }
+PackedStringArray AudioDriverCoreAudio::get_input_device_list() {
+ return _get_device_list(true);
}
-PackedStringArray AudioDriverCoreAudio::capture_get_device_list() {
- return _get_device_list(true);
+String AudioDriverCoreAudio::get_input_device() {
+ return input_device_name;
}
-String AudioDriverCoreAudio::capture_get_device() {
- return capture_device_name;
+void AudioDriverCoreAudio::set_input_device(const String &p_name) {
+ input_device_name = p_name;
+ if (active) {
+ _set_device(input_device_name, true);
+ }
}
#endif
diff --git a/drivers/coreaudio/audio_driver_coreaudio.h b/drivers/coreaudio/audio_driver_coreaudio.h
index 675265757b..67ff3f3efc 100644
--- a/drivers/coreaudio/audio_driver_coreaudio.h
+++ b/drivers/coreaudio/audio_driver_coreaudio.h
@@ -47,8 +47,8 @@ class AudioDriverCoreAudio : public AudioDriver {
bool active = false;
Mutex mutex;
- String device_name = "Default";
- String capture_device_name = "Default";
+ String output_device_name = "Default";
+ String input_device_name = "Default";
int mix_rate = 0;
unsigned int channels = 2;
@@ -60,7 +60,7 @@ class AudioDriverCoreAudio : public AudioDriver {
#ifdef MACOS_ENABLED
PackedStringArray _get_device_list(bool capture = false);
- void _set_device(const String &device, bool capture = false);
+ void _set_device(const String &output_device, bool capture = false);
static OSStatus input_device_address_cb(AudioObjectID inObjectID,
UInt32 inNumberAddresses, const AudioObjectPropertyAddress *inAddresses,
@@ -83,39 +83,39 @@ class AudioDriverCoreAudio : public AudioDriver {
UInt32 inBusNumber, UInt32 inNumberFrames,
AudioBufferList *ioData);
- Error capture_init();
- void capture_finish();
+ Error init_input_device();
+ void finish_input_device();
public:
- const char *get_name() const {
+ virtual const char *get_name() const override {
return "CoreAudio";
};
- virtual Error init();
- virtual void start();
- virtual int get_mix_rate() const;
- virtual SpeakerMode get_speaker_mode() const;
+ virtual Error init() override;
+ virtual void start() override;
+ virtual int get_mix_rate() const override;
+ virtual SpeakerMode get_speaker_mode() const override;
- virtual void lock();
- virtual void unlock();
- virtual void finish();
-
- virtual Error capture_start();
- virtual Error capture_stop();
-
- bool try_lock();
- void stop();
+ virtual void lock() override;
+ virtual void unlock() override;
+ virtual void finish() override;
#ifdef MACOS_ENABLED
- virtual PackedStringArray get_device_list();
- virtual String get_device();
- virtual void set_device(String device);
+ virtual PackedStringArray get_output_device_list() override;
+ virtual String get_output_device() override;
+ virtual void set_output_device(const String &p_name) override;
- virtual PackedStringArray capture_get_device_list();
- virtual void capture_set_device(const String &p_name);
- virtual String capture_get_device();
+ virtual PackedStringArray get_input_device_list() override;
+ virtual String get_input_device() override;
+ virtual void set_input_device(const String &p_name) override;
#endif
+ virtual Error input_start() override;
+ virtual Error input_stop() override;
+
+ bool try_lock();
+ void stop();
+
AudioDriverCoreAudio();
~AudioDriverCoreAudio() {}
};
diff --git a/drivers/gles3/environment/fog.cpp b/drivers/gles3/environment/fog.cpp
index 87470b454b..6083c4da46 100644
--- a/drivers/gles3/environment/fog.cpp
+++ b/drivers/gles3/environment/fog.cpp
@@ -49,7 +49,7 @@ void Fog::fog_volume_free(RID p_rid) {
void Fog::fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape) {
}
-void Fog::fog_volume_set_extents(RID p_fog_volume, const Vector3 &p_extents) {
+void Fog::fog_volume_set_size(RID p_fog_volume, const Vector3 &p_size) {
}
void Fog::fog_volume_set_material(RID p_fog_volume, RID p_material) {
diff --git a/drivers/gles3/environment/fog.h b/drivers/gles3/environment/fog.h
index 99f2e27c44..7dc0265917 100644
--- a/drivers/gles3/environment/fog.h
+++ b/drivers/gles3/environment/fog.h
@@ -49,7 +49,7 @@ public:
virtual void fog_volume_free(RID p_rid) override;
virtual void fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape) override;
- virtual void fog_volume_set_extents(RID p_fog_volume, const Vector3 &p_extents) override;
+ virtual void fog_volume_set_size(RID p_fog_volume, const Vector3 &p_size) override;
virtual void fog_volume_set_material(RID p_fog_volume, RID p_material) override;
virtual AABB fog_volume_get_aabb(RID p_fog_volume) const override;
virtual RS::FogVolumeShape fog_volume_get_shape(RID p_fog_volume) const override;
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index 2887b6b44f..2a524e8c3a 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -113,16 +113,19 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_
// Clear out any state that may have been left from the 3D pass.
reset_canvas();
- if (state.canvas_instance_data_buffers[state.current_buffer].fence != GLsync()) {
+ if (state.canvas_instance_data_buffers[state.current_data_buffer_index].fence != GLsync()) {
GLint syncStatus;
- glGetSynciv(state.canvas_instance_data_buffers[state.current_buffer].fence, GL_SYNC_STATUS, sizeof(GLint), nullptr, &syncStatus);
+ glGetSynciv(state.canvas_instance_data_buffers[state.current_data_buffer_index].fence, GL_SYNC_STATUS, sizeof(GLint), nullptr, &syncStatus);
if (syncStatus == GL_UNSIGNALED) {
// If older than 2 frames, wait for sync OpenGL can have up to 3 frames in flight, any more and we need to sync anyway.
- if (state.canvas_instance_data_buffers[state.current_buffer].last_frame_used < RSG::rasterizer->get_frame_number() - 2) {
+ if (state.canvas_instance_data_buffers[state.current_data_buffer_index].last_frame_used < RSG::rasterizer->get_frame_number() - 2) {
#ifndef WEB_ENABLED
// On web, we do nothing as the glSubBufferData will force a sync anyway and WebGL does not like waiting.
- glClientWaitSync(state.canvas_instance_data_buffers[state.current_buffer].fence, 0, 100000000); // wait for up to 100ms
+ glClientWaitSync(state.canvas_instance_data_buffers[state.current_data_buffer_index].fence, 0, 100000000); // wait for up to 100ms
#endif
+ state.canvas_instance_data_buffers[state.current_data_buffer_index].last_frame_used = RSG::rasterizer->get_frame_number();
+ glDeleteSync(state.canvas_instance_data_buffers[state.current_data_buffer_index].fence);
+ state.canvas_instance_data_buffers[state.current_data_buffer_index].fence = GLsync();
} else {
// Used in last frame or frame before that. OpenGL can get up to two frames behind, so these buffers may still be in use
// Allocate a new buffer and use that.
@@ -130,9 +133,9 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_
}
} else {
// Already finished all rendering commands, we can use it.
- state.canvas_instance_data_buffers[state.current_buffer].last_frame_used = RSG::rasterizer->get_frame_number();
- glDeleteSync(state.canvas_instance_data_buffers[state.current_buffer].fence);
- state.canvas_instance_data_buffers[state.current_buffer].fence = GLsync();
+ state.canvas_instance_data_buffers[state.current_data_buffer_index].last_frame_used = RSG::rasterizer->get_frame_number();
+ glDeleteSync(state.canvas_instance_data_buffers[state.current_data_buffer_index].fence);
+ state.canvas_instance_data_buffers[state.current_data_buffer_index].fence = GLsync();
}
}
@@ -279,7 +282,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_
}
if (light_count > 0) {
- glBindBufferBase(GL_UNIFORM_BUFFER, LIGHT_UNIFORM_LOCATION, state.canvas_instance_data_buffers[state.current_buffer].light_ubo);
+ glBindBufferBase(GL_UNIFORM_BUFFER, LIGHT_UNIFORM_LOCATION, state.canvas_instance_data_buffers[state.current_data_buffer_index].light_ubo);
#ifdef WEB_ENABLED
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(LightUniform) * light_count, state.light_uniforms);
@@ -361,7 +364,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_
state_buffer.tex_to_sdf = 1.0 / ((canvas_scale.x + canvas_scale.y) * 0.5);
- glBindBufferBase(GL_UNIFORM_BUFFER, BASE_UNIFORM_LOCATION, state.canvas_instance_data_buffers[state.current_buffer].state_ubo);
+ glBindBufferBase(GL_UNIFORM_BUFFER, BASE_UNIFORM_LOCATION, state.canvas_instance_data_buffers[state.current_data_buffer_index].state_ubo);
glBufferData(GL_UNIFORM_BUFFER, sizeof(StateBuffer), &state_buffer, GL_STREAM_DRAW);
GLuint global_buffer = material_storage->global_shader_parameters_get_uniform_buffer();
@@ -395,7 +398,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_
Item *ci = p_item_list;
Item *canvas_group_owner = nullptr;
- uint32_t starting_index = 0;
+ state.last_item_index = 0;
while (ci) {
if (ci->copy_back_buffer && canvas_group_owner == nullptr) {
@@ -440,6 +443,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_
const Item::CommandMesh *cm = static_cast<const Item::CommandMesh *>(c);
if (cm->mesh_instance.is_valid()) {
mesh_storage->mesh_instance_check_for_update(cm->mesh_instance);
+ mesh_storage->mesh_instance_set_canvas_item_transform(cm->mesh_instance, canvas_transform_inverse * ci->final_transform);
update_skeletons = true;
}
}
@@ -454,7 +458,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_
update_skeletons = false;
}
// Canvas group begins here, render until before this item
- _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, starting_index, r_sdf_used);
+ _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used);
item_count = 0;
if (ci->canvas_group_owner->canvas_group->mode != RS::CANVAS_GROUP_MODE_TRANSPARENT) {
@@ -485,7 +489,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_
mesh_storage->update_mesh_instances();
update_skeletons = false;
}
- _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, starting_index, r_sdf_used, true);
+ _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used, true);
item_count = 0;
if (ci->canvas_group->blur_mipmaps) {
@@ -504,7 +508,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_
}
//render anything pending, including clearing if no items
- _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, starting_index, r_sdf_used);
+ _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used);
item_count = 0;
texture_storage->render_target_copy_to_back_buffer(p_to_render_target, back_buffer_rect, backbuffer_gen_mipmaps);
@@ -530,7 +534,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_
mesh_storage->update_mesh_instances();
update_skeletons = false;
}
- _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, starting_index, r_sdf_used);
+ _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used);
//then reset
item_count = 0;
}
@@ -542,14 +546,15 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_
RenderingServerDefault::redraw_request();
}
- state.canvas_instance_data_buffers[state.current_buffer].fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+ state.canvas_instance_data_buffers[state.current_data_buffer_index].fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
// Clear out state used in 2D pass
reset_canvas();
- state.current_buffer = (state.current_buffer + 1) % state.canvas_instance_data_buffers.size();
+ state.current_data_buffer_index = (state.current_data_buffer_index + 1) % state.canvas_instance_data_buffers.size();
+ state.current_instance_buffer_index = 0;
}
-void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, uint32_t &r_last_index, bool &r_sdf_used, bool p_to_backbuffer) {
+void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool &r_sdf_used, bool p_to_backbuffer) {
GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
canvas_begin(p_to_render_target, p_to_backbuffer);
@@ -561,21 +566,22 @@ void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_cou
uint32_t index = 0;
Item *current_clip = nullptr;
+ GLES3::CanvasShaderData *shader_data_cache = nullptr;
// Record Batches.
// First item always forms its own batch.
bool batch_broken = false;
- _new_batch(batch_broken, index);
+ _new_batch(batch_broken);
// Override the start position and index as we want to start from where we finished off last time.
- state.canvas_instance_batches[state.current_batch_index].start = r_last_index;
+ state.canvas_instance_batches[state.current_batch_index].start = state.last_item_index;
index = 0;
for (int i = 0; i < p_item_count; i++) {
Item *ci = items[i];
if (ci->final_clip_owner != state.canvas_instance_batches[state.current_batch_index].clip) {
- _new_batch(batch_broken, index);
+ _new_batch(batch_broken);
state.canvas_instance_batches[state.current_batch_index].clip = ci->final_clip_owner;
current_clip = ci->final_clip_owner;
}
@@ -597,9 +603,8 @@ void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_cou
}
}
- GLES3::CanvasShaderData *shader_data_cache = nullptr;
if (material != state.canvas_instance_batches[state.current_batch_index].material) {
- _new_batch(batch_broken, index);
+ _new_batch(batch_broken);
GLES3::CanvasMaterialData *material_data = nullptr;
if (material.is_valid()) {
@@ -629,12 +634,12 @@ void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_cou
}
// Copy over all data needed for rendering.
- glBindBuffer(GL_ARRAY_BUFFER, state.canvas_instance_data_buffers[state.current_buffer].buffer);
+ glBindBuffer(GL_ARRAY_BUFFER, state.canvas_instance_data_buffers[state.current_data_buffer_index].instance_buffers[state.current_instance_buffer_index]);
#ifdef WEB_ENABLED
- glBufferSubData(GL_ARRAY_BUFFER, r_last_index * sizeof(InstanceData), sizeof(InstanceData) * index, state.instance_data_array);
+ glBufferSubData(GL_ARRAY_BUFFER, state.last_item_index * sizeof(InstanceData), sizeof(InstanceData) * index, state.instance_data_array);
#else
// On Desktop and mobile we map the memory without synchronizing for maximum speed.
- void *buffer = glMapBufferRange(GL_ARRAY_BUFFER, r_last_index * sizeof(InstanceData), index * sizeof(InstanceData), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
+ void *buffer = glMapBufferRange(GL_ARRAY_BUFFER, state.last_item_index * sizeof(InstanceData), index * sizeof(InstanceData), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
memcpy(buffer, state.instance_data_array, index * sizeof(InstanceData));
glUnmapBuffer(GL_ARRAY_BUFFER);
#endif
@@ -757,14 +762,14 @@ void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_cou
state.current_batch_index = 0;
state.canvas_instance_batches.clear();
- r_last_index += index;
+ state.last_item_index += index;
}
void RasterizerCanvasGLES3::_record_item_commands(const Item *p_item, RID p_render_target, const Transform2D &p_canvas_transform_inverse, Item *&current_clip, GLES3::CanvasShaderData::BlendMode p_blend_mode, Light *p_lights, uint32_t &r_index, bool &r_batch_broken, bool &r_sdf_used) {
RenderingServer::CanvasItemTextureFilter texture_filter = p_item->texture_filter == RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT ? state.default_filter : p_item->texture_filter;
if (texture_filter != state.canvas_instance_batches[state.current_batch_index].filter) {
- _new_batch(r_batch_broken, r_index);
+ _new_batch(r_batch_broken);
state.canvas_instance_batches[state.current_batch_index].filter = texture_filter;
}
@@ -772,7 +777,7 @@ void RasterizerCanvasGLES3::_record_item_commands(const Item *p_item, RID p_rend
RenderingServer::CanvasItemTextureRepeat texture_repeat = p_item->texture_repeat == RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT ? state.default_repeat : p_item->texture_repeat;
if (texture_repeat != state.canvas_instance_batches[state.current_batch_index].repeat) {
- _new_batch(r_batch_broken, r_index);
+ _new_batch(r_batch_broken);
state.canvas_instance_batches[state.current_batch_index].repeat = texture_repeat;
}
@@ -803,7 +808,7 @@ void RasterizerCanvasGLES3::_record_item_commands(const Item *p_item, RID p_rend
light_count++;
- if (light_count == data.max_lights_per_item) {
+ if (light_count == data.max_lights_per_item - 1) {
break;
}
}
@@ -816,7 +821,7 @@ void RasterizerCanvasGLES3::_record_item_commands(const Item *p_item, RID p_rend
bool lights_disabled = light_count == 0 && !state.using_directional_lights;
if (lights_disabled != state.canvas_instance_batches[state.current_batch_index].lights_disabled) {
- _new_batch(r_batch_broken, r_index);
+ _new_batch(r_batch_broken);
state.canvas_instance_batches[state.current_batch_index].lights_disabled = lights_disabled;
}
@@ -853,18 +858,19 @@ void RasterizerCanvasGLES3::_record_item_commands(const Item *p_item, RID p_rend
state.instance_data_array[r_index].flags = base_flags | (state.instance_data_array[r_index == 0 ? 0 : r_index - 1].flags & (FLAGS_DEFAULT_NORMAL_MAP_USED | FLAGS_DEFAULT_SPECULAR_MAP_USED)); //reset on each command for sanity, keep canvastexture binding config
- Color blend_color;
+ Color blend_color = base_color;
+ GLES3::CanvasShaderData::BlendMode blend_mode = p_blend_mode;
if (c->type == Item::Command::TYPE_RECT) {
const Item::CommandRect *rect = static_cast<const Item::CommandRect *>(c);
if (rect->flags & CANVAS_RECT_LCD) {
- p_blend_mode = GLES3::CanvasShaderData::BLEND_MODE_LCD;
+ blend_mode = GLES3::CanvasShaderData::BLEND_MODE_LCD;
blend_color = rect->modulate * base_color;
}
}
- if (p_blend_mode != state.canvas_instance_batches[state.current_batch_index].blend_mode || blend_color != state.canvas_instance_batches[state.current_batch_index].blend_color) {
- _new_batch(r_batch_broken, r_index);
- state.canvas_instance_batches[state.current_batch_index].blend_mode = p_blend_mode;
+ if (blend_mode != state.canvas_instance_batches[state.current_batch_index].blend_mode || blend_color != state.canvas_instance_batches[state.current_batch_index].blend_color) {
+ _new_batch(r_batch_broken);
+ state.canvas_instance_batches[state.current_batch_index].blend_mode = blend_mode;
state.canvas_instance_batches[state.current_batch_index].blend_color = blend_color;
}
@@ -873,12 +879,12 @@ void RasterizerCanvasGLES3::_record_item_commands(const Item *p_item, RID p_rend
const Item::CommandRect *rect = static_cast<const Item::CommandRect *>(c);
if (rect->flags & CANVAS_RECT_TILE && state.canvas_instance_batches[state.current_batch_index].repeat != RenderingServer::CanvasItemTextureRepeat::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED) {
- _new_batch(r_batch_broken, r_index);
+ _new_batch(r_batch_broken);
state.canvas_instance_batches[state.current_batch_index].repeat = RenderingServer::CanvasItemTextureRepeat::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED;
}
if (rect->texture != state.canvas_instance_batches[state.current_batch_index].tex || state.canvas_instance_batches[state.current_batch_index].command_type != Item::Command::TYPE_RECT) {
- _new_batch(r_batch_broken, r_index);
+ _new_batch(r_batch_broken);
state.canvas_instance_batches[state.current_batch_index].tex = rect->texture;
state.canvas_instance_batches[state.current_batch_index].command_type = Item::Command::TYPE_RECT;
state.canvas_instance_batches[state.current_batch_index].command = c;
@@ -905,14 +911,16 @@ void RasterizerCanvasGLES3::_record_item_commands(const Item *p_item, RID p_rend
if (rect->flags & CANVAS_RECT_FLIP_H) {
src_rect.size.x *= -1;
+ state.instance_data_array[r_index].flags |= FLAGS_FLIP_H;
}
if (rect->flags & CANVAS_RECT_FLIP_V) {
src_rect.size.y *= -1;
+ state.instance_data_array[r_index].flags |= FLAGS_FLIP_V;
}
if (rect->flags & CANVAS_RECT_TRANSPOSE) {
- dst_rect.size.x *= -1; // Encoding in the dst_rect.z uniform
+ state.instance_data_array[r_index].flags |= FLAGS_TRANSPOSE_RECT;
}
if (rect->flags & CANVAS_RECT_CLIP_UV) {
@@ -966,7 +974,7 @@ void RasterizerCanvasGLES3::_record_item_commands(const Item *p_item, RID p_rend
const Item::CommandNinePatch *np = static_cast<const Item::CommandNinePatch *>(c);
if (np->texture != state.canvas_instance_batches[state.current_batch_index].tex || state.canvas_instance_batches[state.current_batch_index].command_type != Item::Command::TYPE_NINEPATCH) {
- _new_batch(r_batch_broken, r_index);
+ _new_batch(r_batch_broken);
state.canvas_instance_batches[state.current_batch_index].tex = np->texture;
state.canvas_instance_batches[state.current_batch_index].command_type = Item::Command::TYPE_NINEPATCH;
state.canvas_instance_batches[state.current_batch_index].command = c;
@@ -1031,7 +1039,7 @@ void RasterizerCanvasGLES3::_record_item_commands(const Item *p_item, RID p_rend
const Item::CommandPolygon *polygon = static_cast<const Item::CommandPolygon *>(c);
// Polygon's can't be batched, so always create a new batch
- _new_batch(r_batch_broken, r_index);
+ _new_batch(r_batch_broken);
state.canvas_instance_batches[state.current_batch_index].tex = polygon->texture;
state.canvas_instance_batches[state.current_batch_index].command_type = Item::Command::TYPE_POLYGON;
@@ -1058,7 +1066,7 @@ void RasterizerCanvasGLES3::_record_item_commands(const Item *p_item, RID p_rend
const Item::CommandPrimitive *primitive = static_cast<const Item::CommandPrimitive *>(c);
if (primitive->point_count != state.canvas_instance_batches[state.current_batch_index].primitive_points || state.canvas_instance_batches[state.current_batch_index].command_type != Item::Command::TYPE_PRIMITIVE) {
- _new_batch(r_batch_broken, r_index);
+ _new_batch(r_batch_broken);
state.canvas_instance_batches[state.current_batch_index].tex = primitive->texture;
state.canvas_instance_batches[state.current_batch_index].primitive_points = primitive->point_count;
state.canvas_instance_batches[state.current_batch_index].command_type = Item::Command::TYPE_PRIMITIVE;
@@ -1083,10 +1091,7 @@ void RasterizerCanvasGLES3::_record_item_commands(const Item *p_item, RID p_rend
if (primitive->point_count == 4) {
// Reset base data.
_update_transform_2d_to_mat2x3(base_transform * draw_transform, state.instance_data_array[r_index].world);
- state.instance_data_array[r_index].color_texture_pixel_size[0] = 0.0;
- state.instance_data_array[r_index].color_texture_pixel_size[1] = 0.0;
-
- state.instance_data_array[r_index].flags = base_flags | (state.instance_data_array[r_index - 1].flags & (FLAGS_DEFAULT_NORMAL_MAP_USED | FLAGS_DEFAULT_SPECULAR_MAP_USED)); //reset on each command for sanity, keep canvastexture binding config
+ _prepare_canvas_texture(state.canvas_instance_batches[state.current_batch_index].tex, state.canvas_instance_batches[state.current_batch_index].filter, state.canvas_instance_batches[state.current_batch_index].repeat, r_index, texpixel_size);
for (uint32_t j = 0; j < 3; j++) {
int offset = j == 0 ? 0 : 1;
@@ -1108,7 +1113,7 @@ void RasterizerCanvasGLES3::_record_item_commands(const Item *p_item, RID p_rend
case Item::Command::TYPE_MULTIMESH:
case Item::Command::TYPE_PARTICLES: {
// Mesh's can't be batched, so always create a new batch
- _new_batch(r_batch_broken, r_index);
+ _new_batch(r_batch_broken);
Color modulate(1, 1, 1, 1);
state.canvas_instance_batches[state.current_batch_index].shader_variant = CanvasShaderGLES3::MODE_ATTRIBUTES;
@@ -1123,6 +1128,12 @@ void RasterizerCanvasGLES3::_record_item_commands(const Item *p_item, RID p_rend
state.canvas_instance_batches[state.current_batch_index].tex = mm->texture;
state.canvas_instance_batches[state.current_batch_index].shader_variant = CanvasShaderGLES3::MODE_INSTANCED;
+ if (GLES3::MeshStorage::get_singleton()->multimesh_uses_colors(mm->multimesh)) {
+ state.instance_data_array[r_index].flags |= FLAGS_INSTANCING_HAS_COLORS;
+ }
+ if (GLES3::MeshStorage::get_singleton()->multimesh_uses_custom_data(mm->multimesh)) {
+ state.instance_data_array[r_index].flags |= FLAGS_INSTANCING_HAS_CUSTOM_DATA;
+ }
} else if (c->type == Item::Command::TYPE_PARTICLES) {
GLES3::ParticlesStorage *particles_storage = GLES3::ParticlesStorage::get_singleton();
GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
@@ -1131,6 +1142,8 @@ void RasterizerCanvasGLES3::_record_item_commands(const Item *p_item, RID p_rend
RID particles = pt->particles;
state.canvas_instance_batches[state.current_batch_index].tex = pt->texture;
state.canvas_instance_batches[state.current_batch_index].shader_variant = CanvasShaderGLES3::MODE_INSTANCED;
+ state.instance_data_array[r_index].flags |= FLAGS_INSTANCING_HAS_COLORS;
+ state.instance_data_array[r_index].flags |= FLAGS_INSTANCING_HAS_CUSTOM_DATA;
if (particles_storage->particles_has_collision(particles) && texture_storage->render_target_is_sdf_enabled(p_render_target)) {
// Pass collision information.
@@ -1180,7 +1193,7 @@ void RasterizerCanvasGLES3::_record_item_commands(const Item *p_item, RID p_rend
const Item::CommandClipIgnore *ci = static_cast<const Item::CommandClipIgnore *>(c);
if (current_clip) {
if (ci->ignore != reclip) {
- _new_batch(r_batch_broken, r_index);
+ _new_batch(r_batch_broken);
if (ci->ignore) {
state.canvas_instance_batches[state.current_batch_index].clip = nullptr;
reclip = true;
@@ -1224,7 +1237,7 @@ void RasterizerCanvasGLES3::_render_batch(Light *p_lights, uint32_t p_index) {
case Item::Command::TYPE_RECT:
case Item::Command::TYPE_NINEPATCH: {
glBindVertexArray(data.indexed_quad_array);
- glBindBuffer(GL_ARRAY_BUFFER, state.canvas_instance_data_buffers[state.current_buffer].buffer);
+ glBindBuffer(GL_ARRAY_BUFFER, state.canvas_instance_data_buffers[state.current_data_buffer_index].instance_buffers[state.canvas_instance_batches[p_index].instance_buffer_index]);
uint32_t range_start = state.canvas_instance_batches[p_index].start * sizeof(InstanceData);
_enable_attributes(range_start, false);
@@ -1240,7 +1253,7 @@ void RasterizerCanvasGLES3::_render_batch(Light *p_lights, uint32_t p_index) {
ERR_FAIL_COND(!pb);
glBindVertexArray(pb->vertex_array);
- glBindBuffer(GL_ARRAY_BUFFER, state.canvas_instance_data_buffers[state.current_buffer].buffer);
+ glBindBuffer(GL_ARRAY_BUFFER, state.canvas_instance_data_buffers[state.current_data_buffer_index].instance_buffers[state.canvas_instance_batches[p_index].instance_buffer_index]);
uint32_t range_start = state.canvas_instance_batches[p_index].start * sizeof(InstanceData);
_enable_attributes(range_start, false);
@@ -1264,7 +1277,7 @@ void RasterizerCanvasGLES3::_render_batch(Light *p_lights, uint32_t p_index) {
case Item::Command::TYPE_PRIMITIVE: {
glBindVertexArray(data.canvas_quad_array);
- glBindBuffer(GL_ARRAY_BUFFER, state.canvas_instance_data_buffers[state.current_buffer].buffer);
+ glBindBuffer(GL_ARRAY_BUFFER, state.canvas_instance_data_buffers[state.current_data_buffer_index].instance_buffers[state.canvas_instance_batches[p_index].instance_buffer_index]);
uint32_t range_start = state.canvas_instance_batches[p_index].start * sizeof(InstanceData);
_enable_attributes(range_start, true);
@@ -1367,7 +1380,7 @@ void RasterizerCanvasGLES3::_render_batch(Light *p_lights, uint32_t p_index) {
index_array_gl = mesh_storage->mesh_surface_get_index_buffer(surface, 0);
bool use_index_buffer = false;
glBindVertexArray(vertex_array_gl);
- glBindBuffer(GL_ARRAY_BUFFER, state.canvas_instance_data_buffers[state.current_buffer].buffer);
+ glBindBuffer(GL_ARRAY_BUFFER, state.canvas_instance_data_buffers[state.current_data_buffer_index].instance_buffers[state.canvas_instance_batches[p_index].instance_buffer_index]);
uint32_t range_start = state.canvas_instance_batches[p_index].start * sizeof(InstanceData);
_enable_attributes(range_start, false, instance_count);
@@ -1424,20 +1437,30 @@ void RasterizerCanvasGLES3::_render_batch(Light *p_lights, uint32_t p_index) {
}
void RasterizerCanvasGLES3::_add_to_batch(uint32_t &r_index, bool &r_batch_broken) {
- if (r_index >= data.max_instances_per_buffer - 1) {
- ERR_PRINT_ONCE("Trying to draw too many items. Please increase maximum number of items in the project settings 'rendering/gl_compatibility/item_buffer_size'");
- return;
- }
-
- if (state.canvas_instance_batches[state.current_batch_index].instance_count >= data.max_instances_per_batch) {
- _new_batch(r_batch_broken, r_index);
- }
-
state.canvas_instance_batches[state.current_batch_index].instance_count++;
r_index++;
+ if (r_index >= data.max_instances_per_buffer) {
+ // Copy over all data needed for rendering right away
+ // then go back to recording item commands.
+ glBindBuffer(GL_ARRAY_BUFFER, state.canvas_instance_data_buffers[state.current_data_buffer_index].instance_buffers[state.current_instance_buffer_index]);
+#ifdef WEB_ENABLED
+ glBufferSubData(GL_ARRAY_BUFFER, state.last_item_index * sizeof(InstanceData), sizeof(InstanceData) * r_index, state.instance_data_array);
+#else
+ // On Desktop and mobile we map the memory without synchronizing for maximum speed.
+ void *buffer = glMapBufferRange(GL_ARRAY_BUFFER, state.last_item_index * sizeof(InstanceData), r_index * sizeof(InstanceData), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
+ memcpy(buffer, state.instance_data_array, r_index * sizeof(InstanceData));
+ glUnmapBuffer(GL_ARRAY_BUFFER);
+#endif
+ _allocate_instance_buffer();
+ r_index = 0;
+ state.last_item_index = 0;
+ r_batch_broken = false; // Force a new batch to be created
+ _new_batch(r_batch_broken);
+ state.canvas_instance_batches[state.current_batch_index].start = 0;
+ }
}
-void RasterizerCanvasGLES3::_new_batch(bool &r_batch_broken, uint32_t &r_index) {
+void RasterizerCanvasGLES3::_new_batch(bool &r_batch_broken) {
if (state.canvas_instance_batches.size() == 0) {
state.canvas_instance_batches.push_back(Batch());
return;
@@ -1453,7 +1476,7 @@ void RasterizerCanvasGLES3::_new_batch(bool &r_batch_broken, uint32_t &r_index)
Batch new_batch = state.canvas_instance_batches[state.current_batch_index];
new_batch.instance_count = 0;
new_batch.start = state.canvas_instance_batches[state.current_batch_index].start + state.canvas_instance_batches[state.current_batch_index].instance_count;
-
+ new_batch.instance_buffer_index = state.current_instance_buffer_index;
state.current_batch_index++;
state.canvas_instance_batches.push_back(new_batch);
}
@@ -1484,6 +1507,9 @@ void RasterizerCanvasGLES3::light_set_texture(RID p_rid, RID p_texture) {
if (cl->texture == p_texture) {
return;
}
+
+ ERR_FAIL_COND(p_texture.is_valid() && !texture_storage->owns_texture(p_texture));
+
if (cl->texture.is_valid()) {
texture_storage->texture_remove_from_texture_atlas(cl->texture);
}
@@ -2233,6 +2259,7 @@ void RasterizerCanvasGLES3::reset_canvas() {
glDisable(GL_DEPTH_TEST);
glDisable(GL_SCISSOR_TEST);
glEnable(GL_BLEND);
+ glBlendEquation(GL_FUNC_ADD);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);
glActiveTexture(GL_TEXTURE0 + GLES3::Config::get_singleton()->max_texture_image_units - 2);
@@ -2430,17 +2457,35 @@ void RasterizerCanvasGLES3::_allocate_instance_data_buffer() {
glBindBuffer(GL_UNIFORM_BUFFER, new_buffers[2]);
glBufferData(GL_UNIFORM_BUFFER, sizeof(StateBuffer), nullptr, GL_STREAM_DRAW);
- state.current_buffer = (state.current_buffer + 1);
+ state.current_data_buffer_index = (state.current_data_buffer_index + 1);
DataBuffer db;
- db.buffer = new_buffers[0];
+ db.instance_buffers.push_back(new_buffers[0]);
db.light_ubo = new_buffers[1];
db.state_ubo = new_buffers[2];
db.last_frame_used = RSG::rasterizer->get_frame_number();
- state.canvas_instance_data_buffers.insert(state.current_buffer, db);
- state.current_buffer = state.current_buffer % state.canvas_instance_data_buffers.size();
+ state.canvas_instance_data_buffers.insert(state.current_data_buffer_index, db);
+ state.current_data_buffer_index = state.current_data_buffer_index % state.canvas_instance_data_buffers.size();
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
+void RasterizerCanvasGLES3::_allocate_instance_buffer() {
+ state.current_instance_buffer_index++;
+
+ if (int(state.current_instance_buffer_index) < state.canvas_instance_data_buffers[state.current_data_buffer_index].instance_buffers.size()) {
+ // We already allocated another buffer in a previous frame, so we can just use it.
+ return;
+ }
+
+ GLuint new_buffer;
+ glGenBuffers(1, &new_buffer);
+
+ glBindBuffer(GL_ARRAY_BUFFER, new_buffer);
+ glBufferData(GL_ARRAY_BUFFER, data.max_instance_buffer_size, nullptr, GL_STREAM_DRAW);
+
+ state.canvas_instance_data_buffers[state.current_data_buffer_index].instance_buffers.push_back(new_buffer);
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+}
void RasterizerCanvasGLES3::set_time(double p_time) {
state.time = p_time;
@@ -2583,14 +2628,12 @@ RasterizerCanvasGLES3::RasterizerCanvasGLES3() {
int uniform_max_size = config->max_uniform_buffer_size;
if (uniform_max_size < 65536) {
data.max_lights_per_render = 64;
- data.max_instances_per_batch = 128;
} else {
data.max_lights_per_render = 256;
- data.max_instances_per_batch = 2048;
}
// Reserve 3 Uniform Buffers for instance data Frame N, N+1 and N+2
- data.max_instances_per_buffer = MAX(data.max_instances_per_batch, uint32_t(GLOBAL_GET("rendering/gl_compatibility/item_buffer_size")));
+ data.max_instances_per_buffer = uint32_t(GLOBAL_GET("rendering/gl_compatibility/item_buffer_size"));
data.max_instance_buffer_size = data.max_instances_per_buffer * sizeof(InstanceData); // 16,384 instances * 128 bytes = 2,097,152 bytes = 2,048 kb
state.canvas_instance_data_buffers.resize(3);
state.canvas_instance_batches.reserve(200);
@@ -2608,7 +2651,7 @@ RasterizerCanvasGLES3::RasterizerCanvasGLES3() {
glBindBuffer(GL_UNIFORM_BUFFER, new_buffers[2]);
glBufferData(GL_UNIFORM_BUFFER, sizeof(StateBuffer), nullptr, GL_STREAM_DRAW);
DataBuffer db;
- db.buffer = new_buffers[0];
+ db.instance_buffers.push_back(new_buffers[0]);
db.light_ubo = new_buffers[1];
db.state_ubo = new_buffers[2];
db.last_frame_used = 0;
@@ -2635,7 +2678,6 @@ RasterizerCanvasGLES3::RasterizerCanvasGLES3() {
String global_defines;
global_defines += "#define MAX_GLOBAL_SHADER_UNIFORMS 256\n"; // TODO: this is arbitrary for now
global_defines += "#define MAX_LIGHTS " + itos(data.max_lights_per_render) + "\n";
- global_defines += "#define MAX_DRAW_DATA_INSTANCES " + itos(data.max_instances_per_batch) + "\n";
GLES3::MaterialStorage::get_singleton()->shaders.canvas_shader.initialize(global_defines, 1);
data.canvas_shader_default_version = GLES3::MaterialStorage::get_singleton()->shaders.canvas_shader.version_create();
@@ -2651,9 +2693,12 @@ RasterizerCanvasGLES3::RasterizerCanvasGLES3() {
// Default CanvasGroup shader.
shader_type canvas_item;
+render_mode unshaded;
+
+uniform sampler2D screen_texture : hint_screen_texture, repeat_disable, filter_nearest;
void fragment() {
- vec4 c = textureLod(SCREEN_TEXTURE, SCREEN_UV, 0.0);
+ vec4 c = textureLod(screen_texture, SCREEN_UV, 0.0);
if (c.a > 0.0001) {
c.rgb /= c.a;
@@ -2676,9 +2721,12 @@ void fragment() {
// Default clip children shader.
shader_type canvas_item;
+render_mode unshaded;
+
+uniform sampler2D screen_texture : hint_screen_texture, repeat_disable, filter_nearest;
void fragment() {
- vec4 c = textureLod(SCREEN_TEXTURE, SCREEN_UV, 0.0);
+ vec4 c = textureLod(screen_texture, SCREEN_UV, 0.0);
COLOR.rgb = c.rgb;
}
)");
diff --git a/drivers/gles3/rasterizer_canvas_gles3.h b/drivers/gles3/rasterizer_canvas_gles3.h
index db9203b249..1c14d0b466 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.h
+++ b/drivers/gles3/rasterizer_canvas_gles3.h
@@ -75,6 +75,9 @@ class RasterizerCanvasGLES3 : public RendererCanvasRender {
FLAGS_USE_MSDF = (1 << 28),
FLAGS_USE_LCD = (1 << 29),
+
+ FLAGS_FLIP_H = (1 << 30),
+ FLAGS_FLIP_V = (1 << 31),
};
enum {
@@ -244,7 +247,6 @@ public:
uint32_t max_lights_per_render = 256;
uint32_t max_lights_per_item = 16;
- uint32_t max_instances_per_batch = 512;
uint32_t max_instances_per_buffer = 16384;
uint32_t max_instance_buffer_size = 16384 * 128;
} data;
@@ -253,6 +255,7 @@ public:
// Position in the UBO measured in bytes
uint32_t start = 0;
uint32_t instance_count = 0;
+ uint32_t instance_buffer_index = 0;
RID tex;
RS::CanvasItemTextureFilter filter = RS::CANVAS_ITEM_TEXTURE_FILTER_MAX;
@@ -278,7 +281,7 @@ public:
// We track them and ensure that they don't get reused until at least 2 frames have passed
// to avoid the GPU stalling to wait for a resource to become available.
struct DataBuffer {
- GLuint buffer = 0;
+ Vector<GLuint> instance_buffers;
GLuint light_ubo = 0;
GLuint state_ubo = 0;
uint64_t last_frame_used = -3;
@@ -288,9 +291,10 @@ public:
struct State {
LocalVector<DataBuffer> canvas_instance_data_buffers;
LocalVector<Batch> canvas_instance_batches;
- uint32_t current_buffer = 0;
- uint32_t current_buffer_index = 0;
+ uint32_t current_data_buffer_index = 0;
+ uint32_t current_instance_buffer_index = 0;
uint32_t current_batch_index = 0;
+ uint32_t last_item_index = 0;
InstanceData *instance_data_array = nullptr;
@@ -351,14 +355,14 @@ public:
void _prepare_canvas_texture(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, uint32_t &r_index, Size2 &r_texpixel_size);
void canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, bool &r_sdf_used) override;
- void _render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, uint32_t &r_last_index, bool &r_sdf_used, bool p_to_backbuffer = false);
+ void _render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool &r_sdf_used, bool p_to_backbuffer = false);
void _record_item_commands(const Item *p_item, RID p_render_target, const Transform2D &p_canvas_transform_inverse, Item *&current_clip, GLES3::CanvasShaderData::BlendMode p_blend_mode, Light *p_lights, uint32_t &r_index, bool &r_break_batch, bool &r_sdf_used);
void _render_batch(Light *p_lights, uint32_t p_index);
bool _bind_material(GLES3::CanvasMaterialData *p_material_data, CanvasShaderGLES3::ShaderVariant p_variant, uint64_t p_specialization);
- void _new_batch(bool &r_batch_broken, uint32_t &r_index);
+ void _new_batch(bool &r_batch_broken);
void _add_to_batch(uint32_t &r_index, bool &r_batch_broken);
void _allocate_instance_data_buffer();
- void _align_instance_data_buffer(uint32_t &r_index);
+ void _allocate_instance_buffer();
void _enable_attributes(uint32_t p_start, bool p_primitive, uint32_t p_rate = 1);
void set_time(double p_time);
diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp
index 672dcacd88..600aa908cc 100644
--- a/drivers/gles3/rasterizer_gles3.cpp
+++ b/drivers/gles3/rasterizer_gles3.cpp
@@ -179,7 +179,8 @@ typedef void (*DEBUGPROCARB)(GLenum source,
typedef void (*DebugMessageCallbackARB)(DEBUGPROCARB callback, const void *userParam);
void RasterizerGLES3::initialize() {
- print_line("OpenGL Renderer: " + RS::get_singleton()->get_video_adapter_name());
+ // NVIDIA suffixes all GPU model names with "/PCIe/SSE2" in OpenGL (but not Vulkan). This isn't necessary to display nowadays, so it can be trimmed.
+ print_line(vformat("OpenGL API %s - Compatibility - Using Device: %s - %s", RS::get_singleton()->get_video_adapter_api_version(), RS::get_singleton()->get_video_adapter_vendor(), RS::get_singleton()->get_video_adapter_name().trim_suffix("/PCIe/SSE2")));
}
void RasterizerGLES3::finalize() {
@@ -305,6 +306,15 @@ void RasterizerGLES3::_blit_render_target_to_screen(RID p_render_target, Display
glReadBuffer(GL_COLOR_ATTACHMENT0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
+
+ if (p_screen_rect.position != Vector2()) {
+ // Viewport doesn't cover entire window so clear window to black before blitting.
+ Size2i win_size = DisplayServer::get_singleton()->window_get_size();
+ glViewport(0, 0, win_size.width, win_size.height);
+ glClearColor(0.0, 0.0, 0.0, 1.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
+
Vector2i screen_rect_end = p_screen_rect.get_end();
glBlitFramebuffer(0, 0, rt->size.x, rt->size.y,
p_screen_rect.position.x, flip_y ? screen_rect_end.y : p_screen_rect.position.y, screen_rect_end.x, flip_y ? p_screen_rect.position.y : screen_rect_end.y,
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index e4bcc424b3..6cc6b8224c 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -145,6 +145,7 @@ void RasterizerSceneGLES3::_geometry_instance_dependency_changed(Dependency::Dep
case Dependency::DEPENDENCY_CHANGED_MULTIMESH:
case Dependency::DEPENDENCY_CHANGED_SKELETON_DATA: {
static_cast<RenderGeometryInstance *>(p_tracker->userdata)->_mark_dirty();
+ static_cast<GeometryInstanceGLES3 *>(p_tracker->userdata)->data->dirty_dependencies = true;
} break;
case Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: {
GeometryInstanceGLES3 *ginstance = static_cast<GeometryInstanceGLES3 *>(p_tracker->userdata);
@@ -160,6 +161,7 @@ void RasterizerSceneGLES3::_geometry_instance_dependency_changed(Dependency::Dep
void RasterizerSceneGLES3::_geometry_instance_dependency_deleted(const RID &p_dependency, DependencyTracker *p_tracker) {
static_cast<RenderGeometryInstance *>(p_tracker->userdata)->_mark_dirty();
+ static_cast<GeometryInstanceGLES3 *>(p_tracker->userdata)->data->dirty_dependencies = true;
}
void RasterizerSceneGLES3::_geometry_instance_add_surface_with_material(GeometryInstanceGLES3 *ginstance, uint32_t p_surface, GLES3::SceneMaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh) {
@@ -729,6 +731,11 @@ void RasterizerSceneGLES3::_setup_sky(const RenderDataGLES3 *p_render_data, cons
}
}
+ if (p_render_data->view_count > 1) {
+ glBindBufferBase(GL_UNIFORM_BUFFER, SKY_MULTIVIEW_UNIFORM_LOCATION, scene_state.multiview_buffer);
+ glBindBuffer(GL_UNIFORM_BUFFER, 0);
+ }
+
if (!sky->radiance) {
_invalidate_sky(sky);
_update_dirty_skys();
@@ -736,7 +743,7 @@ void RasterizerSceneGLES3::_setup_sky(const RenderDataGLES3 *p_render_data, cons
}
}
-void RasterizerSceneGLES3::_draw_sky(RID p_env, const Projection &p_projection, const Transform3D &p_transform, float p_luminance_multiplier) {
+void RasterizerSceneGLES3::_draw_sky(RID p_env, const Projection &p_projection, const Transform3D &p_transform, float p_luminance_multiplier, bool p_use_multiview, bool p_flip_y) {
GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
ERR_FAIL_COND(p_env.is_null());
@@ -746,6 +753,11 @@ void RasterizerSceneGLES3::_draw_sky(RID p_env, const Projection &p_projection,
GLES3::SkyMaterialData *material_data = nullptr;
RID sky_material;
+ uint64_t spec_constants = p_use_multiview ? SkyShaderGLES3::USE_MULTIVIEW : 0;
+ if (p_flip_y) {
+ spec_constants |= SkyShaderGLES3::USE_INVERTED_Y;
+ }
+
RS::EnvironmentBG background = environment_get_background(p_env);
if (sky) {
@@ -790,16 +802,21 @@ void RasterizerSceneGLES3::_draw_sky(RID p_env, const Projection &p_projection,
sky_transform.invert();
sky_transform = sky_transform * p_transform.basis;
- bool success = material_storage->shaders.sky_shader.version_bind_shader(shader_data->version, SkyShaderGLES3::MODE_BACKGROUND);
+ bool success = material_storage->shaders.sky_shader.version_bind_shader(shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);
if (!success) {
return;
}
- material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::ORIENTATION, sky_transform, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND);
- material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::PROJECTION, camera.columns[2][0], camera.columns[0][0], camera.columns[2][1], camera.columns[1][1], shader_data->version, SkyShaderGLES3::MODE_BACKGROUND);
- material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::POSITION, p_transform.origin, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND);
- material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::TIME, time, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND);
- material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::LUMINANCE_MULTIPLIER, p_luminance_multiplier, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND);
+ material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::ORIENTATION, sky_transform, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);
+ material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::PROJECTION, camera.columns[2][0], camera.columns[0][0], camera.columns[2][1], camera.columns[1][1], shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);
+ material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::POSITION, p_transform.origin, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);
+ material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::TIME, time, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);
+ material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::LUMINANCE_MULTIPLIER, p_luminance_multiplier, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);
+
+ if (p_use_multiview) {
+ glBindBufferBase(GL_UNIFORM_BUFFER, SKY_MULTIVIEW_UNIFORM_LOCATION, scene_state.multiview_buffer);
+ glBindBuffer(GL_UNIFORM_BUFFER, 0);
+ }
glBindVertexArray(sky_globals.screen_triangle_array);
glDrawArrays(GL_TRIANGLES, 0, 3);
@@ -1535,8 +1552,6 @@ void RasterizerSceneGLES3::_setup_lights(const RenderDataGLES3 *p_render_data, b
}
}
- li->gl_id = r_omni_light_count;
-
scene_state.omni_light_sort[r_omni_light_count].instance = li;
scene_state.omni_light_sort[r_omni_light_count].depth = distance;
r_omni_light_count++;
@@ -1560,8 +1575,6 @@ void RasterizerSceneGLES3::_setup_lights(const RenderDataGLES3 *p_render_data, b
}
}
- li->gl_id = r_spot_light_count;
-
scene_state.spot_light_sort[r_spot_light_count].instance = li;
scene_state.spot_light_sort[r_spot_light_count].depth = distance;
r_spot_light_count++;
@@ -1584,8 +1597,11 @@ void RasterizerSceneGLES3::_setup_lights(const RenderDataGLES3 *p_render_data, b
LightData &light_data = (i < r_omni_light_count) ? scene_state.omni_lights[index] : scene_state.spot_lights[index];
RS::LightType type = (i < r_omni_light_count) ? RS::LIGHT_OMNI : RS::LIGHT_SPOT;
GLES3::LightInstance *li = (i < r_omni_light_count) ? scene_state.omni_light_sort[index].instance : scene_state.spot_light_sort[index].instance;
+ real_t distance = (i < r_omni_light_count) ? scene_state.omni_light_sort[index].depth : scene_state.spot_light_sort[index].depth;
RID base = li->light;
+ li->gl_id = index;
+
Transform3D light_transform = li->transform;
Vector3 pos = inverse_transform.xform(light_transform.origin);
@@ -1612,13 +1628,11 @@ void RasterizerSceneGLES3::_setup_lights(const RenderDataGLES3 *p_render_data, b
// Reuse fade begin, fade length and distance for shadow LOD determination later.
float fade_begin = 0.0;
float fade_length = 0.0;
- real_t distance = 0.0;
float fade = 1.0;
if (light_storage->light_is_distance_fade_enabled(li->light)) {
fade_begin = light_storage->light_get_distance_fade_begin(li->light);
fade_length = light_storage->light_get_distance_fade_length(li->light);
- distance = p_render_data->cam_transform.origin.distance_to(li->transform.origin);
if (distance > fade_begin) {
// Use `smoothstep()` to make opacity changes more gradual and less noticeable to the player.
@@ -1881,6 +1895,10 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_
glBindFramebuffer(GL_FRAMEBUFFER, rt->fbo);
glViewport(0, 0, rb->width, rb->height);
+ glCullFace(GL_BACK);
+ glEnable(GL_CULL_FACE);
+ scene_state.cull_mode = GLES3::SceneShaderData::CULL_BACK;
+
// Do depth prepass if it's explicitly enabled
bool use_depth_prepass = config->use_depth_prepass;
@@ -1896,9 +1914,6 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glDisable(GL_SCISSOR_TEST);
- glCullFace(GL_BACK);
- glEnable(GL_CULL_FACE);
- scene_state.cull_mode = GLES3::SceneShaderData::CULL_BACK;
glColorMask(0, 0, 0, 0);
glClearDepth(1.0f);
@@ -1976,7 +1991,7 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_
scene_state.current_depth_draw = GLES3::SceneShaderData::DEPTH_DRAW_DISABLED;
scene_state.cull_mode = GLES3::SceneShaderData::CULL_BACK;
- _draw_sky(render_data.environment, render_data.cam_projection, render_data.cam_transform, sky_energy_multiplier);
+ _draw_sky(render_data.environment, render_data.cam_projection, render_data.cam_transform, sky_energy_multiplier, p_camera_data->view_count > 1, flip_y);
}
RENDER_TIMESTAMP("Render 3D Transparent Pass");
diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h
index 7977e562c0..ff043d67f6 100644
--- a/drivers/gles3/rasterizer_scene_gles3.h
+++ b/drivers/gles3/rasterizer_scene_gles3.h
@@ -83,6 +83,7 @@ enum SkyUniformLocation {
SKY_EMPTY, // Unused, put here to avoid conflicts with SCENE_DATA_UNIFORM_LOCATION.
SKY_MATERIAL_UNIFORM_LOCATION,
SKY_DIRECTIONAL_LIGHT_UNIFORM_LOCATION,
+ SKY_MULTIVIEW_UNIFORM_LOCATION,
};
struct RenderDataGLES3 {
@@ -570,7 +571,7 @@ protected:
void _update_dirty_skys();
void _update_sky_radiance(RID p_env, const Projection &p_projection, const Transform3D &p_transform, float p_luminance_multiplier);
void _filter_sky_radiance(Sky *p_sky, int p_base_layer);
- void _draw_sky(RID p_env, const Projection &p_projection, const Transform3D &p_transform, float p_luminance_multiplier);
+ void _draw_sky(RID p_env, const Projection &p_projection, const Transform3D &p_transform, float p_luminance_multiplier, bool p_use_multiview, bool p_flip_y);
void _free_sky_data(Sky *p_sky);
public:
diff --git a/drivers/gles3/shader_gles3.cpp b/drivers/gles3/shader_gles3.cpp
index 71caf3b8e3..10f42bf22b 100644
--- a/drivers/gles3/shader_gles3.cpp
+++ b/drivers/gles3/shader_gles3.cpp
@@ -192,7 +192,7 @@ void ShaderGLES3::_build_variant_code(StringBuilder &builder, uint32_t p_variant
builder.append("#define ViewIndex gl_ViewID_OVR\n");
builder.append("#define MAX_VIEWS 2\n");
builder.append("#else\n");
- builder.append("#define ViewIndex 0\n");
+ builder.append("#define ViewIndex uint(0)\n");
builder.append("#define MAX_VIEWS 1\n");
builder.append("#endif\n");
diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl
index 9a90f33674..ea0a0b660d 100644
--- a/drivers/gles3/shaders/canvas.glsl
+++ b/drivers/gles3/shaders/canvas.glsl
@@ -162,9 +162,13 @@ void main() {
vec2 uv = uv_attrib;
#ifdef USE_INSTANCING
- vec4 instance_color = vec4(unpackHalf2x16(instance_color_custom_data.x), unpackHalf2x16(instance_color_custom_data.y));
- color *= instance_color;
- instance_custom = vec4(unpackHalf2x16(instance_color_custom_data.z), unpackHalf2x16(instance_color_custom_data.w));
+ if (bool(read_draw_data_flags & FLAGS_INSTANCING_HAS_COLORS)) {
+ vec4 instance_color = vec4(unpackHalf2x16(instance_color_custom_data.x), unpackHalf2x16(instance_color_custom_data.y));
+ color *= instance_color;
+ }
+ if (bool(read_draw_data_flags & FLAGS_INSTANCING_HAS_CUSTOM_DATA)) {
+ instance_custom = vec4(unpackHalf2x16(instance_color_custom_data.z), unpackHalf2x16(instance_color_custom_data.w));
+ }
#endif
#else
@@ -277,7 +281,7 @@ flat in uvec4 varying_G;
uniform sampler2D atlas_texture; //texunit:-2
uniform sampler2D shadow_atlas_texture; //texunit:-3
#endif // DISABLE_LIGHTING
-uniform sampler2D screen_texture; //texunit:-4
+uniform sampler2D color_buffer; //texunit:-4
uniform sampler2D sdf_texture; //texunit:-5
uniform sampler2D normal_texture; //texunit:-6
uniform sampler2D specular_texture; //texunit:-7
@@ -579,6 +583,12 @@ void main() {
if (normal_used || (using_light && bool(read_draw_data_flags & FLAGS_DEFAULT_NORMAL_MAP_USED))) {
normal.xy = texture(normal_texture, uv).xy * vec2(2.0, -2.0) - vec2(1.0, -1.0);
+ if (bool(read_draw_data_flags & FLAGS_FLIP_H)) {
+ normal.x = -normal.x;
+ }
+ if (bool(read_draw_data_flags & FLAGS_FLIP_V)) {
+ normal.y = -normal.y;
+ }
normal.z = sqrt(1.0 - dot(normal.xy, normal.xy));
normal_used = true;
} else {
@@ -639,7 +649,7 @@ void main() {
#ifdef MODE_LIGHT_ONLY
color = vec4(0.0);
-#else
+#elif !defined(MODE_UNSHADED)
color *= canvas_modulation;
#endif
diff --git a/drivers/gles3/shaders/canvas_uniforms_inc.glsl b/drivers/gles3/shaders/canvas_uniforms_inc.glsl
index f65558f042..d53c0fcb26 100644
--- a/drivers/gles3/shaders/canvas_uniforms_inc.glsl
+++ b/drivers/gles3/shaders/canvas_uniforms_inc.glsl
@@ -27,6 +27,9 @@
#define FLAGS_USE_MSDF uint(1 << 28)
#define FLAGS_USE_LCD uint(1 << 29)
+#define FLAGS_FLIP_H uint(1 << 30)
+#define FLAGS_FLIP_V uint(1 << 31)
+
layout(std140) uniform GlobalShaderUniformData { //ubo:1
vec4 global_shader_uniforms[MAX_GLOBAL_SHADER_UNIFORMS];
};
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index 1b922fa726..0b389b0478 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -268,9 +268,11 @@ void main() {
#ifdef USE_MULTIVIEW
mat4 projection_matrix = multiview_data.projection_matrix_view[ViewIndex];
mat4 inv_projection_matrix = multiview_data.inv_projection_matrix_view[ViewIndex];
+ vec3 eye_offset = multiview_data.eye_offset[ViewIndex].xyz;
#else
mat4 projection_matrix = scene_data.projection_matrix;
mat4 inv_projection_matrix = scene_data.inv_projection_matrix;
+ vec3 eye_offset = vec3(0.0, 0.0, 0.0);
#endif //USE_MULTIVIEW
#ifdef USE_INSTANCING
@@ -564,10 +566,16 @@ uniform highp samplerCubeShadow positional_shadow; // texunit:-4
#ifdef USE_MULTIVIEW
uniform highp sampler2DArray depth_buffer; // texunit:-6
-uniform highp sampler2DArray screen_texture; // texunit:-5
+uniform highp sampler2DArray color_buffer; // texunit:-5
+vec3 multiview_uv(vec2 uv) {
+ return vec3(uv, ViewIndex);
+}
#else
uniform highp sampler2D depth_buffer; // texunit:-6
-uniform highp sampler2D screen_texture; // texunit:-5
+uniform highp sampler2D color_buffer; // texunit:-5
+vec2 multiview_uv(vec2 uv) {
+ return uv;
+}
#endif
uniform highp mat4 world_transform;
@@ -690,7 +698,8 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte
#endif
#if defined(LIGHT_RIM_USED)
- float rim_light = pow(max(0.0, 1.0 - cNdotV), max(0.0, (1.0 - roughness) * 16.0));
+ // Epsilon min to prevent pow(0, 0) singularity which results in undefined behavior.
+ float rim_light = pow(max(1e-4, 1.0 - cNdotV), max(0.0, (1.0 - roughness) * 16.0));
diffuse_light += rim_light * rim * mix(vec3(1.0), albedo, rim_tint) * light_color;
#endif
}
@@ -923,9 +932,15 @@ void main() {
//lay out everything, whatever is unused is optimized away anyway
vec3 vertex = vertex_interp;
#ifdef USE_MULTIVIEW
- vec3 view = -normalize(vertex_interp - multiview_data.eye_offset[ViewIndex].xyz);
+ vec3 eye_offset = multiview_data.eye_offset[ViewIndex].xyz;
+ vec3 view = -normalize(vertex_interp - eye_offset);
+ mat4 projection_matrix = multiview_data.projection_matrix_view[ViewIndex];
+ mat4 inv_projection_matrix = multiview_data.inv_projection_matrix_view[ViewIndex];
#else
+ vec3 eye_offset = vec3(0.0, 0.0, 0.0);
vec3 view = -normalize(vertex_interp);
+ mat4 projection_matrix = scene_data.projection_matrix;
+ mat4 inv_projection_matrix = scene_data.inv_projection_matrix;
#endif
highp mat4 model_matrix = world_transform;
vec3 albedo = vec3(1.0);
diff --git a/drivers/gles3/shaders/skeleton.glsl b/drivers/gles3/shaders/skeleton.glsl
index a1e3c098f4..aad856a5a2 100644
--- a/drivers/gles3/shaders/skeleton.glsl
+++ b/drivers/gles3/shaders/skeleton.glsl
@@ -87,6 +87,16 @@ uniform highp float blend_weight;
uniform lowp float blend_shape_count;
#endif
+#ifdef USE_SKELETON
+uniform mediump vec2 skeleton_transform_x;
+uniform mediump vec2 skeleton_transform_y;
+uniform mediump vec2 skeleton_transform_offset;
+
+uniform mediump vec2 inverse_transform_x;
+uniform mediump vec2 inverse_transform_y;
+uniform mediump vec2 inverse_transform_offset;
+#endif
+
vec2 signNotZero(vec2 v) {
return mix(vec2(-1.0), vec2(1.0), greaterThanEqual(v.xy, vec2(0.0)));
}
@@ -164,10 +174,13 @@ void main() {
m += GET_BONE_MATRIX(bones.z, bones_a.z, in_weight_attrib.z);
m += GET_BONE_MATRIX(bones.w, bones_a.w, in_weight_attrib.w);
+ mat4 skeleton_matrix = mat4(vec4(skeleton_transform_x, 0.0, 0.0), vec4(skeleton_transform_y, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(skeleton_transform_offset, 0.0, 1.0));
+ mat4 inverse_matrix = mat4(vec4(inverse_transform_x, 0.0, 0.0), vec4(inverse_transform_y, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(inverse_transform_offset, 0.0, 1.0));
mat4 bone_matrix = mat4(m[0], m[1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0));
- //reverse order because its transposed
- out_vertex = (vec4(out_vertex, 0.0, 1.0) * bone_matrix).xy;
+ bone_matrix = skeleton_matrix * transpose(bone_matrix) * inverse_matrix;
+
+ out_vertex = (bone_matrix * vec4(out_vertex, 0.0, 1.0)).xy;
#endif // USE_SKELETON
#else // MODE_2D
diff --git a/drivers/gles3/shaders/sky.glsl b/drivers/gles3/shaders/sky.glsl
index 4c0fe47f6b..e59bca8b07 100644
--- a/drivers/gles3/shaders/sky.glsl
+++ b/drivers/gles3/shaders/sky.glsl
@@ -10,6 +10,9 @@ mode_cubemap_quarter_res = #define USE_CUBEMAP_PASS \n#define USE_QUARTER_RES_PA
#[specializations]
+USE_MULTIVIEW = false
+USE_INVERTED_Y = true
+
#[vertex]
layout(location = 0) in vec2 vertex_attrib;
@@ -19,7 +22,11 @@ out vec2 uv_interp;
void main() {
uv_interp = vertex_attrib;
+#ifdef USE_INVERTED_Y
gl_Position = vec4(uv_interp, 1.0, 1.0);
+#else
+ gl_Position = vec4(uv_interp.x, uv_interp.y * -1.0, 1.0, 1.0);
+#endif
}
/* clang-format off */
@@ -37,6 +44,9 @@ uniform samplerCube radiance; //texunit:-1
#ifdef USE_CUBEMAP_PASS
uniform samplerCube half_res; //texunit:-2
uniform samplerCube quarter_res; //texunit:-3
+#elif defined(USE_MULTIVIEW)
+uniform sampler2DArray half_res; //texunit:-2
+uniform sampler2DArray quarter_res; //texunit:-3
#else
uniform sampler2D half_res; //texunit:-2
uniform sampler2D quarter_res; //texunit:-3
@@ -102,6 +112,15 @@ uniform float fog_density;
uniform float z_far;
uniform uint directional_light_count;
+#ifdef USE_MULTIVIEW
+layout(std140) uniform MultiviewData { // ubo:5
+ highp mat4 projection_matrix_view[MAX_VIEWS];
+ highp mat4 inv_projection_matrix_view[MAX_VIEWS];
+ highp vec4 eye_offset[MAX_VIEWS];
+}
+multiview_data;
+#endif
+
layout(location = 0) out vec4 frag_color;
#ifdef USE_DEBANDING
@@ -115,9 +134,20 @@ vec3 interleaved_gradient_noise(vec2 pos) {
void main() {
vec3 cube_normal;
+#ifdef USE_MULTIVIEW
+ // In multiview our projection matrices will contain positional and rotational offsets that we need to properly unproject.
+ vec4 unproject = vec4(uv_interp.x, uv_interp.y, 1.0, 1.0);
+ vec4 unprojected = multiview_data.inv_projection_matrix_view[ViewIndex] * unproject;
+ cube_normal = unprojected.xyz / unprojected.w;
+ cube_normal += multiview_data.eye_offset[ViewIndex].xyz;
+#else
cube_normal.z = -1.0;
cube_normal.x = (uv_interp.x + projection.x) / projection.y;
cube_normal.y = (-uv_interp.y - projection.z) / projection.w;
+#endif
+#ifndef USE_INVERTED_Y
+ cube_normal.y *= -1.0;
+#endif
cube_normal = mat3(orientation) * cube_normal;
cube_normal = normalize(cube_normal);
@@ -146,12 +176,20 @@ void main() {
#endif
#else
#ifdef USES_HALF_RES_COLOR
+#ifdef USE_MULTIVIEW
+ half_res_color = textureLod(sampler2DArray(half_res, material_samplers[SAMPLER_LINEAR_CLAMP]), vec3(uv, ViewIndex), 0.0);
+#else
half_res_color = textureLod(sampler2D(half_res, material_samplers[SAMPLER_LINEAR_CLAMP]), uv, 0.0);
#endif
+#endif
#ifdef USES_QUARTER_RES_COLOR
+#ifdef USE_MULTIVIEW
+ quarter_res_color = textureLod(sampler2DArray(quarter_res, material_samplers[SAMPLER_LINEAR_CLAMP]), vec3(uv, ViewIndex), 0.0);
+#else
quarter_res_color = textureLod(sampler2D(quarter_res, material_samplers[SAMPLER_LINEAR_CLAMP]), uv, 0.0);
#endif
#endif
+#endif
{
diff --git a/drivers/gles3/shaders/stdlib_inc.glsl b/drivers/gles3/shaders/stdlib_inc.glsl
index 8d4a24cc1f..92bf2d87e4 100644
--- a/drivers/gles3/shaders/stdlib_inc.glsl
+++ b/drivers/gles3/shaders/stdlib_inc.glsl
@@ -2,13 +2,19 @@
#ifdef USE_GLES_OVER_GL
// Floating point pack/unpack functions are part of the GLSL ES 300 specification used by web and mobile.
uint float2half(uint f) {
- return ((f >> uint(16)) & uint(0x8000)) |
- ((((f & uint(0x7f800000)) - uint(0x38000000)) >> uint(13)) & uint(0x7c00)) |
- ((f >> uint(13)) & uint(0x03ff));
+ uint e = f & uint(0x7f800000);
+ if (e <= uint(0x38000000)) {
+ return uint(0);
+ } else {
+ return ((f >> uint(16)) & uint(0x8000)) |
+ (((e - uint(0x38000000)) >> uint(13)) & uint(0x7c00)) |
+ ((f >> uint(13)) & uint(0x03ff));
+ }
}
uint half2float(uint h) {
- return ((h & uint(0x8000)) << uint(16)) | (((h & uint(0x7c00)) + uint(0x1c000)) << uint(13)) | ((h & uint(0x03ff)) << uint(13));
+ uint h_e = h & uint(0x7c00);
+ return ((h & uint(0x8000)) << uint(16)) | uint((h_e >> uint(10)) != uint(0)) * (((h_e + uint(0x1c000)) << uint(13)) | ((h & uint(0x03ff)) << uint(13)));
}
uint packHalf2x16(vec2 v) {
diff --git a/drivers/gles3/storage/config.cpp b/drivers/gles3/storage/config.cpp
index d1a83e6851..77a4553c76 100644
--- a/drivers/gles3/storage/config.cpp
+++ b/drivers/gles3/storage/config.cpp
@@ -65,6 +65,10 @@ Config::Config() {
}
bptc_supported = extensions.has("GL_ARB_texture_compression_bptc") || extensions.has("EXT_texture_compression_bptc");
+ astc_supported = extensions.has("GL_KHR_texture_compression_astc") || extensions.has("GL_OES_texture_compression_astc") || extensions.has("GL_KHR_texture_compression_astc_ldr") || extensions.has("GL_KHR_texture_compression_astc_hdr");
+ astc_hdr_supported = extensions.has("GL_KHR_texture_compression_astc_ldr");
+ astc_layered_supported = extensions.has("GL_KHR_texture_compression_astc_sliced_3d");
+
#ifdef GLES_OVER_GL
float_texture_supported = true;
etc2_supported = false;
diff --git a/drivers/gles3/storage/config.h b/drivers/gles3/storage/config.h
index 8399502675..623f0442bd 100644
--- a/drivers/gles3/storage/config.h
+++ b/drivers/gles3/storage/config.h
@@ -77,6 +77,9 @@ public:
bool rgtc_supported = false;
bool bptc_supported = false;
bool etc2_supported = false;
+ bool astc_supported = false;
+ bool astc_hdr_supported = false;
+ bool astc_layered_supported = false;
bool force_vertex_shading = false;
diff --git a/drivers/gles3/storage/light_storage.cpp b/drivers/gles3/storage/light_storage.cpp
index a325f79d8c..026f7467a8 100644
--- a/drivers/gles3/storage/light_storage.cpp
+++ b/drivers/gles3/storage/light_storage.cpp
@@ -311,6 +311,13 @@ uint64_t LightStorage::light_get_version(RID p_light) const {
return light->version;
}
+uint32_t LightStorage::light_get_cull_mask(RID p_light) const {
+ const Light *light = light_owner.get_or_null(p_light);
+ ERR_FAIL_COND_V(!light, 0);
+
+ return light->cull_mask;
+}
+
AABB LightStorage::light_get_aabb(RID p_light) const {
const Light *light = light_owner.get_or_null(p_light);
ERR_FAIL_COND_V(!light, AABB());
@@ -403,7 +410,7 @@ void LightStorage::reflection_probe_set_ambient_energy(RID p_probe, float p_ener
void LightStorage::reflection_probe_set_max_distance(RID p_probe, float p_distance) {
}
-void LightStorage::reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) {
+void LightStorage::reflection_probe_set_size(RID p_probe, const Vector3 &p_size) {
}
void LightStorage::reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) {
@@ -436,7 +443,7 @@ uint32_t LightStorage::reflection_probe_get_cull_mask(RID p_probe) const {
return 0;
}
-Vector3 LightStorage::reflection_probe_get_extents(RID p_probe) const {
+Vector3 LightStorage::reflection_probe_get_size(RID p_probe) const {
return Vector3();
}
diff --git a/drivers/gles3/storage/light_storage.h b/drivers/gles3/storage/light_storage.h
index a304b6a265..8e6480869b 100644
--- a/drivers/gles3/storage/light_storage.h
+++ b/drivers/gles3/storage/light_storage.h
@@ -113,7 +113,7 @@ struct ReflectionProbe {
Color ambient_color;
float ambient_color_energy = 1.0;
float max_distance = 0;
- Vector3 extents = Vector3(1, 1, 1);
+ Vector3 size = Vector3(20, 20, 20);
Vector3 origin_offset;
bool interior = false;
bool box_projection = false;
@@ -239,13 +239,6 @@ public:
return light->color;
}
- _FORCE_INLINE_ uint32_t light_get_cull_mask(RID p_light) {
- const Light *light = light_owner.get_or_null(p_light);
- ERR_FAIL_COND_V(!light, 0);
-
- return light->cull_mask;
- }
-
_FORCE_INLINE_ bool light_is_distance_fade_enabled(RID p_light) {
const Light *light = light_owner.get_or_null(p_light);
return light->distance_fade;
@@ -297,6 +290,7 @@ public:
virtual RS::LightBakeMode light_get_bake_mode(RID p_light) override;
virtual uint32_t light_get_max_sdfgi_cascade(RID p_light) override { return 0; }
virtual uint64_t light_get_version(RID p_light) const override;
+ virtual uint32_t light_get_cull_mask(RID p_light) const override;
/* LIGHT INSTANCE API */
@@ -332,7 +326,7 @@ public:
virtual void reflection_probe_set_ambient_color(RID p_probe, const Color &p_color) override;
virtual void reflection_probe_set_ambient_energy(RID p_probe, float p_energy) override;
virtual void reflection_probe_set_max_distance(RID p_probe, float p_distance) override;
- virtual void reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) override;
+ virtual void reflection_probe_set_size(RID p_probe, const Vector3 &p_size) override;
virtual void reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) override;
virtual void reflection_probe_set_as_interior(RID p_probe, bool p_enable) override;
virtual void reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) override;
@@ -345,7 +339,7 @@ public:
virtual AABB reflection_probe_get_aabb(RID p_probe) const override;
virtual RS::ReflectionProbeUpdateMode reflection_probe_get_update_mode(RID p_probe) const override;
virtual uint32_t reflection_probe_get_cull_mask(RID p_probe) const override;
- virtual Vector3 reflection_probe_get_extents(RID p_probe) const override;
+ virtual Vector3 reflection_probe_get_size(RID p_probe) const override;
virtual Vector3 reflection_probe_get_origin_offset(RID p_probe) const override;
virtual float reflection_probe_get_origin_max_distance(RID p_probe) const override;
virtual bool reflection_probe_renders_shadows(RID p_probe) const override;
diff --git a/drivers/gles3/storage/material_storage.cpp b/drivers/gles3/storage/material_storage.cpp
index 2d81771898..2c530e3ae6 100644
--- a/drivers/gles3/storage/material_storage.cpp
+++ b/drivers/gles3/storage/material_storage.cpp
@@ -1515,7 +1515,6 @@ MaterialStorage::MaterialStorage() {
actions.renames["SPECULAR_SHININESS_TEXTURE"] = "specular_texture";
actions.renames["SPECULAR_SHININESS"] = "specular_shininess";
actions.renames["SCREEN_UV"] = "screen_uv";
- actions.renames["SCREEN_TEXTURE"] = "screen_texture";
actions.renames["SCREEN_PIXEL_SIZE"] = "screen_pixel_size";
actions.renames["FRAGCOORD"] = "gl_FragCoord";
actions.renames["POINT_COORD"] = "gl_PointCoord";
@@ -1536,7 +1535,6 @@ MaterialStorage::MaterialStorage() {
actions.renames["screen_uv_to_sdf"] = "screen_uv_to_sdf";
actions.usage_defines["COLOR"] = "#define COLOR_USED\n";
- actions.usage_defines["SCREEN_TEXTURE"] = "#define SCREEN_TEXTURE_USED\n";
actions.usage_defines["SCREEN_UV"] = "#define SCREEN_UV_USED\n";
actions.usage_defines["SCREEN_PIXEL_SIZE"] = "@SCREEN_UV";
actions.usage_defines["NORMAL"] = "#define NORMAL_USED\n";
@@ -1548,6 +1546,8 @@ MaterialStorage::MaterialStorage() {
actions.render_mode_defines["unshaded"] = "#define MODE_UNSHADED\n";
actions.render_mode_defines["light_only"] = "#define MODE_LIGHT_ONLY\n";
+ actions.global_buffer_array_variable = "global_shader_uniforms";
+
shaders.compiler_canvas.initialize(actions);
}
@@ -1617,9 +1617,6 @@ MaterialStorage::MaterialStorage() {
actions.renames["POINT_COORD"] = "gl_PointCoord";
actions.renames["INSTANCE_CUSTOM"] = "instance_custom";
actions.renames["SCREEN_UV"] = "screen_uv";
- //actions.renames["SCREEN_TEXTURE"] = "color_buffer"; //Not implemented in 3D yet.
- //actions.renames["DEPTH_TEXTURE"] = "depth_buffer"; // Not implemented in 3D yet.
- //actions.renames["NORMAL_ROUGHNESS_TEXTURE"] = "normal_roughness_buffer"; // Not implemented in 3D yet
actions.renames["DEPTH"] = "gl_FragDepth";
actions.renames["OUTPUT_IS_SRGB"] = "true";
actions.renames["FOG"] = "fog";
@@ -1640,8 +1637,9 @@ MaterialStorage::MaterialStorage() {
actions.renames["NODE_POSITION_VIEW"] = "(model_matrix * scene_data.view_matrix)[3].xyz";
actions.renames["VIEW_INDEX"] = "ViewIndex";
- actions.renames["VIEW_MONO_LEFT"] = "0";
- actions.renames["VIEW_RIGHT"] = "1";
+ actions.renames["VIEW_MONO_LEFT"] = "uint(0)";
+ actions.renames["VIEW_RIGHT"] = "uint(1)";
+ actions.renames["EYE_OFFSET"] = "eye_offset";
//for light
actions.renames["VIEW"] = "view";
@@ -1684,7 +1682,6 @@ MaterialStorage::MaterialStorage() {
actions.usage_defines["SSS_STRENGTH"] = "#define ENABLE_SSS\n";
actions.usage_defines["SSS_TRANSMITTANCE_DEPTH"] = "#define ENABLE_TRANSMITTANCE\n";
actions.usage_defines["BACKLIGHT"] = "#define LIGHT_BACKLIGHT_USED\n";
- actions.usage_defines["SCREEN_TEXTURE"] = "#define SCREEN_TEXTURE_USED\n";
actions.usage_defines["SCREEN_UV"] = "#define SCREEN_UV_USED\n";
actions.usage_defines["DIFFUSE_LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n";
@@ -1724,6 +1721,9 @@ MaterialStorage::MaterialStorage() {
actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP;
actions.default_repeat = ShaderLanguage::REPEAT_ENABLE;
+ actions.check_multiview_samplers = true;
+ actions.global_buffer_array_variable = "global_shader_uniforms";
+
shaders.compiler_scene.initialize(actions);
}
@@ -1779,6 +1779,8 @@ MaterialStorage::MaterialStorage() {
actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP;
actions.default_repeat = ShaderLanguage::REPEAT_ENABLE;
+ actions.global_buffer_array_variable = "global_shader_uniforms";
+
shaders.compiler_particles.initialize(actions);
}
@@ -1832,6 +1834,8 @@ MaterialStorage::MaterialStorage() {
actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP;
actions.default_repeat = ShaderLanguage::REPEAT_ENABLE;
+ actions.global_buffer_array_variable = "global_shader_uniforms";
+
shaders.compiler_sky.initialize(actions);
}
}
@@ -2877,6 +2881,7 @@ void MaterialStorage::material_set_render_priority(RID p_material, int priority)
if (material->data) {
material->data->set_render_priority(priority);
}
+ material->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MATERIAL);
}
bool MaterialStorage::material_is_animated(RID p_material) {
@@ -2960,7 +2965,6 @@ void CanvasShaderData::set_code(const String &p_code) {
actions.render_mode_values["blend_premul_alpha"] = Pair<int *, int>(&blend_modei, BLEND_MODE_PMALPHA);
actions.render_mode_values["blend_disabled"] = Pair<int *, int>(&blend_modei, BLEND_MODE_DISABLED);
- actions.usage_flag_pointers["SCREEN_TEXTURE"] = &uses_screen_texture;
actions.usage_flag_pointers["texture_sdf"] = &uses_sdf;
actions.usage_flag_pointers["TIME"] = &uses_time;
@@ -2974,6 +2978,7 @@ void CanvasShaderData::set_code(const String &p_code) {
blend_mode = BlendMode(blend_modei);
uses_screen_texture_mipmaps = gen_code.uses_screen_texture_mipmaps;
+ uses_screen_texture = gen_code.uses_screen_texture;
#if 0
print_line("**compiling shader:");
@@ -3309,9 +3314,6 @@ void SceneShaderData::set_code(const String &p_code) {
actions.usage_flag_pointers["SSS_STRENGTH"] = &uses_sss;
actions.usage_flag_pointers["SSS_TRANSMITTANCE_DEPTH"] = &uses_transmittance;
- actions.usage_flag_pointers["SCREEN_TEXTURE"] = &uses_screen_texture;
- actions.usage_flag_pointers["DEPTH_TEXTURE"] = &uses_depth_texture;
- actions.usage_flag_pointers["NORMAL_TEXTURE"] = &uses_normal_texture;
actions.usage_flag_pointers["DISCARD"] = &uses_discard;
actions.usage_flag_pointers["TIME"] = &uses_time;
actions.usage_flag_pointers["ROUGHNESS"] = &uses_roughness;
@@ -3364,6 +3366,9 @@ void SceneShaderData::set_code(const String &p_code) {
vertex_input_mask |= uses_bones << 9;
vertex_input_mask |= uses_weights << 10;
uses_screen_texture_mipmaps = gen_code.uses_screen_texture_mipmaps;
+ uses_screen_texture = gen_code.uses_screen_texture;
+ uses_depth_texture = gen_code.uses_depth_texture;
+ uses_normal_texture = gen_code.uses_normal_roughness_texture;
uses_vertex_time = gen_code.uses_vertex_time;
uses_fragment_time = gen_code.uses_fragment_time;
diff --git a/drivers/gles3/storage/mesh_storage.cpp b/drivers/gles3/storage/mesh_storage.cpp
index 71f262af20..1adba019ba 100644
--- a/drivers/gles3/storage/mesh_storage.cpp
+++ b/drivers/gles3/storage/mesh_storage.cpp
@@ -491,6 +491,8 @@ void MeshStorage::mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) {
Mesh *mesh = mesh_owner.get_or_null(p_mesh);
ERR_FAIL_COND(!mesh);
mesh->custom_aabb = p_aabb;
+
+ mesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
}
AABB MeshStorage::mesh_get_custom_aabb(RID p_mesh) const {
@@ -997,6 +999,11 @@ void MeshStorage::mesh_instance_check_for_update(RID p_mesh_instance) {
}
}
+void MeshStorage::mesh_instance_set_canvas_item_transform(RID p_mesh_instance, const Transform2D &p_transform) {
+ MeshInstance *mi = mesh_instance_owner.get_or_null(p_mesh_instance);
+ mi->canvas_item_transform_2d = p_transform;
+}
+
void MeshStorage::_blend_shape_bind_mesh_instance_buffer(MeshInstance *p_mi, uint32_t p_surface) {
glBindBuffer(GL_ARRAY_BUFFER, p_mi->surfaces[p_surface].vertex_buffers[0]);
@@ -1163,6 +1170,16 @@ void MeshStorage::update_mesh_instances() {
skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::BLEND_SHAPE_COUNT, float(mi->mesh->blend_shape_count), skeleton_shader.shader_version, variant, specialization);
if (can_use_skeleton) {
+ Transform2D transform = mi->canvas_item_transform_2d.affine_inverse() * sk->base_transform_2d;
+ skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::SKELETON_TRANSFORM_X, transform[0], skeleton_shader.shader_version, variant, specialization);
+ skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::SKELETON_TRANSFORM_Y, transform[1], skeleton_shader.shader_version, variant, specialization);
+ skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::SKELETON_TRANSFORM_OFFSET, transform[2], skeleton_shader.shader_version, variant, specialization);
+
+ Transform2D inverse_transform = transform.affine_inverse();
+ skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::INVERSE_TRANSFORM_X, inverse_transform[0], skeleton_shader.shader_version, variant, specialization);
+ skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::INVERSE_TRANSFORM_Y, inverse_transform[1], skeleton_shader.shader_version, variant, specialization);
+ skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::INVERSE_TRANSFORM_OFFSET, inverse_transform[2], skeleton_shader.shader_version, variant, specialization);
+
// Do last blendshape in the same pass as the Skeleton.
_compute_skeleton(mi, sk, i);
can_use_skeleton = false;
@@ -1201,6 +1218,16 @@ void MeshStorage::update_mesh_instances() {
continue;
}
+ Transform2D transform = mi->canvas_item_transform_2d.affine_inverse() * sk->base_transform_2d;
+ skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::SKELETON_TRANSFORM_X, transform[0], skeleton_shader.shader_version, variant, specialization);
+ skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::SKELETON_TRANSFORM_Y, transform[1], skeleton_shader.shader_version, variant, specialization);
+ skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::SKELETON_TRANSFORM_OFFSET, transform[2], skeleton_shader.shader_version, variant, specialization);
+
+ Transform2D inverse_transform = transform.affine_inverse();
+ skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::INVERSE_TRANSFORM_X, inverse_transform[0], skeleton_shader.shader_version, variant, specialization);
+ skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::INVERSE_TRANSFORM_Y, inverse_transform[1], skeleton_shader.shader_version, variant, specialization);
+ skeleton_shader.shader.version_set_uniform(SkeletonShaderGLES3::INVERSE_TRANSFORM_OFFSET, inverse_transform[2], skeleton_shader.shader_version, variant, specialization);
+
glBindVertexArray(mi->mesh->surfaces[i]->skeleton_vertex_array);
_compute_skeleton(mi, sk, i);
}
@@ -1659,6 +1686,8 @@ void MeshStorage::multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_b
uint32_t old_stride = multimesh->xform_format == RS::MULTIMESH_TRANSFORM_2D ? 8 : 12;
old_stride += multimesh->uses_colors ? 4 : 0;
old_stride += multimesh->uses_custom_data ? 4 : 0;
+ ERR_FAIL_COND(p_buffer.size() != (multimesh->instances * (int)old_stride));
+
for (int i = 0; i < multimesh->instances; i++) {
{
float *dataptr = w + i * old_stride;
@@ -1808,8 +1837,12 @@ void MeshStorage::multimesh_set_visible_instances(RID p_multimesh, int p_visible
}
if (multimesh->data_cache.size()) {
- //there is a data cache..
+ // There is a data cache, but we may need to update some sections.
_multimesh_mark_all_dirty(multimesh, false, true);
+ int start = multimesh->visible_instances >= 0 ? multimesh->visible_instances : multimesh->instances;
+ for (int i = start; i < p_visible; i++) {
+ _multimesh_mark_dirty(multimesh, i, true);
+ }
}
multimesh->visible_instances = p_visible;
@@ -1841,7 +1874,7 @@ void MeshStorage::_update_dirty_multimeshes() {
if (multimesh->data_cache_used_dirty_regions > 32 || multimesh->data_cache_used_dirty_regions > visible_region_count / 2) {
// If there too many dirty regions, or represent the majority of regions, just copy all, else transfer cost piles up too much
glBindBuffer(GL_ARRAY_BUFFER, multimesh->buffer);
- glBufferData(GL_ARRAY_BUFFER, MIN(visible_region_count * region_size, multimesh->instances * multimesh->stride_cache * sizeof(float)), data, GL_STATIC_DRAW);
+ glBufferSubData(GL_ARRAY_BUFFER, 0, MIN(visible_region_count * region_size, multimesh->instances * multimesh->stride_cache * sizeof(float)), data);
glBindBuffer(GL_ARRAY_BUFFER, 0);
} else {
// Not that many regions? update them all
diff --git a/drivers/gles3/storage/mesh_storage.h b/drivers/gles3/storage/mesh_storage.h
index 2efc57462b..e1c2bc3f63 100644
--- a/drivers/gles3/storage/mesh_storage.h
+++ b/drivers/gles3/storage/mesh_storage.h
@@ -163,6 +163,7 @@ struct MeshInstance {
bool weights_dirty = false;
SelfList<MeshInstance> weight_update_list;
SelfList<MeshInstance> array_update_list;
+ Transform2D canvas_item_transform_2d;
MeshInstance() :
weight_update_list(this), array_update_list(this) {}
};
@@ -423,6 +424,7 @@ public:
virtual void mesh_instance_set_skeleton(RID p_mesh_instance, RID p_skeleton) override;
virtual void mesh_instance_set_blend_shape_weight(RID p_mesh_instance, int p_shape, float p_weight) override;
virtual void mesh_instance_check_for_update(RID p_mesh_instance) override;
+ virtual void mesh_instance_set_canvas_item_transform(RID p_mesh_instance, const Transform2D &p_transform) override;
virtual void update_mesh_instances() override;
// TODO: considering hashing versions with multimesh buffer RID.
diff --git a/drivers/gles3/storage/texture_storage.cpp b/drivers/gles3/storage/texture_storage.cpp
index 489c328f64..ce66943328 100644
--- a/drivers/gles3/storage/texture_storage.cpp
+++ b/drivers/gles3/storage/texture_storage.cpp
@@ -567,27 +567,77 @@ Ref<Image> TextureStorage::_get_gl_image_and_format(const Ref<Image> &p_image, I
}
} break;
case Image::FORMAT_ETC2_RA_AS_RG: {
+#ifndef WEB_ENABLED
if (config->etc2_supported) {
r_gl_internal_format = _EXT_COMPRESSED_RGBA8_ETC2_EAC;
r_gl_format = GL_RGBA;
r_gl_type = GL_UNSIGNED_BYTE;
r_compressed = true;
- } else {
+ } else
+#endif
+ {
need_decompress = true;
}
decompress_ra_to_rg = true;
} break;
case Image::FORMAT_DXT5_RA_AS_RG: {
+#ifndef WEB_ENABLED
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;
r_compressed = true;
- } else {
+ } else
+#endif
+ {
need_decompress = true;
}
decompress_ra_to_rg = true;
} break;
+ case Image::FORMAT_ASTC_4x4: {
+ if (config->astc_supported) {
+ r_gl_internal_format = _EXT_COMPRESSED_RGBA_ASTC_4x4_KHR;
+ r_gl_format = GL_RGBA;
+ r_gl_type = GL_UNSIGNED_BYTE;
+ r_compressed = true;
+
+ } else {
+ need_decompress = true;
+ }
+ } break;
+ case Image::FORMAT_ASTC_4x4_HDR: {
+ if (config->astc_hdr_supported) {
+ r_gl_internal_format = _EXT_COMPRESSED_RGBA_ASTC_4x4_KHR;
+ r_gl_format = GL_RGBA;
+ r_gl_type = GL_UNSIGNED_BYTE;
+ r_compressed = true;
+
+ } else {
+ need_decompress = true;
+ }
+ } break;
+ case Image::FORMAT_ASTC_8x8: {
+ if (config->astc_supported) {
+ r_gl_internal_format = _EXT_COMPRESSED_RGBA_ASTC_8x8_KHR;
+ r_gl_format = GL_RGBA;
+ r_gl_type = GL_UNSIGNED_BYTE;
+ r_compressed = true;
+
+ } else {
+ need_decompress = true;
+ }
+ } break;
+ case Image::FORMAT_ASTC_8x8_HDR: {
+ if (config->astc_hdr_supported) {
+ r_gl_internal_format = _EXT_COMPRESSED_RGBA_ASTC_8x8_KHR;
+ r_gl_format = GL_RGBA;
+ r_gl_type = GL_UNSIGNED_BYTE;
+ r_compressed = true;
+
+ } else {
+ need_decompress = true;
+ }
+ } break;
default: {
ERR_FAIL_V_MSG(Ref<Image>(), "Image Format: " + itos(p_format) + " is not supported by the OpenGL3 Renderer");
}
@@ -756,6 +806,7 @@ void TextureStorage::texture_2d_update(RID p_texture, const Ref<Image> &p_image,
texture_set_data(p_texture, p_image, p_layer);
#ifdef TOOLS_ENABLED
Texture *tex = texture_owner.get_or_null(p_texture);
+ ERR_FAIL_COND(!tex);
tex->image_cache_2d.unref();
#endif
@@ -1137,6 +1188,7 @@ void TextureStorage::texture_set_data(RID p_texture, const Ref<Image> &p_image,
texture->gl_set_filter(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST);
texture->gl_set_repeat(RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
+#ifndef WEB_ENABLED
switch (texture->format) {
#ifdef GLES_OVER_GL
case Image::FORMAT_L8: {
@@ -1151,7 +1203,8 @@ void TextureStorage::texture_set_data(RID p_texture, const Ref<Image> &p_image,
glTexParameteri(texture->target, GL_TEXTURE_SWIZZLE_B, GL_RED);
glTexParameteri(texture->target, GL_TEXTURE_SWIZZLE_A, GL_GREEN);
} break;
-#endif
+#endif // GLES3_OVER_GL
+
case Image::FORMAT_ETC2_RA_AS_RG:
case Image::FORMAT_DXT5_RA_AS_RG: {
glTexParameteri(texture->target, GL_TEXTURE_SWIZZLE_R, GL_RED);
@@ -1172,6 +1225,7 @@ void TextureStorage::texture_set_data(RID p_texture, const Ref<Image> &p_image,
glTexParameteri(texture->target, GL_TEXTURE_SWIZZLE_A, GL_ALPHA);
} break;
}
+#endif // WEB_ENABLED
int mipmaps = img->has_mipmaps() ? img->get_mipmap_count() + 1 : 1;
@@ -1494,7 +1548,7 @@ RID TextureStorage::decal_allocate() {
void TextureStorage::decal_initialize(RID p_rid) {
}
-void TextureStorage::decal_set_extents(RID p_decal, const Vector3 &p_extents) {
+void TextureStorage::decal_set_size(RID p_decal, const Vector3 &p_size) {
}
void TextureStorage::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) {
@@ -1525,18 +1579,6 @@ AABB TextureStorage::decal_get_aabb(RID p_decal) const {
return AABB();
}
-/* DECAL INSTANCE API */
-
-RID TextureStorage::decal_instance_create(RID p_decal) {
- return RID();
-}
-
-void TextureStorage::decal_instance_free(RID p_decal_instance) {
-}
-
-void TextureStorage::decal_instance_set_transform(RID p_decal, const Transform3D &p_transform) {
-}
-
/* RENDER TARGET API */
GLuint TextureStorage::system_fbo = 0;
@@ -1599,9 +1641,13 @@ void TextureStorage::_update_render_target(RenderTarget *rt) {
glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
+#ifndef IOS_ENABLED
if (use_multiview) {
glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, rt->color, 0, 0, rt->view_count);
} else {
+#else
+ {
+#endif
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->color, 0);
}
@@ -1626,9 +1672,13 @@ void TextureStorage::_update_render_target(RenderTarget *rt) {
glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
+#ifndef IOS_ENABLED
if (use_multiview) {
glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, rt->depth, 0, 0, rt->view_count);
} else {
+#else
+ {
+#endif
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->depth, 0);
}
@@ -1773,6 +1823,10 @@ void TextureStorage::_clear_render_target(RenderTarget *rt) {
rt->overridden.color = RID();
} else if (rt->color) {
glDeleteTextures(1, &rt->color);
+ if (rt->texture.is_valid()) {
+ Texture *tex = get_texture(rt->texture);
+ tex->tex_id = 0;
+ }
}
rt->color = 0;
diff --git a/drivers/gles3/storage/texture_storage.h b/drivers/gles3/storage/texture_storage.h
index 9ffe16fd16..fedda6b260 100644
--- a/drivers/gles3/storage/texture_storage.h
+++ b/drivers/gles3/storage/texture_storage.h
@@ -84,6 +84,36 @@ namespace GLES3 {
#define _EXT_COMPRESSED_RGBA8_ETC2_EAC 0x9278
#define _EXT_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279
+#define _EXT_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0
+#define _EXT_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1
+#define _EXT_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2
+#define _EXT_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3
+#define _EXT_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4
+#define _EXT_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5
+#define _EXT_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6
+#define _EXT_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7
+#define _EXT_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8
+#define _EXT_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9
+#define _EXT_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA
+#define _EXT_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB
+#define _EXT_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC
+#define _EXT_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD
+
+#define _EXT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0
+#define _EXT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1
+#define _EXT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2
+#define _EXT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3
+#define _EXT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4
+#define _EXT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5
+#define _EXT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6
+#define _EXT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7
+#define _EXT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8
+#define _EXT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9
+#define _EXT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA
+#define _EXT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB
+#define _EXT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC
+#define _EXT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD
+
#define _GL_TEXTURE_EXTERNAL_OES 0x8D65
#define _EXT_TEXTURE_CUBE_MAP_SEAMLESS 0x884F
@@ -544,7 +574,7 @@ public:
virtual void decal_initialize(RID p_rid) override;
virtual void decal_free(RID p_rid) override{};
- virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) override;
+ virtual void decal_set_size(RID p_decal, const Vector3 &p_size) override;
virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) override;
virtual void decal_set_emission_energy(RID p_decal, float p_energy) override;
virtual void decal_set_albedo_mix(RID p_decal, float p_mix) override;
@@ -555,15 +585,17 @@ public:
virtual void decal_set_normal_fade(RID p_decal, float p_fade) override;
virtual AABB decal_get_aabb(RID p_decal) const override;
+ virtual uint32_t decal_get_cull_mask(RID p_decal) const override { return 0; }
virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
/* DECAL INSTANCE */
- virtual RID decal_instance_create(RID p_decal) override;
- virtual void decal_instance_free(RID p_decal_instance) override;
- virtual void decal_instance_set_transform(RID p_decal, const Transform3D &p_transform) override;
+ virtual RID decal_instance_create(RID p_decal) override { return RID(); }
+ virtual void decal_instance_free(RID p_decal_instance) override {}
+ virtual void decal_instance_set_transform(RID p_decal, const Transform3D &p_transform) override {}
+ virtual void decal_instance_set_sorting_offset(RID p_decal_instance, float p_sorting_offset) override {}
/* RENDER TARGET API */
diff --git a/drivers/gles3/storage/utilities.cpp b/drivers/gles3/storage/utilities.cpp
index e72240c69b..30c3e61ee7 100644
--- a/drivers/gles3/storage/utilities.cpp
+++ b/drivers/gles3/storage/utilities.cpp
@@ -309,6 +309,9 @@ bool Utilities::has_os_feature(const String &p_feature) const {
if (p_feature == "bptc") {
return config->bptc_supported;
}
+ if (p_feature == "astc") {
+ return config->astc_supported;
+ }
if (p_feature == "etc" || p_feature == "etc2") {
return config->etc2_supported;
diff --git a/drivers/pulseaudio/SCsub b/drivers/pulseaudio/SCsub
index 467d1448dc..f48489d787 100644
--- a/drivers/pulseaudio/SCsub
+++ b/drivers/pulseaudio/SCsub
@@ -3,6 +3,7 @@
Import("env")
if "pulseaudio" in env and env["pulseaudio"]:
- env.add_source_files(env.drivers_sources, "pulse-so_wrap.c")
+ if env["use_sowrap"]:
+ env.add_source_files(env.drivers_sources, "pulse-so_wrap.c")
env.add_source_files(env.drivers_sources, "*.cpp")
diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.cpp b/drivers/pulseaudio/audio_driver_pulseaudio.cpp
index 1c1255ce98..797ffd67fe 100644
--- a/drivers/pulseaudio/audio_driver_pulseaudio.cpp
+++ b/drivers/pulseaudio/audio_driver_pulseaudio.cpp
@@ -37,7 +37,11 @@
#include "core/version.h"
#ifdef ALSAMIDI_ENABLED
+#ifdef SOWRAP_ENABLED
#include "drivers/alsa/asound-so_wrap.h"
+#else
+#include <alsa/asoundlib.h>
+#endif
#endif
void AudioDriverPulseAudio::pa_state_cb(pa_context *c, void *userdata) {
@@ -106,15 +110,15 @@ void AudioDriverPulseAudio::pa_server_info_cb(pa_context *c, const pa_server_inf
ERR_FAIL_COND_MSG(!i, "PulseAudio server info is null.");
AudioDriverPulseAudio *ad = static_cast<AudioDriverPulseAudio *>(userdata);
- ad->capture_default_device = i->default_source_name;
- ad->default_device = i->default_sink_name;
+ ad->default_input_device = i->default_source_name;
+ ad->default_output_device = i->default_sink_name;
ad->pa_status++;
}
-Error AudioDriverPulseAudio::detect_channels(bool capture) {
- pa_channel_map_init_stereo(capture ? &pa_rec_map : &pa_map);
+Error AudioDriverPulseAudio::detect_channels(bool input) {
+ pa_channel_map_init_stereo(input ? &pa_rec_map : &pa_map);
- String device = capture ? capture_device_name : device_name;
+ String device = input ? input_device_name : output_device_name;
if (device == "Default") {
// Get the default output device name
pa_status = 0;
@@ -136,7 +140,7 @@ Error AudioDriverPulseAudio::detect_channels(bool capture) {
char dev[1024];
if (device == "Default") {
- strcpy(dev, capture ? capture_default_device.utf8().get_data() : default_device.utf8().get_data());
+ strcpy(dev, input ? default_input_device.utf8().get_data() : default_output_device.utf8().get_data());
} else {
strcpy(dev, device.utf8().get_data());
}
@@ -145,7 +149,7 @@ Error AudioDriverPulseAudio::detect_channels(bool capture) {
// Now using the device name get the amount of channels
pa_status = 0;
pa_operation *pa_op;
- if (capture) {
+ if (input) {
pa_op = pa_context_get_source_info_by_name(pa_ctx, dev, &AudioDriverPulseAudio::pa_source_info_cb, (void *)this);
} else {
pa_op = pa_context_get_sink_info_by_name(pa_ctx, dev, &AudioDriverPulseAudio::pa_sink_info_cb, (void *)this);
@@ -165,7 +169,7 @@ Error AudioDriverPulseAudio::detect_channels(bool capture) {
return FAILED;
}
} else {
- if (capture) {
+ if (input) {
ERR_PRINT("pa_context_get_source_info_by_name error");
} else {
ERR_PRINT("pa_context_get_sink_info_by_name error");
@@ -175,13 +179,13 @@ Error AudioDriverPulseAudio::detect_channels(bool capture) {
return OK;
}
-Error AudioDriverPulseAudio::init_device() {
- // If there is a specified device check that it is really present
- if (device_name != "Default") {
- PackedStringArray list = get_device_list();
- if (list.find(device_name) == -1) {
- device_name = "Default";
- new_device = "Default";
+Error AudioDriverPulseAudio::init_output_device() {
+ // If there is a specified output device, check that it is really present
+ if (output_device_name != "Default") {
+ PackedStringArray list = get_output_device_list();
+ if (list.find(output_device_name) == -1) {
+ output_device_name = "Default";
+ new_output_device = "Default";
}
}
@@ -192,7 +196,7 @@ Error AudioDriverPulseAudio::init_device() {
Error err = detect_channels();
if (err != OK) {
// This most likely means there are no sinks.
- ERR_PRINT("PulseAudio: init device failed to detect number of output channels");
+ ERR_PRINT("PulseAudio: init_output_device failed to detect number of output channels");
return err;
}
@@ -256,7 +260,7 @@ Error AudioDriverPulseAudio::init_device() {
attr.maxlength = (uint32_t)-1;
attr.minreq = (uint32_t)-1;
- const char *dev = device_name == "Default" ? nullptr : device_name.utf8().get_data();
+ const char *dev = output_device_name == "Default" ? nullptr : output_device_name.utf8().get_data();
pa_stream_flags flags = pa_stream_flags(PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_ADJUST_LATENCY | PA_STREAM_AUTO_TIMING_UPDATE);
int error_code = pa_stream_connect_playback(pa_str, dev, &attr, flags, nullptr, nullptr);
ERR_FAIL_COND_V(error_code < 0, ERR_CANT_OPEN);
@@ -264,7 +268,7 @@ Error AudioDriverPulseAudio::init_device() {
samples_in.resize(buffer_frames * channels);
samples_out.resize(pa_buffer_size);
- // Reset audio input to keep synchronisation.
+ // Reset audio input to keep synchronization.
input_position = 0;
input_size = 0;
@@ -272,6 +276,7 @@ Error AudioDriverPulseAudio::init_device() {
}
Error AudioDriverPulseAudio::init() {
+#ifdef SOWRAP_ENABLED
#ifdef DEBUG_ENABLED
int dylibloader_verbose = 1;
#else
@@ -284,7 +289,7 @@ Error AudioDriverPulseAudio::init() {
if (initialize_pulse(dylibloader_verbose)) {
return ERR_CANT_OPEN;
}
-
+#endif
active.clear();
exit_thread.clear();
@@ -346,7 +351,7 @@ Error AudioDriverPulseAudio::init() {
return ERR_CANT_OPEN;
}
- init_device();
+ init_output_device();
thread.start(AudioDriverPulseAudio::thread_func, this);
return OK;
@@ -448,18 +453,18 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
}
}
- // User selected a new device, finish the current one so we'll init the new device
- if (ad->device_name != ad->new_device) {
- ad->device_name = ad->new_device;
- ad->finish_device();
+ // User selected a new output device, finish the current one so we'll init the new output device
+ if (ad->output_device_name != ad->new_output_device) {
+ ad->output_device_name = ad->new_output_device;
+ ad->finish_output_device();
- Error err = ad->init_device();
+ Error err = ad->init_output_device();
if (err != OK) {
- ERR_PRINT("PulseAudio: init_device error");
- ad->device_name = "Default";
- ad->new_device = "Default";
+ ERR_PRINT("PulseAudio: init_output_device error");
+ ad->output_device_name = "Default";
+ ad->new_output_device = "Default";
- err = ad->init_device();
+ err = ad->init_output_device();
if (err != OK) {
ad->active.clear();
ad->exit_thread.set();
@@ -471,11 +476,11 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
write_ofs = 0;
}
- // If we're using the default device check that the current device is still the default
- if (ad->device_name == "Default") {
+ // If we're using the default output device, check that the current output device is still the default
+ if (ad->output_device_name == "Default") {
uint64_t msec = OS::get_singleton()->get_ticks_msec();
if (msec > (default_device_msec + 1000)) {
- String old_default_device = ad->default_device;
+ String old_default_device = ad->default_output_device;
default_device_msec = msec;
@@ -494,12 +499,12 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
ERR_PRINT("pa_context_get_server_info error: " + String(pa_strerror(pa_context_errno(ad->pa_ctx))));
}
- if (old_default_device != ad->default_device) {
- ad->finish_device();
+ if (old_default_device != ad->default_output_device) {
+ ad->finish_output_device();
- Error err = ad->init_device();
+ Error err = ad->init_output_device();
if (err != OK) {
- ERR_PRINT("PulseAudio: init_device error");
+ ERR_PRINT("PulseAudio: init_output_device error");
ad->active.clear();
ad->exit_thread.set();
break;
@@ -541,18 +546,18 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
}
}
- // User selected a new device, finish the current one so we'll init the new device
- if (ad->capture_device_name != ad->capture_new_device) {
- ad->capture_device_name = ad->capture_new_device;
- ad->capture_finish_device();
+ // User selected a new input device, finish the current one so we'll init the new input device
+ if (ad->input_device_name != ad->new_input_device) {
+ ad->input_device_name = ad->new_input_device;
+ ad->finish_input_device();
- Error err = ad->capture_init_device();
+ Error err = ad->init_input_device();
if (err != OK) {
- ERR_PRINT("PulseAudio: capture_init_device error");
- ad->capture_device_name = "Default";
- ad->capture_new_device = "Default";
+ ERR_PRINT("PulseAudio: init_input_device error");
+ ad->input_device_name = "Default";
+ ad->new_input_device = "Default";
- err = ad->capture_init_device();
+ err = ad->init_input_device();
if (err != OK) {
ad->active.clear();
ad->exit_thread.set();
@@ -596,7 +601,7 @@ void AudioDriverPulseAudio::pa_sinklist_cb(pa_context *c, const pa_sink_info *l,
ad->pa_status++;
}
-PackedStringArray AudioDriverPulseAudio::get_device_list() {
+PackedStringArray AudioDriverPulseAudio::get_output_device_list() {
pa_devices.clear();
pa_devices.push_back("Default");
@@ -606,7 +611,7 @@ PackedStringArray AudioDriverPulseAudio::get_device_list() {
lock();
- // Get the device list
+ // Get the output device list
pa_status = 0;
pa_operation *pa_op = pa_context_get_sink_info_list(pa_ctx, pa_sinklist_cb, (void *)this);
if (pa_op) {
@@ -627,13 +632,13 @@ PackedStringArray AudioDriverPulseAudio::get_device_list() {
return pa_devices;
}
-String AudioDriverPulseAudio::get_device() {
- return device_name;
+String AudioDriverPulseAudio::get_output_device() {
+ return output_device_name;
}
-void AudioDriverPulseAudio::set_device(String device) {
+void AudioDriverPulseAudio::set_output_device(const String &p_name) {
lock();
- new_device = device;
+ new_output_device = p_name;
unlock();
}
@@ -645,7 +650,7 @@ void AudioDriverPulseAudio::unlock() {
mutex.unlock();
}
-void AudioDriverPulseAudio::finish_device() {
+void AudioDriverPulseAudio::finish_output_device() {
if (pa_str) {
pa_stream_disconnect(pa_str);
pa_stream_unref(pa_str);
@@ -661,7 +666,7 @@ void AudioDriverPulseAudio::finish() {
exit_thread.set();
thread.wait_to_finish();
- finish_device();
+ finish_output_device();
if (pa_ctx) {
pa_context_disconnect(pa_ctx);
@@ -675,13 +680,13 @@ void AudioDriverPulseAudio::finish() {
}
}
-Error AudioDriverPulseAudio::capture_init_device() {
- // If there is a specified device check that it is really present
- if (capture_device_name != "Default") {
- PackedStringArray list = capture_get_device_list();
- if (list.find(capture_device_name) == -1) {
- capture_device_name = "Default";
- capture_new_device = "Default";
+Error AudioDriverPulseAudio::init_input_device() {
+ // If there is a specified input device, check that it is really present
+ if (input_device_name != "Default") {
+ PackedStringArray list = get_input_device_list();
+ if (list.find(input_device_name) == -1) {
+ input_device_name = "Default";
+ new_input_device = "Default";
}
}
@@ -718,7 +723,7 @@ Error AudioDriverPulseAudio::capture_init_device() {
ERR_FAIL_V(ERR_CANT_OPEN);
}
- const char *dev = capture_device_name == "Default" ? nullptr : capture_device_name.utf8().get_data();
+ const char *dev = input_device_name == "Default" ? nullptr : input_device_name.utf8().get_data();
pa_stream_flags flags = pa_stream_flags(PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_ADJUST_LATENCY | PA_STREAM_AUTO_TIMING_UPDATE);
int error_code = pa_stream_connect_record(pa_rec_str, dev, &attr, flags);
if (error_code < 0) {
@@ -734,7 +739,7 @@ Error AudioDriverPulseAudio::capture_init_device() {
return OK;
}
-void AudioDriverPulseAudio::capture_finish_device() {
+void AudioDriverPulseAudio::finish_input_device() {
if (pa_rec_str) {
int ret = pa_stream_disconnect(pa_rec_str);
if (ret != 0) {
@@ -745,28 +750,22 @@ void AudioDriverPulseAudio::capture_finish_device() {
}
}
-Error AudioDriverPulseAudio::capture_start() {
+Error AudioDriverPulseAudio::input_start() {
lock();
- Error err = capture_init_device();
+ Error err = init_input_device();
unlock();
return err;
}
-Error AudioDriverPulseAudio::capture_stop() {
+Error AudioDriverPulseAudio::input_stop() {
lock();
- capture_finish_device();
+ finish_input_device();
unlock();
return OK;
}
-void AudioDriverPulseAudio::capture_set_device(const String &p_name) {
- lock();
- capture_new_device = p_name;
- unlock();
-}
-
void AudioDriverPulseAudio::pa_sourcelist_cb(pa_context *c, const pa_source_info *l, int eol, void *userdata) {
AudioDriverPulseAudio *ad = static_cast<AudioDriverPulseAudio *>(userdata);
@@ -782,7 +781,7 @@ void AudioDriverPulseAudio::pa_sourcelist_cb(pa_context *c, const pa_source_info
ad->pa_status++;
}
-PackedStringArray AudioDriverPulseAudio::capture_get_device_list() {
+PackedStringArray AudioDriverPulseAudio::get_input_device_list() {
pa_rec_devices.clear();
pa_rec_devices.push_back("Default");
@@ -813,14 +812,20 @@ PackedStringArray AudioDriverPulseAudio::capture_get_device_list() {
return pa_rec_devices;
}
-String AudioDriverPulseAudio::capture_get_device() {
+String AudioDriverPulseAudio::get_input_device() {
lock();
- String name = capture_device_name;
+ String name = input_device_name;
unlock();
return name;
}
+void AudioDriverPulseAudio::set_input_device(const String &p_name) {
+ lock();
+ new_input_device = p_name;
+ unlock();
+}
+
AudioDriverPulseAudio::AudioDriverPulseAudio() {
samples_in.clear();
samples_out.clear();
diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.h b/drivers/pulseaudio/audio_driver_pulseaudio.h
index 16398e67eb..585e882059 100644
--- a/drivers/pulseaudio/audio_driver_pulseaudio.h
+++ b/drivers/pulseaudio/audio_driver_pulseaudio.h
@@ -38,7 +38,11 @@
#include "core/templates/safe_refcount.h"
#include "servers/audio_server.h"
+#ifdef SOWRAP_ENABLED
#include "pulse-so_wrap.h"
+#else
+#include <pulse/pulseaudio.h>
+#endif
class AudioDriverPulseAudio : public AudioDriver {
Thread thread;
@@ -51,13 +55,13 @@ class AudioDriverPulseAudio : public AudioDriver {
pa_channel_map pa_map = {};
pa_channel_map pa_rec_map = {};
- String device_name = "Default";
- String new_device = "Default";
- String default_device;
+ String output_device_name = "Default";
+ String new_output_device = "Default";
+ String default_output_device;
- String capture_device_name;
- String capture_new_device;
- String capture_default_device;
+ String input_device_name;
+ String new_input_device;
+ String default_input_device;
Vector<int32_t> samples_in;
Vector<int16_t> samples_out;
@@ -83,42 +87,41 @@ class AudioDriverPulseAudio : public AudioDriver {
static void pa_sinklist_cb(pa_context *c, const pa_sink_info *l, int eol, void *userdata);
static void pa_sourcelist_cb(pa_context *c, const pa_source_info *l, int eol, void *userdata);
- Error init_device();
- void finish_device();
+ Error init_output_device();
+ void finish_output_device();
- Error capture_init_device();
- void capture_finish_device();
+ Error init_input_device();
+ void finish_input_device();
Error detect_channels(bool capture = false);
static void thread_func(void *p_udata);
public:
- const char *get_name() const {
+ virtual const char *get_name() const override {
return "PulseAudio";
};
- virtual Error init();
- virtual void start();
- virtual int get_mix_rate() const;
- virtual SpeakerMode get_speaker_mode() const;
+ virtual Error init() override;
+ virtual void start() override;
+ virtual int get_mix_rate() const override;
+ virtual SpeakerMode get_speaker_mode() const override;
+ virtual float get_latency() override;
- virtual PackedStringArray get_device_list();
- virtual String get_device();
- virtual void set_device(String device);
+ virtual void lock() override;
+ virtual void unlock() override;
+ virtual void finish() override;
- virtual PackedStringArray capture_get_device_list();
- virtual void capture_set_device(const String &p_name);
- virtual String capture_get_device();
+ virtual PackedStringArray get_output_device_list() override;
+ virtual String get_output_device() override;
+ virtual void set_output_device(const String &p_name) override;
- virtual void lock();
- virtual void unlock();
- virtual void finish();
+ virtual Error input_start() override;
+ virtual Error input_stop() override;
- virtual float get_latency();
-
- virtual Error capture_start();
- virtual Error capture_stop();
+ virtual PackedStringArray get_input_device_list() override;
+ virtual String get_input_device() override;
+ virtual void set_input_device(const String &p_name) override;
AudioDriverPulseAudio();
~AudioDriverPulseAudio() {}
diff --git a/drivers/pulseaudio/pulse-so_wrap.c b/drivers/pulseaudio/pulse-so_wrap.c
index 12bdcc704e..8f477740ce 100644
--- a/drivers/pulseaudio/pulse-so_wrap.c
+++ b/drivers/pulseaudio/pulse-so_wrap.c
@@ -1,7 +1,7 @@
// This file is generated. Do not edit!
// see https://github.com/hpvb/dynload-wrapper for details
-// generated by /home/hp/Projects/godot/pulse/generate-wrapper.py 0.3 on 2021-02-20 00:08:31
-// flags: /home/hp/Projects/godot/pulse/generate-wrapper.py --include /usr/include/pulse/pulseaudio.h --sys-include <pulse/pulseaudio.h> --soname libpulse.so.0 --omit-prefix _pa_ --init-name pulse --output-header pulse-so_wrap.h --output-implementation pulse-so_wrap.c
+// generated by generate-wrapper.py 0.3 on 2023-01-12 10:26:29
+// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/pulse/pulseaudio.h --sys-include "thirdparty/linuxbsd_headers/pulse/pulseaudio.h" --soname libpulse.so.0 --omit-prefix _pa_ --init-name pulse --output-header ./drivers/pulseaudio/pulse-so_wrap.h --output-implementation ./drivers/pulseaudio/pulse-so_wrap.c
//
#include <stdint.h>
@@ -89,10 +89,6 @@
#define pa_format_info_get_prop_string pa_format_info_get_prop_string_dylibloader_orig_pulse
#define pa_format_info_get_prop_string_array pa_format_info_get_prop_string_array_dylibloader_orig_pulse
#define pa_format_info_free_string_array pa_format_info_free_string_array_dylibloader_orig_pulse
-#define pa_format_info_get_sample_format pa_format_info_get_sample_format_dylibloader_orig_pulse
-#define pa_format_info_get_rate pa_format_info_get_rate_dylibloader_orig_pulse
-#define pa_format_info_get_channels pa_format_info_get_channels_dylibloader_orig_pulse
-#define pa_format_info_get_channel_map pa_format_info_get_channel_map_dylibloader_orig_pulse
#define pa_format_info_set_prop_int pa_format_info_set_prop_int_dylibloader_orig_pulse
#define pa_format_info_set_prop_int_array pa_format_info_set_prop_int_array_dylibloader_orig_pulse
#define pa_format_info_set_prop_int_range pa_format_info_set_prop_int_range_dylibloader_orig_pulse
@@ -327,7 +323,6 @@
#define pa_threaded_mainloop_get_api pa_threaded_mainloop_get_api_dylibloader_orig_pulse
#define pa_threaded_mainloop_in_thread pa_threaded_mainloop_in_thread_dylibloader_orig_pulse
#define pa_threaded_mainloop_set_name pa_threaded_mainloop_set_name_dylibloader_orig_pulse
-#define pa_threaded_mainloop_once_unlocked pa_threaded_mainloop_once_unlocked_dylibloader_orig_pulse
#define pa_mainloop_new pa_mainloop_new_dylibloader_orig_pulse
#define pa_mainloop_free pa_mainloop_free_dylibloader_orig_pulse
#define pa_mainloop_prepare pa_mainloop_prepare_dylibloader_orig_pulse
@@ -352,7 +347,6 @@
#define pa_get_binary_name pa_get_binary_name_dylibloader_orig_pulse
#define pa_path_get_filename pa_path_get_filename_dylibloader_orig_pulse
#define pa_msleep pa_msleep_dylibloader_orig_pulse
-#define pa_thread_make_realtime pa_thread_make_realtime_dylibloader_orig_pulse
#define pa_gettimeofday pa_gettimeofday_dylibloader_orig_pulse
#define pa_timeval_diff pa_timeval_diff_dylibloader_orig_pulse
#define pa_timeval_cmp pa_timeval_cmp_dylibloader_orig_pulse
@@ -362,7 +356,7 @@
#define pa_timeval_store pa_timeval_store_dylibloader_orig_pulse
#define pa_timeval_load pa_timeval_load_dylibloader_orig_pulse
#define pa_rtclock_now pa_rtclock_now_dylibloader_orig_pulse
-#include <pulse/pulseaudio.h>
+#include "thirdparty/linuxbsd_headers/pulse/pulseaudio.h"
#undef pa_get_library_version
#undef pa_bytes_per_second
#undef pa_frame_size
@@ -447,10 +441,6 @@
#undef pa_format_info_get_prop_string
#undef pa_format_info_get_prop_string_array
#undef pa_format_info_free_string_array
-#undef pa_format_info_get_sample_format
-#undef pa_format_info_get_rate
-#undef pa_format_info_get_channels
-#undef pa_format_info_get_channel_map
#undef pa_format_info_set_prop_int
#undef pa_format_info_set_prop_int_array
#undef pa_format_info_set_prop_int_range
@@ -685,7 +675,6 @@
#undef pa_threaded_mainloop_get_api
#undef pa_threaded_mainloop_in_thread
#undef pa_threaded_mainloop_set_name
-#undef pa_threaded_mainloop_once_unlocked
#undef pa_mainloop_new
#undef pa_mainloop_free
#undef pa_mainloop_prepare
@@ -710,7 +699,6 @@
#undef pa_get_binary_name
#undef pa_path_get_filename
#undef pa_msleep
-#undef pa_thread_make_realtime
#undef pa_gettimeofday
#undef pa_timeval_diff
#undef pa_timeval_cmp
@@ -751,21 +739,21 @@ int (*pa_proplist_sets_dylibloader_wrapper_pulse)( pa_proplist*,const char*,cons
int (*pa_proplist_setp_dylibloader_wrapper_pulse)( pa_proplist*,const char*);
int (*pa_proplist_setf_dylibloader_wrapper_pulse)( pa_proplist*,const char*,const char*,...);
int (*pa_proplist_set_dylibloader_wrapper_pulse)( pa_proplist*,const char*,const void*, size_t);
-const char* (*pa_proplist_gets_dylibloader_wrapper_pulse)(const pa_proplist*,const char*);
-int (*pa_proplist_get_dylibloader_wrapper_pulse)(const pa_proplist*,const char*,const void**, size_t*);
+const char* (*pa_proplist_gets_dylibloader_wrapper_pulse)( pa_proplist*,const char*);
+int (*pa_proplist_get_dylibloader_wrapper_pulse)( pa_proplist*,const char*,const void**, size_t*);
void (*pa_proplist_update_dylibloader_wrapper_pulse)( pa_proplist*, pa_update_mode_t,const pa_proplist*);
int (*pa_proplist_unset_dylibloader_wrapper_pulse)( pa_proplist*,const char*);
int (*pa_proplist_unset_many_dylibloader_wrapper_pulse)( pa_proplist*,const char* []);
-const char* (*pa_proplist_iterate_dylibloader_wrapper_pulse)(const pa_proplist*, void**);
-char* (*pa_proplist_to_string_dylibloader_wrapper_pulse)(const pa_proplist*);
-char* (*pa_proplist_to_string_sep_dylibloader_wrapper_pulse)(const pa_proplist*,const char*);
+const char* (*pa_proplist_iterate_dylibloader_wrapper_pulse)( pa_proplist*, void**);
+char* (*pa_proplist_to_string_dylibloader_wrapper_pulse)( pa_proplist*);
+char* (*pa_proplist_to_string_sep_dylibloader_wrapper_pulse)( pa_proplist*,const char*);
pa_proplist* (*pa_proplist_from_string_dylibloader_wrapper_pulse)(const char*);
-int (*pa_proplist_contains_dylibloader_wrapper_pulse)(const pa_proplist*,const char*);
+int (*pa_proplist_contains_dylibloader_wrapper_pulse)( pa_proplist*,const char*);
void (*pa_proplist_clear_dylibloader_wrapper_pulse)( pa_proplist*);
pa_proplist* (*pa_proplist_copy_dylibloader_wrapper_pulse)(const pa_proplist*);
-unsigned (*pa_proplist_size_dylibloader_wrapper_pulse)(const pa_proplist*);
-int (*pa_proplist_isempty_dylibloader_wrapper_pulse)(const pa_proplist*);
-int (*pa_proplist_equal_dylibloader_wrapper_pulse)(const pa_proplist*,const pa_proplist*);
+unsigned (*pa_proplist_size_dylibloader_wrapper_pulse)( pa_proplist*);
+int (*pa_proplist_isempty_dylibloader_wrapper_pulse)( pa_proplist*);
+int (*pa_proplist_equal_dylibloader_wrapper_pulse)( pa_proplist*, pa_proplist*);
pa_channel_map* (*pa_channel_map_init_dylibloader_wrapper_pulse)( pa_channel_map*);
pa_channel_map* (*pa_channel_map_init_mono_dylibloader_wrapper_pulse)( pa_channel_map*);
pa_channel_map* (*pa_channel_map_init_stereo_dylibloader_wrapper_pulse)( pa_channel_map*);
@@ -806,10 +794,6 @@ int (*pa_format_info_get_prop_int_array_dylibloader_wrapper_pulse)(const pa_form
int (*pa_format_info_get_prop_string_dylibloader_wrapper_pulse)(const pa_format_info*,const char*, char**);
int (*pa_format_info_get_prop_string_array_dylibloader_wrapper_pulse)(const pa_format_info*,const char*, char***, int*);
void (*pa_format_info_free_string_array_dylibloader_wrapper_pulse)( char**, int);
-int (*pa_format_info_get_sample_format_dylibloader_wrapper_pulse)(const pa_format_info*, pa_sample_format_t*);
-int (*pa_format_info_get_rate_dylibloader_wrapper_pulse)(const pa_format_info*, uint32_t*);
-int (*pa_format_info_get_channels_dylibloader_wrapper_pulse)(const pa_format_info*, uint8_t*);
-int (*pa_format_info_get_channel_map_dylibloader_wrapper_pulse)(const pa_format_info*, pa_channel_map*);
void (*pa_format_info_set_prop_int_dylibloader_wrapper_pulse)( pa_format_info*,const char*, int);
void (*pa_format_info_set_prop_int_array_dylibloader_wrapper_pulse)( pa_format_info*,const char*,const int*, int);
void (*pa_format_info_set_prop_int_range_dylibloader_wrapper_pulse)( pa_format_info*,const char*, int, int);
@@ -822,34 +806,34 @@ void (*pa_format_info_set_channel_map_dylibloader_wrapper_pulse)( pa_format_info
pa_operation* (*pa_operation_ref_dylibloader_wrapper_pulse)( pa_operation*);
void (*pa_operation_unref_dylibloader_wrapper_pulse)( pa_operation*);
void (*pa_operation_cancel_dylibloader_wrapper_pulse)( pa_operation*);
-pa_operation_state_t (*pa_operation_get_state_dylibloader_wrapper_pulse)(const pa_operation*);
+pa_operation_state_t (*pa_operation_get_state_dylibloader_wrapper_pulse)( pa_operation*);
void (*pa_operation_set_state_callback_dylibloader_wrapper_pulse)( pa_operation*, pa_operation_notify_cb_t, void*);
pa_context* (*pa_context_new_dylibloader_wrapper_pulse)( pa_mainloop_api*,const char*);
-pa_context* (*pa_context_new_with_proplist_dylibloader_wrapper_pulse)( pa_mainloop_api*,const char*,const pa_proplist*);
+pa_context* (*pa_context_new_with_proplist_dylibloader_wrapper_pulse)( pa_mainloop_api*,const char*, pa_proplist*);
void (*pa_context_unref_dylibloader_wrapper_pulse)( pa_context*);
pa_context* (*pa_context_ref_dylibloader_wrapper_pulse)( pa_context*);
void (*pa_context_set_state_callback_dylibloader_wrapper_pulse)( pa_context*, pa_context_notify_cb_t, void*);
void (*pa_context_set_event_callback_dylibloader_wrapper_pulse)( pa_context*, pa_context_event_cb_t, void*);
-int (*pa_context_errno_dylibloader_wrapper_pulse)(const pa_context*);
-int (*pa_context_is_pending_dylibloader_wrapper_pulse)(const pa_context*);
-pa_context_state_t (*pa_context_get_state_dylibloader_wrapper_pulse)(const pa_context*);
+int (*pa_context_errno_dylibloader_wrapper_pulse)( pa_context*);
+int (*pa_context_is_pending_dylibloader_wrapper_pulse)( pa_context*);
+pa_context_state_t (*pa_context_get_state_dylibloader_wrapper_pulse)( pa_context*);
int (*pa_context_connect_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_context_flags_t,const pa_spawn_api*);
void (*pa_context_disconnect_dylibloader_wrapper_pulse)( pa_context*);
pa_operation* (*pa_context_drain_dylibloader_wrapper_pulse)( pa_context*, pa_context_notify_cb_t, void*);
pa_operation* (*pa_context_exit_daemon_dylibloader_wrapper_pulse)( pa_context*, pa_context_success_cb_t, void*);
pa_operation* (*pa_context_set_default_sink_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_context_success_cb_t, void*);
pa_operation* (*pa_context_set_default_source_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_context_success_cb_t, void*);
-int (*pa_context_is_local_dylibloader_wrapper_pulse)(const pa_context*);
+int (*pa_context_is_local_dylibloader_wrapper_pulse)( pa_context*);
pa_operation* (*pa_context_set_name_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_context_success_cb_t, void*);
-const char* (*pa_context_get_server_dylibloader_wrapper_pulse)(const pa_context*);
-uint32_t (*pa_context_get_protocol_version_dylibloader_wrapper_pulse)(const pa_context*);
-uint32_t (*pa_context_get_server_protocol_version_dylibloader_wrapper_pulse)(const pa_context*);
-pa_operation* (*pa_context_proplist_update_dylibloader_wrapper_pulse)( pa_context*, pa_update_mode_t,const pa_proplist*, pa_context_success_cb_t, void*);
+const char* (*pa_context_get_server_dylibloader_wrapper_pulse)( pa_context*);
+uint32_t (*pa_context_get_protocol_version_dylibloader_wrapper_pulse)( pa_context*);
+uint32_t (*pa_context_get_server_protocol_version_dylibloader_wrapper_pulse)( pa_context*);
+pa_operation* (*pa_context_proplist_update_dylibloader_wrapper_pulse)( pa_context*, pa_update_mode_t, pa_proplist*, pa_context_success_cb_t, void*);
pa_operation* (*pa_context_proplist_remove_dylibloader_wrapper_pulse)( pa_context*,const char* [], pa_context_success_cb_t, void*);
-uint32_t (*pa_context_get_index_dylibloader_wrapper_pulse)(const pa_context*);
-pa_time_event* (*pa_context_rttime_new_dylibloader_wrapper_pulse)(const pa_context*, pa_usec_t, pa_time_event_cb_t, void*);
-void (*pa_context_rttime_restart_dylibloader_wrapper_pulse)(const pa_context*, pa_time_event*, pa_usec_t);
-size_t (*pa_context_get_tile_size_dylibloader_wrapper_pulse)(const pa_context*,const pa_sample_spec*);
+uint32_t (*pa_context_get_index_dylibloader_wrapper_pulse)( pa_context*);
+pa_time_event* (*pa_context_rttime_new_dylibloader_wrapper_pulse)( pa_context*, pa_usec_t, pa_time_event_cb_t, void*);
+void (*pa_context_rttime_restart_dylibloader_wrapper_pulse)( pa_context*, pa_time_event*, pa_usec_t);
+size_t (*pa_context_get_tile_size_dylibloader_wrapper_pulse)( pa_context*,const pa_sample_spec*);
int (*pa_context_load_cookie_from_file_dylibloader_wrapper_pulse)( pa_context*,const char*);
int (*pa_cvolume_equal_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_cvolume*);
pa_cvolume* (*pa_cvolume_init_dylibloader_wrapper_pulse)( pa_cvolume*);
@@ -888,9 +872,9 @@ pa_cvolume* (*pa_cvolume_set_fade_dylibloader_wrapper_pulse)( pa_cvolume*,const
float (*pa_cvolume_get_lfe_balance_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_channel_map*);
pa_cvolume* (*pa_cvolume_set_lfe_balance_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_channel_map*, float);
pa_cvolume* (*pa_cvolume_scale_dylibloader_wrapper_pulse)( pa_cvolume*, pa_volume_t);
-pa_cvolume* (*pa_cvolume_scale_mask_dylibloader_wrapper_pulse)( pa_cvolume*, pa_volume_t,const pa_channel_map*, pa_channel_position_mask_t);
+pa_cvolume* (*pa_cvolume_scale_mask_dylibloader_wrapper_pulse)( pa_cvolume*, pa_volume_t, pa_channel_map*, pa_channel_position_mask_t);
pa_cvolume* (*pa_cvolume_set_position_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_channel_map*, pa_channel_position_t, pa_volume_t);
-pa_volume_t (*pa_cvolume_get_position_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_channel_map*, pa_channel_position_t);
+pa_volume_t (*pa_cvolume_get_position_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_channel_map*, pa_channel_position_t);
pa_cvolume* (*pa_cvolume_merge_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_cvolume*,const pa_cvolume*);
pa_cvolume* (*pa_cvolume_inc_clamp_dylibloader_wrapper_pulse)( pa_cvolume*, pa_volume_t, pa_volume_t);
pa_cvolume* (*pa_cvolume_inc_dylibloader_wrapper_pulse)( pa_cvolume*, pa_volume_t);
@@ -900,13 +884,13 @@ pa_stream* (*pa_stream_new_with_proplist_dylibloader_wrapper_pulse)( pa_context*
pa_stream* (*pa_stream_new_extended_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_format_info**, unsigned int, pa_proplist*);
void (*pa_stream_unref_dylibloader_wrapper_pulse)( pa_stream*);
pa_stream* (*pa_stream_ref_dylibloader_wrapper_pulse)( pa_stream*);
-pa_stream_state_t (*pa_stream_get_state_dylibloader_wrapper_pulse)(const pa_stream*);
-pa_context* (*pa_stream_get_context_dylibloader_wrapper_pulse)(const pa_stream*);
-uint32_t (*pa_stream_get_index_dylibloader_wrapper_pulse)(const pa_stream*);
-uint32_t (*pa_stream_get_device_index_dylibloader_wrapper_pulse)(const pa_stream*);
-const char* (*pa_stream_get_device_name_dylibloader_wrapper_pulse)(const pa_stream*);
-int (*pa_stream_is_suspended_dylibloader_wrapper_pulse)(const pa_stream*);
-int (*pa_stream_is_corked_dylibloader_wrapper_pulse)(const pa_stream*);
+pa_stream_state_t (*pa_stream_get_state_dylibloader_wrapper_pulse)( pa_stream*);
+pa_context* (*pa_stream_get_context_dylibloader_wrapper_pulse)( pa_stream*);
+uint32_t (*pa_stream_get_index_dylibloader_wrapper_pulse)( pa_stream*);
+uint32_t (*pa_stream_get_device_index_dylibloader_wrapper_pulse)( pa_stream*);
+const char* (*pa_stream_get_device_name_dylibloader_wrapper_pulse)( pa_stream*);
+int (*pa_stream_is_suspended_dylibloader_wrapper_pulse)( pa_stream*);
+int (*pa_stream_is_corked_dylibloader_wrapper_pulse)( pa_stream*);
int (*pa_stream_connect_playback_dylibloader_wrapper_pulse)( pa_stream*,const char*,const pa_buffer_attr*, pa_stream_flags_t,const pa_cvolume*, pa_stream*);
int (*pa_stream_connect_record_dylibloader_wrapper_pulse)( pa_stream*,const char*,const pa_buffer_attr*, pa_stream_flags_t);
int (*pa_stream_disconnect_dylibloader_wrapper_pulse)( pa_stream*);
@@ -916,15 +900,15 @@ int (*pa_stream_write_dylibloader_wrapper_pulse)( pa_stream*,const void*, size_t
int (*pa_stream_write_ext_free_dylibloader_wrapper_pulse)( pa_stream*,const void*, size_t, pa_free_cb_t, void*, int64_t, pa_seek_mode_t);
int (*pa_stream_peek_dylibloader_wrapper_pulse)( pa_stream*,const void**, size_t*);
int (*pa_stream_drop_dylibloader_wrapper_pulse)( pa_stream*);
-size_t (*pa_stream_writable_size_dylibloader_wrapper_pulse)(const pa_stream*);
-size_t (*pa_stream_readable_size_dylibloader_wrapper_pulse)(const pa_stream*);
+size_t (*pa_stream_writable_size_dylibloader_wrapper_pulse)( pa_stream*);
+size_t (*pa_stream_readable_size_dylibloader_wrapper_pulse)( pa_stream*);
pa_operation* (*pa_stream_drain_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_success_cb_t, void*);
pa_operation* (*pa_stream_update_timing_info_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_success_cb_t, void*);
void (*pa_stream_set_state_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*);
void (*pa_stream_set_write_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_request_cb_t, void*);
void (*pa_stream_set_read_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_request_cb_t, void*);
void (*pa_stream_set_overflow_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*);
-int64_t (*pa_stream_get_underflow_index_dylibloader_wrapper_pulse)(const pa_stream*);
+int64_t (*pa_stream_get_underflow_index_dylibloader_wrapper_pulse)( pa_stream*);
void (*pa_stream_set_underflow_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*);
void (*pa_stream_set_started_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*);
void (*pa_stream_set_latency_update_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*);
@@ -942,14 +926,14 @@ int (*pa_stream_get_latency_dylibloader_wrapper_pulse)( pa_stream*, pa_usec_t*,
const pa_timing_info* (*pa_stream_get_timing_info_dylibloader_wrapper_pulse)( pa_stream*);
const pa_sample_spec* (*pa_stream_get_sample_spec_dylibloader_wrapper_pulse)( pa_stream*);
const pa_channel_map* (*pa_stream_get_channel_map_dylibloader_wrapper_pulse)( pa_stream*);
-const pa_format_info* (*pa_stream_get_format_info_dylibloader_wrapper_pulse)(const pa_stream*);
+const pa_format_info* (*pa_stream_get_format_info_dylibloader_wrapper_pulse)( pa_stream*);
const pa_buffer_attr* (*pa_stream_get_buffer_attr_dylibloader_wrapper_pulse)( pa_stream*);
pa_operation* (*pa_stream_set_buffer_attr_dylibloader_wrapper_pulse)( pa_stream*,const pa_buffer_attr*, pa_stream_success_cb_t, void*);
pa_operation* (*pa_stream_update_sample_rate_dylibloader_wrapper_pulse)( pa_stream*, uint32_t, pa_stream_success_cb_t, void*);
pa_operation* (*pa_stream_proplist_update_dylibloader_wrapper_pulse)( pa_stream*, pa_update_mode_t, pa_proplist*, pa_stream_success_cb_t, void*);
pa_operation* (*pa_stream_proplist_remove_dylibloader_wrapper_pulse)( pa_stream*,const char* [], pa_stream_success_cb_t, void*);
int (*pa_stream_set_monitor_stream_dylibloader_wrapper_pulse)( pa_stream*, uint32_t);
-uint32_t (*pa_stream_get_monitor_stream_dylibloader_wrapper_pulse)(const pa_stream*);
+uint32_t (*pa_stream_get_monitor_stream_dylibloader_wrapper_pulse)( pa_stream*);
pa_operation* (*pa_context_get_sink_info_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_sink_info_cb_t, void*);
pa_operation* (*pa_context_get_sink_info_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_sink_info_cb_t, void*);
pa_operation* (*pa_context_get_sink_info_list_dylibloader_wrapper_pulse)( pa_context*, pa_sink_info_cb_t, void*);
@@ -1016,7 +1000,7 @@ int (*pa_stream_connect_upload_dylibloader_wrapper_pulse)( pa_stream*, size_t);
int (*pa_stream_finish_upload_dylibloader_wrapper_pulse)( pa_stream*);
pa_operation* (*pa_context_remove_sample_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_context_success_cb_t, void*);
pa_operation* (*pa_context_play_sample_dylibloader_wrapper_pulse)( pa_context*,const char*,const char*, pa_volume_t, pa_context_success_cb_t, void*);
-pa_operation* (*pa_context_play_sample_with_proplist_dylibloader_wrapper_pulse)( pa_context*,const char*,const char*, pa_volume_t,const pa_proplist*, pa_context_play_sample_cb_t, void*);
+pa_operation* (*pa_context_play_sample_with_proplist_dylibloader_wrapper_pulse)( pa_context*,const char*,const char*, pa_volume_t, pa_proplist*, pa_context_play_sample_cb_t, void*);
const char* (*pa_strerror_dylibloader_wrapper_pulse)( int);
void* (*pa_xmalloc_dylibloader_wrapper_pulse)( size_t);
void* (*pa_xmalloc0_dylibloader_wrapper_pulse)( size_t);
@@ -1040,17 +1024,16 @@ void (*pa_threaded_mainloop_unlock_dylibloader_wrapper_pulse)( pa_threaded_mainl
void (*pa_threaded_mainloop_wait_dylibloader_wrapper_pulse)( pa_threaded_mainloop*);
void (*pa_threaded_mainloop_signal_dylibloader_wrapper_pulse)( pa_threaded_mainloop*, int);
void (*pa_threaded_mainloop_accept_dylibloader_wrapper_pulse)( pa_threaded_mainloop*);
-int (*pa_threaded_mainloop_get_retval_dylibloader_wrapper_pulse)(const pa_threaded_mainloop*);
+int (*pa_threaded_mainloop_get_retval_dylibloader_wrapper_pulse)( pa_threaded_mainloop*);
pa_mainloop_api* (*pa_threaded_mainloop_get_api_dylibloader_wrapper_pulse)( pa_threaded_mainloop*);
int (*pa_threaded_mainloop_in_thread_dylibloader_wrapper_pulse)( pa_threaded_mainloop*);
void (*pa_threaded_mainloop_set_name_dylibloader_wrapper_pulse)( pa_threaded_mainloop*,const char*);
-void (*pa_threaded_mainloop_once_unlocked_dylibloader_wrapper_pulse)( pa_threaded_mainloop*, void*, void*);
pa_mainloop* (*pa_mainloop_new_dylibloader_wrapper_pulse)( void);
void (*pa_mainloop_free_dylibloader_wrapper_pulse)( pa_mainloop*);
int (*pa_mainloop_prepare_dylibloader_wrapper_pulse)( pa_mainloop*, int);
int (*pa_mainloop_poll_dylibloader_wrapper_pulse)( pa_mainloop*);
int (*pa_mainloop_dispatch_dylibloader_wrapper_pulse)( pa_mainloop*);
-int (*pa_mainloop_get_retval_dylibloader_wrapper_pulse)(const pa_mainloop*);
+int (*pa_mainloop_get_retval_dylibloader_wrapper_pulse)( pa_mainloop*);
int (*pa_mainloop_iterate_dylibloader_wrapper_pulse)( pa_mainloop*, int, int*);
int (*pa_mainloop_run_dylibloader_wrapper_pulse)( pa_mainloop*, int*);
pa_mainloop_api* (*pa_mainloop_get_api_dylibloader_wrapper_pulse)( pa_mainloop*);
@@ -1069,7 +1052,6 @@ char* (*pa_get_home_dir_dylibloader_wrapper_pulse)( char*, size_t);
char* (*pa_get_binary_name_dylibloader_wrapper_pulse)( char*, size_t);
char* (*pa_path_get_filename_dylibloader_wrapper_pulse)(const char*);
int (*pa_msleep_dylibloader_wrapper_pulse)( unsigned long);
-int (*pa_thread_make_realtime_dylibloader_wrapper_pulse)( int);
struct timeval* (*pa_gettimeofday_dylibloader_wrapper_pulse)(struct timeval*);
pa_usec_t (*pa_timeval_diff_dylibloader_wrapper_pulse)(struct timeval*,struct timeval*);
int (*pa_timeval_cmp_dylibloader_wrapper_pulse)(struct timeval*,struct timeval*);
@@ -1762,38 +1744,6 @@ int initialize_pulse(int verbose) {
fprintf(stderr, "%s\n", error);
}
}
-// pa_format_info_get_sample_format
- *(void **) (&pa_format_info_get_sample_format_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_get_sample_format");
- if (verbose) {
- error = dlerror();
- if (error != NULL) {
- fprintf(stderr, "%s\n", error);
- }
- }
-// pa_format_info_get_rate
- *(void **) (&pa_format_info_get_rate_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_get_rate");
- if (verbose) {
- error = dlerror();
- if (error != NULL) {
- fprintf(stderr, "%s\n", error);
- }
- }
-// pa_format_info_get_channels
- *(void **) (&pa_format_info_get_channels_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_get_channels");
- if (verbose) {
- error = dlerror();
- if (error != NULL) {
- fprintf(stderr, "%s\n", error);
- }
- }
-// pa_format_info_get_channel_map
- *(void **) (&pa_format_info_get_channel_map_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_get_channel_map");
- if (verbose) {
- error = dlerror();
- if (error != NULL) {
- fprintf(stderr, "%s\n", error);
- }
- }
// pa_format_info_set_prop_int
*(void **) (&pa_format_info_set_prop_int_dylibloader_wrapper_pulse) = dlsym(handle, "pa_format_info_set_prop_int");
if (verbose) {
@@ -3666,14 +3616,6 @@ int initialize_pulse(int verbose) {
fprintf(stderr, "%s\n", error);
}
}
-// pa_threaded_mainloop_once_unlocked
- *(void **) (&pa_threaded_mainloop_once_unlocked_dylibloader_wrapper_pulse) = dlsym(handle, "pa_threaded_mainloop_once_unlocked");
- if (verbose) {
- error = dlerror();
- if (error != NULL) {
- fprintf(stderr, "%s\n", error);
- }
- }
// pa_mainloop_new
*(void **) (&pa_mainloop_new_dylibloader_wrapper_pulse) = dlsym(handle, "pa_mainloop_new");
if (verbose) {
@@ -3866,14 +3808,6 @@ int initialize_pulse(int verbose) {
fprintf(stderr, "%s\n", error);
}
}
-// pa_thread_make_realtime
- *(void **) (&pa_thread_make_realtime_dylibloader_wrapper_pulse) = dlsym(handle, "pa_thread_make_realtime");
- if (verbose) {
- error = dlerror();
- if (error != NULL) {
- fprintf(stderr, "%s\n", error);
- }
- }
// pa_gettimeofday
*(void **) (&pa_gettimeofday_dylibloader_wrapper_pulse) = dlsym(handle, "pa_gettimeofday");
if (verbose) {
diff --git a/drivers/pulseaudio/pulse-so_wrap.h b/drivers/pulseaudio/pulse-so_wrap.h
index 7f9a70fae1..bba8fd36a6 100644
--- a/drivers/pulseaudio/pulse-so_wrap.h
+++ b/drivers/pulseaudio/pulse-so_wrap.h
@@ -2,8 +2,8 @@
#define DYLIBLOAD_WRAPPER_PULSE
// This file is generated. Do not edit!
// see https://github.com/hpvb/dynload-wrapper for details
-// generated by /home/hp/Projects/godot/pulse/generate-wrapper.py 0.3 on 2021-02-20 00:08:31
-// flags: /home/hp/Projects/godot/pulse/generate-wrapper.py --include /usr/include/pulse/pulseaudio.h --sys-include <pulse/pulseaudio.h> --soname libpulse.so.0 --omit-prefix _pa_ --init-name pulse --output-header pulse-so_wrap.h --output-implementation pulse-so_wrap.c
+// generated by generate-wrapper.py 0.3 on 2023-01-12 10:26:29
+// flags: generate-wrapper.py --include ./thirdparty/linuxbsd_headers/pulse/pulseaudio.h --sys-include "thirdparty/linuxbsd_headers/pulse/pulseaudio.h" --soname libpulse.so.0 --omit-prefix _pa_ --init-name pulse --output-header ./drivers/pulseaudio/pulse-so_wrap.h --output-implementation ./drivers/pulseaudio/pulse-so_wrap.c
//
#include <stdint.h>
@@ -91,10 +91,6 @@
#define pa_format_info_get_prop_string pa_format_info_get_prop_string_dylibloader_orig_pulse
#define pa_format_info_get_prop_string_array pa_format_info_get_prop_string_array_dylibloader_orig_pulse
#define pa_format_info_free_string_array pa_format_info_free_string_array_dylibloader_orig_pulse
-#define pa_format_info_get_sample_format pa_format_info_get_sample_format_dylibloader_orig_pulse
-#define pa_format_info_get_rate pa_format_info_get_rate_dylibloader_orig_pulse
-#define pa_format_info_get_channels pa_format_info_get_channels_dylibloader_orig_pulse
-#define pa_format_info_get_channel_map pa_format_info_get_channel_map_dylibloader_orig_pulse
#define pa_format_info_set_prop_int pa_format_info_set_prop_int_dylibloader_orig_pulse
#define pa_format_info_set_prop_int_array pa_format_info_set_prop_int_array_dylibloader_orig_pulse
#define pa_format_info_set_prop_int_range pa_format_info_set_prop_int_range_dylibloader_orig_pulse
@@ -329,7 +325,6 @@
#define pa_threaded_mainloop_get_api pa_threaded_mainloop_get_api_dylibloader_orig_pulse
#define pa_threaded_mainloop_in_thread pa_threaded_mainloop_in_thread_dylibloader_orig_pulse
#define pa_threaded_mainloop_set_name pa_threaded_mainloop_set_name_dylibloader_orig_pulse
-#define pa_threaded_mainloop_once_unlocked pa_threaded_mainloop_once_unlocked_dylibloader_orig_pulse
#define pa_mainloop_new pa_mainloop_new_dylibloader_orig_pulse
#define pa_mainloop_free pa_mainloop_free_dylibloader_orig_pulse
#define pa_mainloop_prepare pa_mainloop_prepare_dylibloader_orig_pulse
@@ -354,7 +349,6 @@
#define pa_get_binary_name pa_get_binary_name_dylibloader_orig_pulse
#define pa_path_get_filename pa_path_get_filename_dylibloader_orig_pulse
#define pa_msleep pa_msleep_dylibloader_orig_pulse
-#define pa_thread_make_realtime pa_thread_make_realtime_dylibloader_orig_pulse
#define pa_gettimeofday pa_gettimeofday_dylibloader_orig_pulse
#define pa_timeval_diff pa_timeval_diff_dylibloader_orig_pulse
#define pa_timeval_cmp pa_timeval_cmp_dylibloader_orig_pulse
@@ -364,7 +358,7 @@
#define pa_timeval_store pa_timeval_store_dylibloader_orig_pulse
#define pa_timeval_load pa_timeval_load_dylibloader_orig_pulse
#define pa_rtclock_now pa_rtclock_now_dylibloader_orig_pulse
-#include <pulse/pulseaudio.h>
+#include "thirdparty/linuxbsd_headers/pulse/pulseaudio.h"
#undef pa_get_library_version
#undef pa_bytes_per_second
#undef pa_frame_size
@@ -449,10 +443,6 @@
#undef pa_format_info_get_prop_string
#undef pa_format_info_get_prop_string_array
#undef pa_format_info_free_string_array
-#undef pa_format_info_get_sample_format
-#undef pa_format_info_get_rate
-#undef pa_format_info_get_channels
-#undef pa_format_info_get_channel_map
#undef pa_format_info_set_prop_int
#undef pa_format_info_set_prop_int_array
#undef pa_format_info_set_prop_int_range
@@ -687,7 +677,6 @@
#undef pa_threaded_mainloop_get_api
#undef pa_threaded_mainloop_in_thread
#undef pa_threaded_mainloop_set_name
-#undef pa_threaded_mainloop_once_unlocked
#undef pa_mainloop_new
#undef pa_mainloop_free
#undef pa_mainloop_prepare
@@ -712,7 +701,6 @@
#undef pa_get_binary_name
#undef pa_path_get_filename
#undef pa_msleep
-#undef pa_thread_make_realtime
#undef pa_gettimeofday
#undef pa_timeval_diff
#undef pa_timeval_cmp
@@ -809,10 +797,6 @@ extern "C" {
#define pa_format_info_get_prop_string pa_format_info_get_prop_string_dylibloader_wrapper_pulse
#define pa_format_info_get_prop_string_array pa_format_info_get_prop_string_array_dylibloader_wrapper_pulse
#define pa_format_info_free_string_array pa_format_info_free_string_array_dylibloader_wrapper_pulse
-#define pa_format_info_get_sample_format pa_format_info_get_sample_format_dylibloader_wrapper_pulse
-#define pa_format_info_get_rate pa_format_info_get_rate_dylibloader_wrapper_pulse
-#define pa_format_info_get_channels pa_format_info_get_channels_dylibloader_wrapper_pulse
-#define pa_format_info_get_channel_map pa_format_info_get_channel_map_dylibloader_wrapper_pulse
#define pa_format_info_set_prop_int pa_format_info_set_prop_int_dylibloader_wrapper_pulse
#define pa_format_info_set_prop_int_array pa_format_info_set_prop_int_array_dylibloader_wrapper_pulse
#define pa_format_info_set_prop_int_range pa_format_info_set_prop_int_range_dylibloader_wrapper_pulse
@@ -1047,7 +1031,6 @@ extern "C" {
#define pa_threaded_mainloop_get_api pa_threaded_mainloop_get_api_dylibloader_wrapper_pulse
#define pa_threaded_mainloop_in_thread pa_threaded_mainloop_in_thread_dylibloader_wrapper_pulse
#define pa_threaded_mainloop_set_name pa_threaded_mainloop_set_name_dylibloader_wrapper_pulse
-#define pa_threaded_mainloop_once_unlocked pa_threaded_mainloop_once_unlocked_dylibloader_wrapper_pulse
#define pa_mainloop_new pa_mainloop_new_dylibloader_wrapper_pulse
#define pa_mainloop_free pa_mainloop_free_dylibloader_wrapper_pulse
#define pa_mainloop_prepare pa_mainloop_prepare_dylibloader_wrapper_pulse
@@ -1072,7 +1055,6 @@ extern "C" {
#define pa_get_binary_name pa_get_binary_name_dylibloader_wrapper_pulse
#define pa_path_get_filename pa_path_get_filename_dylibloader_wrapper_pulse
#define pa_msleep pa_msleep_dylibloader_wrapper_pulse
-#define pa_thread_make_realtime pa_thread_make_realtime_dylibloader_wrapper_pulse
#define pa_gettimeofday pa_gettimeofday_dylibloader_wrapper_pulse
#define pa_timeval_diff pa_timeval_diff_dylibloader_wrapper_pulse
#define pa_timeval_cmp pa_timeval_cmp_dylibloader_wrapper_pulse
@@ -1111,21 +1093,21 @@ extern int (*pa_proplist_sets_dylibloader_wrapper_pulse)( pa_proplist*,const cha
extern int (*pa_proplist_setp_dylibloader_wrapper_pulse)( pa_proplist*,const char*);
extern int (*pa_proplist_setf_dylibloader_wrapper_pulse)( pa_proplist*,const char*,const char*,...);
extern int (*pa_proplist_set_dylibloader_wrapper_pulse)( pa_proplist*,const char*,const void*, size_t);
-extern const char* (*pa_proplist_gets_dylibloader_wrapper_pulse)(const pa_proplist*,const char*);
-extern int (*pa_proplist_get_dylibloader_wrapper_pulse)(const pa_proplist*,const char*,const void**, size_t*);
+extern const char* (*pa_proplist_gets_dylibloader_wrapper_pulse)( pa_proplist*,const char*);
+extern int (*pa_proplist_get_dylibloader_wrapper_pulse)( pa_proplist*,const char*,const void**, size_t*);
extern void (*pa_proplist_update_dylibloader_wrapper_pulse)( pa_proplist*, pa_update_mode_t,const pa_proplist*);
extern int (*pa_proplist_unset_dylibloader_wrapper_pulse)( pa_proplist*,const char*);
extern int (*pa_proplist_unset_many_dylibloader_wrapper_pulse)( pa_proplist*,const char* []);
-extern const char* (*pa_proplist_iterate_dylibloader_wrapper_pulse)(const pa_proplist*, void**);
-extern char* (*pa_proplist_to_string_dylibloader_wrapper_pulse)(const pa_proplist*);
-extern char* (*pa_proplist_to_string_sep_dylibloader_wrapper_pulse)(const pa_proplist*,const char*);
+extern const char* (*pa_proplist_iterate_dylibloader_wrapper_pulse)( pa_proplist*, void**);
+extern char* (*pa_proplist_to_string_dylibloader_wrapper_pulse)( pa_proplist*);
+extern char* (*pa_proplist_to_string_sep_dylibloader_wrapper_pulse)( pa_proplist*,const char*);
extern pa_proplist* (*pa_proplist_from_string_dylibloader_wrapper_pulse)(const char*);
-extern int (*pa_proplist_contains_dylibloader_wrapper_pulse)(const pa_proplist*,const char*);
+extern int (*pa_proplist_contains_dylibloader_wrapper_pulse)( pa_proplist*,const char*);
extern void (*pa_proplist_clear_dylibloader_wrapper_pulse)( pa_proplist*);
extern pa_proplist* (*pa_proplist_copy_dylibloader_wrapper_pulse)(const pa_proplist*);
-extern unsigned (*pa_proplist_size_dylibloader_wrapper_pulse)(const pa_proplist*);
-extern int (*pa_proplist_isempty_dylibloader_wrapper_pulse)(const pa_proplist*);
-extern int (*pa_proplist_equal_dylibloader_wrapper_pulse)(const pa_proplist*,const pa_proplist*);
+extern unsigned (*pa_proplist_size_dylibloader_wrapper_pulse)( pa_proplist*);
+extern int (*pa_proplist_isempty_dylibloader_wrapper_pulse)( pa_proplist*);
+extern int (*pa_proplist_equal_dylibloader_wrapper_pulse)( pa_proplist*, pa_proplist*);
extern pa_channel_map* (*pa_channel_map_init_dylibloader_wrapper_pulse)( pa_channel_map*);
extern pa_channel_map* (*pa_channel_map_init_mono_dylibloader_wrapper_pulse)( pa_channel_map*);
extern pa_channel_map* (*pa_channel_map_init_stereo_dylibloader_wrapper_pulse)( pa_channel_map*);
@@ -1166,10 +1148,6 @@ extern int (*pa_format_info_get_prop_int_array_dylibloader_wrapper_pulse)(const
extern int (*pa_format_info_get_prop_string_dylibloader_wrapper_pulse)(const pa_format_info*,const char*, char**);
extern int (*pa_format_info_get_prop_string_array_dylibloader_wrapper_pulse)(const pa_format_info*,const char*, char***, int*);
extern void (*pa_format_info_free_string_array_dylibloader_wrapper_pulse)( char**, int);
-extern int (*pa_format_info_get_sample_format_dylibloader_wrapper_pulse)(const pa_format_info*, pa_sample_format_t*);
-extern int (*pa_format_info_get_rate_dylibloader_wrapper_pulse)(const pa_format_info*, uint32_t*);
-extern int (*pa_format_info_get_channels_dylibloader_wrapper_pulse)(const pa_format_info*, uint8_t*);
-extern int (*pa_format_info_get_channel_map_dylibloader_wrapper_pulse)(const pa_format_info*, pa_channel_map*);
extern void (*pa_format_info_set_prop_int_dylibloader_wrapper_pulse)( pa_format_info*,const char*, int);
extern void (*pa_format_info_set_prop_int_array_dylibloader_wrapper_pulse)( pa_format_info*,const char*,const int*, int);
extern void (*pa_format_info_set_prop_int_range_dylibloader_wrapper_pulse)( pa_format_info*,const char*, int, int);
@@ -1182,34 +1160,34 @@ extern void (*pa_format_info_set_channel_map_dylibloader_wrapper_pulse)( pa_form
extern pa_operation* (*pa_operation_ref_dylibloader_wrapper_pulse)( pa_operation*);
extern void (*pa_operation_unref_dylibloader_wrapper_pulse)( pa_operation*);
extern void (*pa_operation_cancel_dylibloader_wrapper_pulse)( pa_operation*);
-extern pa_operation_state_t (*pa_operation_get_state_dylibloader_wrapper_pulse)(const pa_operation*);
+extern pa_operation_state_t (*pa_operation_get_state_dylibloader_wrapper_pulse)( pa_operation*);
extern void (*pa_operation_set_state_callback_dylibloader_wrapper_pulse)( pa_operation*, pa_operation_notify_cb_t, void*);
extern pa_context* (*pa_context_new_dylibloader_wrapper_pulse)( pa_mainloop_api*,const char*);
-extern pa_context* (*pa_context_new_with_proplist_dylibloader_wrapper_pulse)( pa_mainloop_api*,const char*,const pa_proplist*);
+extern pa_context* (*pa_context_new_with_proplist_dylibloader_wrapper_pulse)( pa_mainloop_api*,const char*, pa_proplist*);
extern void (*pa_context_unref_dylibloader_wrapper_pulse)( pa_context*);
extern pa_context* (*pa_context_ref_dylibloader_wrapper_pulse)( pa_context*);
extern void (*pa_context_set_state_callback_dylibloader_wrapper_pulse)( pa_context*, pa_context_notify_cb_t, void*);
extern void (*pa_context_set_event_callback_dylibloader_wrapper_pulse)( pa_context*, pa_context_event_cb_t, void*);
-extern int (*pa_context_errno_dylibloader_wrapper_pulse)(const pa_context*);
-extern int (*pa_context_is_pending_dylibloader_wrapper_pulse)(const pa_context*);
-extern pa_context_state_t (*pa_context_get_state_dylibloader_wrapper_pulse)(const pa_context*);
+extern int (*pa_context_errno_dylibloader_wrapper_pulse)( pa_context*);
+extern int (*pa_context_is_pending_dylibloader_wrapper_pulse)( pa_context*);
+extern pa_context_state_t (*pa_context_get_state_dylibloader_wrapper_pulse)( pa_context*);
extern int (*pa_context_connect_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_context_flags_t,const pa_spawn_api*);
extern void (*pa_context_disconnect_dylibloader_wrapper_pulse)( pa_context*);
extern pa_operation* (*pa_context_drain_dylibloader_wrapper_pulse)( pa_context*, pa_context_notify_cb_t, void*);
extern pa_operation* (*pa_context_exit_daemon_dylibloader_wrapper_pulse)( pa_context*, pa_context_success_cb_t, void*);
extern pa_operation* (*pa_context_set_default_sink_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_context_success_cb_t, void*);
extern pa_operation* (*pa_context_set_default_source_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_context_success_cb_t, void*);
-extern int (*pa_context_is_local_dylibloader_wrapper_pulse)(const pa_context*);
+extern int (*pa_context_is_local_dylibloader_wrapper_pulse)( pa_context*);
extern pa_operation* (*pa_context_set_name_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_context_success_cb_t, void*);
-extern const char* (*pa_context_get_server_dylibloader_wrapper_pulse)(const pa_context*);
-extern uint32_t (*pa_context_get_protocol_version_dylibloader_wrapper_pulse)(const pa_context*);
-extern uint32_t (*pa_context_get_server_protocol_version_dylibloader_wrapper_pulse)(const pa_context*);
-extern pa_operation* (*pa_context_proplist_update_dylibloader_wrapper_pulse)( pa_context*, pa_update_mode_t,const pa_proplist*, pa_context_success_cb_t, void*);
+extern const char* (*pa_context_get_server_dylibloader_wrapper_pulse)( pa_context*);
+extern uint32_t (*pa_context_get_protocol_version_dylibloader_wrapper_pulse)( pa_context*);
+extern uint32_t (*pa_context_get_server_protocol_version_dylibloader_wrapper_pulse)( pa_context*);
+extern pa_operation* (*pa_context_proplist_update_dylibloader_wrapper_pulse)( pa_context*, pa_update_mode_t, pa_proplist*, pa_context_success_cb_t, void*);
extern pa_operation* (*pa_context_proplist_remove_dylibloader_wrapper_pulse)( pa_context*,const char* [], pa_context_success_cb_t, void*);
-extern uint32_t (*pa_context_get_index_dylibloader_wrapper_pulse)(const pa_context*);
-extern pa_time_event* (*pa_context_rttime_new_dylibloader_wrapper_pulse)(const pa_context*, pa_usec_t, pa_time_event_cb_t, void*);
-extern void (*pa_context_rttime_restart_dylibloader_wrapper_pulse)(const pa_context*, pa_time_event*, pa_usec_t);
-extern size_t (*pa_context_get_tile_size_dylibloader_wrapper_pulse)(const pa_context*,const pa_sample_spec*);
+extern uint32_t (*pa_context_get_index_dylibloader_wrapper_pulse)( pa_context*);
+extern pa_time_event* (*pa_context_rttime_new_dylibloader_wrapper_pulse)( pa_context*, pa_usec_t, pa_time_event_cb_t, void*);
+extern void (*pa_context_rttime_restart_dylibloader_wrapper_pulse)( pa_context*, pa_time_event*, pa_usec_t);
+extern size_t (*pa_context_get_tile_size_dylibloader_wrapper_pulse)( pa_context*,const pa_sample_spec*);
extern int (*pa_context_load_cookie_from_file_dylibloader_wrapper_pulse)( pa_context*,const char*);
extern int (*pa_cvolume_equal_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_cvolume*);
extern pa_cvolume* (*pa_cvolume_init_dylibloader_wrapper_pulse)( pa_cvolume*);
@@ -1248,9 +1226,9 @@ extern pa_cvolume* (*pa_cvolume_set_fade_dylibloader_wrapper_pulse)( pa_cvolume*
extern float (*pa_cvolume_get_lfe_balance_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_channel_map*);
extern pa_cvolume* (*pa_cvolume_set_lfe_balance_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_channel_map*, float);
extern pa_cvolume* (*pa_cvolume_scale_dylibloader_wrapper_pulse)( pa_cvolume*, pa_volume_t);
-extern pa_cvolume* (*pa_cvolume_scale_mask_dylibloader_wrapper_pulse)( pa_cvolume*, pa_volume_t,const pa_channel_map*, pa_channel_position_mask_t);
+extern pa_cvolume* (*pa_cvolume_scale_mask_dylibloader_wrapper_pulse)( pa_cvolume*, pa_volume_t, pa_channel_map*, pa_channel_position_mask_t);
extern pa_cvolume* (*pa_cvolume_set_position_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_channel_map*, pa_channel_position_t, pa_volume_t);
-extern pa_volume_t (*pa_cvolume_get_position_dylibloader_wrapper_pulse)(const pa_cvolume*,const pa_channel_map*, pa_channel_position_t);
+extern pa_volume_t (*pa_cvolume_get_position_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_channel_map*, pa_channel_position_t);
extern pa_cvolume* (*pa_cvolume_merge_dylibloader_wrapper_pulse)( pa_cvolume*,const pa_cvolume*,const pa_cvolume*);
extern pa_cvolume* (*pa_cvolume_inc_clamp_dylibloader_wrapper_pulse)( pa_cvolume*, pa_volume_t, pa_volume_t);
extern pa_cvolume* (*pa_cvolume_inc_dylibloader_wrapper_pulse)( pa_cvolume*, pa_volume_t);
@@ -1260,13 +1238,13 @@ extern pa_stream* (*pa_stream_new_with_proplist_dylibloader_wrapper_pulse)( pa_c
extern pa_stream* (*pa_stream_new_extended_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_format_info**, unsigned int, pa_proplist*);
extern void (*pa_stream_unref_dylibloader_wrapper_pulse)( pa_stream*);
extern pa_stream* (*pa_stream_ref_dylibloader_wrapper_pulse)( pa_stream*);
-extern pa_stream_state_t (*pa_stream_get_state_dylibloader_wrapper_pulse)(const pa_stream*);
-extern pa_context* (*pa_stream_get_context_dylibloader_wrapper_pulse)(const pa_stream*);
-extern uint32_t (*pa_stream_get_index_dylibloader_wrapper_pulse)(const pa_stream*);
-extern uint32_t (*pa_stream_get_device_index_dylibloader_wrapper_pulse)(const pa_stream*);
-extern const char* (*pa_stream_get_device_name_dylibloader_wrapper_pulse)(const pa_stream*);
-extern int (*pa_stream_is_suspended_dylibloader_wrapper_pulse)(const pa_stream*);
-extern int (*pa_stream_is_corked_dylibloader_wrapper_pulse)(const pa_stream*);
+extern pa_stream_state_t (*pa_stream_get_state_dylibloader_wrapper_pulse)( pa_stream*);
+extern pa_context* (*pa_stream_get_context_dylibloader_wrapper_pulse)( pa_stream*);
+extern uint32_t (*pa_stream_get_index_dylibloader_wrapper_pulse)( pa_stream*);
+extern uint32_t (*pa_stream_get_device_index_dylibloader_wrapper_pulse)( pa_stream*);
+extern const char* (*pa_stream_get_device_name_dylibloader_wrapper_pulse)( pa_stream*);
+extern int (*pa_stream_is_suspended_dylibloader_wrapper_pulse)( pa_stream*);
+extern int (*pa_stream_is_corked_dylibloader_wrapper_pulse)( pa_stream*);
extern int (*pa_stream_connect_playback_dylibloader_wrapper_pulse)( pa_stream*,const char*,const pa_buffer_attr*, pa_stream_flags_t,const pa_cvolume*, pa_stream*);
extern int (*pa_stream_connect_record_dylibloader_wrapper_pulse)( pa_stream*,const char*,const pa_buffer_attr*, pa_stream_flags_t);
extern int (*pa_stream_disconnect_dylibloader_wrapper_pulse)( pa_stream*);
@@ -1276,15 +1254,15 @@ extern int (*pa_stream_write_dylibloader_wrapper_pulse)( pa_stream*,const void*,
extern int (*pa_stream_write_ext_free_dylibloader_wrapper_pulse)( pa_stream*,const void*, size_t, pa_free_cb_t, void*, int64_t, pa_seek_mode_t);
extern int (*pa_stream_peek_dylibloader_wrapper_pulse)( pa_stream*,const void**, size_t*);
extern int (*pa_stream_drop_dylibloader_wrapper_pulse)( pa_stream*);
-extern size_t (*pa_stream_writable_size_dylibloader_wrapper_pulse)(const pa_stream*);
-extern size_t (*pa_stream_readable_size_dylibloader_wrapper_pulse)(const pa_stream*);
+extern size_t (*pa_stream_writable_size_dylibloader_wrapper_pulse)( pa_stream*);
+extern size_t (*pa_stream_readable_size_dylibloader_wrapper_pulse)( pa_stream*);
extern pa_operation* (*pa_stream_drain_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_success_cb_t, void*);
extern pa_operation* (*pa_stream_update_timing_info_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_success_cb_t, void*);
extern void (*pa_stream_set_state_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*);
extern void (*pa_stream_set_write_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_request_cb_t, void*);
extern void (*pa_stream_set_read_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_request_cb_t, void*);
extern void (*pa_stream_set_overflow_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*);
-extern int64_t (*pa_stream_get_underflow_index_dylibloader_wrapper_pulse)(const pa_stream*);
+extern int64_t (*pa_stream_get_underflow_index_dylibloader_wrapper_pulse)( pa_stream*);
extern void (*pa_stream_set_underflow_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*);
extern void (*pa_stream_set_started_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*);
extern void (*pa_stream_set_latency_update_callback_dylibloader_wrapper_pulse)( pa_stream*, pa_stream_notify_cb_t, void*);
@@ -1302,14 +1280,14 @@ extern int (*pa_stream_get_latency_dylibloader_wrapper_pulse)( pa_stream*, pa_us
extern const pa_timing_info* (*pa_stream_get_timing_info_dylibloader_wrapper_pulse)( pa_stream*);
extern const pa_sample_spec* (*pa_stream_get_sample_spec_dylibloader_wrapper_pulse)( pa_stream*);
extern const pa_channel_map* (*pa_stream_get_channel_map_dylibloader_wrapper_pulse)( pa_stream*);
-extern const pa_format_info* (*pa_stream_get_format_info_dylibloader_wrapper_pulse)(const pa_stream*);
+extern const pa_format_info* (*pa_stream_get_format_info_dylibloader_wrapper_pulse)( pa_stream*);
extern const pa_buffer_attr* (*pa_stream_get_buffer_attr_dylibloader_wrapper_pulse)( pa_stream*);
extern pa_operation* (*pa_stream_set_buffer_attr_dylibloader_wrapper_pulse)( pa_stream*,const pa_buffer_attr*, pa_stream_success_cb_t, void*);
extern pa_operation* (*pa_stream_update_sample_rate_dylibloader_wrapper_pulse)( pa_stream*, uint32_t, pa_stream_success_cb_t, void*);
extern pa_operation* (*pa_stream_proplist_update_dylibloader_wrapper_pulse)( pa_stream*, pa_update_mode_t, pa_proplist*, pa_stream_success_cb_t, void*);
extern pa_operation* (*pa_stream_proplist_remove_dylibloader_wrapper_pulse)( pa_stream*,const char* [], pa_stream_success_cb_t, void*);
extern int (*pa_stream_set_monitor_stream_dylibloader_wrapper_pulse)( pa_stream*, uint32_t);
-extern uint32_t (*pa_stream_get_monitor_stream_dylibloader_wrapper_pulse)(const pa_stream*);
+extern uint32_t (*pa_stream_get_monitor_stream_dylibloader_wrapper_pulse)( pa_stream*);
extern pa_operation* (*pa_context_get_sink_info_by_name_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_sink_info_cb_t, void*);
extern pa_operation* (*pa_context_get_sink_info_by_index_dylibloader_wrapper_pulse)( pa_context*, uint32_t, pa_sink_info_cb_t, void*);
extern pa_operation* (*pa_context_get_sink_info_list_dylibloader_wrapper_pulse)( pa_context*, pa_sink_info_cb_t, void*);
@@ -1376,7 +1354,7 @@ extern int (*pa_stream_connect_upload_dylibloader_wrapper_pulse)( pa_stream*, si
extern int (*pa_stream_finish_upload_dylibloader_wrapper_pulse)( pa_stream*);
extern pa_operation* (*pa_context_remove_sample_dylibloader_wrapper_pulse)( pa_context*,const char*, pa_context_success_cb_t, void*);
extern pa_operation* (*pa_context_play_sample_dylibloader_wrapper_pulse)( pa_context*,const char*,const char*, pa_volume_t, pa_context_success_cb_t, void*);
-extern pa_operation* (*pa_context_play_sample_with_proplist_dylibloader_wrapper_pulse)( pa_context*,const char*,const char*, pa_volume_t,const pa_proplist*, pa_context_play_sample_cb_t, void*);
+extern pa_operation* (*pa_context_play_sample_with_proplist_dylibloader_wrapper_pulse)( pa_context*,const char*,const char*, pa_volume_t, pa_proplist*, pa_context_play_sample_cb_t, void*);
extern const char* (*pa_strerror_dylibloader_wrapper_pulse)( int);
extern void* (*pa_xmalloc_dylibloader_wrapper_pulse)( size_t);
extern void* (*pa_xmalloc0_dylibloader_wrapper_pulse)( size_t);
@@ -1400,17 +1378,16 @@ extern void (*pa_threaded_mainloop_unlock_dylibloader_wrapper_pulse)( pa_threade
extern void (*pa_threaded_mainloop_wait_dylibloader_wrapper_pulse)( pa_threaded_mainloop*);
extern void (*pa_threaded_mainloop_signal_dylibloader_wrapper_pulse)( pa_threaded_mainloop*, int);
extern void (*pa_threaded_mainloop_accept_dylibloader_wrapper_pulse)( pa_threaded_mainloop*);
-extern int (*pa_threaded_mainloop_get_retval_dylibloader_wrapper_pulse)(const pa_threaded_mainloop*);
+extern int (*pa_threaded_mainloop_get_retval_dylibloader_wrapper_pulse)( pa_threaded_mainloop*);
extern pa_mainloop_api* (*pa_threaded_mainloop_get_api_dylibloader_wrapper_pulse)( pa_threaded_mainloop*);
extern int (*pa_threaded_mainloop_in_thread_dylibloader_wrapper_pulse)( pa_threaded_mainloop*);
extern void (*pa_threaded_mainloop_set_name_dylibloader_wrapper_pulse)( pa_threaded_mainloop*,const char*);
-extern void (*pa_threaded_mainloop_once_unlocked_dylibloader_wrapper_pulse)( pa_threaded_mainloop*, void*, void*);
extern pa_mainloop* (*pa_mainloop_new_dylibloader_wrapper_pulse)( void);
extern void (*pa_mainloop_free_dylibloader_wrapper_pulse)( pa_mainloop*);
extern int (*pa_mainloop_prepare_dylibloader_wrapper_pulse)( pa_mainloop*, int);
extern int (*pa_mainloop_poll_dylibloader_wrapper_pulse)( pa_mainloop*);
extern int (*pa_mainloop_dispatch_dylibloader_wrapper_pulse)( pa_mainloop*);
-extern int (*pa_mainloop_get_retval_dylibloader_wrapper_pulse)(const pa_mainloop*);
+extern int (*pa_mainloop_get_retval_dylibloader_wrapper_pulse)( pa_mainloop*);
extern int (*pa_mainloop_iterate_dylibloader_wrapper_pulse)( pa_mainloop*, int, int*);
extern int (*pa_mainloop_run_dylibloader_wrapper_pulse)( pa_mainloop*, int*);
extern pa_mainloop_api* (*pa_mainloop_get_api_dylibloader_wrapper_pulse)( pa_mainloop*);
@@ -1429,7 +1406,6 @@ extern char* (*pa_get_home_dir_dylibloader_wrapper_pulse)( char*, size_t);
extern char* (*pa_get_binary_name_dylibloader_wrapper_pulse)( char*, size_t);
extern char* (*pa_path_get_filename_dylibloader_wrapper_pulse)(const char*);
extern int (*pa_msleep_dylibloader_wrapper_pulse)( unsigned long);
-extern int (*pa_thread_make_realtime_dylibloader_wrapper_pulse)( int);
extern struct timeval* (*pa_gettimeofday_dylibloader_wrapper_pulse)(struct timeval*);
extern pa_usec_t (*pa_timeval_diff_dylibloader_wrapper_pulse)(struct timeval*,struct timeval*);
extern int (*pa_timeval_cmp_dylibloader_wrapper_pulse)(struct timeval*,struct timeval*);
diff --git a/drivers/unix/dir_access_unix.cpp b/drivers/unix/dir_access_unix.cpp
index 557060c907..a162f46103 100644
--- a/drivers/unix/dir_access_unix.cpp
+++ b/drivers/unix/dir_access_unix.cpp
@@ -189,7 +189,7 @@ void DirAccessUnix::list_dir_end() {
_cisdir = false;
}
-#if defined(HAVE_MNTENT) && defined(X11_ENABLED)
+#if defined(HAVE_MNTENT) && defined(LINUXBSD_ENABLED)
static bool _filter_drive(struct mntent *mnt) {
// Ignore devices that don't point to /dev
if (strncmp(mnt->mnt_fsname, "/dev", 4) != 0) {
@@ -213,7 +213,7 @@ static void _get_drives(List<String> *list) {
// Add root.
list->push_back("/");
-#if defined(HAVE_MNTENT) && defined(X11_ENABLED)
+#if defined(HAVE_MNTENT) && defined(LINUXBSD_ENABLED)
// Check /etc/mtab for the list of mounted partitions.
FILE *mtab = setmntent("/etc/mtab", "r");
if (mtab) {
diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp
index 43d3f53904..ee3cb876cf 100644
--- a/drivers/unix/file_access_unix.cpp
+++ b/drivers/unix/file_access_unix.cpp
@@ -318,6 +318,10 @@ Error FileAccessUnix::_set_unix_permissions(const String &p_file, uint32_t p_per
return FAILED;
}
+void FileAccessUnix::close() {
+ _close();
+}
+
CloseNotificationFunc FileAccessUnix::close_notification_func = nullptr;
FileAccessUnix::~FileAccessUnix() {
diff --git a/drivers/unix/file_access_unix.h b/drivers/unix/file_access_unix.h
index 884fb9567f..79c4e73636 100644
--- a/drivers/unix/file_access_unix.h
+++ b/drivers/unix/file_access_unix.h
@@ -82,6 +82,8 @@ public:
virtual uint32_t _get_unix_permissions(const String &p_file) override;
virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override;
+ virtual void close() override;
+
FileAccessUnix() {}
virtual ~FileAccessUnix();
};
diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp
index c37b3d9c87..178f01b185 100644
--- a/drivers/unix/os_unix.cpp
+++ b/drivers/unix/os_unix.cpp
@@ -411,10 +411,6 @@ bool OS_Unix::is_process_running(const ProcessID &p_pid) const {
return true;
}
-bool OS_Unix::has_environment(const String &p_var) const {
- return getenv(p_var.utf8().get_data()) != nullptr;
-}
-
String OS_Unix::get_locale() const {
if (!has_environment("LANG")) {
return "en";
@@ -487,6 +483,10 @@ Error OS_Unix::set_cwd(const String &p_cwd) {
return OK;
}
+bool OS_Unix::has_environment(const String &p_var) const {
+ return getenv(p_var.utf8().get_data()) != nullptr;
+}
+
String OS_Unix::get_environment(const String &p_var) const {
if (getenv(p_var.utf8().get_data())) {
return getenv(p_var.utf8().get_data());
@@ -494,8 +494,15 @@ String OS_Unix::get_environment(const String &p_var) const {
return "";
}
-bool OS_Unix::set_environment(const String &p_var, const String &p_value) const {
- return setenv(p_var.utf8().get_data(), p_value.utf8().get_data(), /* overwrite: */ true) == 0;
+void OS_Unix::set_environment(const String &p_var, const String &p_value) const {
+ ERR_FAIL_COND_MSG(p_var.is_empty() || p_var.contains("="), vformat("Invalid environment variable name '%s', cannot be empty or include '='.", p_var));
+ int err = setenv(p_var.utf8().get_data(), p_value.utf8().get_data(), /* overwrite: */ 1);
+ ERR_FAIL_COND_MSG(err != 0, vformat("Failed setting environment variable '%s', the system is out of memory.", p_var));
+}
+
+void OS_Unix::unset_environment(const String &p_var) const {
+ ERR_FAIL_COND_MSG(p_var.is_empty() || p_var.contains("="), vformat("Invalid environment variable name '%s', cannot be empty or include '='.", p_var));
+ unsetenv(p_var.utf8().get_data());
}
String OS_Unix::get_user_data_dir() const {
diff --git a/drivers/unix/os_unix.h b/drivers/unix/os_unix.h
index 416311307c..03429622ae 100644
--- a/drivers/unix/os_unix.h
+++ b/drivers/unix/os_unix.h
@@ -81,7 +81,9 @@ public:
virtual bool has_environment(const String &p_var) const override;
virtual String get_environment(const String &p_var) const override;
- virtual bool set_environment(const String &p_var, const String &p_value) const override;
+ virtual void set_environment(const String &p_var, const String &p_value) const override;
+ virtual void unset_environment(const String &p_var) const override;
+
virtual String get_locale() const override;
virtual void initialize_debugging() override;
diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp
index 6c833c8a26..91a746636a 100644
--- a/drivers/vulkan/rendering_device_vulkan.cpp
+++ b/drivers/vulkan/rendering_device_vulkan.cpp
@@ -1666,34 +1666,27 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T
image_create_info.pNext = nullptr;
image_create_info.flags = 0;
- // TODO: Check for support via RenderingDevice to enable on mobile when possible.
-
-#ifndef ANDROID_ENABLED
-
- // vkCreateImage fails with format list on Android (VK_ERROR_OUT_OF_HOST_MEMORY)
VkImageFormatListCreateInfoKHR format_list_create_info; // Keep out of the if, needed for creation.
Vector<VkFormat> allowed_formats; // Keep out of the if, needed for creation.
-#endif
if (p_format.shareable_formats.size()) {
image_create_info.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
-#ifndef ANDROID_ENABLED
-
- for (int i = 0; i < p_format.shareable_formats.size(); i++) {
- allowed_formats.push_back(vulkan_formats[p_format.shareable_formats[i]]);
- }
+ if (context->is_device_extension_enabled(VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME)) {
+ for (int i = 0; i < p_format.shareable_formats.size(); i++) {
+ allowed_formats.push_back(vulkan_formats[p_format.shareable_formats[i]]);
+ }
- format_list_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR;
- format_list_create_info.pNext = nullptr;
- format_list_create_info.viewFormatCount = allowed_formats.size();
- format_list_create_info.pViewFormats = allowed_formats.ptr();
- image_create_info.pNext = &format_list_create_info;
+ format_list_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR;
+ format_list_create_info.pNext = nullptr;
+ format_list_create_info.viewFormatCount = allowed_formats.size();
+ format_list_create_info.pViewFormats = allowed_formats.ptr();
+ image_create_info.pNext = &format_list_create_info;
- ERR_FAIL_COND_V_MSG(p_format.shareable_formats.find(p_format.format) == -1, RID(),
- "If supplied a list of shareable formats, the current format must be present in the list");
- ERR_FAIL_COND_V_MSG(p_view.format_override != DATA_FORMAT_MAX && p_format.shareable_formats.find(p_view.format_override) == -1, RID(),
- "If supplied a list of shareable formats, the current view format override must be present in the list");
-#endif
+ ERR_FAIL_COND_V_MSG(p_format.shareable_formats.find(p_format.format) == -1, RID(),
+ "If supplied a list of shareable formats, the current format must be present in the list");
+ ERR_FAIL_COND_V_MSG(p_view.format_override != DATA_FORMAT_MAX && p_format.shareable_formats.find(p_view.format_override) == -1, RID(),
+ "If supplied a list of shareable formats, the current view format override must be present in the list");
+ }
}
if (p_format.texture_type == TEXTURE_TYPE_CUBE || p_format.texture_type == TEXTURE_TYPE_CUBE_ARRAY) {
@@ -2096,49 +2089,54 @@ RID RenderingDeviceVulkan::texture_create_shared(const TextureView &p_view, RID
}
VkImageViewUsageCreateInfo usage_info;
- usage_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO;
- usage_info.pNext = nullptr;
- if (p_view.format_override != DATA_FORMAT_MAX) {
- // Need to validate usage with vulkan.
+ if (context->is_device_extension_enabled(VK_KHR_MAINTENANCE_2_EXTENSION_NAME)) {
+ // May need to make VK_KHR_maintenance2 manditory and thus has Vulkan 1.1 be our minimum supported version
+ // if we require setting this information. Vulkan 1.0 may simply not care..
- usage_info.usage = 0;
+ usage_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO;
+ usage_info.pNext = nullptr;
+ if (p_view.format_override != DATA_FORMAT_MAX) {
+ // Need to validate usage with vulkan.
- if (texture.usage_flags & TEXTURE_USAGE_SAMPLING_BIT) {
- usage_info.usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
- }
+ usage_info.usage = 0;
- if (texture.usage_flags & TEXTURE_USAGE_STORAGE_BIT) {
- if (texture_is_format_supported_for_usage(p_view.format_override, TEXTURE_USAGE_STORAGE_BIT)) {
- usage_info.usage |= VK_IMAGE_USAGE_STORAGE_BIT;
+ if (texture.usage_flags & TEXTURE_USAGE_SAMPLING_BIT) {
+ usage_info.usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
}
- }
- if (texture.usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
- if (texture_is_format_supported_for_usage(p_view.format_override, TEXTURE_USAGE_COLOR_ATTACHMENT_BIT)) {
- usage_info.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+ if (texture.usage_flags & TEXTURE_USAGE_STORAGE_BIT) {
+ if (texture_is_format_supported_for_usage(p_view.format_override, TEXTURE_USAGE_STORAGE_BIT)) {
+ usage_info.usage |= VK_IMAGE_USAGE_STORAGE_BIT;
+ }
}
- }
- if (texture.usage_flags & TEXTURE_USAGE_INPUT_ATTACHMENT_BIT) {
- usage_info.usage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
- }
+ if (texture.usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
+ if (texture_is_format_supported_for_usage(p_view.format_override, TEXTURE_USAGE_COLOR_ATTACHMENT_BIT)) {
+ usage_info.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+ }
+ }
- if (texture.usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
- usage_info.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
- }
+ if (texture.usage_flags & TEXTURE_USAGE_INPUT_ATTACHMENT_BIT) {
+ usage_info.usage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
+ }
- if (texture.usage_flags & TEXTURE_USAGE_CAN_UPDATE_BIT) {
- usage_info.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
- }
- if (texture.usage_flags & TEXTURE_USAGE_CAN_COPY_FROM_BIT) {
- usage_info.usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
- }
+ if (texture.usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
+ usage_info.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
+ }
- if (texture.usage_flags & TEXTURE_USAGE_CAN_COPY_TO_BIT) {
- usage_info.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
- }
+ if (texture.usage_flags & TEXTURE_USAGE_CAN_UPDATE_BIT) {
+ usage_info.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
+ }
+ if (texture.usage_flags & TEXTURE_USAGE_CAN_COPY_FROM_BIT) {
+ usage_info.usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
+ }
+
+ if (texture.usage_flags & TEXTURE_USAGE_CAN_COPY_TO_BIT) {
+ usage_info.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
+ }
- image_view_create_info.pNext = &usage_info;
+ image_view_create_info.pNext = &usage_info;
+ }
}
VkResult err = vkCreateImageView(device, &image_view_create_info, nullptr, &texture.view);
@@ -2296,7 +2294,7 @@ RID RenderingDeviceVulkan::texture_create_from_extension(TextureType p_type, Dat
return id;
}
-RID RenderingDeviceVulkan::texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, uint32_t p_mipmaps, TextureSliceType p_slice_type) {
+RID RenderingDeviceVulkan::texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, uint32_t p_mipmaps, TextureSliceType p_slice_type, uint32_t p_layers) {
_THREAD_SAFE_METHOD_
Texture *src_texture = texture_owner.get_or_null(p_with_texture);
@@ -2324,7 +2322,11 @@ RID RenderingDeviceVulkan::texture_create_shared_from_slice(const TextureView &p
ERR_FAIL_UNSIGNED_INDEX_V(p_layer, src_texture->layers, RID());
int slice_layers = 1;
- if (p_slice_type == TEXTURE_SLICE_2D_ARRAY) {
+ if (p_layers != 0) {
+ ERR_FAIL_COND_V_MSG(p_layers > 1 && p_slice_type != TEXTURE_SLICE_2D_ARRAY, RID(), "layer slicing only supported for 2D arrays");
+ ERR_FAIL_COND_V_MSG(p_layer + p_layers > src_texture->layers, RID(), "layer slice is out of bounds");
+ slice_layers = p_layers;
+ } else if (p_slice_type == TEXTURE_SLICE_2D_ARRAY) {
ERR_FAIL_COND_V_MSG(p_layer != 0, RID(), "layer must be 0 when obtaining a 2D array mipmap slice");
slice_layers = src_texture->layers;
} else if (p_slice_type == TEXTURE_SLICE_CUBEMAP) {
@@ -4278,7 +4280,7 @@ RID RenderingDeviceVulkan::sampler_create(const SamplerState &p_state) {
sampler_create_info.addressModeW = address_modes[p_state.repeat_w];
sampler_create_info.mipLodBias = p_state.lod_bias;
- sampler_create_info.anisotropyEnable = p_state.use_anisotropy;
+ sampler_create_info.anisotropyEnable = p_state.use_anisotropy && context->get_physical_device_features().samplerAnisotropy;
sampler_create_info.maxAnisotropy = p_state.anisotropy_max;
sampler_create_info.compareEnable = p_state.enable_compare;
@@ -5925,7 +5927,7 @@ Error RenderingDeviceVulkan::buffer_clear(RID p_buffer, uint32_t p_offset, uint3
return OK;
}
-Vector<uint8_t> RenderingDeviceVulkan::buffer_get_data(RID p_buffer) {
+Vector<uint8_t> RenderingDeviceVulkan::buffer_get_data(RID p_buffer, uint32_t p_offset, uint32_t p_size) {
_THREAD_SAFE_METHOD_
// It could be this buffer was just created.
@@ -5942,12 +5944,20 @@ Vector<uint8_t> RenderingDeviceVulkan::buffer_get_data(RID p_buffer) {
VkCommandBuffer command_buffer = frames[frame].setup_command_buffer;
+ // Size of buffer to retrieve.
+ if (!p_size) {
+ p_size = buffer->size;
+ } else {
+ ERR_FAIL_COND_V_MSG(p_size + p_offset > buffer->size, Vector<uint8_t>(),
+ "Size is larger than the buffer.");
+ }
+
Buffer tmp_buffer;
- _buffer_allocate(&tmp_buffer, buffer->size, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VMA_MEMORY_USAGE_AUTO_PREFER_HOST, VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT);
+ _buffer_allocate(&tmp_buffer, p_size, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VMA_MEMORY_USAGE_AUTO_PREFER_HOST, VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT);
VkBufferCopy region;
- region.srcOffset = 0;
+ region.srcOffset = p_offset;
region.dstOffset = 0;
- region.size = buffer->size;
+ region.size = p_size;
vkCmdCopyBuffer(command_buffer, buffer->buffer, tmp_buffer.buffer, 1, &region); // Dst buffer is in CPU, but I wonder if src buffer needs a barrier for this.
// Flush everything so memory can be safely mapped.
_flush(true);
@@ -5958,9 +5968,9 @@ Vector<uint8_t> RenderingDeviceVulkan::buffer_get_data(RID p_buffer) {
Vector<uint8_t> buffer_data;
{
- buffer_data.resize(buffer->size);
+ buffer_data.resize(p_size);
uint8_t *w = buffer_data.ptrw();
- memcpy(w, buffer_mem, buffer->size);
+ memcpy(w, buffer_mem, p_size);
}
vmaUnmapMemory(allocator, tmp_buffer.allocation);
@@ -8452,14 +8462,17 @@ void RenderingDeviceVulkan::set_resource_name(RID p_id, const String p_name) {
}
void RenderingDeviceVulkan::draw_command_begin_label(String p_label_name, const Color p_color) {
+ _THREAD_SAFE_METHOD_
context->command_begin_label(frames[frame].draw_command_buffer, p_label_name, p_color);
}
void RenderingDeviceVulkan::draw_command_insert_label(String p_label_name, const Color p_color) {
+ _THREAD_SAFE_METHOD_
context->command_insert_label(frames[frame].draw_command_buffer, p_label_name, p_color);
}
void RenderingDeviceVulkan::draw_command_end_label() {
+ _THREAD_SAFE_METHOD_
context->command_end_label(frames[frame].draw_command_buffer);
}
@@ -9368,11 +9381,11 @@ bool RenderingDeviceVulkan::has_feature(const Features p_feature) const {
return multiview_capabilies.is_supported && multiview_capabilies.max_view_count > 1;
} break;
case SUPPORTS_FSR_HALF_FLOAT: {
- return context->get_shader_capabilities().shader_float16_is_supported && context->get_storage_buffer_capabilities().storage_buffer_16_bit_access_is_supported;
+ return context->get_shader_capabilities().shader_float16_is_supported && context->get_physical_device_features().shaderInt16 && context->get_storage_buffer_capabilities().storage_buffer_16_bit_access_is_supported;
} break;
case SUPPORTS_ATTACHMENT_VRS: {
VulkanContext::VRSCapabilities vrs_capabilities = context->get_vrs_capabilities();
- return vrs_capabilities.attachment_vrs_supported;
+ return vrs_capabilities.attachment_vrs_supported && context->get_physical_device_features().shaderStorageImageExtendedFormats;
} break;
default: {
return false;
diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h
index b2c2a03a87..91a09fa970 100644
--- a/drivers/vulkan/rendering_device_vulkan.h
+++ b/drivers/vulkan/rendering_device_vulkan.h
@@ -1047,7 +1047,7 @@ public:
virtual RID texture_create_shared(const TextureView &p_view, RID p_with_texture);
virtual RID texture_create_from_extension(TextureType p_type, DataFormat p_format, TextureSamples p_samples, uint64_t p_flags, uint64_t p_image, uint64_t p_width, uint64_t p_height, uint64_t p_depth, uint64_t p_layers);
- virtual RID texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, uint32_t p_mipmaps = 1, TextureSliceType p_slice_type = TEXTURE_SLICE_2D);
+ virtual RID texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, uint32_t p_mipmaps = 1, TextureSliceType p_slice_type = TEXTURE_SLICE_2D, uint32_t p_layers = 0);
virtual Error texture_update(RID p_texture, uint32_t p_layer, const Vector<uint8_t> &p_data, BitField<BarrierMask> p_post_barrier = BARRIER_MASK_ALL_BARRIERS);
virtual Vector<uint8_t> texture_get_data(RID p_texture, uint32_t p_layer);
@@ -1122,7 +1122,7 @@ public:
virtual Error buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const void *p_data, BitField<BarrierMask> p_post_barrier = BARRIER_MASK_ALL_BARRIERS); // Works for any buffer.
virtual Error buffer_clear(RID p_buffer, uint32_t p_offset, uint32_t p_size, BitField<BarrierMask> p_post_barrier = BARRIER_MASK_ALL_BARRIERS);
- virtual Vector<uint8_t> buffer_get_data(RID p_buffer);
+ virtual Vector<uint8_t> buffer_get_data(RID p_buffer, uint32_t p_offset = 0, uint32_t p_size = 0);
/*************************/
/**** RENDER PIPELINE ****/
diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp
index 0bccefede8..b8cea7136d 100644
--- a/drivers/vulkan/vulkan_context.cpp
+++ b/drivers/vulkan/vulkan_context.cpp
@@ -353,11 +353,11 @@ Error VulkanContext::_get_preferred_validation_layers(uint32_t *count, const cha
ERR_FAIL_V(ERR_CANT_CREATE);
}
- for (uint32_t i = 0; i < instance_validation_layers_alt.size(); i++) {
- if (_check_layers(instance_validation_layers_alt[i].size(), instance_validation_layers_alt[i].ptr(), instance_layer_count, instance_layers)) {
- *count = instance_validation_layers_alt[i].size();
+ for (const LocalVector<const char *> &layer : instance_validation_layers_alt) {
+ if (_check_layers(layer.size(), layer.ptr(), instance_layer_count, instance_layers)) {
+ *count = layer.size();
if (names != nullptr) {
- *names = instance_validation_layers_alt[i].ptr();
+ *names = layer.ptr();
}
break;
}
@@ -413,6 +413,7 @@ Error VulkanContext::_initialize_instance_extensions() {
register_requested_instance_extension(VK_EXT_DEBUG_REPORT_EXTENSION_NAME, false);
}
+ // This extension allows us to use the properties2 features to query additional device capabilities
register_requested_instance_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, false);
// Only enable debug utils in verbose mode or DEV_ENABLED.
@@ -493,7 +494,10 @@ Error VulkanContext::_initialize_device_extensions() {
register_requested_device_extension(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME, false);
register_requested_device_extension(VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME, false);
register_requested_device_extension(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME, false);
+ register_requested_device_extension(VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME, false);
register_requested_device_extension(VK_KHR_16BIT_STORAGE_EXTENSION_NAME, false);
+ register_requested_device_extension(VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME, false);
+ register_requested_device_extension(VK_KHR_MAINTENANCE_2_EXTENSION_NAME, false);
// TODO consider the following extensions:
// - VK_KHR_spirv_1_4
@@ -744,48 +748,90 @@ Error VulkanContext::_check_capabilities() {
}
if (vkGetPhysicalDeviceFeatures2_func != nullptr) {
// Check our extended features.
- VkPhysicalDeviceFragmentShadingRateFeaturesKHR vrs_features = {
- /*sType*/ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR,
- /*pNext*/ nullptr,
- /*pipelineFragmentShadingRate*/ false,
- /*primitiveFragmentShadingRate*/ false,
- /*attachmentFragmentShadingRate*/ false,
- };
+ void *next = nullptr;
- VkPhysicalDeviceShaderFloat16Int8FeaturesKHR shader_features = {
- /*sType*/ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR,
- /*pNext*/ &vrs_features,
- /*shaderFloat16*/ false,
- /*shaderInt8*/ false,
- };
+ // We must check that the relative extension is present before assuming a
+ // feature as enabled.
+ // See also: https://github.com/godotengine/godot/issues/65409
- VkPhysicalDevice16BitStorageFeaturesKHR storage_feature = {
- /*sType*/ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR,
- /*pNext*/ &shader_features,
- /*storageBuffer16BitAccess*/ false,
- /*uniformAndStorageBuffer16BitAccess*/ false,
- /*storagePushConstant16*/ false,
- /*storageInputOutput16*/ false,
- };
+ VkPhysicalDeviceVulkan12Features device_features_vk12 = {};
+ VkPhysicalDeviceShaderFloat16Int8FeaturesKHR shader_features = {};
+ VkPhysicalDeviceFragmentShadingRateFeaturesKHR vrs_features = {};
+ VkPhysicalDevice16BitStorageFeaturesKHR storage_feature = {};
+ VkPhysicalDeviceMultiviewFeatures multiview_features = {};
- VkPhysicalDeviceMultiviewFeatures multiview_features = {
- /*sType*/ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES,
- /*pNext*/ &storage_feature,
- /*multiview*/ false,
- /*multiviewGeometryShader*/ false,
- /*multiviewTessellationShader*/ false,
- };
+ if (device_api_version >= VK_API_VERSION_1_2) {
+ device_features_vk12.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
+ device_features_vk12.pNext = next;
+ next = &device_features_vk12;
+ } else {
+ if (is_device_extension_enabled(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME)) {
+ shader_features = {
+ /*sType*/ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR,
+ /*pNext*/ next,
+ /*shaderFloat16*/ false,
+ /*shaderInt8*/ false,
+ };
+ next = &shader_features;
+ }
+ }
+
+ if (is_device_extension_enabled(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME)) {
+ vrs_features = {
+ /*sType*/ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR,
+ /*pNext*/ next,
+ /*pipelineFragmentShadingRate*/ false,
+ /*primitiveFragmentShadingRate*/ false,
+ /*attachmentFragmentShadingRate*/ false,
+ };
+ next = &vrs_features;
+ }
+
+ if (is_device_extension_enabled(VK_KHR_16BIT_STORAGE_EXTENSION_NAME)) {
+ storage_feature = {
+ /*sType*/ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR,
+ /*pNext*/ next,
+ /*storageBuffer16BitAccess*/ false,
+ /*uniformAndStorageBuffer16BitAccess*/ false,
+ /*storagePushConstant16*/ false,
+ /*storageInputOutput16*/ false,
+ };
+ next = &storage_feature;
+ }
+
+ if (is_device_extension_enabled(VK_KHR_MULTIVIEW_EXTENSION_NAME)) {
+ multiview_features = {
+ /*sType*/ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES,
+ /*pNext*/ next,
+ /*multiview*/ false,
+ /*multiviewGeometryShader*/ false,
+ /*multiviewTessellationShader*/ false,
+ };
+ next = &multiview_features;
+ }
VkPhysicalDeviceFeatures2 device_features;
device_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
- device_features.pNext = &multiview_features;
+ device_features.pNext = next;
vkGetPhysicalDeviceFeatures2_func(gpu, &device_features);
- // We must check that the relative extension is present before assuming a
- // feature as enabled. Actually, according to the spec we shouldn't add the
- // structs in pNext at all, but this works fine.
- // See also: https://github.com/godotengine/godot/issues/65409
+ if (device_api_version >= VK_API_VERSION_1_2) {
+#ifdef MACOS_ENABLED
+ ERR_FAIL_COND_V_MSG(!device_features_vk12.shaderSampledImageArrayNonUniformIndexing, ERR_CANT_CREATE, "Your GPU doesn't support shaderSampledImageArrayNonUniformIndexing which is required to use the Vulkan-based renderers in Godot.");
+#endif
+
+ if (is_device_extension_enabled(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME)) {
+ shader_capabilities.shader_float16_is_supported = device_features_vk12.shaderFloat16;
+ shader_capabilities.shader_int8_is_supported = device_features_vk12.shaderInt8;
+ }
+ } else {
+ if (is_device_extension_enabled(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME)) {
+ shader_capabilities.shader_float16_is_supported = shader_features.shaderFloat16;
+ shader_capabilities.shader_int8_is_supported = shader_features.shaderInt8;
+ }
+ }
+
if (is_device_extension_enabled(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME)) {
vrs_capabilities.pipeline_vrs_supported = vrs_features.pipelineFragmentShadingRate;
vrs_capabilities.primitive_vrs_supported = vrs_features.primitiveFragmentShadingRate;
@@ -798,11 +844,6 @@ Error VulkanContext::_check_capabilities() {
multiview_capabilities.tessellation_shader_is_supported = multiview_features.multiviewTessellationShader;
}
- if (is_device_extension_enabled(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME)) {
- shader_capabilities.shader_float16_is_supported = shader_features.shaderFloat16;
- shader_capabilities.shader_int8_is_supported = shader_features.shaderInt8;
- }
-
if (is_device_extension_enabled(VK_KHR_16BIT_STORAGE_EXTENSION_NAME)) {
storage_buffer_capabilities.storage_buffer_16_bit_access_is_supported = storage_feature.storageBuffer16BitAccess;
storage_buffer_capabilities.uniform_and_storage_buffer_16_bit_access_is_supported = storage_feature.uniformAndStorageBuffer16BitAccess;
@@ -1258,8 +1299,15 @@ Error VulkanContext::_create_physical_device(VkSurfaceKHR p_surface) {
// Get device version
device_api_version = gpu_props.apiVersion;
+ String rendering_method;
+ if (OS::get_singleton()->get_current_rendering_method() == "mobile") {
+ rendering_method = "Forward Mobile";
+ } else {
+ rendering_method = "Forward+";
+ }
+
// Output our device version
- print_line("Vulkan API " + get_device_api_version() + " - " + "Using Vulkan Device #" + itos(device_index) + ": " + device_vendor + " - " + device_name);
+ print_line(vformat("Vulkan API %s - %s - Using Vulkan Device #%d: %s - %s", get_device_api_version(), rendering_method, device_index, device_vendor, device_name));
{
Error _err = _initialize_device_extensions();
@@ -1279,6 +1327,10 @@ Error VulkanContext::_create_physical_device(VkSurfaceKHR p_surface) {
// features based on this query
vkGetPhysicalDeviceFeatures(gpu, &physical_device_features);
+ // Check required features
+ ERR_FAIL_COND_V_MSG(!physical_device_features.imageCubeArray, ERR_CANT_CREATE, "Your GPU doesn't support image cube arrays which are required to use the Vulkan-based renderers in Godot.");
+ ERR_FAIL_COND_V_MSG(!physical_device_features.independentBlend, ERR_CANT_CREATE, "Your GPU doesn't support independentBlend which is required to use the Vulkan-based renderers in Godot.");
+
physical_device_features.robustBufferAccess = false; // Turn off robust buffer access, which can hamper performance on some hardware.
#define GET_INSTANCE_PROC_ADDR(inst, entrypoint) \
@@ -1819,7 +1871,10 @@ Error VulkanContext::_update_swap_chain(Window *window) {
// Set the windows present mode if it is available, otherwise FIFO is used (guaranteed supported).
if (present_mode_available) {
- window->presentMode = requested_present_mode;
+ if (window->presentMode != requested_present_mode) {
+ window->presentMode = requested_present_mode;
+ print_verbose("Using present mode: " + String(string_VkPresentModeKHR(window->presentMode)));
+ }
} else {
String present_mode_string;
switch (window->vsync_mode) {
@@ -1840,8 +1895,6 @@ Error VulkanContext::_update_swap_chain(Window *window) {
window->vsync_mode = DisplayServer::VSYNC_ENABLED; // Set to default.
}
- print_verbose("Using present mode: " + String(string_VkPresentModeKHR(window->presentMode)));
-
free(presentModes);
// Determine the number of VkImages to use in the swap chain.
@@ -2219,7 +2272,7 @@ Error VulkanContext::prepare_buffers() {
print_verbose("Vulkan: Early suboptimal swapchain.");
break;
} else if (err != VK_SUCCESS) {
- ERR_BREAK_MSG(err != VK_SUCCESS, "Vulkan: Did not create swapchain successfully.");
+ ERR_BREAK_MSG(err != VK_SUCCESS, "Vulkan: Did not create swapchain successfully. Error code: " + String(string_VkResult(err)));
} else {
w->semaphore_acquired = true;
}
@@ -2252,7 +2305,7 @@ Error VulkanContext::swap_buffers() {
// simple that it doesn't do either of those.
}
#endif
- // Wait for the image acquired semaphore to be signalled to ensure
+ // Wait for the image acquired semaphore to be signaled to ensure
// that the image won't be rendered to until the presentation
// engine has fully released ownership to the application, and it is
// okay to render to the image.
@@ -2296,7 +2349,7 @@ Error VulkanContext::swap_buffers() {
submit_info.signalSemaphoreCount = 1;
submit_info.pSignalSemaphores = &draw_complete_semaphores[frame_index];
err = vkQueueSubmit(graphics_queue, 1, &submit_info, fences[frame_index]);
- ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
+ ERR_FAIL_COND_V_MSG(err, ERR_CANT_CREATE, "Vulkan: Cannot submit graphics queue. Error code: " + String(string_VkResult(err)));
command_buffer_queue.write[0] = nullptr;
command_buffer_count = 1;
@@ -2304,7 +2357,7 @@ Error VulkanContext::swap_buffers() {
if (separate_present_queue) {
// If we are using separate queues, change image ownership to the
// present queue before presenting, waiting for the draw complete
- // semaphore and signalling the ownership released semaphore when finished.
+ // semaphore and signaling the ownership released semaphore when finished.
VkFence nullFence = VK_NULL_HANDLE;
pipe_stage_flags[0] = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
submit_info.waitSemaphoreCount = 1;
@@ -2327,7 +2380,7 @@ Error VulkanContext::swap_buffers() {
submit_info.signalSemaphoreCount = 1;
submit_info.pSignalSemaphores = &image_ownership_semaphores[frame_index];
err = vkQueueSubmit(present_queue, 1, &submit_info, nullFence);
- ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
+ ERR_FAIL_COND_V_MSG(err, ERR_CANT_CREATE, "Vulkan: Cannot submit present queue. Error code: " + String(string_VkResult(err)));
}
// If we are using separate queues, we have to wait for image ownership,
@@ -2436,14 +2489,14 @@ Error VulkanContext::swap_buffers() {
if (err == VK_ERROR_OUT_OF_DATE_KHR) {
// Swapchain is out of date (e.g. the window was resized) and
// must be recreated.
- print_verbose("Vulkan: Swapchain is out of date, recreating.");
+ print_verbose("Vulkan queue submit: Swapchain is out of date, recreating.");
resize_notify();
} else if (err == VK_SUBOPTIMAL_KHR) {
// Swapchain is not as optimal as it could be, but the platform's
// presentation engine will still present the image correctly.
- print_verbose("Vulkan: Swapchain is suboptimal.");
+ print_verbose("Vulkan queue submit: Swapchain is suboptimal.");
} else {
- ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
+ ERR_FAIL_COND_V_MSG(err, ERR_CANT_CREATE, "Error code: " + String(string_VkResult(err)));
}
buffers_prepared = false;
diff --git a/drivers/vulkan/vulkan_context.h b/drivers/vulkan/vulkan_context.h
index 7044064e12..9fd2c40a06 100644
--- a/drivers/vulkan/vulkan_context.h
+++ b/drivers/vulkan/vulkan_context.h
@@ -280,6 +280,7 @@ public:
const VRSCapabilities &get_vrs_capabilities() const { return vrs_capabilities; };
const ShaderCapabilities &get_shader_capabilities() const { return shader_capabilities; };
const StorageBufferCapabilities &get_storage_buffer_capabilities() const { return storage_buffer_capabilities; };
+ const VkPhysicalDeviceFeatures &get_physical_device_features() const { return physical_device_features; };
VkDevice get_device();
VkPhysicalDevice get_physical_device();
diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp
index b2745b1e86..72ec0c19ab 100644
--- a/drivers/wasapi/audio_driver_wasapi.cpp
+++ b/drivers/wasapi/audio_driver_wasapi.cpp
@@ -118,8 +118,8 @@ const IID IID_IAudioCaptureClient = __uuidof(IAudioCaptureClient);
#define CAPTURE_BUFFER_CHANNELS 2
-static bool default_render_device_changed = false;
-static bool default_capture_device_changed = false;
+static bool default_output_device_changed = false;
+static bool default_input_device_changed = false;
// Silence warning due to a COM API weirdness (GH-35194).
#if defined(__GNUC__) && !defined(__clang__)
@@ -181,9 +181,9 @@ public:
HRESULT STDMETHODCALLTYPE OnDefaultDeviceChanged(EDataFlow flow, ERole role, LPCWSTR pwstrDeviceId) {
if (role == eConsole) {
if (flow == eRender) {
- default_render_device_changed = true;
+ default_output_device_changed = true;
} else if (flow == eCapture) {
- default_capture_device_changed = true;
+ default_input_device_changed = true;
}
}
@@ -201,10 +201,10 @@ public:
static CMMNotificationClient notif_client;
-Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_capture, bool p_reinit, bool p_no_audio_client_3) {
+Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_input, bool p_reinit, bool p_no_audio_client_3) {
WAVEFORMATEX *pwfex;
IMMDeviceEnumerator *enumerator = nullptr;
- IMMDevice *device = nullptr;
+ IMMDevice *output_device = nullptr;
CoInitialize(nullptr);
@@ -212,11 +212,11 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_c
ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);
if (p_device->device_name == "Default") {
- hr = enumerator->GetDefaultAudioEndpoint(p_capture ? eCapture : eRender, eConsole, &device);
+ hr = enumerator->GetDefaultAudioEndpoint(p_input ? eCapture : eRender, eConsole, &output_device);
} else {
IMMDeviceCollection *devices = nullptr;
- hr = enumerator->EnumAudioEndpoints(p_capture ? eCapture : eRender, DEVICE_STATE_ACTIVE, &devices);
+ hr = enumerator->EnumAudioEndpoints(p_input ? eCapture : eRender, DEVICE_STATE_ACTIVE, &devices);
ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);
LPWSTR strId = nullptr;
@@ -255,20 +255,20 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_c
}
if (found) {
- hr = enumerator->GetDevice(strId, &device);
+ hr = enumerator->GetDevice(strId, &output_device);
}
if (strId) {
CoTaskMemFree(strId);
}
- if (device == nullptr) {
- hr = enumerator->GetDefaultAudioEndpoint(p_capture ? eCapture : eRender, eConsole, &device);
+ if (output_device == nullptr) {
+ hr = enumerator->GetDefaultAudioEndpoint(p_input ? eCapture : eRender, eConsole, &output_device);
}
}
if (p_reinit) {
- // In case we're trying to re-initialize the device prevent throwing this error on the console,
+ // In case we're trying to re-initialize the device, prevent throwing this error on the console,
// otherwise if there is currently no device available this will spam the console.
if (hr != S_OK) {
return ERR_CANT_OPEN;
@@ -284,28 +284,28 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_c
ERR_PRINT("WASAPI: RegisterEndpointNotificationCallback error");
}
- using_audio_client_3 = !p_capture; // IID_IAudioClient3 is only used for adjustable output latency (not input)
+ using_audio_client_3 = !p_input; // IID_IAudioClient3 is only used for adjustable output latency (not input)
if (p_no_audio_client_3) {
using_audio_client_3 = false;
}
if (using_audio_client_3) {
- hr = device->Activate(IID_IAudioClient3, CLSCTX_ALL, nullptr, (void **)&p_device->audio_client);
+ hr = output_device->Activate(IID_IAudioClient3, CLSCTX_ALL, nullptr, (void **)&p_device->audio_client);
if (hr != S_OK) {
// IID_IAudioClient3 will never activate on OS versions before Windows 10.
// Older Windows versions should fall back gracefully.
using_audio_client_3 = false;
- print_verbose("WASAPI: Couldn't activate device with IAudioClient3 interface, falling back to IAudioClient interface");
+ print_verbose("WASAPI: Couldn't activate output_device with IAudioClient3 interface, falling back to IAudioClient interface");
} else {
- print_verbose("WASAPI: Activated device using IAudioClient3 interface");
+ print_verbose("WASAPI: Activated output_device using IAudioClient3 interface");
}
}
if (!using_audio_client_3) {
- hr = device->Activate(IID_IAudioClient, CLSCTX_ALL, nullptr, (void **)&p_device->audio_client);
+ hr = output_device->Activate(IID_IAudioClient, CLSCTX_ALL, nullptr, (void **)&p_device->audio_client);
}
- SAFE_RELEASE(device)
+ SAFE_RELEASE(output_device)
if (p_reinit) {
if (hr != S_OK) {
@@ -339,7 +339,7 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_c
WAVEFORMATEX *closest = nullptr;
hr = p_device->audio_client->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED, pwfex, &closest);
if (hr == S_FALSE) {
- WARN_PRINT("WASAPI: Mix format is not supported by the Device");
+ WARN_PRINT("WASAPI: Mix format is not supported by the output_device");
if (closest) {
print_verbose("WASAPI: closest->wFormatTag = " + itos(closest->wFormatTag));
print_verbose("WASAPI: closest->nChannels = " + itos(closest->nChannels));
@@ -385,14 +385,14 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_c
pwfex->nSamplesPerSec = mix_rate;
pwfex->nAvgBytesPerSec = pwfex->nSamplesPerSec * pwfex->nChannels * (pwfex->wBitsPerSample / 8);
}
- hr = p_device->audio_client->Initialize(AUDCLNT_SHAREMODE_SHARED, streamflags, p_capture ? REFTIMES_PER_SEC : 0, 0, pwfex, nullptr);
+ hr = p_device->audio_client->Initialize(AUDCLNT_SHAREMODE_SHARED, streamflags, p_input ? REFTIMES_PER_SEC : 0, 0, pwfex, nullptr);
ERR_FAIL_COND_V_MSG(hr != S_OK, ERR_CANT_OPEN, "WASAPI: Initialize failed with error 0x" + String::num_uint64(hr, 16) + ".");
UINT32 max_frames;
hr = p_device->audio_client->GetBufferSize(&max_frames);
ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);
// Due to WASAPI Shared Mode we have no control of the buffer size
- if (!p_capture) {
+ if (!p_input) {
buffer_frames = max_frames;
int64_t latency = 0;
@@ -421,8 +421,8 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_c
if (hr != S_OK) {
print_verbose("WASAPI: GetSharedModeEnginePeriod failed with error 0x" + String::num_uint64(hr, 16) + ", falling back to IAudioClient.");
CoTaskMemFree(pwfex);
- SAFE_RELEASE(device)
- return audio_device_init(p_device, p_capture, p_reinit, true);
+ SAFE_RELEASE(output_device)
+ return audio_device_init(p_device, p_input, p_reinit, true);
}
// Period frames must be an integral multiple of fundamental_period_frames or IAudioClient3 initialization will fail,
@@ -443,8 +443,8 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_c
if (hr != S_OK) {
print_verbose("WASAPI: InitializeSharedAudioStream failed with error 0x" + String::num_uint64(hr, 16) + ", falling back to IAudioClient.");
CoTaskMemFree(pwfex);
- SAFE_RELEASE(device);
- return audio_device_init(p_device, p_capture, p_reinit, true);
+ SAFE_RELEASE(output_device);
+ return audio_device_init(p_device, p_input, p_reinit, true);
} else {
uint32_t output_latency_in_frames;
WAVEFORMATEX *current_pwfex;
@@ -455,13 +455,13 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_c
} else {
print_verbose("WASAPI: GetCurrentSharedModeEnginePeriod failed with error 0x" + String::num_uint64(hr, 16) + ", falling back to IAudioClient.");
CoTaskMemFree(pwfex);
- SAFE_RELEASE(device);
- return audio_device_init(p_device, p_capture, p_reinit, true);
+ SAFE_RELEASE(output_device);
+ return audio_device_init(p_device, p_input, p_reinit, true);
}
}
}
- if (p_capture) {
+ if (p_input) {
hr = p_device->audio_client->GetService(IID_IAudioCaptureClient, (void **)&p_device->capture_client);
} else {
hr = p_device->audio_client->GetService(IID_IAudioRenderClient, (void **)&p_device->render_client);
@@ -470,12 +470,12 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_c
// Free memory
CoTaskMemFree(pwfex);
- SAFE_RELEASE(device)
+ SAFE_RELEASE(output_device)
return OK;
}
-Error AudioDriverWASAPI::init_render_device(bool p_reinit) {
+Error AudioDriverWASAPI::init_output_device(bool p_reinit) {
Error err = audio_device_init(&audio_output, false, p_reinit);
if (err != OK) {
return err;
@@ -507,7 +507,7 @@ Error AudioDriverWASAPI::init_render_device(bool p_reinit) {
return OK;
}
-Error AudioDriverWASAPI::init_capture_device(bool p_reinit) {
+Error AudioDriverWASAPI::init_input_device(bool p_reinit) {
Error err = audio_device_init(&audio_input, true, p_reinit);
if (err != OK) {
return err;
@@ -538,11 +538,11 @@ Error AudioDriverWASAPI::audio_device_finish(AudioDeviceWASAPI *p_device) {
return OK;
}
-Error AudioDriverWASAPI::finish_render_device() {
+Error AudioDriverWASAPI::finish_output_device() {
return audio_device_finish(&audio_output);
}
-Error AudioDriverWASAPI::finish_capture_device() {
+Error AudioDriverWASAPI::finish_input_device() {
return audio_device_finish(&audio_input);
}
@@ -551,9 +551,9 @@ Error AudioDriverWASAPI::init() {
target_latency_ms = GLOBAL_GET("audio/driver/output_latency");
- Error err = init_render_device();
+ Error err = init_output_device();
if (err != OK) {
- ERR_PRINT("WASAPI: init_render_device error");
+ ERR_PRINT("WASAPI: init_output_device error");
}
exit_thread.clear();
@@ -575,7 +575,7 @@ AudioDriver::SpeakerMode AudioDriverWASAPI::get_speaker_mode() const {
return get_speaker_mode_by_total_channels(channels);
}
-PackedStringArray AudioDriverWASAPI::audio_device_get_list(bool p_capture) {
+PackedStringArray AudioDriverWASAPI::audio_device_get_list(bool p_input) {
PackedStringArray list;
IMMDeviceCollection *devices = nullptr;
IMMDeviceEnumerator *enumerator = nullptr;
@@ -587,7 +587,7 @@ PackedStringArray AudioDriverWASAPI::audio_device_get_list(bool p_capture) {
HRESULT hr = CoCreateInstance(CLSID_MMDeviceEnumerator, nullptr, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void **)&enumerator);
ERR_FAIL_COND_V(hr != S_OK, PackedStringArray());
- hr = enumerator->EnumAudioEndpoints(p_capture ? eCapture : eRender, DEVICE_STATE_ACTIVE, &devices);
+ hr = enumerator->EnumAudioEndpoints(p_input ? eCapture : eRender, DEVICE_STATE_ACTIVE, &devices);
ERR_FAIL_COND_V(hr != S_OK, PackedStringArray());
UINT count = 0;
@@ -595,13 +595,13 @@ PackedStringArray AudioDriverWASAPI::audio_device_get_list(bool p_capture) {
ERR_FAIL_COND_V(hr != S_OK, PackedStringArray());
for (ULONG i = 0; i < count; i++) {
- IMMDevice *device = nullptr;
+ IMMDevice *output_device = nullptr;
- hr = devices->Item(i, &device);
+ hr = devices->Item(i, &output_device);
ERR_BREAK(hr != S_OK);
IPropertyStore *props = nullptr;
- hr = device->OpenPropertyStore(STGM_READ, &props);
+ hr = output_device->OpenPropertyStore(STGM_READ, &props);
ERR_BREAK(hr != S_OK);
PROPVARIANT propvar;
@@ -614,7 +614,7 @@ PackedStringArray AudioDriverWASAPI::audio_device_get_list(bool p_capture) {
PropVariantClear(&propvar);
props->Release();
- device->Release();
+ output_device->Release();
}
devices->Release();
@@ -622,11 +622,11 @@ PackedStringArray AudioDriverWASAPI::audio_device_get_list(bool p_capture) {
return list;
}
-PackedStringArray AudioDriverWASAPI::get_device_list() {
+PackedStringArray AudioDriverWASAPI::get_output_device_list() {
return audio_device_get_list(false);
}
-String AudioDriverWASAPI::get_device() {
+String AudioDriverWASAPI::get_output_device() {
lock();
String name = audio_output.device_name;
unlock();
@@ -634,9 +634,9 @@ String AudioDriverWASAPI::get_device() {
return name;
}
-void AudioDriverWASAPI::set_device(String device) {
+void AudioDriverWASAPI::set_output_device(const String &p_name) {
lock();
- audio_output.new_device = device;
+ audio_output.new_device = p_name;
unlock();
}
@@ -769,13 +769,13 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
avail_frames -= write_frames;
written_frames += write_frames;
} else if (hr == AUDCLNT_E_DEVICE_INVALIDATED) {
- // Device is not valid anymore, reopen it
+ // output_device is not valid anymore, reopen it
- Error err = ad->finish_render_device();
+ Error err = ad->finish_output_device();
if (err != OK) {
- ERR_PRINT("WASAPI: finish_render_device error");
+ ERR_PRINT("WASAPI: finish_output_device error");
} else {
- // We reopened the device and samples_in may have resized, so invalidate the current avail_frames
+ // We reopened the output device and samples_in may have resized, so invalidate the current avail_frames
avail_frames = 0;
}
} else {
@@ -790,37 +790,37 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
}
if (invalidated) {
- // Device is not valid anymore
- WARN_PRINT("WASAPI: Current device invalidated, closing device");
+ // output_device is not valid anymore
+ WARN_PRINT("WASAPI: Current output_device invalidated, closing output_device");
- Error err = ad->finish_render_device();
+ Error err = ad->finish_output_device();
if (err != OK) {
- ERR_PRINT("WASAPI: finish_render_device error");
+ ERR_PRINT("WASAPI: finish_output_device error");
}
}
}
- // If we're using the Default device and it changed finish it so we'll re-init the device
- if (ad->audio_output.device_name == "Default" && default_render_device_changed) {
- Error err = ad->finish_render_device();
+ // If we're using the Default output device and it changed finish it so we'll re-init the output device
+ if (ad->audio_output.device_name == "Default" && default_output_device_changed) {
+ Error err = ad->finish_output_device();
if (err != OK) {
- ERR_PRINT("WASAPI: finish_render_device error");
+ ERR_PRINT("WASAPI: finish_output_device error");
}
- default_render_device_changed = false;
+ default_output_device_changed = false;
}
- // User selected a new device, finish the current one so we'll init the new device
+ // User selected a new output device, finish the current one so we'll init the new output device
if (ad->audio_output.device_name != ad->audio_output.new_device) {
ad->audio_output.device_name = ad->audio_output.new_device;
- Error err = ad->finish_render_device();
+ Error err = ad->finish_output_device();
if (err != OK) {
- ERR_PRINT("WASAPI: finish_render_device error");
+ ERR_PRINT("WASAPI: finish_output_device error");
}
}
if (!ad->audio_output.audio_client) {
- Error err = ad->init_render_device(true);
+ Error err = ad->init_output_device(true);
if (err == OK) {
ad->start();
}
@@ -873,29 +873,29 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
}
}
- // If we're using the Default device and it changed finish it so we'll re-init the device
- if (ad->audio_input.device_name == "Default" && default_capture_device_changed) {
- Error err = ad->finish_capture_device();
+ // If we're using the Default output device and it changed finish it so we'll re-init the output device
+ if (ad->audio_input.device_name == "Default" && default_input_device_changed) {
+ Error err = ad->finish_input_device();
if (err != OK) {
- ERR_PRINT("WASAPI: finish_capture_device error");
+ ERR_PRINT("WASAPI: finish_input_device error");
}
- default_capture_device_changed = false;
+ default_input_device_changed = false;
}
- // User selected a new device, finish the current one so we'll init the new device
+ // User selected a new input device, finish the current one so we'll init the new input device
if (ad->audio_input.device_name != ad->audio_input.new_device) {
ad->audio_input.device_name = ad->audio_input.new_device;
- Error err = ad->finish_capture_device();
+ Error err = ad->finish_input_device();
if (err != OK) {
- ERR_PRINT("WASAPI: finish_capture_device error");
+ ERR_PRINT("WASAPI: finish_input_device error");
}
}
if (!ad->audio_input.audio_client) {
- Error err = ad->init_capture_device(true);
+ Error err = ad->init_input_device(true);
if (err == OK) {
- ad->capture_start();
+ ad->input_start();
}
}
}
@@ -933,14 +933,14 @@ void AudioDriverWASAPI::finish() {
exit_thread.set();
thread.wait_to_finish();
- finish_capture_device();
- finish_render_device();
+ finish_input_device();
+ finish_output_device();
}
-Error AudioDriverWASAPI::capture_start() {
- Error err = init_capture_device();
+Error AudioDriverWASAPI::input_start() {
+ Error err = init_input_device();
if (err != OK) {
- ERR_PRINT("WASAPI: init_capture_device error");
+ ERR_PRINT("WASAPI: init_input_device error");
return err;
}
@@ -953,7 +953,7 @@ Error AudioDriverWASAPI::capture_start() {
return OK;
}
-Error AudioDriverWASAPI::capture_stop() {
+Error AudioDriverWASAPI::input_stop() {
if (audio_input.active.is_set()) {
audio_input.audio_client->Stop();
audio_input.active.clear();
@@ -964,17 +964,11 @@ Error AudioDriverWASAPI::capture_stop() {
return FAILED;
}
-void AudioDriverWASAPI::capture_set_device(const String &p_name) {
- lock();
- audio_input.new_device = p_name;
- unlock();
-}
-
-PackedStringArray AudioDriverWASAPI::capture_get_device_list() {
+PackedStringArray AudioDriverWASAPI::get_input_device_list() {
return audio_device_get_list(true);
}
-String AudioDriverWASAPI::capture_get_device() {
+String AudioDriverWASAPI::get_input_device() {
lock();
String name = audio_input.device_name;
unlock();
@@ -982,6 +976,12 @@ String AudioDriverWASAPI::capture_get_device() {
return name;
}
+void AudioDriverWASAPI::set_input_device(const String &p_name) {
+ lock();
+ audio_input.new_device = p_name;
+ unlock();
+}
+
AudioDriverWASAPI::AudioDriverWASAPI() {
samples_in.clear();
}
diff --git a/drivers/wasapi/audio_driver_wasapi.h b/drivers/wasapi/audio_driver_wasapi.h
index 6eea24f78a..367c30607a 100644
--- a/drivers/wasapi/audio_driver_wasapi.h
+++ b/drivers/wasapi/audio_driver_wasapi.h
@@ -47,8 +47,8 @@ class AudioDriverWASAPI : public AudioDriver {
class AudioDeviceWASAPI {
public:
IAudioClient *audio_client = nullptr;
- IAudioRenderClient *render_client = nullptr;
- IAudioCaptureClient *capture_client = nullptr;
+ IAudioRenderClient *render_client = nullptr; // Output
+ IAudioCaptureClient *capture_client = nullptr; // Input
SafeFlag active;
WORD format_tag = 0;
@@ -56,8 +56,8 @@ class AudioDriverWASAPI : public AudioDriver {
unsigned int channels = 0;
unsigned int frame_size = 0;
- String device_name = "Default";
- String new_device = "Default";
+ String device_name = "Default"; // Output OR Input
+ String new_device = "Default"; // Output OR Input
AudioDeviceWASAPI() {}
};
@@ -83,38 +83,41 @@ class AudioDriverWASAPI : public AudioDriver {
static _FORCE_INLINE_ int32_t read_sample(WORD format_tag, int bits_per_sample, BYTE *buffer, int i);
static void thread_func(void *p_udata);
- Error init_render_device(bool p_reinit = false);
- Error init_capture_device(bool p_reinit = false);
+ Error init_output_device(bool p_reinit = false);
+ Error init_input_device(bool p_reinit = false);
- Error finish_render_device();
- Error finish_capture_device();
+ Error finish_output_device();
+ Error finish_input_device();
- Error audio_device_init(AudioDeviceWASAPI *p_device, bool p_capture, bool p_reinit, bool p_no_audio_client_3 = false);
+ Error audio_device_init(AudioDeviceWASAPI *p_device, bool p_input, bool p_reinit, bool p_no_audio_client_3 = false);
Error audio_device_finish(AudioDeviceWASAPI *p_device);
- PackedStringArray audio_device_get_list(bool p_capture);
+ PackedStringArray audio_device_get_list(bool p_input);
public:
- virtual const char *get_name() const {
+ virtual const char *get_name() const override {
return "WASAPI";
}
- virtual Error init();
- virtual void start();
- virtual int get_mix_rate() const;
- virtual float get_latency();
- virtual SpeakerMode get_speaker_mode() const;
- virtual PackedStringArray get_device_list();
- virtual String get_device();
- virtual void set_device(String device);
- virtual void lock();
- virtual void unlock();
- virtual void finish();
-
- virtual Error capture_start();
- virtual Error capture_stop();
- virtual PackedStringArray capture_get_device_list();
- virtual void capture_set_device(const String &p_name);
- virtual String capture_get_device();
+ virtual Error init() override;
+ virtual void start() override;
+ virtual int get_mix_rate() const override;
+ virtual SpeakerMode get_speaker_mode() const override;
+ virtual float get_latency() override;
+
+ virtual void lock() override;
+ virtual void unlock() override;
+ virtual void finish() override;
+
+ virtual PackedStringArray get_output_device_list() override;
+ virtual String get_output_device() override;
+ virtual void set_output_device(const String &p_name) override;
+
+ virtual Error input_start() override;
+ virtual Error input_stop() override;
+
+ virtual PackedStringArray get_input_device_list() override;
+ virtual String get_input_device() override;
+ virtual void set_input_device(const String &p_name) override;
AudioDriverWASAPI();
};
diff --git a/drivers/windows/file_access_windows.cpp b/drivers/windows/file_access_windows.cpp
index 37a94ce4cc..0e51586b5a 100644
--- a/drivers/windows/file_access_windows.cpp
+++ b/drivers/windows/file_access_windows.cpp
@@ -34,7 +34,6 @@
#include "core/os/os.h"
#include "core/string/print_string.h"
-
#include <share.h> // _SH_DENYNO
#include <shlwapi.h>
#define WIN32_LEAN_AND_MEAN
@@ -58,7 +57,27 @@ void FileAccessWindows::check_errors() const {
}
}
+bool FileAccessWindows::is_path_invalid(const String &p_path) {
+ // Check for invalid operating system file.
+ String fname = p_path;
+ int dot = fname.find(".");
+ if (dot != -1) {
+ fname = fname.substr(0, dot);
+ }
+ fname = fname.to_lower();
+ return invalid_files.has(fname);
+}
+
Error FileAccessWindows::open_internal(const String &p_path, int p_mode_flags) {
+ if (is_path_invalid(p_path)) {
+#ifdef DEBUG_ENABLED
+ if (p_mode_flags != READ) {
+ WARN_PRINT("The path :" + p_path + " is a reserved Windows system pipe, so it can't be used for creating files.");
+ }
+#endif
+ return ERR_INVALID_PARAMETER;
+ }
+
_close();
path_src = p_path;
@@ -313,6 +332,10 @@ void FileAccessWindows::store_buffer(const uint8_t *p_src, uint64_t p_length) {
}
bool FileAccessWindows::file_exists(const String &p_name) {
+ if (is_path_invalid(p_name)) {
+ return false;
+ }
+
String filename = fix_path(p_name);
FILE *g = _wfsopen((LPCWSTR)(filename.utf16().get_data()), L"rb", _SH_DENYNO);
if (g == nullptr) {
@@ -324,6 +347,10 @@ bool FileAccessWindows::file_exists(const String &p_name) {
}
uint64_t FileAccessWindows::_get_modified_time(const String &p_file) {
+ if (is_path_invalid(p_file)) {
+ return 0;
+ }
+
String file = fix_path(p_file);
if (file.ends_with("/") && file != "/") {
file = file.substr(0, file.length() - 1);
@@ -348,8 +375,29 @@ Error FileAccessWindows::_set_unix_permissions(const String &p_file, uint32_t p_
return ERR_UNAVAILABLE;
}
+void FileAccessWindows::close() {
+ _close();
+}
+
FileAccessWindows::~FileAccessWindows() {
_close();
}
+HashSet<String> FileAccessWindows::invalid_files;
+
+void FileAccessWindows::initialize() {
+ static const char *reserved_files[]{
+ "con", "prn", "aux", "nul", "com0", "com1", "com2", "com3", "com4", "com5", "com6", "com7", "com8", "com9", "lpt0", "lpt1", "lpt2", "lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9", nullptr
+ };
+ int reserved_file_index = 0;
+ while (reserved_files[reserved_file_index] != nullptr) {
+ invalid_files.insert(reserved_files[reserved_file_index]);
+ reserved_file_index++;
+ }
+}
+
+void FileAccessWindows::finalize() {
+ invalid_files.clear();
+}
+
#endif // WINDOWS_ENABLED
diff --git a/drivers/windows/file_access_windows.h b/drivers/windows/file_access_windows.h
index 832cef3363..453f8d3b5f 100644
--- a/drivers/windows/file_access_windows.h
+++ b/drivers/windows/file_access_windows.h
@@ -50,6 +50,9 @@ class FileAccessWindows : public FileAccess {
void _close();
+ static bool is_path_invalid(const String &p_path);
+ static HashSet<String> invalid_files;
+
public:
virtual Error open_internal(const String &p_path, int p_mode_flags) override; ///< open a file
virtual bool is_open() const override; ///< true when file is open
@@ -79,6 +82,11 @@ public:
virtual uint32_t _get_unix_permissions(const String &p_file) override;
virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override;
+ virtual void close() override;
+
+ static void initialize();
+ static void finalize();
+
FileAccessWindows() {}
virtual ~FileAccessWindows();
};
diff --git a/drivers/xaudio2/audio_driver_xaudio2.cpp b/drivers/xaudio2/audio_driver_xaudio2.cpp
index cd1b29e17d..44ce01d4d7 100644
--- a/drivers/xaudio2/audio_driver_xaudio2.cpp
+++ b/drivers/xaudio2/audio_driver_xaudio2.cpp
@@ -33,10 +33,6 @@
#include "core/config/project_settings.h"
#include "core/os/os.h"
-const char *AudioDriverXAudio2::get_name() const {
- return "XAudio2";
-}
-
Error AudioDriverXAudio2::init() {
active.clear();
exit_thread.clear();
diff --git a/drivers/xaudio2/audio_driver_xaudio2.h b/drivers/xaudio2/audio_driver_xaudio2.h
index df5ef52e88..c659b6ffdc 100644
--- a/drivers/xaudio2/audio_driver_xaudio2.h
+++ b/drivers/xaudio2/audio_driver_xaudio2.h
@@ -91,16 +91,19 @@ class AudioDriverXAudio2 : public AudioDriver {
XAudio2DriverVoiceCallback voice_callback;
public:
- const char *get_name() const;
-
- virtual Error init();
- virtual void start();
- virtual int get_mix_rate() const;
- virtual SpeakerMode get_speaker_mode() const;
- virtual float get_latency();
- virtual void lock();
- virtual void unlock();
- virtual void finish();
+ virtual const char *get_name() const override {
+ return "XAudio2";
+ }
+
+ virtual Error init() override;
+ virtual void start() override;
+ virtual int get_mix_rate() const override;
+ virtual SpeakerMode get_speaker_mode() const override;
+ virtual float get_latency() override;
+
+ virtual void lock() override;
+ virtual void unlock() override;
+ virtual void finish() override;
AudioDriverXAudio2();
~AudioDriverXAudio2() {}