mirror of
https://github.com/godotengine/godot.git
synced 2024-11-22 12:12:28 +00:00
Switched AnimatedTexture to a readers-writers lock, solves a race condition and fixes #20221
This commit is contained in:
parent
0edb50f629
commit
a1b594c2fc
@ -56,8 +56,10 @@ class RWLockRead {
|
||||
RWLock *lock;
|
||||
|
||||
public:
|
||||
RWLockRead(RWLock *p_lock) {
|
||||
lock = p_lock;
|
||||
RWLockRead(const RWLock *p_lock) {
|
||||
if (p_lock) {
|
||||
lock = const_cast<RWLock *>(p_lock);
|
||||
}
|
||||
if (lock) lock->read_lock();
|
||||
}
|
||||
~RWLockRead() {
|
||||
|
@ -124,8 +124,10 @@ void RemoteTransform::_notification(int p_what) {
|
||||
void RemoteTransform::set_remote_node(const NodePath &p_remote_node) {
|
||||
|
||||
remote_node = p_remote_node;
|
||||
if (is_inside_tree())
|
||||
if (is_inside_tree()) {
|
||||
_update_cache();
|
||||
_update_remote();
|
||||
}
|
||||
|
||||
update_configuration_warning();
|
||||
}
|
||||
|
@ -1666,7 +1666,7 @@ ProxyTexture::~ProxyTexture() {
|
||||
|
||||
void AnimatedTexture::_update_proxy() {
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
RWLockRead r(rw_lock);
|
||||
|
||||
float delta;
|
||||
if (prev_ticks == 0) {
|
||||
@ -1712,7 +1712,7 @@ void AnimatedTexture::_update_proxy() {
|
||||
void AnimatedTexture::set_frames(int p_frames) {
|
||||
ERR_FAIL_COND(p_frames < 1 || p_frames > MAX_FRAMES);
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
RWLockWrite r(rw_lock);
|
||||
|
||||
frame_count = p_frames;
|
||||
}
|
||||
@ -1723,14 +1723,14 @@ int AnimatedTexture::get_frames() const {
|
||||
void AnimatedTexture::set_frame_texture(int p_frame, const Ref<Texture> &p_texture) {
|
||||
ERR_FAIL_INDEX(p_frame, MAX_FRAMES);
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
RWLockWrite w(rw_lock);
|
||||
|
||||
frames[p_frame].texture = p_texture;
|
||||
}
|
||||
Ref<Texture> AnimatedTexture::get_frame_texture(int p_frame) const {
|
||||
ERR_FAIL_INDEX_V(p_frame, MAX_FRAMES, Ref<Texture>());
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
RWLockRead r(rw_lock);
|
||||
|
||||
return frames[p_frame].texture;
|
||||
}
|
||||
@ -1738,14 +1738,14 @@ Ref<Texture> AnimatedTexture::get_frame_texture(int p_frame) const {
|
||||
void AnimatedTexture::set_frame_delay(int p_frame, float p_delay_sec) {
|
||||
ERR_FAIL_INDEX(p_frame, MAX_FRAMES);
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
RWLockRead r(rw_lock);
|
||||
|
||||
frames[p_frame].delay_sec = p_delay_sec;
|
||||
}
|
||||
float AnimatedTexture::get_frame_delay(int p_frame) const {
|
||||
ERR_FAIL_INDEX_V(p_frame, MAX_FRAMES, 0);
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
RWLockRead r(rw_lock);
|
||||
|
||||
return frames[p_frame].delay_sec;
|
||||
}
|
||||
@ -1760,8 +1760,7 @@ float AnimatedTexture::get_fps() const {
|
||||
}
|
||||
|
||||
int AnimatedTexture::get_width() const {
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
RWLockRead r(rw_lock);
|
||||
|
||||
if (!frames[current_frame].texture.is_valid()) {
|
||||
return 1;
|
||||
@ -1770,8 +1769,7 @@ int AnimatedTexture::get_width() const {
|
||||
return frames[current_frame].texture->get_width();
|
||||
}
|
||||
int AnimatedTexture::get_height() const {
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
RWLockRead r(rw_lock);
|
||||
|
||||
if (!frames[current_frame].texture.is_valid()) {
|
||||
return 1;
|
||||
@ -1785,7 +1783,7 @@ RID AnimatedTexture::get_rid() const {
|
||||
|
||||
bool AnimatedTexture::has_alpha() const {
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
RWLockRead r(rw_lock);
|
||||
|
||||
if (!frames[current_frame].texture.is_valid()) {
|
||||
return false;
|
||||
@ -1796,7 +1794,7 @@ bool AnimatedTexture::has_alpha() const {
|
||||
|
||||
Ref<Image> AnimatedTexture::get_data() const {
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
RWLockRead r(rw_lock);
|
||||
|
||||
if (!frames[current_frame].texture.is_valid()) {
|
||||
return Ref<Image>();
|
||||
@ -1809,7 +1807,7 @@ void AnimatedTexture::set_flags(uint32_t p_flags) {
|
||||
}
|
||||
uint32_t AnimatedTexture::get_flags() const {
|
||||
|
||||
_THREAD_SAFE_METHOD_
|
||||
RWLockRead r(rw_lock);
|
||||
|
||||
if (!frames[current_frame].texture.is_valid()) {
|
||||
return 0;
|
||||
@ -1862,10 +1860,19 @@ AnimatedTexture::AnimatedTexture() {
|
||||
prev_ticks = 0;
|
||||
current_frame = 0;
|
||||
VisualServer::get_singleton()->connect("frame_pre_draw", this, "_update_proxy");
|
||||
|
||||
#ifndef NO_THREADS
|
||||
rw_lock = RWLock::create();
|
||||
#else
|
||||
rw_lock = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
AnimatedTexture::~AnimatedTexture() {
|
||||
VS::get_singleton()->free(proxy);
|
||||
if (rw_lock) {
|
||||
memdelete(rw_lock);
|
||||
}
|
||||
}
|
||||
///////////////////////////////
|
||||
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "curve.h"
|
||||
#include "io/resource_loader.h"
|
||||
#include "os/mutex.h"
|
||||
#include "os/rw_lock.h"
|
||||
#include "os/thread_safe.h"
|
||||
#include "rect2.h"
|
||||
#include "resource.h"
|
||||
@ -609,7 +610,8 @@ public:
|
||||
class AnimatedTexture : public Texture {
|
||||
GDCLASS(AnimatedTexture, Texture)
|
||||
|
||||
_THREAD_SAFE_CLASS_
|
||||
//use readers writers lock for this, since its far more times read than written to
|
||||
RWLock *rw_lock;
|
||||
|
||||
private:
|
||||
enum {
|
||||
|
Loading…
Reference in New Issue
Block a user