Refactor: Make viewport to use ViewRender

This change replaces a bare RenderEngine owned by a viewport
with a VeiwRender. This unlocks a possibility of accessing
RenderResult for viewport renders. Currently it is not done,
but it will be needed for an upcoming work towards unification
of the render passes handling.

Ref #108618

Pull Request: https://projects.blender.org/blender/blender/pulls/110244
This commit is contained in:
Sergey Sharybin
2023-07-18 17:17:48 +02:00
committed by Gitea
parent 78c544a571
commit ae543c01a4
13 changed files with 52 additions and 22 deletions

View File

@@ -2372,7 +2372,7 @@ bool BKE_sculptsession_use_pbvh_draw(const Object *ob, const RegionView3D *rv3d)
if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) {
/* Regular mesh only draws from PBVH without modifiers and shape keys, or for
* external engines that do not have access to the PBVH like Eevee does. */
const bool external_engine = rv3d && rv3d->render_engine != nullptr;
const bool external_engine = rv3d && rv3d->view_render != nullptr;
return !(ss->shapekey_active || ss->deform_modifiers_active || external_engine);
}

View File

@@ -1343,7 +1343,7 @@ static void direct_link_region(BlendDataReader *reader, ARegion *region, int spa
BLO_read_data_address(reader, &rv3d->localvd);
BLO_read_data_address(reader, &rv3d->clipbb);
rv3d->render_engine = nullptr;
rv3d->view_render = nullptr;
rv3d->sms = nullptr;
rv3d->smooth_timer = nullptr;

View File

@@ -244,16 +244,20 @@ static void external_draw_scene_do_v3d(void *vedata)
GPU_apply_state();
/* Create render engine. */
if (!rv3d->render_engine) {
RenderEngine *render_engine = nullptr;
if (!rv3d->view_render) {
RenderEngineType *engine_type = draw_ctx->engine_type;
if (!(engine_type->view_update && engine_type->view_draw)) {
return;
}
RenderEngine *engine = RE_engine_create(engine_type);
engine_type->view_update(engine, draw_ctx->evil_C, draw_ctx->depsgraph);
rv3d->render_engine = engine;
rv3d->view_render = RE_NewViewRender(engine_type);
render_engine = RE_view_engine_get(rv3d->view_render);
engine_type->view_update(render_engine, draw_ctx->evil_C, draw_ctx->depsgraph);
}
else {
render_engine = RE_view_engine_get(rv3d->view_render);
}
/* Rendered draw. */
@@ -262,8 +266,8 @@ static void external_draw_scene_do_v3d(void *vedata)
ED_region_pixelspace(region);
/* Render result draw. */
const RenderEngineType *type = rv3d->render_engine->type;
type->view_draw(rv3d->render_engine, draw_ctx->evil_C, draw_ctx->depsgraph);
const RenderEngineType *type = render_engine->type;
type->view_draw(render_engine, draw_ctx->evil_C, draw_ctx->depsgraph);
GPU_bgl_end();
@@ -272,8 +276,8 @@ static void external_draw_scene_do_v3d(void *vedata)
/* Set render info. */
EXTERNAL_Data *data = static_cast<EXTERNAL_Data *>(vedata);
if (rv3d->render_engine->text[0] != '\0') {
STRNCPY(data->info, rv3d->render_engine->text);
if (render_engine->text[0] != '\0') {
STRNCPY(data->info, render_engine->text);
}
else {
data->info[0] = '\0';

View File

@@ -72,7 +72,7 @@ void ED_render_view3d_update(Depsgraph *depsgraph,
View3D *v3d = static_cast<View3D *>(area->spacedata.first);
RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
RenderEngine *engine = rv3d->render_engine;
RenderEngine *engine = rv3d->view_render ? RE_view_engine_get(rv3d->view_render) : nullptr;
/* call update if the scene changed, or if the render engine
* tagged itself for update (e.g. because it was busy at the

View File

@@ -216,7 +216,7 @@ void ED_view3d_stop_render_preview(wmWindowManager *wm, ARegion *region)
{
RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
if (rv3d->render_engine) {
if (rv3d->view_render) {
#ifdef WITH_PYTHON
BPy_BEGIN_ALLOW_THREADS;
#endif
@@ -227,8 +227,8 @@ void ED_view3d_stop_render_preview(wmWindowManager *wm, ARegion *region)
BPy_END_ALLOW_THREADS;
#endif
RE_engine_free(rv3d->render_engine);
rv3d->render_engine = nullptr;
RE_FreeViewRender(rv3d->view_render);
rv3d->view_render = nullptr;
}
/* A bit overkill but this make sure the viewport is reset completely. (fclem) */
@@ -1082,8 +1082,8 @@ static void view3d_main_region_free(ARegion *region)
MEM_freeN(rv3d->clipbb);
}
if (rv3d->render_engine) {
RE_engine_free(rv3d->render_engine);
if (rv3d->view_render) {
RE_FreeViewRender(rv3d->view_render);
}
if (rv3d->sms) {
@@ -1110,7 +1110,7 @@ static void *view3d_main_region_duplicate(void *poin)
new_rv3d->clipbb = static_cast<BoundBox *>(MEM_dupallocN(rv3d->clipbb));
}
new_rv3d->render_engine = nullptr;
new_rv3d->view_render = nullptr;
new_rv3d->sms = nullptr;
new_rv3d->smooth_timer = nullptr;

View File

@@ -279,7 +279,7 @@ void ED_view3d_smooth_view_ex(
}
/* Skip smooth viewing for external render engine draw. */
if (smooth_viewtx && !(v3d->shading.type == OB_RENDER && rv3d->render_engine)) {
if (smooth_viewtx && !(v3d->shading.type == OB_RENDER && rv3d->view_render)) {
/* original values */
if (sview->camera_old) {

View File

@@ -10,7 +10,7 @@
struct BoundBox;
struct Object;
struct RenderEngine;
struct ViewRender;
struct SmoothView3DStore;
struct SpaceLink;
struct bGPdata;
@@ -58,7 +58,7 @@ typedef struct RegionView3D {
/** Allocated backup of itself while in local-view. */
struct RegionView3D *localvd;
struct RenderEngine *render_engine;
struct ViewRender *view_render;
/** Animated smooth view. */
struct SmoothView3DStore *sms;

View File

@@ -32,6 +32,7 @@ struct RenderResult;
struct ReportList;
struct Scene;
struct ViewLayer;
struct ViewRender;
struct bNode;
struct bNodeTree;
@@ -242,6 +243,7 @@ void RE_engine_register_pass(struct RenderEngine *engine,
bool RE_engine_use_persistent_data(struct RenderEngine *engine);
struct RenderEngine *RE_engine_get(const struct Render *re);
struct RenderEngine *RE_view_engine_get(const struct ViewRender *view_render);
/* Acquire render engine for drawing via its `draw()` callback.
*

View File

@@ -160,6 +160,9 @@ struct Scene;
struct Render *RE_NewSceneRender(const struct Scene *scene);
struct Render *RE_GetSceneRender(const struct Scene *scene);
struct RenderEngineType;
struct ViewRender *RE_NewViewRender(struct RenderEngineType *engine_type);
/* Assign default dummy callbacks. */
/**
@@ -174,6 +177,7 @@ void RE_InitRenderCB(struct Render *re);
* Only call this while you know it will remove the link too.
*/
void RE_FreeRender(struct Render *re);
void RE_FreeViewRender(struct ViewRender *view_render);
/**
* Only called on exit.
*/

View File

@@ -1219,6 +1219,11 @@ RenderEngine *RE_engine_get(const Render *re)
return re->engine;
}
RenderEngine *RE_view_engine_get(const ViewRender *view_render)
{
return view_render->engine;
}
bool RE_engine_draw_acquire(Render *re)
{
RenderEngine *engine = re->engine;

View File

@@ -507,6 +507,13 @@ Render *RE_NewRender(const char *name)
return re;
}
ViewRender *RE_NewViewRender(RenderEngineType *engine_type)
{
ViewRender *view_render = MEM_new<ViewRender>("new view render");
view_render->engine = RE_engine_create(engine_type);
return view_render;
}
/* MAX_ID_NAME + sizeof(Library->name) + space + null-terminator. */
#define MAX_SCENE_RENDER_NAME (MAX_ID_NAME + 1024 + 2)
@@ -560,6 +567,11 @@ void RE_FreeRender(Render *re)
MEM_delete(re);
}
void RE_FreeViewRender(ViewRender *view_render)
{
MEM_delete(view_render);
}
void RE_FreeAllRender()
{
while (!RenderGlobal.render_list.empty()) {

View File

@@ -53,6 +53,9 @@ struct BaseRender {
ThreadMutex engine_draw_mutex = BLI_MUTEX_INITIALIZER;
};
struct ViewRender : public BaseRender {
};
/* Controls state of render, everything that's read-only during render stage */
struct Render : public BaseRender {
/* NOTE: Currently unused, provision for the future.

View File

@@ -406,7 +406,7 @@ static bool wm_draw_region_stereo_set(Main *bmain,
View3D *v3d = area->spacedata.first;
if (v3d->camera && v3d->camera->type == OB_CAMERA) {
RegionView3D *rv3d = region->regiondata;
RenderEngine *engine = rv3d->render_engine;
RenderEngine *engine = rv3d->view_render ? RE_view_engine_get(rv3d->view_render) : NULL;
if (engine && !(engine->type->flag & RE_USE_STEREO_VIEWPORT)) {
return false;
}
@@ -495,7 +495,7 @@ static void wm_region_test_render_do_draw(const Scene *scene,
/* tag region for redraw from render engine preview running inside of it */
if (area->spacetype == SPACE_VIEW3D && region->regiontype == RGN_TYPE_WINDOW) {
RegionView3D *rv3d = region->regiondata;
RenderEngine *engine = rv3d->render_engine;
RenderEngine *engine = rv3d->view_render ? RE_view_engine_get(rv3d->view_render) : NULL;
GPUViewport *viewport = WM_draw_region_get_viewport(region);
if (engine && (engine->flag & RE_ENGINE_DO_DRAW)) {