summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/alsa/audio_driver_alsa.cpp25
-rw-r--r--drivers/alsa/audio_driver_alsa.h6
-rw-r--r--drivers/alsamidi/midi_driver_alsamidi.cpp8
-rw-r--r--drivers/alsamidi/midi_driver_alsamidi.h3
-rw-r--r--drivers/coreaudio/audio_driver_coreaudio.cpp2
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp151
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.h3
-rw-r--r--drivers/gles3/shaders/canvas.glsl8
-rw-r--r--drivers/gles3/shaders/canvas_uniforms_inc.glsl1
-rw-r--r--drivers/gles3/storage/material_storage.h1
-rw-r--r--drivers/png/SCsub2
-rw-r--r--drivers/png/image_loader_png.cpp4
-rw-r--r--drivers/png/image_loader_png.h2
-rw-r--r--drivers/pulseaudio/audio_driver_pulseaudio.cpp27
-rw-r--r--drivers/pulseaudio/audio_driver_pulseaudio.h6
-rw-r--r--drivers/vulkan/rendering_device_vulkan.cpp10
-rw-r--r--drivers/vulkan/rendering_device_vulkan.h1
-rw-r--r--drivers/wasapi/audio_driver_wasapi.cpp29
-rw-r--r--drivers/wasapi/audio_driver_wasapi.h6
-rw-r--r--drivers/xaudio2/audio_driver_xaudio2.cpp17
-rw-r--r--drivers/xaudio2/audio_driver_xaudio2.h6
21 files changed, 179 insertions, 139 deletions
diff --git a/drivers/alsa/audio_driver_alsa.cpp b/drivers/alsa/audio_driver_alsa.cpp
index 1f40641b80..f4c87da9e9 100644
--- a/drivers/alsa/audio_driver_alsa.cpp
+++ b/drivers/alsa/audio_driver_alsa.cpp
@@ -168,9 +168,8 @@ Error AudioDriverALSA::init() {
return ERR_CANT_OPEN;
}
- active = false;
- thread_exited = false;
- exit_thread = false;
+ active.clear();
+ exit_thread.clear();
Error err = init_device();
if (err == OK) {
@@ -183,11 +182,11 @@ Error AudioDriverALSA::init() {
void AudioDriverALSA::thread_func(void *p_udata) {
AudioDriverALSA *ad = static_cast<AudioDriverALSA *>(p_udata);
- while (!ad->exit_thread) {
+ while (!ad->exit_thread.is_set()) {
ad->lock();
ad->start_counting_ticks();
- if (!ad->active) {
+ if (!ad->active.is_set()) {
for (uint64_t i = 0; i < ad->period_size * ad->channels; i++) {
ad->samples_out.write[i] = 0;
}
@@ -203,7 +202,7 @@ void AudioDriverALSA::thread_func(void *p_udata) {
int todo = ad->period_size;
int total = 0;
- while (todo && !ad->exit_thread) {
+ while (todo && !ad->exit_thread.is_set()) {
int16_t *src = (int16_t *)ad->samples_out.ptr();
int wrote = snd_pcm_writei(ad->pcm_handle, (void *)(src + (total * ad->channels)), todo);
@@ -222,8 +221,8 @@ void AudioDriverALSA::thread_func(void *p_udata) {
wrote = snd_pcm_recover(ad->pcm_handle, wrote, 0);
if (wrote < 0) {
ERR_PRINT("ALSA: Failed and can't recover: " + String(snd_strerror(wrote)));
- ad->active = false;
- ad->exit_thread = true;
+ ad->active.clear();
+ ad->exit_thread.set();
}
}
}
@@ -241,8 +240,8 @@ void AudioDriverALSA::thread_func(void *p_udata) {
err = ad->init_device();
if (err != OK) {
- ad->active = false;
- ad->exit_thread = true;
+ ad->active.clear();
+ ad->exit_thread.set();
}
}
}
@@ -250,12 +249,10 @@ void AudioDriverALSA::thread_func(void *p_udata) {
ad->stop_counting_ticks();
ad->unlock();
}
-
- ad->thread_exited = true;
}
void AudioDriverALSA::start() {
- active = true;
+ active.set();
}
int AudioDriverALSA::get_mix_rate() const {
@@ -327,7 +324,7 @@ void AudioDriverALSA::finish_device() {
}
void AudioDriverALSA::finish() {
- exit_thread = true;
+ exit_thread.set();
thread.wait_to_finish();
finish_device();
diff --git a/drivers/alsa/audio_driver_alsa.h b/drivers/alsa/audio_driver_alsa.h
index 3f9d9b33fb..fa1dba38ed 100644
--- a/drivers/alsa/audio_driver_alsa.h
+++ b/drivers/alsa/audio_driver_alsa.h
@@ -35,6 +35,7 @@
#include "core/os/mutex.h"
#include "core/os/thread.h"
+#include "core/templates/safe_refcount.h"
#include "servers/audio_server.h"
#include "asound-so_wrap.h"
@@ -64,9 +65,8 @@ class AudioDriverALSA : public AudioDriver {
snd_pcm_uframes_t period_size;
int channels = 0;
- bool active = false;
- bool thread_exited = false;
- mutable bool exit_thread = false;
+ SafeFlag active;
+ SafeFlag exit_thread;
public:
const char *get_name() const {
diff --git a/drivers/alsamidi/midi_driver_alsamidi.cpp b/drivers/alsamidi/midi_driver_alsamidi.cpp
index c334146dd2..d2a0076023 100644
--- a/drivers/alsamidi/midi_driver_alsamidi.cpp
+++ b/drivers/alsamidi/midi_driver_alsamidi.cpp
@@ -79,7 +79,7 @@ void MIDIDriverALSAMidi::thread_func(void *p_udata) {
int expected_size = 255;
int bytes = 0;
- while (!md->exit_thread) {
+ while (!md->exit_thread.is_set()) {
int ret;
md->lock();
@@ -149,14 +149,14 @@ Error MIDIDriverALSAMidi::open() {
}
snd_device_name_free_hint(hints);
- exit_thread = false;
+ exit_thread.clear();
thread.start(MIDIDriverALSAMidi::thread_func, this);
return OK;
}
void MIDIDriverALSAMidi::close() {
- exit_thread = true;
+ exit_thread.set();
thread.wait_to_finish();
for (int i = 0; i < connected_inputs.size(); i++) {
@@ -193,7 +193,7 @@ PackedStringArray MIDIDriverALSAMidi::get_connected_inputs() {
}
MIDIDriverALSAMidi::MIDIDriverALSAMidi() {
- exit_thread = false;
+ exit_thread.clear();
}
MIDIDriverALSAMidi::~MIDIDriverALSAMidi() {
diff --git a/drivers/alsamidi/midi_driver_alsamidi.h b/drivers/alsamidi/midi_driver_alsamidi.h
index b0fa8c297a..ac3530b1b2 100644
--- a/drivers/alsamidi/midi_driver_alsamidi.h
+++ b/drivers/alsamidi/midi_driver_alsamidi.h
@@ -36,6 +36,7 @@
#include "core/os/midi_driver.h"
#include "core/os/mutex.h"
#include "core/os/thread.h"
+#include "core/templates/safe_refcount.h"
#include "core/templates/vector.h"
#include "../alsa/asound-so_wrap.h"
@@ -47,7 +48,7 @@ class MIDIDriverALSAMidi : public MIDIDriver {
Vector<snd_rawmidi_t *> connected_inputs;
- bool exit_thread;
+ SafeFlag exit_thread;
static void thread_func(void *p_udata);
diff --git a/drivers/coreaudio/audio_driver_coreaudio.cpp b/drivers/coreaudio/audio_driver_coreaudio.cpp
index 51fb1f99e0..1db85e2a60 100644
--- a/drivers/coreaudio/audio_driver_coreaudio.cpp
+++ b/drivers/coreaudio/audio_driver_coreaudio.cpp
@@ -215,6 +215,7 @@ OSStatus AudioDriverCoreAudio::input_callback(void *inRefCon,
}
ad->lock();
+ ad->start_counting_ticks();
AudioBufferList bufferList;
bufferList.mNumberBuffers = 1;
@@ -237,6 +238,7 @@ OSStatus AudioDriverCoreAudio::input_callback(void *inRefCon,
ERR_PRINT("AudioUnitRender failed, code: " + itos(result));
}
+ ad->stop_counting_ticks();
ad->unlock();
return result;
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index 28802f571c..b397d0c665 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -322,6 +322,7 @@ void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_cou
RID prev_material;
uint32_t index = 0;
GLES3::CanvasShaderData::BlendMode last_blend_mode = GLES3::CanvasShaderData::BLEND_MODE_MIX;
+ Color last_blend_color;
GLES3::CanvasShaderData *shader_data_cache = nullptr;
state.current_tex = texture_storage->texture_gl_get_default(GLES3::DEFAULT_GL_TEXTURE_WHITE);
@@ -378,8 +379,80 @@ void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_cou
GLES3::CanvasShaderData::BlendMode blend_mode = shader_data_cache ? shader_data_cache->blend_mode : GLES3::CanvasShaderData::BLEND_MODE_MIX;
- if (last_blend_mode != blend_mode) {
- if (last_blend_mode == GLES3::CanvasShaderData::BLEND_MODE_DISABLED) {
+ _render_item(p_to_render_target, ci, canvas_transform_inverse, current_clip, p_lights, index, blend_mode, last_blend_mode, last_blend_color);
+ }
+ // Render last command
+ _render_batch(index);
+}
+
+void RasterizerCanvasGLES3::_render_item(RID p_render_target, const Item *p_item, const Transform2D &p_canvas_transform_inverse, Item *&current_clip, Light *p_lights, uint32_t &r_index, GLES3::CanvasShaderData::BlendMode p_blend_mode, GLES3::CanvasShaderData::BlendMode &r_last_blend_mode, Color &r_last_blend_color) {
+ // Used by Polygon and Mesh.
+ static const GLenum prim[5] = { GL_POINTS, GL_LINES, GL_LINE_STRIP, GL_TRIANGLES, GL_TRIANGLE_STRIP };
+
+ RS::CanvasItemTextureFilter current_filter = state.default_filter;
+ RS::CanvasItemTextureRepeat current_repeat = state.default_repeat;
+
+ if (p_item->texture_filter != RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT) {
+ current_filter = p_item->texture_filter;
+ }
+
+ if (p_item->texture_repeat != RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) {
+ current_repeat = p_item->texture_repeat;
+ }
+
+ Transform2D base_transform = p_canvas_transform_inverse * p_item->final_transform;
+ Transform2D draw_transform; // Used by transform command
+
+ Color base_color = p_item->final_modulate;
+
+ uint32_t base_flags = 0;
+
+ bool reclip = false;
+
+ bool skipping = false;
+
+ const Item::Command *c = p_item->commands;
+ while (c) {
+ if (skipping && c->type != Item::Command::TYPE_ANIMATION_SLICE) {
+ c = c->next;
+ continue;
+ }
+
+ if (c->type != Item::Command::TYPE_MESH) {
+ // For Meshes, this gets updated below.
+ _update_transform_2d_to_mat2x3(base_transform * draw_transform, state.instance_data_array[r_index].world);
+ }
+
+ for (int i = 0; i < 4; i++) {
+ state.instance_data_array[r_index].modulation[i] = 0.0;
+ state.instance_data_array[r_index].ninepatch_margins[i] = 0.0;
+ state.instance_data_array[r_index].src_rect[i] = 0.0;
+ state.instance_data_array[r_index].dst_rect[i] = 0.0;
+ state.instance_data_array[r_index].lights[i] = uint32_t(0);
+ }
+ 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].pad[0] = 0.0;
+ state.instance_data_array[r_index].pad[1] = 0.0;
+
+ 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
+
+ GLES3::CanvasShaderData::BlendMode blend_mode = p_blend_mode;
+ Color blend_color;
+
+ if (c->type == Item::Command::TYPE_RECT) {
+ const Item::CommandRect *rect = static_cast<const Item::CommandRect *>(c);
+ if (rect->flags & CANVAS_RECT_LCD) {
+ blend_mode = GLES3::CanvasShaderData::BLEND_MODE_LCD;
+ blend_color = rect->modulate;
+ }
+ }
+
+ if (r_last_blend_mode != blend_mode || r_last_blend_color != blend_color) {
+ _render_batch(r_index);
+
+ if (r_last_blend_mode == GLES3::CanvasShaderData::BLEND_MODE_DISABLED) {
// re-enable it
glEnable(GL_BLEND);
} else if (blend_mode == GLES3::CanvasShaderData::BLEND_MODE_DISABLED) {
@@ -392,6 +465,16 @@ void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_cou
// Nothing to do here.
} break;
+ case GLES3::CanvasShaderData::BLEND_MODE_LCD: {
+ glBlendEquation(GL_FUNC_ADD);
+ if (state.transparent_render_target) {
+ glBlendFuncSeparate(GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ } else {
+ glBlendFuncSeparate(GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_ZERO, GL_ONE);
+ }
+ glBlendColor(blend_color.r, blend_color.g, blend_color.b, blend_color.a);
+
+ } break;
case GLES3::CanvasShaderData::BLEND_MODE_MIX: {
glBlendEquation(GL_FUNC_ADD);
if (state.transparent_render_target) {
@@ -437,68 +520,10 @@ void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_cou
} break;
}
- last_blend_mode = blend_mode;
- }
-
- _render_item(p_to_render_target, ci, canvas_transform_inverse, current_clip, p_lights, index);
- }
- // Render last command
- _render_batch(index);
-}
-
-void RasterizerCanvasGLES3::_render_item(RID p_render_target, const Item *p_item, const Transform2D &p_canvas_transform_inverse, Item *&current_clip, Light *p_lights, uint32_t &r_index) {
- // Used by Polygon and Mesh.
- static const GLenum prim[5] = { GL_POINTS, GL_LINES, GL_LINE_STRIP, GL_TRIANGLES, GL_TRIANGLE_STRIP };
-
- RS::CanvasItemTextureFilter current_filter = state.default_filter;
- RS::CanvasItemTextureRepeat current_repeat = state.default_repeat;
-
- if (p_item->texture_filter != RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT) {
- current_filter = p_item->texture_filter;
- }
-
- if (p_item->texture_repeat != RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT) {
- current_repeat = p_item->texture_repeat;
- }
-
- Transform2D base_transform = p_canvas_transform_inverse * p_item->final_transform;
- Transform2D draw_transform; // Used by transform command
-
- Color base_color = p_item->final_modulate;
-
- uint32_t base_flags = 0;
-
- bool reclip = false;
-
- bool skipping = false;
-
- const Item::Command *c = p_item->commands;
- while (c) {
- if (skipping && c->type != Item::Command::TYPE_ANIMATION_SLICE) {
- c = c->next;
- continue;
- }
-
- if (c->type != Item::Command::TYPE_MESH) {
- // For Meshes, this gets updated below.
- _update_transform_2d_to_mat2x3(base_transform * draw_transform, state.instance_data_array[r_index].world);
+ r_last_blend_mode = blend_mode;
+ r_last_blend_color = blend_color;
}
- for (int i = 0; i < 4; i++) {
- state.instance_data_array[r_index].modulation[i] = 0.0;
- state.instance_data_array[r_index].ninepatch_margins[i] = 0.0;
- state.instance_data_array[r_index].src_rect[i] = 0.0;
- state.instance_data_array[r_index].dst_rect[i] = 0.0;
- state.instance_data_array[r_index].lights[i] = uint32_t(0);
- }
- 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].pad[0] = 0.0;
- state.instance_data_array[r_index].pad[1] = 0.0;
-
- 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
-
switch (c->type) {
case Item::Command::TYPE_RECT: {
const Item::CommandRect *rect = static_cast<const Item::CommandRect *>(c);
@@ -569,6 +594,8 @@ void RasterizerCanvasGLES3::_render_item(RID p_render_target, const Item *p_item
state.instance_data_array[r_index].msdf[1] = rect->outline; // Outline size.
state.instance_data_array[r_index].msdf[2] = 0.f; // Reserved.
state.instance_data_array[r_index].msdf[3] = 0.f; // Reserved.
+ } else if (rect->flags & CANVAS_RECT_LCD) {
+ state.instance_data_array[r_index].flags |= FLAGS_USE_LCD;
}
state.instance_data_array[r_index].modulation[0] = rect->modulate.r * base_color.r;
diff --git a/drivers/gles3/rasterizer_canvas_gles3.h b/drivers/gles3/rasterizer_canvas_gles3.h
index f920e37130..372ac00493 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.h
+++ b/drivers/gles3/rasterizer_canvas_gles3.h
@@ -73,6 +73,7 @@ class RasterizerCanvasGLES3 : public RendererCanvasRender {
FLAGS_DEFAULT_SPECULAR_MAP_USED = (1 << 27),
FLAGS_USE_MSDF = (1 << 28),
+ FLAGS_USE_LCD = (1 << 29),
};
enum {
@@ -249,7 +250,7 @@ public:
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, bool p_to_backbuffer = false);
- void _render_item(RID p_render_target, const Item *p_item, const Transform2D &p_canvas_transform_inverse, Item *&current_clip, Light *p_lights, uint32_t &r_index);
+ void _render_item(RID p_render_target, const Item *p_item, const Transform2D &p_canvas_transform_inverse, Item *&current_clip, Light *p_lights, uint32_t &r_index, GLES3::CanvasShaderData::BlendMode p_blend_mode, GLES3::CanvasShaderData::BlendMode &r_last_blend_mode, Color &r_last_blend_color);
void _render_batch(uint32_t &p_max_index);
void _bind_instance_data_buffer(uint32_t p_max_index);
void _allocate_instance_data_buffer();
diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl
index 4df818cd4c..5ec25327be 100644
--- a/drivers/gles3/shaders/canvas.glsl
+++ b/drivers/gles3/shaders/canvas.glsl
@@ -473,7 +473,13 @@ void main() {
float a = clamp(d * px_size + 0.5, 0.0, 1.0);
color.a = a * color.a;
}
-
+ } else if (bool(draw_data[draw_data_instance].flags & FLAGS_USE_LCD)) {
+ vec4 lcd_sample = texture(color_texture, uv);
+ if (lcd_sample.a == 1.0) {
+ color.rgb = lcd_sample.rgb * color.a;
+ } else {
+ color = vec4(0.0, 0.0, 0.0, 0.0);
+ }
} else {
#else
{
diff --git a/drivers/gles3/shaders/canvas_uniforms_inc.glsl b/drivers/gles3/shaders/canvas_uniforms_inc.glsl
index 852dccf415..6b61fe9375 100644
--- a/drivers/gles3/shaders/canvas_uniforms_inc.glsl
+++ b/drivers/gles3/shaders/canvas_uniforms_inc.glsl
@@ -25,6 +25,7 @@
#define FLAGS_DEFAULT_SPECULAR_MAP_USED uint(1 << 27)
#define FLAGS_USE_MSDF uint(1 << 28)
+#define FLAGS_USE_LCD uint(1 << 29)
// must be always 128 bytes long
struct DrawData {
diff --git a/drivers/gles3/storage/material_storage.h b/drivers/gles3/storage/material_storage.h
index d135357f6a..a2a7554821 100644
--- a/drivers/gles3/storage/material_storage.h
+++ b/drivers/gles3/storage/material_storage.h
@@ -142,6 +142,7 @@ struct CanvasShaderData : public ShaderData {
BLEND_MODE_MUL,
BLEND_MODE_PMALPHA,
BLEND_MODE_DISABLED,
+ BLEND_MODE_LCD,
};
bool valid;
diff --git a/drivers/png/SCsub b/drivers/png/SCsub
index 39d296e7cf..ad7aaf1ee8 100644
--- a/drivers/png/SCsub
+++ b/drivers/png/SCsub
@@ -37,7 +37,7 @@ if env["builtin_libpng"]:
import os
# Enable ARM NEON instructions on 32-bit Android to compile more optimized code.
- use_neon = "android_arch" in env and env["android_arch"] == "armv7" and os.name != "nt"
+ use_neon = env["platform"] == "android" and env["arch"] == "arm32" and os.name != "nt"
if use_neon:
env_png.Append(CPPDEFINES=[("PNG_ARM_NEON_OPT", 2)])
else:
diff --git a/drivers/png/image_loader_png.cpp b/drivers/png/image_loader_png.cpp
index 917bfec574..8d2f8a7ed6 100644
--- a/drivers/png/image_loader_png.cpp
+++ b/drivers/png/image_loader_png.cpp
@@ -36,7 +36,7 @@
#include <string.h>
-Error ImageLoaderPNG::load_image(Ref<Image> p_image, Ref<FileAccess> f, bool p_force_linear, float p_scale) {
+Error ImageLoaderPNG::load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t p_flags, float p_scale) {
const uint64_t buffer_size = f->get_length();
Vector<uint8_t> file_buffer;
Error err = file_buffer.resize(buffer_size);
@@ -48,7 +48,7 @@ Error ImageLoaderPNG::load_image(Ref<Image> p_image, Ref<FileAccess> f, bool p_f
f->get_buffer(writer, buffer_size);
}
const uint8_t *reader = file_buffer.ptr();
- return PNGDriverCommon::png_to_image(reader, buffer_size, p_force_linear, p_image);
+ return PNGDriverCommon::png_to_image(reader, buffer_size, p_flags & FLAG_FORCE_LINEAR, p_image);
}
void ImageLoaderPNG::get_recognized_extensions(List<String> *p_extensions) const {
diff --git a/drivers/png/image_loader_png.h b/drivers/png/image_loader_png.h
index 9bcfb720d3..91c3c8925f 100644
--- a/drivers/png/image_loader_png.h
+++ b/drivers/png/image_loader_png.h
@@ -40,7 +40,7 @@ private:
static Ref<Image> load_mem_png(const uint8_t *p_png, int p_size);
public:
- virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> f, bool p_force_linear, float p_scale);
+ virtual Error load_image(Ref<Image> p_image, Ref<FileAccess> f, uint32_t p_flags, float p_scale);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
ImageLoaderPNG();
};
diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.cpp b/drivers/pulseaudio/audio_driver_pulseaudio.cpp
index b18d383119..b25cf1d5b4 100644
--- a/drivers/pulseaudio/audio_driver_pulseaudio.cpp
+++ b/drivers/pulseaudio/audio_driver_pulseaudio.cpp
@@ -285,9 +285,8 @@ Error AudioDriverPulseAudio::init() {
return ERR_CANT_OPEN;
}
- active = false;
- thread_exited = false;
- exit_thread = false;
+ active.clear();
+ exit_thread.clear();
mix_rate = GLOBAL_GET("audio/driver/mix_rate");
@@ -384,7 +383,7 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
size_t avail_bytes = 0;
uint64_t default_device_msec = OS::get_singleton()->get_ticks_msec();
- while (!ad->exit_thread) {
+ while (!ad->exit_thread.is_set()) {
size_t read_bytes = 0;
size_t written_bytes = 0;
@@ -392,7 +391,7 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
ad->lock();
ad->start_counting_ticks();
- if (!ad->active) {
+ if (!ad->active.is_set()) {
ad->samples_out.fill(0);
} else {
ad->audio_server_process(ad->buffer_frames, ad->samples_in.ptrw());
@@ -462,8 +461,8 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
err = ad->init_device();
if (err != OK) {
- ad->active = false;
- ad->exit_thread = true;
+ ad->active.clear();
+ ad->exit_thread.set();
break;
}
}
@@ -501,8 +500,8 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
Error err = ad->init_device();
if (err != OK) {
ERR_PRINT("PulseAudio: init_device error");
- ad->active = false;
- ad->exit_thread = true;
+ ad->active.clear();
+ ad->exit_thread.set();
break;
}
@@ -555,8 +554,8 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
err = ad->capture_init_device();
if (err != OK) {
- ad->active = false;
- ad->exit_thread = true;
+ ad->active.clear();
+ ad->exit_thread.set();
break;
}
}
@@ -571,12 +570,10 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
OS::get_singleton()->delay_usec(1000);
}
}
-
- ad->thread_exited = true;
}
void AudioDriverPulseAudio::start() {
- active = true;
+ active.set();
}
int AudioDriverPulseAudio::get_mix_rate() const {
@@ -661,7 +658,7 @@ void AudioDriverPulseAudio::finish() {
return;
}
- exit_thread = true;
+ exit_thread.set();
thread.wait_to_finish();
finish_device();
diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.h b/drivers/pulseaudio/audio_driver_pulseaudio.h
index 27c684578e..85e328b49f 100644
--- a/drivers/pulseaudio/audio_driver_pulseaudio.h
+++ b/drivers/pulseaudio/audio_driver_pulseaudio.h
@@ -35,6 +35,7 @@
#include "core/os/mutex.h"
#include "core/os/thread.h"
+#include "core/templates/safe_refcount.h"
#include "servers/audio_server.h"
#include "pulse-so_wrap.h"
@@ -70,9 +71,8 @@ class AudioDriverPulseAudio : public AudioDriver {
PackedStringArray pa_devices;
PackedStringArray pa_rec_devices;
- bool active = false;
- bool thread_exited = false;
- mutable bool exit_thread = false;
+ SafeFlag active;
+ SafeFlag exit_thread;
float latency = 0;
diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp
index 2debba1b83..f2d78636d7 100644
--- a/drivers/vulkan/rendering_device_vulkan.cpp
+++ b/drivers/vulkan/rendering_device_vulkan.cpp
@@ -7543,6 +7543,16 @@ RenderingDeviceVulkan::DrawList *RenderingDeviceVulkan::_get_draw_list_ptr(DrawL
}
}
+void RenderingDeviceVulkan::draw_list_set_blend_constants(DrawListID p_list, const Color &p_color) {
+ DrawList *dl = _get_draw_list_ptr(p_list);
+ ERR_FAIL_COND(!dl);
+#ifdef DEBUG_ENABLED
+ ERR_FAIL_COND_MSG(!dl->validation.active, "Submitted Draw Lists can no longer be modified.");
+#endif
+
+ vkCmdSetBlendConstants(dl->command_buffer, p_color.components);
+}
+
void RenderingDeviceVulkan::draw_list_bind_render_pipeline(DrawListID p_list, RID p_render_pipeline) {
DrawList *dl = _get_draw_list_ptr(p_list);
ERR_FAIL_COND(!dl);
diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h
index 6572de7c52..6007e1ab4d 100644
--- a/drivers/vulkan/rendering_device_vulkan.h
+++ b/drivers/vulkan/rendering_device_vulkan.h
@@ -1155,6 +1155,7 @@ public:
virtual DrawListID draw_list_begin(RID p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2(), const Vector<RID> &p_storage_textures = Vector<RID>());
virtual Error draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, DrawListID *r_split_ids, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2(), const Vector<RID> &p_storage_textures = Vector<RID>());
+ virtual void draw_list_set_blend_constants(DrawListID p_list, const Color &p_color);
virtual void draw_list_bind_render_pipeline(DrawListID p_list, RID p_render_pipeline);
virtual void draw_list_bind_uniform_set(DrawListID p_list, RID p_uniform_set, uint32_t p_index);
virtual void draw_list_bind_vertex_array(DrawListID p_list, RID p_vertex_array);
diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp
index 8f5e35b251..fb90b776cf 100644
--- a/drivers/wasapi/audio_driver_wasapi.cpp
+++ b/drivers/wasapi/audio_driver_wasapi.cpp
@@ -501,11 +501,11 @@ Error AudioDriverWASAPI::init_capture_device(bool reinit) {
}
Error AudioDriverWASAPI::audio_device_finish(AudioDeviceWASAPI *p_device) {
- if (p_device->active) {
+ if (p_device->active.is_set()) {
if (p_device->audio_client) {
p_device->audio_client->Stop();
}
- p_device->active = false;
+ p_device->active.clear();
}
SAFE_RELEASE(p_device->audio_client)
@@ -533,8 +533,7 @@ Error AudioDriverWASAPI::init() {
ERR_PRINT("WASAPI: init_render_device error");
}
- exit_thread = false;
- thread_exited = false;
+ exit_thread.clear();
thread.start(thread_func, this);
@@ -684,7 +683,7 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
uint32_t avail_frames = 0;
uint32_t write_ofs = 0;
- while (!ad->exit_thread) {
+ while (!ad->exit_thread.is_set()) {
uint32_t read_frames = 0;
uint32_t written_frames = 0;
@@ -692,7 +691,7 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
ad->lock();
ad->start_counting_ticks();
- if (ad->audio_output.active) {
+ if (ad->audio_output.active.is_set()) {
ad->audio_server_process(ad->buffer_frames, ad->samples_in.ptrw());
} else {
for (int i = 0; i < ad->samples_in.size(); i++) {
@@ -758,7 +757,7 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
}
} else {
ERR_PRINT("WASAPI: Get buffer error");
- ad->exit_thread = true;
+ ad->exit_thread.set();
}
}
} else if (hr == AUDCLNT_E_DEVICE_INVALIDATED) {
@@ -807,7 +806,7 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
write_ofs = 0;
}
- if (ad->audio_input.active) {
+ if (ad->audio_input.active.is_set()) {
UINT32 packet_length = 0;
BYTE *data;
UINT32 num_frames_available;
@@ -886,8 +885,6 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
OS::get_singleton()->delay_usec(1000);
}
}
-
- ad->thread_exited = true;
}
void AudioDriverWASAPI::start() {
@@ -896,7 +893,7 @@ void AudioDriverWASAPI::start() {
if (hr != S_OK) {
ERR_PRINT("WASAPI: Start failed");
} else {
- audio_output.active = true;
+ audio_output.active.set();
}
}
}
@@ -910,7 +907,7 @@ void AudioDriverWASAPI::unlock() {
}
void AudioDriverWASAPI::finish() {
- exit_thread = true;
+ exit_thread.set();
thread.wait_to_finish();
finish_capture_device();
@@ -924,19 +921,19 @@ Error AudioDriverWASAPI::capture_start() {
return err;
}
- if (audio_input.active) {
+ if (audio_input.active.is_set()) {
return FAILED;
}
audio_input.audio_client->Start();
- audio_input.active = true;
+ audio_input.active.set();
return OK;
}
Error AudioDriverWASAPI::capture_stop() {
- if (audio_input.active) {
+ if (audio_input.active.is_set()) {
audio_input.audio_client->Stop();
- audio_input.active = false;
+ audio_input.active.clear();
return OK;
}
diff --git a/drivers/wasapi/audio_driver_wasapi.h b/drivers/wasapi/audio_driver_wasapi.h
index d71e2e914b..c30a54c042 100644
--- a/drivers/wasapi/audio_driver_wasapi.h
+++ b/drivers/wasapi/audio_driver_wasapi.h
@@ -35,6 +35,7 @@
#include "core/os/mutex.h"
#include "core/os/thread.h"
+#include "core/templates/safe_refcount.h"
#include "servers/audio_server.h"
#include <audioclient.h>
@@ -48,7 +49,7 @@ class AudioDriverWASAPI : public AudioDriver {
IAudioClient *audio_client = nullptr;
IAudioRenderClient *render_client = nullptr;
IAudioCaptureClient *capture_client = nullptr;
- bool active = false;
+ SafeFlag active;
WORD format_tag = 0;
WORD bits_per_sample = 0;
@@ -76,8 +77,7 @@ class AudioDriverWASAPI : public AudioDriver {
float real_latency = 0.0;
bool using_audio_client_3 = false;
- bool thread_exited = false;
- mutable bool exit_thread = false;
+ SafeFlag exit_thread;
static _FORCE_INLINE_ void write_sample(WORD format_tag, int bits_per_sample, BYTE *buffer, int i, int32_t sample);
static _FORCE_INLINE_ int32_t read_sample(WORD format_tag, int bits_per_sample, BYTE *buffer, int i);
diff --git a/drivers/xaudio2/audio_driver_xaudio2.cpp b/drivers/xaudio2/audio_driver_xaudio2.cpp
index c32c7cf1e5..6c48c1a844 100644
--- a/drivers/xaudio2/audio_driver_xaudio2.cpp
+++ b/drivers/xaudio2/audio_driver_xaudio2.cpp
@@ -38,9 +38,8 @@ const char *AudioDriverXAudio2::get_name() const {
}
Error AudioDriverXAudio2::init() {
- active = false;
- thread_exited = false;
- exit_thread = false;
+ active.clear();
+ exit_thread.clear();
pcm_open = false;
samples_in = nullptr;
@@ -86,17 +85,19 @@ Error AudioDriverXAudio2::init() {
void AudioDriverXAudio2::thread_func(void *p_udata) {
AudioDriverXAudio2 *ad = static_cast<AudioDriverXAudio2 *>(p_udata);
- while (!ad->exit_thread) {
- if (!ad->active) {
+ while (!ad->exit_thread.is_set()) {
+ if (!ad->active.is_set()) {
for (int i = 0; i < AUDIO_BUFFERS; i++) {
ad->xaudio_buffer[i].Flags = XAUDIO2_END_OF_STREAM;
}
} else {
ad->lock();
+ ad->start_counting_ticks();
ad->audio_server_process(ad->buffer_size, ad->samples_in);
+ ad->stop_counting_ticks();
ad->unlock();
for (unsigned int i = 0; i < ad->buffer_size * ad->channels; i++) {
@@ -117,12 +118,10 @@ void AudioDriverXAudio2::thread_func(void *p_udata) {
}
}
}
-
- ad->thread_exited = true;
}
void AudioDriverXAudio2::start() {
- active = true;
+ active.set();
HRESULT hr = source_voice->Start(0);
ERR_FAIL_COND_MSG(hr != S_OK, "Error starting XAudio2 driver. Error code: " + itos(hr) + ".");
}
@@ -154,7 +153,7 @@ void AudioDriverXAudio2::unlock() {
}
void AudioDriverXAudio2::finish() {
- exit_thread = true;
+ exit_thread.set();
thread.wait_to_finish();
if (source_voice) {
diff --git a/drivers/xaudio2/audio_driver_xaudio2.h b/drivers/xaudio2/audio_driver_xaudio2.h
index 81432ceb8e..0f64d54a1f 100644
--- a/drivers/xaudio2/audio_driver_xaudio2.h
+++ b/drivers/xaudio2/audio_driver_xaudio2.h
@@ -33,6 +33,7 @@
#include "core/os/mutex.h"
#include "core/os/thread.h"
+#include "core/templates/safe_refcount.h"
#include "servers/audio_server.h"
#include <mmsystem.h>
@@ -77,9 +78,8 @@ class AudioDriverXAudio2 : public AudioDriver {
int channels = 0;
- bool active = false;
- bool thread_exited = false;
- mutable bool exit_thread = false;
+ SafeFlag active;
+ SafeFlag exit_thread;
bool pcm_open = false;
WAVEFORMATEX wave_format = { 0 };