mirror of
https://github.com/Relintai/voxelman.git
synced 2025-01-12 15:01:09 +01:00
More improvements to chunk's threading logic. Also removed the build_phase_done function I added a few hours ago, and made build_phase return a bool (true if the phase is completed, false if not), essentially achieving the same effect.
This commit is contained in:
parent
8a2524dc57
commit
3a8310c51f
@ -38,6 +38,19 @@ _FORCE_INLINE_ void VoxelChunk::set_is_build_threaded(bool value) {
|
|||||||
_is_build_threaded = value;
|
_is_build_threaded = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VoxelChunk::get_build_phase_done() const {
|
||||||
|
_build_phase_done_mutex->lock();
|
||||||
|
bool v = _build_phase_done_mutex;
|
||||||
|
_build_phase_done_mutex->unlock();
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
void VoxelChunk::set_build_phase_done(bool value) {
|
||||||
|
_build_phase_done_mutex->lock();
|
||||||
|
_build_phase_done = value;
|
||||||
|
_build_phase_done_mutex->unlock();
|
||||||
|
}
|
||||||
|
|
||||||
_FORCE_INLINE_ bool VoxelChunk::get_dirty() const {
|
_FORCE_INLINE_ bool VoxelChunk::get_dirty() const {
|
||||||
return _dirty;
|
return _dirty;
|
||||||
}
|
}
|
||||||
@ -570,46 +583,33 @@ void VoxelChunk::build_prioritized() {
|
|||||||
void VoxelChunk::_build_step() {
|
void VoxelChunk::_build_step() {
|
||||||
ERR_FAIL_COND(!has_next_phase());
|
ERR_FAIL_COND(!has_next_phase());
|
||||||
|
|
||||||
if (_is_build_threaded) {
|
while (has_next_phase() && build_phase())
|
||||||
if (is_phase_threaded(get_current_build_phase())) {
|
;
|
||||||
ERR_FAIL_COND(_build_thread != NULL);
|
|
||||||
|
|
||||||
_build_thread = Thread::create(_build_threaded, this);
|
//call the next non-threaded phase aswell
|
||||||
} else {
|
if (has_next_phase())
|
||||||
if (has_next_phase())
|
build_phase();
|
||||||
build_phase();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
while (is_phase_threaded(get_current_build_phase()) && has_next_phase()) {
|
|
||||||
build_phase();
|
|
||||||
}
|
|
||||||
|
|
||||||
//call the next non-threaded phase aswell
|
|
||||||
if (has_next_phase())
|
|
||||||
build_phase();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelChunk::_build_threaded(void *_userdata) {
|
void VoxelChunk::_build_threaded(void *_userdata) {
|
||||||
VoxelChunk *vc = (VoxelChunk *)_userdata;
|
VoxelChunk *vc = (VoxelChunk *)_userdata;
|
||||||
|
|
||||||
while (vc->is_phase_threaded(vc->get_current_build_phase()) && vc->has_next_phase()) {
|
while (vc->has_next_phase() && vc->build_phase())
|
||||||
vc->build_phase();
|
;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelChunk::build_phase() {
|
bool VoxelChunk::build_phase() {
|
||||||
_build_phase_done = false;
|
set_build_phase_done(false);
|
||||||
|
|
||||||
call("_build_phase", _current_build_phase);
|
return call("_build_phase", _current_build_phase);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelChunk::_build_phase(int phase) {
|
bool VoxelChunk::_build_phase(int phase) {
|
||||||
ERR_FAIL_COND(!_library.is_valid());
|
ERR_FAIL_COND_V(!_library.is_valid(), true);
|
||||||
|
|
||||||
switch (phase) {
|
switch (phase) {
|
||||||
case BUILD_PHASE_DONE:
|
case BUILD_PHASE_DONE:
|
||||||
return;
|
return true;
|
||||||
case BUILD_PHASE_SETUP: {
|
case BUILD_PHASE_SETUP: {
|
||||||
if (_meshers.size() == 0) {
|
if (_meshers.size() == 0) {
|
||||||
create_meshers();
|
create_meshers();
|
||||||
@ -626,7 +626,7 @@ void VoxelChunk::_build_phase(int phase) {
|
|||||||
|
|
||||||
next_phase();
|
next_phase();
|
||||||
|
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
case BUILD_PHASE_TERRARIN_MESH_SETUP: {
|
case BUILD_PHASE_TERRARIN_MESH_SETUP: {
|
||||||
for (int i = 0; i < _meshers.size(); ++i) {
|
for (int i = 0; i < _meshers.size(); ++i) {
|
||||||
@ -639,7 +639,7 @@ void VoxelChunk::_build_phase(int phase) {
|
|||||||
|
|
||||||
next_phase();
|
next_phase();
|
||||||
|
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
case BUILD_PHASE_TERRARIN_MESH_COLLIDER: {
|
case BUILD_PHASE_TERRARIN_MESH_COLLIDER: {
|
||||||
if (get_create_collider()) {
|
if (get_create_collider()) {
|
||||||
@ -648,7 +648,7 @@ void VoxelChunk::_build_phase(int phase) {
|
|||||||
|
|
||||||
next_phase();
|
next_phase();
|
||||||
|
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
case BUILD_PHASE_TERRARIN_MESH: {
|
case BUILD_PHASE_TERRARIN_MESH: {
|
||||||
for (int i = 0; i < _meshers.size(); ++i) {
|
for (int i = 0; i < _meshers.size(); ++i) {
|
||||||
@ -663,7 +663,7 @@ void VoxelChunk::_build_phase(int phase) {
|
|||||||
|
|
||||||
next_phase();
|
next_phase();
|
||||||
|
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
case BUILD_PHASE_PROP_MESH: {
|
case BUILD_PHASE_PROP_MESH: {
|
||||||
for (int i = 0; i < _meshers.size(); ++i) {
|
for (int i = 0; i < _meshers.size(); ++i) {
|
||||||
@ -681,7 +681,7 @@ void VoxelChunk::_build_phase(int phase) {
|
|||||||
|
|
||||||
next_phase();
|
next_phase();
|
||||||
|
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
case BUILD_PHASE_PROP_COLLIDER: {
|
case BUILD_PHASE_PROP_COLLIDER: {
|
||||||
|
|
||||||
@ -701,7 +701,7 @@ void VoxelChunk::_build_phase(int phase) {
|
|||||||
|
|
||||||
next_phase();
|
next_phase();
|
||||||
|
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
case BUILD_PHASE_LIQUID: {
|
case BUILD_PHASE_LIQUID: {
|
||||||
@ -728,10 +728,11 @@ void VoxelChunk::_build_phase(int phase) {
|
|||||||
|
|
||||||
next_phase();
|
next_phase();
|
||||||
|
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
//next_phase();
|
//next_phase();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -743,7 +744,7 @@ bool VoxelChunk::has_next_phase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void VoxelChunk::next_phase() {
|
void VoxelChunk::next_phase() {
|
||||||
_build_phase_done = true;
|
set_build_phase_done(true);
|
||||||
|
|
||||||
if (_abort_build) {
|
if (_abort_build) {
|
||||||
_current_build_phase = BUILD_PHASE_DONE;
|
_current_build_phase = BUILD_PHASE_DONE;
|
||||||
@ -764,25 +765,6 @@ void VoxelChunk::next_phase() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VoxelChunk::is_phase_threaded(int phase) {
|
|
||||||
return call("_is_phase_threaded", phase);
|
|
||||||
}
|
|
||||||
bool VoxelChunk::_is_phase_threaded(int phase) {
|
|
||||||
switch (phase) {
|
|
||||||
case BUILD_PHASE_SETUP:
|
|
||||||
case BUILD_PHASE_TERRARIN_MESH_SETUP:
|
|
||||||
case BUILD_PHASE_TERRARIN_MESH_COLLIDER:
|
|
||||||
//case BUILD_PHASE_LIGHTS:
|
|
||||||
case BUILD_PHASE_TERRARIN_MESH:
|
|
||||||
//case BUILD_PHASE_PROP_MESH:
|
|
||||||
case BUILD_PHASE_PROP_COLLIDER:
|
|
||||||
case BUILD_PHASE_FINALIZE:
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VoxelChunk::clear() {
|
void VoxelChunk::clear() {
|
||||||
_voxel_lights.clear();
|
_voxel_lights.clear();
|
||||||
}
|
}
|
||||||
@ -1280,6 +1262,7 @@ VoxelChunk::VoxelChunk() {
|
|||||||
_margin_end = 0;
|
_margin_end = 0;
|
||||||
|
|
||||||
_build_prioritized = false;
|
_build_prioritized = false;
|
||||||
|
_build_phase_done_mutex = Mutex::create();
|
||||||
_build_phase_done = false;
|
_build_phase_done = false;
|
||||||
_build_thread = NULL;
|
_build_thread = NULL;
|
||||||
}
|
}
|
||||||
@ -1310,6 +1293,8 @@ VoxelChunk::~VoxelChunk() {
|
|||||||
memdelete_arr(ch);
|
memdelete_arr(ch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memdelete(_build_phase_done_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelChunk::_notification(int p_what) {
|
void VoxelChunk::_notification(int p_what) {
|
||||||
@ -1322,16 +1307,7 @@ void VoxelChunk::_notification(int p_what) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case NOTIFICATION_INTERNAL_PROCESS: {
|
case NOTIFICATION_INTERNAL_PROCESS: {
|
||||||
//if (_build_prioritized) {
|
if (has_next_phase() && get_build_phase_done()) {
|
||||||
//while (has_next_phase() && _build_phase_done) {
|
|
||||||
// _build_step();
|
|
||||||
// wait_and_finish_thread();
|
|
||||||
//}
|
|
||||||
|
|
||||||
// return;
|
|
||||||
//}
|
|
||||||
|
|
||||||
if (has_next_phase() && _build_phase_done) {
|
|
||||||
wait_and_finish_thread();
|
wait_and_finish_thread();
|
||||||
|
|
||||||
_build_step();
|
_build_step();
|
||||||
@ -1351,10 +1327,6 @@ void VoxelChunk::wait_and_finish_thread() {
|
|||||||
void VoxelChunk::_bind_methods() {
|
void VoxelChunk::_bind_methods() {
|
||||||
ADD_SIGNAL(MethodInfo("mesh_generation_finished", PropertyInfo(Variant::OBJECT, "chunk", PROPERTY_HINT_RESOURCE_TYPE, "VoxelChunk")));
|
ADD_SIGNAL(MethodInfo("mesh_generation_finished", PropertyInfo(Variant::OBJECT, "chunk", PROPERTY_HINT_RESOURCE_TYPE, "VoxelChunk")));
|
||||||
|
|
||||||
BIND_VMETHOD(MethodInfo("_is_phase_threaded", PropertyInfo(Variant::INT, "phase")));
|
|
||||||
ClassDB::bind_method(D_METHOD("is_phase_threaded", "phase"), &VoxelChunk::is_phase_threaded);
|
|
||||||
ClassDB::bind_method(D_METHOD("_is_phase_threaded", "phase"), &VoxelChunk::_is_phase_threaded);
|
|
||||||
|
|
||||||
BIND_VMETHOD(MethodInfo("_prop_added", PropertyInfo(Variant::OBJECT, "prop", PROPERTY_HINT_RESOURCE_TYPE, "VoxelChunkPropData")));
|
BIND_VMETHOD(MethodInfo("_prop_added", PropertyInfo(Variant::OBJECT, "prop", PROPERTY_HINT_RESOURCE_TYPE, "VoxelChunkPropData")));
|
||||||
|
|
||||||
BIND_VMETHOD(MethodInfo("_create_meshers"));
|
BIND_VMETHOD(MethodInfo("_create_meshers"));
|
||||||
@ -1500,7 +1472,7 @@ void VoxelChunk::_bind_methods() {
|
|||||||
//Meshes
|
//Meshes
|
||||||
ClassDB::bind_method(D_METHOD("finalize_mesh"), &VoxelChunk::finalize_mesh);
|
ClassDB::bind_method(D_METHOD("finalize_mesh"), &VoxelChunk::finalize_mesh);
|
||||||
|
|
||||||
BIND_VMETHOD(MethodInfo("_build_phase", PropertyInfo(Variant::INT, "phase")));
|
BIND_VMETHOD(MethodInfo(PropertyInfo(Variant::BOOL, "is_done"), "_build_phase", PropertyInfo(Variant::INT, "phase")));
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("build_deferred"), &VoxelChunk::build_deferred);
|
ClassDB::bind_method(D_METHOD("build_deferred"), &VoxelChunk::build_deferred);
|
||||||
ClassDB::bind_method(D_METHOD("build_prioritized"), &VoxelChunk::build_prioritized);
|
ClassDB::bind_method(D_METHOD("build_prioritized"), &VoxelChunk::build_prioritized);
|
||||||
|
@ -26,6 +26,7 @@ SOFTWARE.
|
|||||||
#include "scene/3d/spatial.h"
|
#include "scene/3d/spatial.h"
|
||||||
|
|
||||||
#include "core/engine.h"
|
#include "core/engine.h"
|
||||||
|
#include "core/os/mutex.h"
|
||||||
#include "core/os/thread.h"
|
#include "core/os/thread.h"
|
||||||
#include "core/os/thread_safe.h"
|
#include "core/os/thread_safe.h"
|
||||||
#include "core/ustring.h"
|
#include "core/ustring.h"
|
||||||
@ -109,6 +110,9 @@ public:
|
|||||||
bool get_is_build_threaded() const;
|
bool get_is_build_threaded() const;
|
||||||
void set_is_build_threaded(bool value);
|
void set_is_build_threaded(bool value);
|
||||||
|
|
||||||
|
bool get_build_phase_done() const;
|
||||||
|
void set_build_phase_done(bool value);
|
||||||
|
|
||||||
bool get_dirty() const;
|
bool get_dirty() const;
|
||||||
void set_dirty(bool value);
|
void set_dirty(bool value);
|
||||||
|
|
||||||
@ -222,13 +226,11 @@ public:
|
|||||||
void build_prioritized();
|
void build_prioritized();
|
||||||
static void _build_threaded(void *_userdata);
|
static void _build_threaded(void *_userdata);
|
||||||
|
|
||||||
void build_phase();
|
bool build_phase();
|
||||||
void _build_step();
|
void _build_step();
|
||||||
void _build_phase(int phase);
|
bool _build_phase(int phase);
|
||||||
bool has_next_phase();
|
bool has_next_phase();
|
||||||
void next_phase();
|
void next_phase();
|
||||||
bool is_phase_threaded(int phase);
|
|
||||||
bool _is_phase_threaded(int phase);
|
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
@ -377,6 +379,7 @@ protected:
|
|||||||
bool _bake_lights;
|
bool _bake_lights;
|
||||||
|
|
||||||
bool _build_prioritized;
|
bool _build_prioritized;
|
||||||
|
Mutex *_build_phase_done_mutex;
|
||||||
bool _build_phase_done;
|
bool _build_phase_done;
|
||||||
Thread *_build_thread;
|
Thread *_build_thread;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user