BLEN-365: Improve creation algorithm of PreviewEngine #21

Merged
Bogdan Nagirniak merged 11 commits from BLEN-365 into hydra-render 2023-04-10 12:44:48 +02:00
12 changed files with 99 additions and 27 deletions
Showing only changes of commit 05576e067b - Show all commits

View File

@ -19,7 +19,7 @@ class CustomHydraRenderEngine(HydraRenderEngine):
def register(cls): def register(cls):
super().register() 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): def get_delegate_settings(self, engine_type):
return { return {
@ -58,6 +58,7 @@ class HydraRenderEngine(bpy.types.RenderEngine):
return return
_bpy_hydra.engine_free(self.engine_ptr) _bpy_hydra.engine_free(self.engine_ptr)
del self.engine_ptr
@classmethod @classmethod
def register(cls): def register(cls):
@ -74,20 +75,18 @@ class HydraRenderEngine(bpy.types.RenderEngine):
# final render # final render
def update(self, data, depsgraph): def update(self, data, depsgraph):
pass
def render(self, depsgraph):
engine_type = 'PREVIEW' if self.is_preview else 'FINAL' engine_type = 'PREVIEW' if self.is_preview else 'FINAL'
self.engine_ptr = _bpy_hydra.engine_create(self.as_pointer(), engine_type, self.delegate_id) self.engine_ptr = _bpy_hydra.engine_create(self.as_pointer(), engine_type, self.delegate_id)
delegate_settings = self.get_delegate_settings(engine_type) 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_sync(self.engine_ptr, depsgraph.as_pointer(), bpy.context.as_pointer(), delegate_settings)
def render(self, depsgraph):
if hasattr(self, 'engine_ptr'):
_bpy_hydra.engine_render(self.engine_ptr, depsgraph.as_pointer()) _bpy_hydra.engine_render(self.engine_ptr, depsgraph.as_pointer())
# viewport render # viewport render
def view_update(self, context, depsgraph): 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) self.engine_ptr = _bpy_hydra.engine_create(self.as_pointer(), 'VIEWPORT', self.delegate_id)
delegate_settings = self.get_delegate_settings('VIEWPORT') delegate_settings = self.get_delegate_settings('VIEWPORT')

View File

@ -42,6 +42,11 @@ Engine::Engine(RenderEngine *bl_engine, const std::string &delegate_id) : bl_eng
} }
engine = std::make_unique<pxr::HdEngine>(); engine = std::make_unique<pxr::HdEngine>();
scene_delegate = std::make_unique<BlenderSceneDelegate>(
render_index.get(),
pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene"),
BlenderSceneDelegate::EngineType::PREVIEW);
DagerD marked this conversation as resolved Outdated

There could be other types of engines

There could be other types of engines
} }
Engine::~Engine() Engine::~Engine()
@ -54,6 +59,7 @@ Engine::~Engine()
render_delegate = nullptr; render_delegate = nullptr;
engine = nullptr; engine = nullptr;
DagerD marked this conversation as resolved Outdated

This function is not needed

This function is not needed
hgi = nullptr; hgi = nullptr;
bl_engine = nullptr;
} }
float Engine::renderer_percent_done() float Engine::renderer_percent_done()

View File

@ -34,12 +34,12 @@ class Engine {
bContext *context, bContext *context,
pxr::HdRenderSettingsMap &render_settings) = 0; pxr::HdRenderSettingsMap &render_settings) = 0;
virtual void render(Depsgraph *depsgraph) = 0; virtual void render(Depsgraph *depsgraph) = 0;
RenderEngine *bl_engine;
protected: protected:
float renderer_percent_done(); float renderer_percent_done();
protected: protected:
RenderEngine *bl_engine;
pxr::HdPluginRenderDelegateUniqueHandle render_delegate; pxr::HdPluginRenderDelegateUniqueHandle render_delegate;
std::unique_ptr<pxr::HdRenderIndex> render_index; std::unique_ptr<pxr::HdRenderIndex> render_index;

View File

@ -16,10 +16,6 @@ void FinalEngine::sync(Depsgraph *depsgraph,
bContext *context, bContext *context,
pxr::HdRenderSettingsMap &render_settings) pxr::HdRenderSettingsMap &render_settings)
{ {
scene_delegate = std::make_unique<BlenderSceneDelegate>(
render_index.get(),
pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene"),
BlenderSceneDelegate::EngineType::FINAL);
scene_delegate->populate(depsgraph, context); scene_delegate->populate(depsgraph, context);
for (auto const &setting : render_settings) { for (auto const &setting : render_settings) {

View File

@ -12,19 +12,37 @@ void PreviewEngine::sync(Depsgraph *depsgraph,
bContext *context, bContext *context,
pxr::HdRenderSettingsMap &render_settings) pxr::HdRenderSettingsMap &render_settings)
{ {
scene_delegate = std::make_unique<BlenderSceneDelegate>( is_synced = false;
render_index.get(),
pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene"), scene_delegate->clear_data();
DagerD marked this conversation as resolved Outdated

Move this to clear()

Move this to clear()
BlenderSceneDelegate::EngineType::PREVIEW); 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); scene_delegate->populate(depsgraph, context);
for (auto &prim : render_index->GetRprimIds()) {
std::cout << "sync populate: " << prim.GetText() << "\n";
}
for (auto const &setting : render_settings) { for (auto const &setting : render_settings) {
render_delegate->SetRenderSetting(setting.first, setting.second); render_delegate->SetRenderSetting(setting.first, setting.second);
} }
is_synced = true;
} }
void PreviewEngine::render(Depsgraph *depsgraph) void PreviewEngine::render(Depsgraph *depsgraph)
{ {
//if (!is_synced) {
// return;
//}
Scene *scene = DEG_get_input_scene(depsgraph); Scene *scene = DEG_get_input_scene(depsgraph);
ViewLayer *view_layer = DEG_get_input_view_layer(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)); CameraData(scene->camera, res, pxr::GfVec4f(0, 0, 1, 1)).gf_camera(pxr::GfVec4f(0, 0, 1, 1));
free_camera_delegate->SetCamera(camera); free_camera_delegate->SetCamera(camera);
//render_task_delegate->clear_renderer_aovs();
render_task_delegate->set_camera_and_viewport(free_camera_delegate->GetCameraId(), render_task_delegate->set_camera_and_viewport(free_camera_delegate->GetCameraId(),
pxr::GfVec4d(0, 0, res[0], res[1])); pxr::GfVec4d(0, 0, res[0], res[1]));
render_task_delegate->set_renderer_aov(pxr::HdAovTokens->color); 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); 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, void PreviewEngine::update_render_result(const std::string &layer_name,
int width, int width,
int height, int height,

View File

@ -14,6 +14,9 @@ class PreviewEngine : public FinalEngine {
bContext *context, bContext *context,
pxr::HdRenderSettingsMap &render_settings) override; pxr::HdRenderSettingsMap &render_settings) override;
void render(Depsgraph *depsgraph) override; void render(Depsgraph *depsgraph) override;
void stop_renderer();
bool is_synced = false;
protected: protected:
void update_render_result(const std::string &layer_name, void update_render_result(const std::string &layer_name,

View File

@ -16,8 +16,25 @@
#include "utils.h" #include "utils.h"
#include "viewport_engine.h" #include "viewport_engine.h"
#include "BLI_timer.h"
namespace blender::render::hydra { namespace blender::render::hydra {
static double preview_engine_lifetime = 60.0;
DagerD marked this conversation as resolved Outdated

move to PreviewEngine class as static

move to PreviewEngine class as static
static PreviewEngine *preview_engine;
DagerD marked this conversation as resolved Outdated

Use unique_ptr

Use unique_ptr
double timer_func(uintptr_t uuid, void *user_data)
{
if (preview_engine) {
preview_engine->stop_renderer();
DagerD marked this conversation as resolved Outdated

add logging

add logging

Do not stop render, check if it is in render process, then return preview_engine_lifetime.

Do not stop render, check if it is in render process, then return preview_engine_lifetime.
delete preview_engine;
preview_engine = nullptr;
return -1;
}
return preview_engine_lifetime;
}
DagerD marked this conversation as resolved Outdated

Move this function to preview_engein.cc
Probably it can be static function of PreviewEngine class

Move this function to preview_engein.cc Probably it can be static function of PreviewEngine class
static PyObject *init_func(PyObject * /*self*/, PyObject *args) static PyObject *init_func(PyObject * /*self*/, PyObject *args)
{ {
CLOG_INFO(LOG_EN, 1, "Init"); CLOG_INFO(LOG_EN, 1, "Init");
@ -107,13 +124,21 @@ static PyObject *engine_create_func(PyObject * /*self*/, PyObject *args)
RenderEngine *bl_engine = (RenderEngine *)PyLong_AsVoidPtr(pyengine); RenderEngine *bl_engine = (RenderEngine *)PyLong_AsVoidPtr(pyengine);
Engine *engine; Engine *engine;
DagerD marked this conversation as resolved Outdated

This block should be like:
engine = PreviewEngine::get(bl_engine, render_delegate_id);

This block should be like: `engine = PreviewEngine::get(bl_engine, render_delegate_id);`
if (STREQ(engine_type, "VIEWPORT")) { if (STREQ(engine_type, "VIEWPORT")) {
engine = new ViewportEngine(bl_engine, render_delegate_id); engine = new ViewportEngine(bl_engine, render_delegate_id);
} }
else if (STREQ(engine_type, "PREVIEW")) { 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;
DagerD marked this conversation as resolved Outdated

Add PreviewEngine::update_engine() instead public usage of bl_engine

Add PreviewEngine::update_engine() instead public usage of bl_engine
CLOG_INFO(LOG_EN, 2, "Engine %016llx %s", engine, engine_type);
return PyLong_FromVoidPtr(preview_engine);
} }
else { else {
if (bl_engine->type->flag & RE_USE_GPU_CONTEXT) { if (bl_engine->type->flag & RE_USE_GPU_CONTEXT) {
@ -137,6 +162,12 @@ static PyObject *engine_free_func(PyObject * /*self*/, PyObject *args)
} }
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; delete engine;
CLOG_INFO(LOG_EN, 2, "Engine %016llx", engine); CLOG_INFO(LOG_EN, 2, "Engine %016llx", engine);

View File

@ -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 } // namespace blender::render::hydra

View File

@ -27,6 +27,7 @@ class RenderTaskDelegate : public pxr::HdSceneDelegate {
pxr::HdTaskSharedPtr get_task(); pxr::HdTaskSharedPtr get_task();
void set_camera_and_viewport(pxr::SdfPath const &cameraId, pxr::GfVec4d const &viewport); void set_camera_and_viewport(pxr::SdfPath const &cameraId, pxr::GfVec4d const &viewport);
void clear_renderer_aovs();
private: private:
pxr::HdxRenderTaskParams task_params; pxr::HdxRenderTaskParams task_params;

View File

@ -477,4 +477,10 @@ pxr::VtValue BlenderSceneDelegate::GetLightParamValue(pxr::SdfPath const &id,
return pxr::VtValue(); return pxr::VtValue();
} }
void BlenderSceneDelegate::clear_data()
DagerD marked this conversation as resolved Outdated

Rename to just "clear"

Rename to just "clear"
{
objects.clear();
materials.clear();
}
} // namespace blender::render::hydra } // namespace blender::render::hydra

View File

@ -29,6 +29,7 @@ class BlenderSceneDelegate : public pxr::HdSceneDelegate {
~BlenderSceneDelegate() override = default; ~BlenderSceneDelegate() override = default;
void populate(Depsgraph *depsgraph, bContext *context); void populate(Depsgraph *depsgraph, bContext *context);
void clear_data();
// delegate methods // delegate methods
pxr::HdMeshTopology GetMeshTopology(pxr::SdfPath const &id) override; pxr::HdMeshTopology GetMeshTopology(pxr::SdfPath const &id) override;

View File

@ -244,12 +244,6 @@ void ViewportEngine::sync(Depsgraph *depsgraph,
bContext *context, bContext *context,
pxr::HdRenderSettingsMap &render_settings) pxr::HdRenderSettingsMap &render_settings)
{ {
if (!scene_delegate) {
scene_delegate = std::make_unique<BlenderSceneDelegate>(
render_index.get(),
pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene"),
BlenderSceneDelegate::EngineType::VIEWPORT);
}
scene_delegate->populate(depsgraph, context); scene_delegate->populate(depsgraph, context);
for (auto const &setting : render_settings) { for (auto const &setting : render_settings) {