summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYuri Sizov <yuris@humnom.net>2023-07-31 21:01:21 +0200
committerYuri Sizov <yuris@humnom.net>2023-07-31 21:01:21 +0200
commit79d3468246939795e82677e9f185b20875a3eaff (patch)
treed46bb011081daa83815a52b54e235fc41c8d6d83
parent25f3f660c5bf9ba0098e4329cd18204918b6a692 (diff)
parentc7fb6cea3d745c6d06d26b99e083f3fdf3cd7e8b (diff)
downloadredot-engine-79d3468246939795e82677e9f185b20875a3eaff.tar.gz
Merge pull request #79696 from reduz/call-on-render-thread
Add ability to call code on rendering thread
-rw-r--r--doc/classes/RenderingServer.xml7
-rw-r--r--servers/rendering/rendering_server_default.cpp6
-rw-r--r--servers/rendering/rendering_server_default.h11
-rw-r--r--servers/rendering_server.cpp2
-rw-r--r--servers/rendering_server.h2
5 files changed, 28 insertions, 0 deletions
diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml
index 64d54b3ba0..02c1286392 100644
--- a/doc/classes/RenderingServer.xml
+++ b/doc/classes/RenderingServer.xml
@@ -27,6 +27,13 @@
Bakes the material data of the Mesh passed in the [param base] parameter with optional [param material_overrides] to a set of [Image]s of size [param image_size]. Returns an array of [Image]s containing material properties as specified in [enum BakeChannels].
</description>
</method>
+ <method name="call_on_render_thread">
+ <return type="void" />
+ <param index="0" name="callable" type="Callable" />
+ <description>
+ As the RenderingServer actual logic may run on an separate thread, accessing its internals from the main (or any other) thread will result in errors. To make it easier to run code that can safely access the rendering internals (such as [RenderingDevice] and similar RD classes), push a callable via this function so it will be executed on the render thread.
+ </description>
+ </method>
<method name="camera_attributes_create">
<return type="RID" />
<description>
diff --git a/servers/rendering/rendering_server_default.cpp b/servers/rendering/rendering_server_default.cpp
index ff6bf3a6ba..c4464cb180 100644
--- a/servers/rendering/rendering_server_default.cpp
+++ b/servers/rendering/rendering_server_default.cpp
@@ -386,6 +386,12 @@ void RenderingServerDefault::draw(bool p_swap_buffers, double frame_step) {
}
}
+void RenderingServerDefault::_call_on_render_thread(const Callable &p_callable) {
+ Variant ret;
+ Callable::CallError ce;
+ p_callable.callp(nullptr, 0, ret, ce);
+}
+
RenderingServerDefault::RenderingServerDefault(bool p_create_thread) :
command_queue(p_create_thread) {
RenderingServer::init();
diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h
index c79d3a64cf..e9b40eb082 100644
--- a/servers/rendering/rendering_server_default.h
+++ b/servers/rendering/rendering_server_default.h
@@ -97,6 +97,8 @@ class RenderingServerDefault : public RenderingServer {
void _free(RID p_rid);
+ void _call_on_render_thread(const Callable &p_callable);
+
public:
//if editor is redrawing when it shouldn't, enable this and put a breakpoint in _changes_changed()
//#define DEBUG_CHANGES
@@ -991,6 +993,15 @@ public:
virtual void init() override;
virtual void finish() override;
+ virtual void call_on_render_thread(const Callable &p_callable) override {
+ if (Thread::get_caller_id() == server_thread) {
+ command_queue.flush_if_pending();
+ _call_on_render_thread(p_callable);
+ } else {
+ command_queue.push(this, &RenderingServerDefault::_call_on_render_thread, p_callable);
+ }
+ }
+
/* TESTING */
virtual double get_frame_setup_time_cpu() const override;
diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp
index 4a95dc1963..48b38cf2b7 100644
--- a/servers/rendering_server.cpp
+++ b/servers/rendering_server.cpp
@@ -2811,6 +2811,8 @@ void RenderingServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("force_draw", "swap_buffers", "frame_step"), &RenderingServer::draw, DEFVAL(true), DEFVAL(0.0));
ClassDB::bind_method(D_METHOD("get_rendering_device"), &RenderingServer::get_rendering_device);
ClassDB::bind_method(D_METHOD("create_local_rendering_device"), &RenderingServer::create_local_rendering_device);
+
+ ClassDB::bind_method(D_METHOD("call_on_render_thread", "callable"), &RenderingServer::call_on_render_thread);
}
void RenderingServer::mesh_add_surface_from_mesh_data(RID p_mesh, const Geometry3D::MeshData &p_mesh_data) {
diff --git a/servers/rendering_server.h b/servers/rendering_server.h
index 9ea55c31b4..618ceb3091 100644
--- a/servers/rendering_server.h
+++ b/servers/rendering_server.h
@@ -1602,6 +1602,8 @@ public:
bool is_render_loop_enabled() const;
void set_render_loop_enabled(bool p_enabled);
+ virtual void call_on_render_thread(const Callable &p_callable) = 0;
+
RenderingServer();
virtual ~RenderingServer();