From 05576e067b3c72382fa5bffc38cbe15b2644138f Mon Sep 17 00:00:00 2001 From: "georgiy.m.markelov@gmail.com" Date: Tue, 4 Apr 2023 13:40:16 +0300 Subject: [PATCH 1/9] BLEN-365: Improve creation algorithm of PreviewEngine --- scripts/modules/bpy_hydra.py | 15 ++++---- source/blender/render/hydra/engine.cc | 6 +++ source/blender/render/hydra/engine.h | 4 +- source/blender/render/hydra/final_engine.cc | 4 -- source/blender/render/hydra/preview_engine.cc | 34 +++++++++++++++-- source/blender/render/hydra/preview_engine.h | 3 ++ source/blender/render/hydra/python.cc | 37 +++++++++++++++++-- .../render/hydra/render_task_delegate.cc | 9 +++++ .../render/hydra/render_task_delegate.h | 1 + .../scene_delegate/blender_scene_delegate.cc | 6 +++ .../scene_delegate/blender_scene_delegate.h | 1 + .../blender/render/hydra/viewport_engine.cc | 6 --- 12 files changed, 99 insertions(+), 27 deletions(-) diff --git a/scripts/modules/bpy_hydra.py b/scripts/modules/bpy_hydra.py index 6b2b0a3e5cd8..b0f1323419b6 100644 --- a/scripts/modules/bpy_hydra.py +++ b/scripts/modules/bpy_hydra.py @@ -19,7 +19,7 @@ class CustomHydraRenderEngine(HydraRenderEngine): def register(cls): super().register() - bpy_hydra.register_plugins(["/path/to/plugin")], ["/additional/system/path")]) + bpy_hydra.register_plugins(["/path/to/plugin")]) def get_delegate_settings(self, engine_type): return { @@ -58,6 +58,7 @@ class HydraRenderEngine(bpy.types.RenderEngine): return _bpy_hydra.engine_free(self.engine_ptr) + del self.engine_ptr @classmethod def register(cls): @@ -74,20 +75,18 @@ class HydraRenderEngine(bpy.types.RenderEngine): # final render def update(self, data, depsgraph): - pass - - def render(self, depsgraph): engine_type = 'PREVIEW' if self.is_preview else 'FINAL' - self.engine_ptr = _bpy_hydra.engine_create(self.as_pointer(), engine_type, self.delegate_id) delegate_settings = self.get_delegate_settings(engine_type) - _bpy_hydra.engine_sync(self.engine_ptr, depsgraph.as_pointer(), bpy.context.as_pointer(), delegate_settings) - _bpy_hydra.engine_render(self.engine_ptr, depsgraph.as_pointer()) + + def render(self, depsgraph): + if hasattr(self, 'engine_ptr'): + _bpy_hydra.engine_render(self.engine_ptr, depsgraph.as_pointer()) # viewport render def view_update(self, context, depsgraph): - if not self.engine_ptr: + if not hasattr(self, 'engine_ptr'): self.engine_ptr = _bpy_hydra.engine_create(self.as_pointer(), 'VIEWPORT', self.delegate_id) delegate_settings = self.get_delegate_settings('VIEWPORT') diff --git a/source/blender/render/hydra/engine.cc b/source/blender/render/hydra/engine.cc index 6452e1ddf866..178909069298 100644 --- a/source/blender/render/hydra/engine.cc +++ b/source/blender/render/hydra/engine.cc @@ -42,6 +42,11 @@ Engine::Engine(RenderEngine *bl_engine, const std::string &delegate_id) : bl_eng } engine = std::make_unique(); + + scene_delegate = std::make_unique( + render_index.get(), + pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene"), + BlenderSceneDelegate::EngineType::PREVIEW); } Engine::~Engine() @@ -54,6 +59,7 @@ Engine::~Engine() render_delegate = nullptr; engine = nullptr; hgi = nullptr; + bl_engine = nullptr; } float Engine::renderer_percent_done() diff --git a/source/blender/render/hydra/engine.h b/source/blender/render/hydra/engine.h index 3e6a5ad95056..6cd546bf5424 100644 --- a/source/blender/render/hydra/engine.h +++ b/source/blender/render/hydra/engine.h @@ -34,12 +34,12 @@ class Engine { bContext *context, pxr::HdRenderSettingsMap &render_settings) = 0; virtual void render(Depsgraph *depsgraph) = 0; - + RenderEngine *bl_engine; protected: float renderer_percent_done(); protected: - RenderEngine *bl_engine; + pxr::HdPluginRenderDelegateUniqueHandle render_delegate; std::unique_ptr render_index; diff --git a/source/blender/render/hydra/final_engine.cc b/source/blender/render/hydra/final_engine.cc index 4052b81fe26e..c0a109d7e137 100644 --- a/source/blender/render/hydra/final_engine.cc +++ b/source/blender/render/hydra/final_engine.cc @@ -16,10 +16,6 @@ void FinalEngine::sync(Depsgraph *depsgraph, bContext *context, pxr::HdRenderSettingsMap &render_settings) { - scene_delegate = std::make_unique( - render_index.get(), - pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene"), - BlenderSceneDelegate::EngineType::FINAL); scene_delegate->populate(depsgraph, context); for (auto const &setting : render_settings) { diff --git a/source/blender/render/hydra/preview_engine.cc b/source/blender/render/hydra/preview_engine.cc index d135da4ce785..7970067000ce 100644 --- a/source/blender/render/hydra/preview_engine.cc +++ b/source/blender/render/hydra/preview_engine.cc @@ -12,19 +12,37 @@ void PreviewEngine::sync(Depsgraph *depsgraph, bContext *context, pxr::HdRenderSettingsMap &render_settings) { - scene_delegate = std::make_unique( - render_index.get(), - pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene"), - BlenderSceneDelegate::EngineType::PREVIEW); + is_synced = false; + + scene_delegate->clear_data(); + for (auto &prim : render_index->GetRprimIds()) { + render_index->RemoveRprim(prim); + render_index->RemoveInstancer(prim); + std::cout << "sync RemoveRprim: " << prim.GetText() << " " << render_index->HasRprim(prim) + << "\n"; + } + + for (auto &prim : render_index->GetRprimIds()) { + std::cout << "sync after Remove: " << prim.GetText() << "\n"; + } + scene_delegate->populate(depsgraph, context); + for (auto &prim : render_index->GetRprimIds()) { + std::cout << "sync populate: " << prim.GetText() << "\n"; + } + for (auto const &setting : render_settings) { render_delegate->SetRenderSetting(setting.first, setting.second); } + is_synced = true; } void PreviewEngine::render(Depsgraph *depsgraph) { + //if (!is_synced) { + // return; + //} Scene *scene = DEG_get_input_scene(depsgraph); ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph); @@ -35,6 +53,7 @@ void PreviewEngine::render(Depsgraph *depsgraph) CameraData(scene->camera, res, pxr::GfVec4f(0, 0, 1, 1)).gf_camera(pxr::GfVec4f(0, 0, 1, 1)); free_camera_delegate->SetCamera(camera); + //render_task_delegate->clear_renderer_aovs(); render_task_delegate->set_camera_and_viewport(free_camera_delegate->GetCameraId(), pxr::GfVec4d(0, 0, res[0], res[1])); render_task_delegate->set_renderer_aov(pxr::HdAovTokens->color); @@ -70,6 +89,13 @@ void PreviewEngine::render(Depsgraph *depsgraph) update_render_result(layer_name, res[0], res[1], pixels); } +void PreviewEngine::stop_renderer() +{ + if (render_delegate) { + render_delegate->Stop(); + } +} + void PreviewEngine::update_render_result(const std::string &layer_name, int width, int height, diff --git a/source/blender/render/hydra/preview_engine.h b/source/blender/render/hydra/preview_engine.h index a0b38b1d0653..fa5e9a24109a 100644 --- a/source/blender/render/hydra/preview_engine.h +++ b/source/blender/render/hydra/preview_engine.h @@ -14,6 +14,9 @@ class PreviewEngine : public FinalEngine { bContext *context, pxr::HdRenderSettingsMap &render_settings) override; void render(Depsgraph *depsgraph) override; + void stop_renderer(); + + bool is_synced = false; protected: void update_render_result(const std::string &layer_name, diff --git a/source/blender/render/hydra/python.cc b/source/blender/render/hydra/python.cc index 9401a76a8f91..64eeec3b150d 100644 --- a/source/blender/render/hydra/python.cc +++ b/source/blender/render/hydra/python.cc @@ -16,8 +16,25 @@ #include "utils.h" #include "viewport_engine.h" +#include "BLI_timer.h" + namespace blender::render::hydra { +static double preview_engine_lifetime = 60.0; +static PreviewEngine *preview_engine; + +double timer_func(uintptr_t uuid, void *user_data) +{ + if (preview_engine) { + preview_engine->stop_renderer(); + delete preview_engine; + preview_engine = nullptr; + return -1; + } + + return preview_engine_lifetime; +} + static PyObject *init_func(PyObject * /*self*/, PyObject *args) { CLOG_INFO(LOG_EN, 1, "Init"); @@ -106,14 +123,22 @@ static PyObject *engine_create_func(PyObject * /*self*/, PyObject *args) } RenderEngine *bl_engine = (RenderEngine *)PyLong_AsVoidPtr(pyengine); - Engine *engine; if (STREQ(engine_type, "VIEWPORT")) { engine = new ViewportEngine(bl_engine, render_delegate_id); } else if (STREQ(engine_type, "PREVIEW")) { - engine = new PreviewEngine(bl_engine, render_delegate_id); + if (!preview_engine) { + preview_engine = new PreviewEngine(bl_engine, render_delegate_id); + } + if (BLI_timer_is_registered(1)) { + BLI_timer_unregister(1); + } + preview_engine->bl_engine = bl_engine; + + CLOG_INFO(LOG_EN, 2, "Engine %016llx %s", engine, engine_type); + return PyLong_FromVoidPtr(preview_engine); } else { if (bl_engine->type->flag & RE_USE_GPU_CONTEXT) { @@ -136,7 +161,13 @@ static PyObject *engine_free_func(PyObject * /*self*/, PyObject *args) Py_RETURN_NONE; } - Engine *engine = (Engine *) PyLong_AsVoidPtr(pyengine); + Engine *engine = (Engine *)PyLong_AsVoidPtr(pyengine); + + if (preview_engine) { + BLI_timer_register(1, timer_func, nullptr, nullptr, preview_engine_lifetime, true); + Py_RETURN_NONE; + } + delete engine; CLOG_INFO(LOG_EN, 2, "Engine %016llx", engine); diff --git a/source/blender/render/hydra/render_task_delegate.cc b/source/blender/render/hydra/render_task_delegate.cc index 250b86619da8..a853992ac6fd 100644 --- a/source/blender/render/hydra/render_task_delegate.cc +++ b/source/blender/render/hydra/render_task_delegate.cc @@ -132,4 +132,13 @@ void RenderTaskDelegate::set_camera_and_viewport(pxr::SdfPath const &camera_id, } } +void RenderTaskDelegate::clear_renderer_aovs() +{ + for (pxr::HdRenderPassAovBinding &binding : task_params.aovBindings) { + std::cout << "clear_renderer_aovs: " << binding.renderBufferId.GetText() << "\n"; + GetRenderIndex().RemoveBprim(pxr::HdPrimTypeTokens->renderBuffer, binding.renderBufferId); + buffer_descriptors.erase(binding.renderBufferId); + } +} + } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/render_task_delegate.h b/source/blender/render/hydra/render_task_delegate.h index f7119fc83e2a..8c50072c06e9 100644 --- a/source/blender/render/hydra/render_task_delegate.h +++ b/source/blender/render/hydra/render_task_delegate.h @@ -27,6 +27,7 @@ class RenderTaskDelegate : public pxr::HdSceneDelegate { pxr::HdTaskSharedPtr get_task(); void set_camera_and_viewport(pxr::SdfPath const &cameraId, pxr::GfVec4d const &viewport); + void clear_renderer_aovs(); private: pxr::HdxRenderTaskParams task_params; diff --git a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc index de574193c48e..6b310a10a8b8 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc @@ -477,4 +477,10 @@ pxr::VtValue BlenderSceneDelegate::GetLightParamValue(pxr::SdfPath const &id, return pxr::VtValue(); } +void BlenderSceneDelegate::clear_data() +{ + objects.clear(); + materials.clear(); +} + } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h index cf03fd74f0c7..0bab7c6e9ddf 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h @@ -29,6 +29,7 @@ class BlenderSceneDelegate : public pxr::HdSceneDelegate { ~BlenderSceneDelegate() override = default; void populate(Depsgraph *depsgraph, bContext *context); + void clear_data(); // delegate methods pxr::HdMeshTopology GetMeshTopology(pxr::SdfPath const &id) override; diff --git a/source/blender/render/hydra/viewport_engine.cc b/source/blender/render/hydra/viewport_engine.cc index 94f8ab8dad24..b9f7496cb46f 100644 --- a/source/blender/render/hydra/viewport_engine.cc +++ b/source/blender/render/hydra/viewport_engine.cc @@ -244,12 +244,6 @@ void ViewportEngine::sync(Depsgraph *depsgraph, bContext *context, pxr::HdRenderSettingsMap &render_settings) { - if (!scene_delegate) { - scene_delegate = std::make_unique( - render_index.get(), - pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene"), - BlenderSceneDelegate::EngineType::VIEWPORT); - } scene_delegate->populate(depsgraph, context); for (auto const &setting : render_settings) { -- 2.30.2 From cca11e5b171a2a5b7005655742ca1c6a7e1fb7d8 Mon Sep 17 00:00:00 2001 From: "georgiy.m.markelov@gmail.com" Date: Tue, 4 Apr 2023 13:49:46 +0300 Subject: [PATCH 2/9] clean up code --- source/blender/render/hydra/engine.h | 5 +++-- source/blender/render/hydra/preview_engine.cc | 18 +----------------- source/blender/render/hydra/preview_engine.h | 2 -- source/blender/render/hydra/python.cc | 5 +++-- 4 files changed, 7 insertions(+), 23 deletions(-) diff --git a/source/blender/render/hydra/engine.h b/source/blender/render/hydra/engine.h index 6cd546bf5424..7fd868b5efb9 100644 --- a/source/blender/render/hydra/engine.h +++ b/source/blender/render/hydra/engine.h @@ -34,13 +34,14 @@ class Engine { bContext *context, pxr::HdRenderSettingsMap &render_settings) = 0; virtual void render(Depsgraph *depsgraph) = 0; + + public: RenderEngine *bl_engine; + protected: float renderer_percent_done(); protected: - - pxr::HdPluginRenderDelegateUniqueHandle render_delegate; std::unique_ptr render_index; std::unique_ptr scene_delegate; diff --git a/source/blender/render/hydra/preview_engine.cc b/source/blender/render/hydra/preview_engine.cc index 7970067000ce..4a791af817b0 100644 --- a/source/blender/render/hydra/preview_engine.cc +++ b/source/blender/render/hydra/preview_engine.cc @@ -12,37 +12,22 @@ void PreviewEngine::sync(Depsgraph *depsgraph, bContext *context, pxr::HdRenderSettingsMap &render_settings) { - is_synced = false; - scene_delegate->clear_data(); + for (auto &prim : render_index->GetRprimIds()) { render_index->RemoveRprim(prim); render_index->RemoveInstancer(prim); - std::cout << "sync RemoveRprim: " << prim.GetText() << " " << render_index->HasRprim(prim) - << "\n"; - } - - for (auto &prim : render_index->GetRprimIds()) { - std::cout << "sync after Remove: " << prim.GetText() << "\n"; } scene_delegate->populate(depsgraph, context); - for (auto &prim : render_index->GetRprimIds()) { - std::cout << "sync populate: " << prim.GetText() << "\n"; - } - for (auto const &setting : render_settings) { render_delegate->SetRenderSetting(setting.first, setting.second); } - is_synced = true; } void PreviewEngine::render(Depsgraph *depsgraph) { - //if (!is_synced) { - // return; - //} Scene *scene = DEG_get_input_scene(depsgraph); ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph); @@ -53,7 +38,6 @@ void PreviewEngine::render(Depsgraph *depsgraph) CameraData(scene->camera, res, pxr::GfVec4f(0, 0, 1, 1)).gf_camera(pxr::GfVec4f(0, 0, 1, 1)); free_camera_delegate->SetCamera(camera); - //render_task_delegate->clear_renderer_aovs(); render_task_delegate->set_camera_and_viewport(free_camera_delegate->GetCameraId(), pxr::GfVec4d(0, 0, res[0], res[1])); render_task_delegate->set_renderer_aov(pxr::HdAovTokens->color); diff --git a/source/blender/render/hydra/preview_engine.h b/source/blender/render/hydra/preview_engine.h index fa5e9a24109a..52f2877f890f 100644 --- a/source/blender/render/hydra/preview_engine.h +++ b/source/blender/render/hydra/preview_engine.h @@ -16,8 +16,6 @@ class PreviewEngine : public FinalEngine { void render(Depsgraph *depsgraph) override; void stop_renderer(); - bool is_synced = false; - protected: void update_render_result(const std::string &layer_name, int width, diff --git a/source/blender/render/hydra/python.cc b/source/blender/render/hydra/python.cc index 64eeec3b150d..1a6fb7027202 100644 --- a/source/blender/render/hydra/python.cc +++ b/source/blender/render/hydra/python.cc @@ -23,7 +23,7 @@ namespace blender::render::hydra { static double preview_engine_lifetime = 60.0; static PreviewEngine *preview_engine; -double timer_func(uintptr_t uuid, void *user_data) +double delete_preview_engine(uintptr_t uuid, void *user_data) { if (preview_engine) { preview_engine->stop_renderer(); @@ -164,7 +164,8 @@ static PyObject *engine_free_func(PyObject * /*self*/, PyObject *args) Engine *engine = (Engine *)PyLong_AsVoidPtr(pyengine); if (preview_engine) { - BLI_timer_register(1, timer_func, nullptr, nullptr, preview_engine_lifetime, true); + BLI_timer_register(1, delete_preview_engine, nullptr, nullptr, preview_engine_lifetime, true); + CLOG_INFO(LOG_EN, 2, "Engine %016llx", engine); Py_RETURN_NONE; } -- 2.30.2 From a1bf008904e803d183fa80210062c9b85c21cd5f Mon Sep 17 00:00:00 2001 From: "georgiy.m.markelov@gmail.com" Date: Tue, 4 Apr 2023 13:59:57 +0300 Subject: [PATCH 3/9] clean up code --- scripts/modules/bpy_hydra.py | 4 ++-- source/blender/render/hydra/render_task_delegate.cc | 9 --------- source/blender/render/hydra/render_task_delegate.h | 1 - 3 files changed, 2 insertions(+), 12 deletions(-) diff --git a/scripts/modules/bpy_hydra.py b/scripts/modules/bpy_hydra.py index b0f1323419b6..061692873def 100644 --- a/scripts/modules/bpy_hydra.py +++ b/scripts/modules/bpy_hydra.py @@ -81,12 +81,12 @@ class HydraRenderEngine(bpy.types.RenderEngine): _bpy_hydra.engine_sync(self.engine_ptr, depsgraph.as_pointer(), bpy.context.as_pointer(), delegate_settings) def render(self, depsgraph): - if hasattr(self, 'engine_ptr'): + if self.engine_ptr: _bpy_hydra.engine_render(self.engine_ptr, depsgraph.as_pointer()) # viewport render def view_update(self, context, depsgraph): - if not hasattr(self, 'engine_ptr'): + if not self.engine_ptr: self.engine_ptr = _bpy_hydra.engine_create(self.as_pointer(), 'VIEWPORT', self.delegate_id) delegate_settings = self.get_delegate_settings('VIEWPORT') diff --git a/source/blender/render/hydra/render_task_delegate.cc b/source/blender/render/hydra/render_task_delegate.cc index a853992ac6fd..250b86619da8 100644 --- a/source/blender/render/hydra/render_task_delegate.cc +++ b/source/blender/render/hydra/render_task_delegate.cc @@ -132,13 +132,4 @@ void RenderTaskDelegate::set_camera_and_viewport(pxr::SdfPath const &camera_id, } } -void RenderTaskDelegate::clear_renderer_aovs() -{ - for (pxr::HdRenderPassAovBinding &binding : task_params.aovBindings) { - std::cout << "clear_renderer_aovs: " << binding.renderBufferId.GetText() << "\n"; - GetRenderIndex().RemoveBprim(pxr::HdPrimTypeTokens->renderBuffer, binding.renderBufferId); - buffer_descriptors.erase(binding.renderBufferId); - } -} - } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/render_task_delegate.h b/source/blender/render/hydra/render_task_delegate.h index 8c50072c06e9..f7119fc83e2a 100644 --- a/source/blender/render/hydra/render_task_delegate.h +++ b/source/blender/render/hydra/render_task_delegate.h @@ -27,7 +27,6 @@ class RenderTaskDelegate : public pxr::HdSceneDelegate { pxr::HdTaskSharedPtr get_task(); void set_camera_and_viewport(pxr::SdfPath const &cameraId, pxr::GfVec4d const &viewport); - void clear_renderer_aovs(); private: pxr::HdxRenderTaskParams task_params; -- 2.30.2 From d33f8ef37dbe0a41c0b3db27dd45c65a8744c6ff Mon Sep 17 00:00:00 2001 From: "georgiy.m.markelov@gmail.com" Date: Thu, 6 Apr 2023 16:52:45 +0300 Subject: [PATCH 4/9] fix review comments --- source/blender/render/hydra/engine.cc | 10 +++---- source/blender/render/hydra/engine.h | 6 ++-- source/blender/render/hydra/final_engine.cc | 4 +++ source/blender/render/hydra/preview_engine.cc | 28 +++++++++++++------ source/blender/render/hydra/preview_engine.h | 6 +++- source/blender/render/hydra/python.cc | 28 +++++++------------ .../scene_delegate/blender_scene_delegate.cc | 12 ++++++-- .../scene_delegate/blender_scene_delegate.h | 2 +- .../render/hydra/scene_delegate/material.cc | 2 +- .../render/hydra/scene_delegate/mesh.cc | 2 +- .../blender/render/hydra/viewport_engine.cc | 6 ++++ 11 files changed, 65 insertions(+), 41 deletions(-) diff --git a/source/blender/render/hydra/engine.cc b/source/blender/render/hydra/engine.cc index 178909069298..8dfc656ce18f 100644 --- a/source/blender/render/hydra/engine.cc +++ b/source/blender/render/hydra/engine.cc @@ -42,11 +42,6 @@ Engine::Engine(RenderEngine *bl_engine, const std::string &delegate_id) : bl_eng } engine = std::make_unique(); - - scene_delegate = std::make_unique( - render_index.get(), - pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene"), - BlenderSceneDelegate::EngineType::PREVIEW); } Engine::~Engine() @@ -62,6 +57,11 @@ Engine::~Engine() bl_engine = nullptr; } +bool Engine::is_converged() +{ + return render_task_delegate->is_converged(); +} + float Engine::renderer_percent_done() { pxr::VtDictionary render_stats = render_delegate->GetRenderStats(); diff --git a/source/blender/render/hydra/engine.h b/source/blender/render/hydra/engine.h index 7fd868b5efb9..5391448e96c3 100644 --- a/source/blender/render/hydra/engine.h +++ b/source/blender/render/hydra/engine.h @@ -34,14 +34,14 @@ class Engine { bContext *context, pxr::HdRenderSettingsMap &render_settings) = 0; virtual void render(Depsgraph *depsgraph) = 0; - - public: - RenderEngine *bl_engine; + bool is_converged(); protected: float renderer_percent_done(); protected: + RenderEngine *bl_engine; + pxr::HdPluginRenderDelegateUniqueHandle render_delegate; std::unique_ptr render_index; std::unique_ptr scene_delegate; diff --git a/source/blender/render/hydra/final_engine.cc b/source/blender/render/hydra/final_engine.cc index c0a109d7e137..4052b81fe26e 100644 --- a/source/blender/render/hydra/final_engine.cc +++ b/source/blender/render/hydra/final_engine.cc @@ -16,6 +16,10 @@ void FinalEngine::sync(Depsgraph *depsgraph, bContext *context, pxr::HdRenderSettingsMap &render_settings) { + scene_delegate = std::make_unique( + render_index.get(), + pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene"), + BlenderSceneDelegate::EngineType::FINAL); scene_delegate->populate(depsgraph, context); for (auto const &setting : render_settings) { diff --git a/source/blender/render/hydra/preview_engine.cc b/source/blender/render/hydra/preview_engine.cc index 4a791af817b0..77ff6dc8a997 100644 --- a/source/blender/render/hydra/preview_engine.cc +++ b/source/blender/render/hydra/preview_engine.cc @@ -12,13 +12,13 @@ void PreviewEngine::sync(Depsgraph *depsgraph, bContext *context, pxr::HdRenderSettingsMap &render_settings) { - scene_delegate->clear_data(); - - for (auto &prim : render_index->GetRprimIds()) { - render_index->RemoveRprim(prim); - render_index->RemoveInstancer(prim); + if (!scene_delegate) { + scene_delegate = std::make_unique( + render_index.get(), + pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene"), + BlenderSceneDelegate::EngineType::PREVIEW); } - + scene_delegate->clear(); scene_delegate->populate(depsgraph, context); for (auto const &setting : render_settings) { @@ -73,11 +73,21 @@ void PreviewEngine::render(Depsgraph *depsgraph) update_render_result(layer_name, res[0], res[1], pixels); } -void PreviewEngine::stop_renderer() +void PreviewEngine::update_bl_engine(RenderEngine *bl_engine) { - if (render_delegate) { - render_delegate->Stop(); + this->bl_engine = bl_engine; +} + +double PreviewEngine::delete_preview_engine(uintptr_t uuid, void *user_data) +{ + std::unique_ptr *preview_engine = static_cast*>(user_data); + if (preview_engine && preview_engine->get()->is_converged()) { + CLOG_INFO(LOG_EN, 1, "Delete preview engine"); + preview_engine->reset(); + return -1; } + + return preview_engine_lifetime; } void PreviewEngine::update_render_result(const std::string &layer_name, diff --git a/source/blender/render/hydra/preview_engine.h b/source/blender/render/hydra/preview_engine.h index 52f2877f890f..1dffc0c07aaa 100644 --- a/source/blender/render/hydra/preview_engine.h +++ b/source/blender/render/hydra/preview_engine.h @@ -14,7 +14,8 @@ class PreviewEngine : public FinalEngine { bContext *context, pxr::HdRenderSettingsMap &render_settings) override; void render(Depsgraph *depsgraph) override; - void stop_renderer(); + void update_bl_engine(RenderEngine *bl_engine); + static double delete_preview_engine(uintptr_t uuid, void *user_data); protected: void update_render_result(const std::string &layer_name, @@ -22,6 +23,9 @@ class PreviewEngine : public FinalEngine { int height, std::vector &pixels); + public: + static inline double preview_engine_lifetime = 180.0; + protected: pxr::HdRenderSettingsMap render_settings; }; diff --git a/source/blender/render/hydra/python.cc b/source/blender/render/hydra/python.cc index 1a6fb7027202..c6e43e964b21 100644 --- a/source/blender/render/hydra/python.cc +++ b/source/blender/render/hydra/python.cc @@ -20,20 +20,7 @@ namespace blender::render::hydra { -static double preview_engine_lifetime = 60.0; -static PreviewEngine *preview_engine; - -double delete_preview_engine(uintptr_t uuid, void *user_data) -{ - if (preview_engine) { - preview_engine->stop_renderer(); - delete preview_engine; - preview_engine = nullptr; - return -1; - } - - return preview_engine_lifetime; -} +static std::unique_ptr preview_engine; static PyObject *init_func(PyObject * /*self*/, PyObject *args) { @@ -130,15 +117,15 @@ static PyObject *engine_create_func(PyObject * /*self*/, PyObject *args) } else if (STREQ(engine_type, "PREVIEW")) { if (!preview_engine) { - preview_engine = new PreviewEngine(bl_engine, render_delegate_id); + preview_engine = std::make_unique(bl_engine, render_delegate_id); } if (BLI_timer_is_registered(1)) { BLI_timer_unregister(1); } - preview_engine->bl_engine = bl_engine; + preview_engine->update_bl_engine(bl_engine); CLOG_INFO(LOG_EN, 2, "Engine %016llx %s", engine, engine_type); - return PyLong_FromVoidPtr(preview_engine); + return PyLong_FromVoidPtr(preview_engine.get()); } else { if (bl_engine->type->flag & RE_USE_GPU_CONTEXT) { @@ -164,7 +151,12 @@ static PyObject *engine_free_func(PyObject * /*self*/, PyObject *args) Engine *engine = (Engine *)PyLong_AsVoidPtr(pyengine); if (preview_engine) { - BLI_timer_register(1, delete_preview_engine, nullptr, nullptr, preview_engine_lifetime, true); + BLI_timer_register(1, + preview_engine->delete_preview_engine, + &preview_engine, + nullptr, + preview_engine->preview_engine_lifetime, + true); CLOG_INFO(LOG_EN, 2, "Engine %016llx", engine); Py_RETURN_NONE; } diff --git a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc index 6b310a10a8b8..f1f24f1ea7c6 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc @@ -477,10 +477,18 @@ pxr::VtValue BlenderSceneDelegate::GetLightParamValue(pxr::SdfPath const &id, return pxr::VtValue(); } -void BlenderSceneDelegate::clear_data() +void BlenderSceneDelegate::clear() { - objects.clear(); + for (auto it = materials.begin(); it != materials.end(); ++it) { + it->second->remove_prim(); + } + + for (auto it = objects.begin(); it != objects.end(); ++it) { + it->second->remove_prim(); + } + materials.clear(); + objects.clear(); } } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h index 0bab7c6e9ddf..bd885c3f0aee 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h @@ -29,7 +29,7 @@ class BlenderSceneDelegate : public pxr::HdSceneDelegate { ~BlenderSceneDelegate() override = default; void populate(Depsgraph *depsgraph, bContext *context); - void clear_data(); + void clear(); // delegate methods pxr::HdMeshTopology GetMeshTopology(pxr::SdfPath const &id) override; diff --git a/source/blender/render/hydra/scene_delegate/material.cc b/source/blender/render/hydra/scene_delegate/material.cc index c460b76b651d..4c60531640ef 100644 --- a/source/blender/render/hydra/scene_delegate/material.cc +++ b/source/blender/render/hydra/scene_delegate/material.cc @@ -120,7 +120,7 @@ void MaterialData::remove_prim() { pxr::SdfPath p_id = prim_id(scene_delegate, (Material *)id); scene_delegate->GetRenderIndex().RemoveSprim(pxr::HdPrimTypeTokens->material, p_id); - CLOG_INFO(LOG_BSD, 2, "Remove: %s", name().c_str()); + //CLOG_INFO(LOG_BSD, 2, "Remove: %s", name().c_str()); } void MaterialData::mark_prim_dirty(DirtyBits dirty_bits) diff --git a/source/blender/render/hydra/scene_delegate/mesh.cc b/source/blender/render/hydra/scene_delegate/mesh.cc index 09bbe3828089..a2e4ee062d99 100644 --- a/source/blender/render/hydra/scene_delegate/mesh.cc +++ b/source/blender/render/hydra/scene_delegate/mesh.cc @@ -219,7 +219,7 @@ void MeshData::remove_prim() } scene_delegate->GetRenderIndex().RemoveRprim(p_id); - CLOG_INFO(LOG_BSD, 2, "Remove: %s", name().c_str()); + //CLOG_INFO(LOG_BSD, 2, "Remove: %s", name().c_str()); } void MeshData::mark_prim_dirty(DirtyBits dirty_bits) diff --git a/source/blender/render/hydra/viewport_engine.cc b/source/blender/render/hydra/viewport_engine.cc index b9f7496cb46f..94f8ab8dad24 100644 --- a/source/blender/render/hydra/viewport_engine.cc +++ b/source/blender/render/hydra/viewport_engine.cc @@ -244,6 +244,12 @@ void ViewportEngine::sync(Depsgraph *depsgraph, bContext *context, pxr::HdRenderSettingsMap &render_settings) { + if (!scene_delegate) { + scene_delegate = std::make_unique( + render_index.get(), + pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene"), + BlenderSceneDelegate::EngineType::VIEWPORT); + } scene_delegate->populate(depsgraph, context); for (auto const &setting : render_settings) { -- 2.30.2 From a4286c6fd47c1a1dcbbad681c3e02c37925c3051 Mon Sep 17 00:00:00 2001 From: "georgiy.m.markelov@gmail.com" Date: Fri, 7 Apr 2023 10:28:24 +0300 Subject: [PATCH 5/9] fix after merge --- .../render/hydra/scene_delegate/blender_scene_delegate.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc index 02dead83349f..e4b43d1fcc05 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc @@ -437,11 +437,11 @@ pxr::VtValue BlenderSceneDelegate::GetLightParamValue(pxr::SdfPath const &id, void BlenderSceneDelegate::clear() { for (auto it = materials.begin(); it != materials.end(); ++it) { - it->second->remove_prim(); + it->second->remove(); } for (auto it = objects.begin(); it != objects.end(); ++it) { - it->second->remove_prim(); + it->second->remove(); } materials.clear(); -- 2.30.2 From 5cbc5ff6d4805b04cf322c5930b242e62d83499d Mon Sep 17 00:00:00 2001 From: "georgiy.m.markelov@gmail.com" Date: Fri, 7 Apr 2023 13:26:45 +0300 Subject: [PATCH 6/9] fix light update --- .../render/hydra/scene_delegate/light.cc | 18 +++++++++++++----- .../render/hydra/scene_delegate/light.h | 2 ++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/source/blender/render/hydra/scene_delegate/light.cc b/source/blender/render/hydra/scene_delegate/light.cc index 9d95abb1b218..676270802c9e 100644 --- a/source/blender/render/hydra/scene_delegate/light.cc +++ b/source/blender/render/hydra/scene_delegate/light.cc @@ -80,15 +80,17 @@ void LightData::init() break; } + p_type = light->type; + p_shape = light->area_shape; + /* TODO: temporary value, it should be delivered through Python UI */ data[pxr::HdLightTokens->exposure] = 1.0f; } pxr::TfToken LightData::prim_type() { - Light *light = (Light *)((Object *)id)->data; pxr::TfToken ret; - switch (light->type) { + switch (p_type) { case LA_LOCAL: case LA_SPOT: ret = pxr::HdPrimTypeTokens->sphereLight; @@ -99,7 +101,7 @@ pxr::TfToken LightData::prim_type() break; case LA_AREA: - switch (light->area_shape) { + switch (p_shape) { case LA_AREA_SQUARE: case LA_AREA_RECT: ret = pxr::HdPrimTypeTokens->rectLight; @@ -166,10 +168,16 @@ void LightData::remove() void LightData::update() { - /* TODO: prim_type was changed we have to do remove..add light */ - CLOG_INFO(LOG_BSD, 2, "%s", id->name); + Light *light = (Light *)((Object *)id)->data; + if (light->type != p_type || light->area_shape != p_shape) { + remove(); + init(); + insert(); + return; + } + pxr::HdDirtyBits bits = pxr::HdLight::Clean; if (id->recalc & ID_RECALC_GEOMETRY) { init(); diff --git a/source/blender/render/hydra/scene_delegate/light.h b/source/blender/render/hydra/scene_delegate/light.h index 12d1988e80ed..59733a5d31ca 100644 --- a/source/blender/render/hydra/scene_delegate/light.h +++ b/source/blender/render/hydra/scene_delegate/light.h @@ -24,6 +24,8 @@ class LightData : public ObjectData { private: std::map data; + short p_type; + short p_shape; pxr::TfToken prim_type(); }; -- 2.30.2 From a439e99ab85e3c70cdb5d2bc90d72ece0824c423 Mon Sep 17 00:00:00 2001 From: "georgiy.m.markelov@gmail.com" Date: Fri, 7 Apr 2023 18:55:28 +0300 Subject: [PATCH 7/9] fix review comments --- source/blender/render/hydra/engine.cc | 6 ---- source/blender/render/hydra/engine.h | 1 - source/blender/render/hydra/preview_engine.cc | 33 +++++++++++++++++-- source/blender/render/hydra/preview_engine.h | 4 +++ source/blender/render/hydra/python.cc | 23 ++----------- .../scene_delegate/blender_scene_delegate.cc | 8 ++--- .../render/hydra/scene_delegate/light.cc | 16 ++++----- .../render/hydra/scene_delegate/light.h | 7 ++-- 8 files changed, 53 insertions(+), 45 deletions(-) diff --git a/source/blender/render/hydra/engine.cc b/source/blender/render/hydra/engine.cc index 8dfc656ce18f..6452e1ddf866 100644 --- a/source/blender/render/hydra/engine.cc +++ b/source/blender/render/hydra/engine.cc @@ -54,12 +54,6 @@ Engine::~Engine() render_delegate = nullptr; engine = nullptr; hgi = nullptr; - bl_engine = nullptr; -} - -bool Engine::is_converged() -{ - return render_task_delegate->is_converged(); } float Engine::renderer_percent_done() diff --git a/source/blender/render/hydra/engine.h b/source/blender/render/hydra/engine.h index 5391448e96c3..3e6a5ad95056 100644 --- a/source/blender/render/hydra/engine.h +++ b/source/blender/render/hydra/engine.h @@ -34,7 +34,6 @@ class Engine { bContext *context, pxr::HdRenderSettingsMap &render_settings) = 0; virtual void render(Depsgraph *depsgraph) = 0; - bool is_converged(); protected: float renderer_percent_done(); diff --git a/source/blender/render/hydra/preview_engine.cc b/source/blender/render/hydra/preview_engine.cc index 77ff6dc8a997..041075a72c4a 100644 --- a/source/blender/render/hydra/preview_engine.cc +++ b/source/blender/render/hydra/preview_engine.cc @@ -5,9 +5,38 @@ #include "camera.h" #include "preview_engine.h" +#include "BLI_timer.h" namespace blender::render::hydra { +std::unique_ptr PreviewEngine::preview_engine; + +void PreviewEngine::free() +{ + if (preview_engine) { + BLI_timer_register((uintptr_t)preview_engine.get(), + preview_engine->delete_preview_engine, + &preview_engine, + nullptr, + preview_engine->preview_engine_lifetime, + true); + } +} + +std::unique_ptr *PreviewEngine::get(RenderEngine *bl_engine, + char *render_delegate_id) +{ + if (!preview_engine) { + preview_engine = std::make_unique(bl_engine, render_delegate_id); + } + if (BLI_timer_is_registered((uintptr_t)preview_engine.get())) { + BLI_timer_unregister((uintptr_t)preview_engine.get()); + } + preview_engine->update_bl_engine(bl_engine); + + return &preview_engine; +} + void PreviewEngine::sync(Depsgraph *depsgraph, bContext *context, pxr::HdRenderSettingsMap &render_settings) @@ -81,8 +110,8 @@ void PreviewEngine::update_bl_engine(RenderEngine *bl_engine) double PreviewEngine::delete_preview_engine(uintptr_t uuid, void *user_data) { std::unique_ptr *preview_engine = static_cast*>(user_data); - if (preview_engine && preview_engine->get()->is_converged()) { - CLOG_INFO(LOG_EN, 1, "Delete preview engine"); + if (preview_engine && preview_engine->get()->render_task_delegate->is_converged()) { + CLOG_INFO(LOG_EN, uuid, "Delete preview engine"); preview_engine->reset(); return -1; } diff --git a/source/blender/render/hydra/preview_engine.h b/source/blender/render/hydra/preview_engine.h index 1dffc0c07aaa..006d2012f6c2 100644 --- a/source/blender/render/hydra/preview_engine.h +++ b/source/blender/render/hydra/preview_engine.h @@ -10,6 +10,9 @@ namespace blender::render::hydra { class PreviewEngine : public FinalEngine { public: using FinalEngine::FinalEngine; + static void free(); + static std::unique_ptr *get(RenderEngine *bl_engine = nullptr, + char *render_delegate_id = nullptr); void sync(Depsgraph *depsgraph, bContext *context, pxr::HdRenderSettingsMap &render_settings) override; @@ -27,6 +30,7 @@ class PreviewEngine : public FinalEngine { static inline double preview_engine_lifetime = 180.0; protected: + static std::unique_ptr preview_engine; pxr::HdRenderSettingsMap render_settings; }; diff --git a/source/blender/render/hydra/python.cc b/source/blender/render/hydra/python.cc index c6e43e964b21..cefba258ac69 100644 --- a/source/blender/render/hydra/python.cc +++ b/source/blender/render/hydra/python.cc @@ -20,8 +20,6 @@ namespace blender::render::hydra { -static std::unique_ptr preview_engine; - static PyObject *init_func(PyObject * /*self*/, PyObject *args) { CLOG_INFO(LOG_EN, 1, "Init"); @@ -116,16 +114,7 @@ static PyObject *engine_create_func(PyObject * /*self*/, PyObject *args) engine = new ViewportEngine(bl_engine, render_delegate_id); } else if (STREQ(engine_type, "PREVIEW")) { - if (!preview_engine) { - preview_engine = std::make_unique(bl_engine, render_delegate_id); - } - if (BLI_timer_is_registered(1)) { - BLI_timer_unregister(1); - } - preview_engine->update_bl_engine(bl_engine); - - CLOG_INFO(LOG_EN, 2, "Engine %016llx %s", engine, engine_type); - return PyLong_FromVoidPtr(preview_engine.get()); + engine = PreviewEngine::get(bl_engine, render_delegate_id)->get(); } else { if (bl_engine->type->flag & RE_USE_GPU_CONTEXT) { @@ -149,15 +138,9 @@ static PyObject *engine_free_func(PyObject * /*self*/, PyObject *args) } Engine *engine = (Engine *)PyLong_AsVoidPtr(pyengine); - + PreviewEngine *preview_engine = dynamic_cast(engine); if (preview_engine) { - BLI_timer_register(1, - preview_engine->delete_preview_engine, - &preview_engine, - nullptr, - preview_engine->preview_engine_lifetime, - true); - CLOG_INFO(LOG_EN, 2, "Engine %016llx", engine); + preview_engine->free(); Py_RETURN_NONE; } diff --git a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc index e4b43d1fcc05..38346736b41e 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc @@ -436,12 +436,12 @@ pxr::VtValue BlenderSceneDelegate::GetLightParamValue(pxr::SdfPath const &id, void BlenderSceneDelegate::clear() { - for (auto it = materials.begin(); it != materials.end(); ++it) { - it->second->remove(); + for (auto &it : materials) { + it.second->remove(); } - for (auto it = objects.begin(); it != objects.end(); ++it) { - it->second->remove(); + for (auto &it : objects) { + it.second->remove(); } materials.clear(); diff --git a/source/blender/render/hydra/scene_delegate/light.cc b/source/blender/render/hydra/scene_delegate/light.cc index 676270802c9e..3b104e7f11e1 100644 --- a/source/blender/render/hydra/scene_delegate/light.cc +++ b/source/blender/render/hydra/scene_delegate/light.cc @@ -7,7 +7,6 @@ #include #include -#include "BKE_light.h" #include "DNA_light_types.h" #include "blender_scene_delegate.h" @@ -80,17 +79,16 @@ void LightData::init() break; } - p_type = light->type; - p_shape = light->area_shape; + p_type = prim_type(light); /* TODO: temporary value, it should be delivered through Python UI */ data[pxr::HdLightTokens->exposure] = 1.0f; } -pxr::TfToken LightData::prim_type() +pxr::TfToken LightData::prim_type(Light *light) { pxr::TfToken ret; - switch (p_type) { + switch (light->type) { case LA_LOCAL: case LA_SPOT: ret = pxr::HdPrimTypeTokens->sphereLight; @@ -101,7 +99,7 @@ pxr::TfToken LightData::prim_type() break; case LA_AREA: - switch (p_shape) { + switch (light->area_shape) { case LA_AREA_SQUARE: case LA_AREA_RECT: ret = pxr::HdPrimTypeTokens->rectLight; @@ -157,13 +155,13 @@ bool LightData::update_visibility(View3D *view3d) void LightData::insert() { CLOG_INFO(LOG_BSD, 2, "%s", id->name); - scene_delegate->GetRenderIndex().InsertSprim(prim_type(), scene_delegate, p_id); + scene_delegate->GetRenderIndex().InsertSprim(p_type, scene_delegate, p_id); } void LightData::remove() { CLOG_INFO(LOG_BSD, 2, "%s", id->name); - scene_delegate->GetRenderIndex().RemoveSprim(prim_type(), p_id); + scene_delegate->GetRenderIndex().RemoveSprim(p_type, p_id); } void LightData::update() @@ -171,7 +169,7 @@ void LightData::update() CLOG_INFO(LOG_BSD, 2, "%s", id->name); Light *light = (Light *)((Object *)id)->data; - if (light->type != p_type || light->area_shape != p_shape) { + if (prim_type(light) != p_type) { remove(); init(); insert(); diff --git a/source/blender/render/hydra/scene_delegate/light.h b/source/blender/render/hydra/scene_delegate/light.h index 59733a5d31ca..f351450c084b 100644 --- a/source/blender/render/hydra/scene_delegate/light.h +++ b/source/blender/render/hydra/scene_delegate/light.h @@ -7,6 +7,8 @@ #include #include +#include "BKE_light.h" + #include "object.h" namespace blender::render::hydra { @@ -24,9 +26,8 @@ class LightData : public ObjectData { private: std::map data; - short p_type; - short p_shape; - pxr::TfToken prim_type(); + pxr::TfToken p_type; + pxr::TfToken prim_type(Light *light); }; } // namespace blender::render::hydra -- 2.30.2 From 44cce409743e3317c97f3a1e332fdde07459e0d9 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Mon, 10 Apr 2023 12:58:15 +0300 Subject: [PATCH 8/9] Code simplification and renamings --- source/blender/render/hydra/preview_engine.cc | 63 ++++++++++--------- source/blender/render/hydra/preview_engine.h | 18 +++--- source/blender/render/hydra/python.cc | 10 +-- 3 files changed, 46 insertions(+), 45 deletions(-) diff --git a/source/blender/render/hydra/preview_engine.cc b/source/blender/render/hydra/preview_engine.cc index 041075a72c4a..34bbe04b8f4f 100644 --- a/source/blender/render/hydra/preview_engine.cc +++ b/source/blender/render/hydra/preview_engine.cc @@ -9,32 +9,47 @@ namespace blender::render::hydra { -std::unique_ptr PreviewEngine::preview_engine; +const double LIFETIME = 180.0; -void PreviewEngine::free() +std::unique_ptr PreviewEngine::instance; + +void PreviewEngine::schedule_free() { - if (preview_engine) { - BLI_timer_register((uintptr_t)preview_engine.get(), - preview_engine->delete_preview_engine, - &preview_engine, - nullptr, - preview_engine->preview_engine_lifetime, - true); - } + instance->render_delegate->Stop(); + + /* Register timer for schedule free PreviewEngine instance */ + BLI_timer_register((uintptr_t)instance.get(), + free_instance, + nullptr, + nullptr, + LIFETIME, + true); } -std::unique_ptr *PreviewEngine::get(RenderEngine *bl_engine, - char *render_delegate_id) +PreviewEngine *PreviewEngine::get_instance(RenderEngine *bl_engine, const std::string &render_delegate_id) { - if (!preview_engine) { - preview_engine = std::make_unique(bl_engine, render_delegate_id); + if (!instance) { + instance = std::make_unique(bl_engine, render_delegate_id); } - if (BLI_timer_is_registered((uintptr_t)preview_engine.get())) { - BLI_timer_unregister((uintptr_t)preview_engine.get()); + if (BLI_timer_is_registered((uintptr_t)instance.get())) { + /* Unregister timer while PreviewEngine is working */ + BLI_timer_unregister((uintptr_t)instance.get()); } - preview_engine->update_bl_engine(bl_engine); + instance->update_bl_engine(bl_engine); - return &preview_engine; + return instance.get(); +} + +double PreviewEngine::free_instance(uintptr_t uuid, void *user_data) +{ + if (!instance->render_task_delegate->is_converged()) { + /* Restart timer if render isn't completed */ + return LIFETIME; + } + + CLOG_INFO(LOG_EN, 2, ""); + instance = nullptr; + return -1; } void PreviewEngine::sync(Depsgraph *depsgraph, @@ -107,18 +122,6 @@ void PreviewEngine::update_bl_engine(RenderEngine *bl_engine) this->bl_engine = bl_engine; } -double PreviewEngine::delete_preview_engine(uintptr_t uuid, void *user_data) -{ - std::unique_ptr *preview_engine = static_cast*>(user_data); - if (preview_engine && preview_engine->get()->render_task_delegate->is_converged()) { - CLOG_INFO(LOG_EN, uuid, "Delete preview engine"); - preview_engine->reset(); - return -1; - } - - return preview_engine_lifetime; -} - void PreviewEngine::update_render_result(const std::string &layer_name, int width, int height, diff --git a/source/blender/render/hydra/preview_engine.h b/source/blender/render/hydra/preview_engine.h index 006d2012f6c2..6d17fddc90ca 100644 --- a/source/blender/render/hydra/preview_engine.h +++ b/source/blender/render/hydra/preview_engine.h @@ -8,17 +8,21 @@ namespace blender::render::hydra { class PreviewEngine : public FinalEngine { + private: + /* Singleton class instance */ + static std::unique_ptr instance; + static double free_instance(uintptr_t uuid, void *user_data); + public: + static PreviewEngine *get_instance(RenderEngine *bl_engine, const std::string &render_delegate_id); + static void schedule_free(); + using FinalEngine::FinalEngine; - static void free(); - static std::unique_ptr *get(RenderEngine *bl_engine = nullptr, - char *render_delegate_id = nullptr); void sync(Depsgraph *depsgraph, bContext *context, pxr::HdRenderSettingsMap &render_settings) override; void render(Depsgraph *depsgraph) override; void update_bl_engine(RenderEngine *bl_engine); - static double delete_preview_engine(uintptr_t uuid, void *user_data); protected: void update_render_result(const std::string &layer_name, @@ -26,12 +30,6 @@ class PreviewEngine : public FinalEngine { int height, std::vector &pixels); - public: - static inline double preview_engine_lifetime = 180.0; - - protected: - static std::unique_ptr preview_engine; - pxr::HdRenderSettingsMap render_settings; }; } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/python.cc b/source/blender/render/hydra/python.cc index cefba258ac69..b97a31b15555 100644 --- a/source/blender/render/hydra/python.cc +++ b/source/blender/render/hydra/python.cc @@ -114,7 +114,7 @@ static PyObject *engine_create_func(PyObject * /*self*/, PyObject *args) engine = new ViewportEngine(bl_engine, render_delegate_id); } else if (STREQ(engine_type, "PREVIEW")) { - engine = PreviewEngine::get(bl_engine, render_delegate_id)->get(); + engine = PreviewEngine::get_instance(bl_engine, render_delegate_id); } else { if (bl_engine->type->flag & RE_USE_GPU_CONTEXT) { @@ -140,11 +140,11 @@ static PyObject *engine_free_func(PyObject * /*self*/, PyObject *args) Engine *engine = (Engine *)PyLong_AsVoidPtr(pyengine); PreviewEngine *preview_engine = dynamic_cast(engine); if (preview_engine) { - preview_engine->free(); - Py_RETURN_NONE; + PreviewEngine::schedule_free(); + } + else { + delete engine; } - - delete engine; CLOG_INFO(LOG_EN, 2, "Engine %016llx", engine); Py_RETURN_NONE; -- 2.30.2 From f73befb068965a7efa7e642ba8903aa90633bcc5 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Mon, 10 Apr 2023 13:42:25 +0300 Subject: [PATCH 9/9] Code improvement, added TODO. --- source/blender/render/hydra/preview_engine.cc | 5 +++-- source/blender/render/hydra/preview_engine.h | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/source/blender/render/hydra/preview_engine.cc b/source/blender/render/hydra/preview_engine.cc index 34bbe04b8f4f..ffb9891952e2 100644 --- a/source/blender/render/hydra/preview_engine.cc +++ b/source/blender/render/hydra/preview_engine.cc @@ -35,7 +35,7 @@ PreviewEngine *PreviewEngine::get_instance(RenderEngine *bl_engine, const std::s /* Unregister timer while PreviewEngine is working */ BLI_timer_unregister((uintptr_t)instance.get()); } - instance->update_bl_engine(bl_engine); + instance->update(bl_engine, render_delegate_id); return instance.get(); } @@ -117,9 +117,10 @@ void PreviewEngine::render(Depsgraph *depsgraph) update_render_result(layer_name, res[0], res[1], pixels); } -void PreviewEngine::update_bl_engine(RenderEngine *bl_engine) +void PreviewEngine::update(RenderEngine *bl_engine, const std::string &render_delegate_id) { this->bl_engine = bl_engine; + /* TODO: recreate render_delegate when render_delegate_id is changed */ } void PreviewEngine::update_render_result(const std::string &layer_name, diff --git a/source/blender/render/hydra/preview_engine.h b/source/blender/render/hydra/preview_engine.h index 6d17fddc90ca..97ee9da93a3e 100644 --- a/source/blender/render/hydra/preview_engine.h +++ b/source/blender/render/hydra/preview_engine.h @@ -22,9 +22,9 @@ class PreviewEngine : public FinalEngine { bContext *context, pxr::HdRenderSettingsMap &render_settings) override; void render(Depsgraph *depsgraph) override; - void update_bl_engine(RenderEngine *bl_engine); - protected: + private: + void update(RenderEngine *bl_engine, const std::string &render_delegate_id); void update_render_result(const std::string &layer_name, int width, int height, -- 2.30.2