diff --git a/source/blender/gpu/GPU_shader.hh b/source/blender/gpu/GPU_shader.hh index 3d7f28bfadd..ea04ee794cc 100644 --- a/source/blender/gpu/GPU_shader.hh +++ b/source/blender/gpu/GPU_shader.hh @@ -109,6 +109,10 @@ blender::Vector GPU_shader_batch_finalize(BatchHandle &handle); * WARNING: The handle will be invalidated by this call. */ void GPU_shader_batch_cancel(BatchHandle &handle); +/** + * Returns true if there's any batch still being compiled. + */ +bool GPU_shader_batch_is_compiling(); /** * Wait until all the requested batches have been compiled. */ diff --git a/source/blender/gpu/intern/gpu_shader.cc b/source/blender/gpu/intern/gpu_shader.cc index 3876e7592b1..3df3bf39780 100644 --- a/source/blender/gpu/intern/gpu_shader.cc +++ b/source/blender/gpu/intern/gpu_shader.cc @@ -393,6 +393,11 @@ void GPU_shader_batch_cancel(BatchHandle &handle) GPUBackend::get()->get_compiler()->batch_cancel(handle); } +bool GPU_shader_batch_is_compiling() +{ + return GPUBackend::get()->get_compiler()->is_compiling(); +} + void GPU_shader_batch_wait_for_all() { GPUBackend::get()->get_compiler()->wait_for_all(); @@ -1170,22 +1175,34 @@ void ShaderCompiler::do_work(void *work_payload) compilation_finished_notification_.notify_all(); } +bool ShaderCompiler::is_compiling_impl() +{ + /* The mutex should be locked befor calling this function. */ + BLI_assert(!mutex_.try_lock()); + + if (!compilation_queue_.is_empty()) { + return true; + } + + for (Batch *batch : batches_.values()) { + if (!batch->is_ready()) { + return true; + } + } + + return false; +} + +bool ShaderCompiler::is_compiling() +{ + std::unique_lock lock(mutex_); + return is_compiling_impl(); +} + void ShaderCompiler::wait_for_all() { std::unique_lock lock(mutex_); - compilation_finished_notification_.wait(lock, [&]() { - if (!compilation_queue_.is_empty()) { - return false; - } - - for (Batch *batch : batches_.values()) { - if (!batch->is_ready()) { - return false; - } - } - - return true; - }); + compilation_finished_notification_.wait(lock, [&]() { return !is_compiling_impl(); }); } /** \} */ diff --git a/source/blender/gpu/intern/gpu_shader_private.hh b/source/blender/gpu/intern/gpu_shader_private.hh index ca7cac59559..a7cd012d94f 100644 --- a/source/blender/gpu/intern/gpu_shader_private.hh +++ b/source/blender/gpu/intern/gpu_shader_private.hh @@ -270,6 +270,8 @@ class ShaderCompiler { BatchHandle next_batch_handle_ = 1; + bool is_compiling_impl(); + protected: /* Must be called earlier from the destructor of the subclass if the compilation process relies * on subclass resources. */ @@ -300,6 +302,7 @@ class ShaderCompiler { bool specialization_batch_is_ready(SpecializationBatchHandle &handle); + bool is_compiling(); void wait_for_all(); }; diff --git a/source/blender/python/intern/bpy_app.cc b/source/blender/python/intern/bpy_app.cc index 2f1eb426ab4..21e2c44b75b 100644 --- a/source/blender/python/intern/bpy_app.cc +++ b/source/blender/python/intern/bpy_app.cc @@ -42,6 +42,8 @@ #include "BKE_global.hh" #include "BKE_main.hh" +#include "GPU_shader.hh" + #include "UI_interface_icons.hh" #include "MEM_guardedalloc.h" @@ -595,6 +597,11 @@ static PyObject *bpy_app_is_job_running(PyObject * /*self*/, PyObject *args, PyO return nullptr; } wmWindowManager *wm = static_cast(G_MAIN->wm.first); + if (job_type_enum.value == WM_JOB_TYPE_SHADER_COMPILATION) { + /* Shader compilation no longer uses the WM_job API, so we handle this as a special case + * to avoid breaking the Python API. */ + return PyBool_FromLong(GPU_shader_batch_is_compiling()); + } return PyBool_FromLong(WM_jobs_has_running_type(wm, job_type_enum.value)); }