Refactor: Introduce ViewRender for viewport renders #110244
|
@ -2372,7 +2372,7 @@ bool BKE_sculptsession_use_pbvh_draw(const Object *ob, const RegionView3D *rv3d)
|
||||||
if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) {
|
if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) {
|
||||||
/* Regular mesh only draws from PBVH without modifiers and shape keys, or for
|
/* 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. */
|
* 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);
|
return !(ss->shapekey_active || ss->deform_modifiers_active || external_engine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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->localvd);
|
||||||
BLO_read_data_address(reader, &rv3d->clipbb);
|
BLO_read_data_address(reader, &rv3d->clipbb);
|
||||||
|
|
||||||
rv3d->render_engine = nullptr;
|
rv3d->view_render = nullptr;
|
||||||
rv3d->sms = nullptr;
|
rv3d->sms = nullptr;
|
||||||
rv3d->smooth_timer = nullptr;
|
rv3d->smooth_timer = nullptr;
|
||||||
|
|
||||||
|
|
|
@ -244,16 +244,20 @@ static void external_draw_scene_do_v3d(void *vedata)
|
||||||
GPU_apply_state();
|
GPU_apply_state();
|
||||||
|
|
||||||
/* Create render engine. */
|
/* Create render engine. */
|
||||||
if (!rv3d->render_engine) {
|
RenderEngine *render_engine = nullptr;
|
||||||
|
if (!rv3d->view_render) {
|
||||||
RenderEngineType *engine_type = draw_ctx->engine_type;
|
RenderEngineType *engine_type = draw_ctx->engine_type;
|
||||||
|
|
||||||
if (!(engine_type->view_update && engine_type->view_draw)) {
|
if (!(engine_type->view_update && engine_type->view_draw)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderEngine *engine = RE_engine_create(engine_type);
|
rv3d->view_render = RE_NewViewRender(engine_type);
|
||||||
engine_type->view_update(engine, draw_ctx->evil_C, draw_ctx->depsgraph);
|
render_engine = RE_view_engine_get(rv3d->view_render);
|
||||||
rv3d->render_engine = engine;
|
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. */
|
/* Rendered draw. */
|
||||||
|
@ -262,8 +266,8 @@ static void external_draw_scene_do_v3d(void *vedata)
|
||||||
ED_region_pixelspace(region);
|
ED_region_pixelspace(region);
|
||||||
|
|
||||||
/* Render result draw. */
|
/* Render result draw. */
|
||||||
const RenderEngineType *type = rv3d->render_engine->type;
|
const RenderEngineType *type = render_engine->type;
|
||||||
type->view_draw(rv3d->render_engine, draw_ctx->evil_C, draw_ctx->depsgraph);
|
type->view_draw(render_engine, draw_ctx->evil_C, draw_ctx->depsgraph);
|
||||||
|
|
||||||
GPU_bgl_end();
|
GPU_bgl_end();
|
||||||
|
|
||||||
|
@ -272,8 +276,8 @@ static void external_draw_scene_do_v3d(void *vedata)
|
||||||
|
|
||||||
/* Set render info. */
|
/* Set render info. */
|
||||||
EXTERNAL_Data *data = static_cast<EXTERNAL_Data *>(vedata);
|
EXTERNAL_Data *data = static_cast<EXTERNAL_Data *>(vedata);
|
||||||
if (rv3d->render_engine->text[0] != '\0') {
|
if (render_engine->text[0] != '\0') {
|
||||||
STRNCPY(data->info, rv3d->render_engine->text);
|
STRNCPY(data->info, render_engine->text);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
data->info[0] = '\0';
|
data->info[0] = '\0';
|
||||||
|
|
|
@ -72,7 +72,7 @@ void ED_render_view3d_update(Depsgraph *depsgraph,
|
||||||
|
|
||||||
View3D *v3d = static_cast<View3D *>(area->spacedata.first);
|
View3D *v3d = static_cast<View3D *>(area->spacedata.first);
|
||||||
RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
|
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
|
/* call update if the scene changed, or if the render engine
|
||||||
* tagged itself for update (e.g. because it was busy at the
|
* tagged itself for update (e.g. because it was busy at the
|
||||||
|
|
|
@ -216,7 +216,7 @@ void ED_view3d_stop_render_preview(wmWindowManager *wm, ARegion *region)
|
||||||
{
|
{
|
||||||
RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
|
RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
|
||||||
|
|
||||||
if (rv3d->render_engine) {
|
if (rv3d->view_render) {
|
||||||
#ifdef WITH_PYTHON
|
#ifdef WITH_PYTHON
|
||||||
BPy_BEGIN_ALLOW_THREADS;
|
BPy_BEGIN_ALLOW_THREADS;
|
||||||
#endif
|
#endif
|
||||||
|
@ -227,8 +227,8 @@ void ED_view3d_stop_render_preview(wmWindowManager *wm, ARegion *region)
|
||||||
BPy_END_ALLOW_THREADS;
|
BPy_END_ALLOW_THREADS;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
RE_engine_free(rv3d->render_engine);
|
RE_FreeViewRender(rv3d->view_render);
|
||||||
rv3d->render_engine = nullptr;
|
rv3d->view_render = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A bit overkill but this make sure the viewport is reset completely. (fclem) */
|
/* 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);
|
MEM_freeN(rv3d->clipbb);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rv3d->render_engine) {
|
if (rv3d->view_render) {
|
||||||
RE_engine_free(rv3d->render_engine);
|
RE_FreeViewRender(rv3d->view_render);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rv3d->sms) {
|
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->clipbb = static_cast<BoundBox *>(MEM_dupallocN(rv3d->clipbb));
|
||||||
}
|
}
|
||||||
|
|
||||||
new_rv3d->render_engine = nullptr;
|
new_rv3d->view_render = nullptr;
|
||||||
new_rv3d->sms = nullptr;
|
new_rv3d->sms = nullptr;
|
||||||
new_rv3d->smooth_timer = nullptr;
|
new_rv3d->smooth_timer = nullptr;
|
||||||
|
|
||||||
|
|
|
@ -279,7 +279,7 @@ void ED_view3d_smooth_view_ex(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Skip smooth viewing for external render engine draw. */
|
/* 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 */
|
/* original values */
|
||||||
if (sview->camera_old) {
|
if (sview->camera_old) {
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
struct BoundBox;
|
struct BoundBox;
|
||||||
struct Object;
|
struct Object;
|
||||||
struct RenderEngine;
|
struct ViewRender;
|
||||||
struct SmoothView3DStore;
|
struct SmoothView3DStore;
|
||||||
struct SpaceLink;
|
struct SpaceLink;
|
||||||
struct bGPdata;
|
struct bGPdata;
|
||||||
|
@ -58,7 +58,7 @@ typedef struct RegionView3D {
|
||||||
|
|
||||||
/** Allocated backup of itself while in local-view. */
|
/** Allocated backup of itself while in local-view. */
|
||||||
struct RegionView3D *localvd;
|
struct RegionView3D *localvd;
|
||||||
struct RenderEngine *render_engine;
|
struct ViewRender *view_render;
|
||||||
|
|
||||||
/** Animated smooth view. */
|
/** Animated smooth view. */
|
||||||
struct SmoothView3DStore *sms;
|
struct SmoothView3DStore *sms;
|
||||||
|
|
|
@ -34,6 +34,7 @@ set(SRC
|
||||||
intern/multires_bake.cc
|
intern/multires_bake.cc
|
||||||
intern/pipeline.cc
|
intern/pipeline.cc
|
||||||
intern/render_result.cc
|
intern/render_result.cc
|
||||||
|
intern/render_types.cc
|
||||||
intern/texture_image.c
|
intern/texture_image.c
|
||||||
intern/texture_margin.cc
|
intern/texture_margin.cc
|
||||||
intern/texture_pointdensity.c
|
intern/texture_pointdensity.c
|
||||||
|
|
|
@ -32,6 +32,7 @@ struct RenderResult;
|
||||||
struct ReportList;
|
struct ReportList;
|
||||||
struct Scene;
|
struct Scene;
|
||||||
struct ViewLayer;
|
struct ViewLayer;
|
||||||
|
struct ViewRender;
|
||||||
struct bNode;
|
struct bNode;
|
||||||
struct bNodeTree;
|
struct bNodeTree;
|
||||||
|
|
||||||
|
@ -242,6 +243,7 @@ void RE_engine_register_pass(struct RenderEngine *engine,
|
||||||
bool RE_engine_use_persistent_data(struct RenderEngine *engine);
|
bool RE_engine_use_persistent_data(struct RenderEngine *engine);
|
||||||
|
|
||||||
struct RenderEngine *RE_engine_get(const struct Render *re);
|
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.
|
/* Acquire render engine for drawing via its `draw()` callback.
|
||||||
*
|
*
|
||||||
|
|
|
@ -160,6 +160,9 @@ struct Scene;
|
||||||
struct Render *RE_NewSceneRender(const struct Scene *scene);
|
struct Render *RE_NewSceneRender(const struct Scene *scene);
|
||||||
struct Render *RE_GetSceneRender(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. */
|
/* 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.
|
* Only call this while you know it will remove the link too.
|
||||||
*/
|
*/
|
||||||
void RE_FreeRender(struct Render *re);
|
void RE_FreeRender(struct Render *re);
|
||||||
|
void RE_FreeViewRender(struct ViewRender *view_render);
|
||||||
/**
|
/**
|
||||||
* Only called on exit.
|
* Only called on exit.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1219,14 +1219,34 @@ RenderEngine *RE_engine_get(const Render *re)
|
||||||
return re->engine;
|
return re->engine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RenderEngine *RE_view_engine_get(const ViewRender *view_render)
|
||||||
|
{
|
||||||
|
return view_render->engine;
|
||||||
|
}
|
||||||
|
|
||||||
bool RE_engine_draw_acquire(Render *re)
|
bool RE_engine_draw_acquire(Render *re)
|
||||||
{
|
{
|
||||||
BLI_mutex_lock(&re->engine_draw_mutex);
|
|
||||||
|
|
||||||
RenderEngine *engine = re->engine;
|
RenderEngine *engine = re->engine;
|
||||||
|
|
||||||
if (engine == nullptr || engine->type->draw == nullptr ||
|
if (!engine) {
|
||||||
(engine->flag & RE_ENGINE_CAN_DRAW) == 0) {
|
/* \No engine-side drawing if the engine does not exist. */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!engine->type->draw) {
|
||||||
|
/* Required callbacks are not implemented on the engine side. */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Lock before checking the flag, to avoid possible conflicts with the render thread. */
|
||||||
|
BLI_mutex_lock(&re->engine_draw_mutex);
|
||||||
|
|
||||||
|
if ((engine->flag & RE_ENGINE_CAN_DRAW) == 0) {
|
||||||
|
/* The rendering is not started yet, or has finished.
|
||||||
|
*
|
||||||
|
* In the former case there will nothing to be drawn, so can simply use RenderResult drawing
|
||||||
|
* pipeline. In the latter case the engine has destroyed its display-only resources (textures,
|
||||||
|
* graphics interops, etc..) so need to use use the RenderResult drawing pipeline. */
|
||||||
BLI_mutex_unlock(&re->engine_draw_mutex);
|
BLI_mutex_unlock(&re->engine_draw_mutex);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <forward_list>
|
||||||
|
|
||||||
#include "DNA_anim_types.h"
|
#include "DNA_anim_types.h"
|
||||||
#include "DNA_collection_types.h"
|
#include "DNA_collection_types.h"
|
||||||
|
@ -127,8 +128,8 @@
|
||||||
|
|
||||||
/* here we store all renders */
|
/* here we store all renders */
|
||||||
static struct {
|
static struct {
|
||||||
ListBase renderlist;
|
std::forward_list<Render *> render_list;
|
||||||
} RenderGlobal = {{nullptr, nullptr}};
|
} RenderGlobal;
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
||||||
|
@ -297,7 +298,7 @@ static bool render_scene_has_layers_to_render(Scene *scene, ViewLayer *single_la
|
||||||
Render *RE_GetRender(const char *name)
|
Render *RE_GetRender(const char *name)
|
||||||
{
|
{
|
||||||
/* search for existing renders */
|
/* search for existing renders */
|
||||||
LISTBASE_FOREACH (Render *, re, &RenderGlobal.renderlist) {
|
for (Render *re : RenderGlobal.render_list) {
|
||||||
if (STREQLEN(re->name, name, RE_MAXNAME)) {
|
if (STREQLEN(re->name, name, RE_MAXNAME)) {
|
||||||
return re;
|
return re;
|
||||||
}
|
}
|
||||||
|
@ -496,13 +497,9 @@ Render *RE_NewRender(const char *name)
|
||||||
if (re == nullptr) {
|
if (re == nullptr) {
|
||||||
|
|
||||||
/* new render data struct */
|
/* new render data struct */
|
||||||
re = MEM_cnew<Render>("new render");
|
re = MEM_new<Render>("new render");
|
||||||
BLI_addtail(&RenderGlobal.renderlist, re);
|
RenderGlobal.render_list.push_front(re);
|
||||||
STRNCPY(re->name, name);
|
STRNCPY(re->name, name);
|
||||||
BLI_rw_mutex_init(&re->resultmutex);
|
|
||||||
BLI_mutex_init(&re->engine_draw_mutex);
|
|
||||||
BLI_mutex_init(&re->highlighted_tiles_mutex);
|
|
||||||
BLI_mutex_init(&re->gpu_compositor_mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RE_InitRenderCB(re);
|
RE_InitRenderCB(re);
|
||||||
|
@ -510,6 +507,13 @@ Render *RE_NewRender(const char *name)
|
||||||
return re;
|
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. */
|
/* MAX_ID_NAME + sizeof(Library->name) + space + null-terminator. */
|
||||||
#define MAX_SCENE_RENDER_NAME (MAX_ID_NAME + 1024 + 2)
|
#define MAX_SCENE_RENDER_NAME (MAX_ID_NAME + 1024 + 2)
|
||||||
|
|
||||||
|
@ -558,41 +562,20 @@ void RE_InitRenderCB(Render *re)
|
||||||
|
|
||||||
void RE_FreeRender(Render *re)
|
void RE_FreeRender(Render *re)
|
||||||
{
|
{
|
||||||
if (re->engine) {
|
RenderGlobal.render_list.remove(re);
|
||||||
RE_engine_free(re->engine);
|
|
||||||
}
|
|
||||||
|
|
||||||
RE_compositor_free(*re);
|
MEM_delete(re);
|
||||||
|
}
|
||||||
|
|
||||||
RE_blender_gpu_context_free(re);
|
void RE_FreeViewRender(ViewRender *view_render)
|
||||||
RE_system_gpu_context_free(re);
|
{
|
||||||
|
MEM_delete(view_render);
|
||||||
BLI_rw_mutex_end(&re->resultmutex);
|
|
||||||
BLI_mutex_end(&re->engine_draw_mutex);
|
|
||||||
BLI_mutex_end(&re->highlighted_tiles_mutex);
|
|
||||||
BLI_mutex_end(&re->gpu_compositor_mutex);
|
|
||||||
|
|
||||||
BKE_curvemapping_free_data(&re->r.mblur_shutter_curve);
|
|
||||||
|
|
||||||
if (re->highlighted_tiles != nullptr) {
|
|
||||||
BLI_gset_free(re->highlighted_tiles, MEM_freeN);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* main dbase can already be invalid now, some database-free code checks it */
|
|
||||||
re->main = nullptr;
|
|
||||||
re->scene = nullptr;
|
|
||||||
|
|
||||||
render_result_free(re->result);
|
|
||||||
render_result_free(re->pushedresult);
|
|
||||||
|
|
||||||
BLI_remlink(&RenderGlobal.renderlist, re);
|
|
||||||
MEM_freeN(re);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RE_FreeAllRender()
|
void RE_FreeAllRender()
|
||||||
{
|
{
|
||||||
while (RenderGlobal.renderlist.first) {
|
while (!RenderGlobal.render_list.empty()) {
|
||||||
RE_FreeRender(static_cast<Render *>(RenderGlobal.renderlist.first));
|
RE_FreeRender(static_cast<Render *>(RenderGlobal.render_list.front()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WITH_FREESTYLE
|
#ifdef WITH_FREESTYLE
|
||||||
|
@ -603,7 +586,7 @@ void RE_FreeAllRender()
|
||||||
|
|
||||||
void RE_FreeAllRenderResults()
|
void RE_FreeAllRenderResults()
|
||||||
{
|
{
|
||||||
LISTBASE_FOREACH (Render *, re, &RenderGlobal.renderlist) {
|
for (Render *re : RenderGlobal.render_list) {
|
||||||
render_result_free(re->result);
|
render_result_free(re->result);
|
||||||
render_result_free(re->pushedresult);
|
render_result_free(re->pushedresult);
|
||||||
|
|
||||||
|
@ -615,7 +598,7 @@ void RE_FreeAllRenderResults()
|
||||||
|
|
||||||
void RE_FreeAllPersistentData()
|
void RE_FreeAllPersistentData()
|
||||||
{
|
{
|
||||||
LISTBASE_FOREACH (Render *, re, &RenderGlobal.renderlist) {
|
for (Render *re : RenderGlobal.render_list) {
|
||||||
if (re->engine != nullptr) {
|
if (re->engine != nullptr) {
|
||||||
BLI_assert(!(re->engine->flag & RE_ENGINE_RENDERING));
|
BLI_assert(!(re->engine->flag & RE_ENGINE_RENDERING));
|
||||||
RE_engine_free(re->engine);
|
RE_engine_free(re->engine);
|
||||||
|
@ -644,7 +627,7 @@ static void re_gpu_texture_caches_free(Render *re)
|
||||||
|
|
||||||
void RE_FreeGPUTextureCaches()
|
void RE_FreeGPUTextureCaches()
|
||||||
{
|
{
|
||||||
LISTBASE_FOREACH (Render *, re, &RenderGlobal.renderlist) {
|
for (Render *re : RenderGlobal.render_list) {
|
||||||
re_gpu_texture_caches_free(re);
|
re_gpu_texture_caches_free(re);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -655,7 +638,7 @@ void RE_FreeUnusedGPUResources()
|
||||||
|
|
||||||
wmWindowManager *wm = static_cast<wmWindowManager *>(G_MAIN->wm.first);
|
wmWindowManager *wm = static_cast<wmWindowManager *>(G_MAIN->wm.first);
|
||||||
|
|
||||||
LISTBASE_FOREACH (Render *, re, &RenderGlobal.renderlist) {
|
for (Render *re : RenderGlobal.render_list) {
|
||||||
bool do_free = true;
|
bool do_free = true;
|
||||||
|
|
||||||
LISTBASE_FOREACH (const wmWindow *, win, &wm->windows) {
|
LISTBASE_FOREACH (const wmWindow *, win, &wm->windows) {
|
||||||
|
@ -728,7 +711,7 @@ void RE_FreePersistentData(const Scene *scene)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LISTBASE_FOREACH (Render *, re, &RenderGlobal.renderlist) {
|
for (Render *re : RenderGlobal.render_list) {
|
||||||
re_free_persistent_data(re);
|
re_free_persistent_data(re);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1949,7 +1932,6 @@ static bool use_eevee_for_freestyle_render(Render *re)
|
||||||
|
|
||||||
void RE_RenderFreestyleStrokes(Render *re, Main *bmain, Scene *scene, const bool render)
|
void RE_RenderFreestyleStrokes(Render *re, Main *bmain, Scene *scene, const bool render)
|
||||||
{
|
{
|
||||||
re->result_ok = false;
|
|
||||||
if (render_init_from_main(re, &scene->r, bmain, scene, nullptr, nullptr, false, false)) {
|
if (render_init_from_main(re, &scene->r, bmain, scene, nullptr, nullptr, false, false)) {
|
||||||
if (render) {
|
if (render) {
|
||||||
char scene_engine[32];
|
char scene_engine[32];
|
||||||
|
@ -1963,7 +1945,6 @@ void RE_RenderFreestyleStrokes(Render *re, Main *bmain, Scene *scene, const bool
|
||||||
change_renderdata_engine(re, scene_engine);
|
change_renderdata_engine(re, scene_engine);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
re->result_ok = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RE_RenderFreestyleExternal(Render *re)
|
void RE_RenderFreestyleExternal(Render *re)
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
/* SPDX-FileCopyrightText: 2023 Blender Foundation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
/** \file
|
||||||
|
* \ingroup render
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "render_types.h"
|
||||||
|
|
||||||
|
#include "BLI_ghash.h"
|
||||||
|
|
||||||
|
#include "BKE_colortools.h"
|
||||||
|
|
||||||
|
#include "RE_compositor.hh"
|
||||||
|
#include "RE_engine.h"
|
||||||
|
|
||||||
|
#include "render_result.h"
|
||||||
|
|
||||||
|
BaseRender::~BaseRender()
|
||||||
|
{
|
||||||
|
if (engine) {
|
||||||
|
RE_engine_free(engine);
|
||||||
|
}
|
||||||
|
|
||||||
|
render_result_free(result);
|
||||||
|
|
||||||
|
BLI_rw_mutex_end(&resultmutex);
|
||||||
|
BLI_mutex_end(&engine_draw_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
Render::~Render()
|
||||||
|
{
|
||||||
|
RE_compositor_free(*this);
|
||||||
|
|
||||||
|
RE_blender_gpu_context_free(this);
|
||||||
|
RE_system_gpu_context_free(this);
|
||||||
|
|
||||||
|
BLI_mutex_end(&highlighted_tiles_mutex);
|
||||||
|
BLI_mutex_end(&gpu_compositor_mutex);
|
||||||
|
|
||||||
|
BKE_curvemapping_free_data(&r.mblur_shutter_curve);
|
||||||
|
|
||||||
|
if (highlighted_tiles != nullptr) {
|
||||||
|
BLI_gset_free(highlighted_tiles, MEM_freeN);
|
||||||
|
}
|
||||||
|
|
||||||
|
render_result_free(pushedresult);
|
||||||
|
}
|
|
@ -30,109 +30,123 @@ struct ReportList;
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct HighlightedTile {
|
struct HighlightedTile {
|
||||||
rcti rect;
|
rcti rect;
|
||||||
} HighlightedTile;
|
};
|
||||||
|
|
||||||
/* controls state of render, everything that's read-only during render stage */
|
struct BaseRender {
|
||||||
struct Render {
|
BaseRender() = default;
|
||||||
struct Render *next, *prev;
|
virtual ~BaseRender();
|
||||||
char name[RE_MAXNAME];
|
|
||||||
int slot;
|
|
||||||
|
|
||||||
/* state settings */
|
/* Result of rendering */
|
||||||
short flag;
|
RenderResult *result = nullptr;
|
||||||
bool ok, result_ok;
|
|
||||||
|
|
||||||
/* result of rendering */
|
/* Read/write mutex, all internal code that writes to the `result` must use a
|
||||||
RenderResult *result;
|
* write lock, all external code must use a read lock. Internal code is assumed
|
||||||
/* if render with single-layer option, other rendered layers are stored here */
|
* to not conflict with writes, so no lock used for that. */
|
||||||
RenderResult *pushedresult;
|
ThreadRWMutex resultmutex = BLI_RWLOCK_INITIALIZER;
|
||||||
/** A list of #RenderResults, for full-samples. */
|
|
||||||
ListBase fullresult;
|
/* Render engine. */
|
||||||
/* read/write mutex, all internal code that writes to re->result must use a
|
struct RenderEngine *engine = nullptr;
|
||||||
* write lock, all external code must use a read lock. internal code is assumed
|
|
||||||
* to not conflict with writes, so no lock used for that */
|
|
||||||
ThreadRWMutex resultmutex;
|
|
||||||
/* True if result has GPU textures, to quickly skip cache clear. */
|
|
||||||
bool result_has_gpu_texture_caches;
|
|
||||||
|
|
||||||
/* Guard for drawing render result using engine's `draw()` callback. */
|
/* Guard for drawing render result using engine's `draw()` callback. */
|
||||||
ThreadMutex engine_draw_mutex;
|
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.
|
||||||
|
* Add these now to allow the guarded memory allocator to catch C-specific function calls. */
|
||||||
|
Render() = default;
|
||||||
|
virtual ~Render();
|
||||||
|
|
||||||
|
char name[RE_MAXNAME] = "";
|
||||||
|
int slot = 0;
|
||||||
|
|
||||||
|
/* state settings */
|
||||||
|
short flag = 0;
|
||||||
|
bool ok = false;
|
||||||
|
|
||||||
|
/* if render with single-layer option, other rendered layers are stored here */
|
||||||
|
RenderResult *pushedresult = nullptr;
|
||||||
|
/** A list of #RenderResults, for full-samples. */
|
||||||
|
ListBase fullresult = {nullptr, nullptr};
|
||||||
|
/* True if result has GPU textures, to quickly skip cache clear. */
|
||||||
|
bool result_has_gpu_texture_caches = false;
|
||||||
|
|
||||||
/** Window size, display rect, viewplane.
|
/** Window size, display rect, viewplane.
|
||||||
* \note Buffer width and height with percentage applied
|
* \note Buffer width and height with percentage applied
|
||||||
* without border & crop. convert to long before multiplying together to avoid overflow. */
|
* without border & crop. convert to long before multiplying together to avoid overflow. */
|
||||||
int winx, winy;
|
int winx = 0, winy = 0;
|
||||||
rcti disprect; /* part within winx winy */
|
rcti disprect = {0, 0, 0, 0}; /* part within winx winy */
|
||||||
rctf viewplane; /* mapped on winx winy */
|
rctf viewplane = {0, 0, 0, 0}; /* mapped on winx winy */
|
||||||
|
|
||||||
/* final picture width and height (within disprect) */
|
/* final picture width and height (within disprect) */
|
||||||
int rectx, recty;
|
int rectx = 0, recty = 0;
|
||||||
|
|
||||||
/* Camera transform, only used by Freestyle. */
|
/* Camera transform, only used by Freestyle. */
|
||||||
float winmat[4][4];
|
float winmat[4][4] = {{0}};
|
||||||
|
|
||||||
/* Clipping. */
|
/* Clipping. */
|
||||||
float clip_start;
|
float clip_start = 0.0f;
|
||||||
float clip_end;
|
float clip_end = 0.0f;
|
||||||
|
|
||||||
/* main, scene, and its full copy of renderdata and world */
|
/* main, scene, and its full copy of renderdata and world */
|
||||||
struct Main *main;
|
struct Main *main = nullptr;
|
||||||
Scene *scene;
|
Scene *scene = nullptr;
|
||||||
RenderData r;
|
RenderData r = {};
|
||||||
char single_view_layer[MAX_NAME];
|
char single_view_layer[MAX_NAME] = "";
|
||||||
struct Object *camera_override;
|
struct Object *camera_override = nullptr;
|
||||||
|
|
||||||
ThreadMutex highlighted_tiles_mutex;
|
ThreadMutex highlighted_tiles_mutex = BLI_MUTEX_INITIALIZER;
|
||||||
struct GSet *highlighted_tiles;
|
struct GSet *highlighted_tiles = nullptr;
|
||||||
|
|
||||||
/* render engine */
|
|
||||||
struct RenderEngine *engine;
|
|
||||||
|
|
||||||
/* NOTE: This is a minimal dependency graph and evaluated scene which is enough to access view
|
/* NOTE: This is a minimal dependency graph and evaluated scene which is enough to access view
|
||||||
* layer visibility and use for postprocessing (compositor and sequencer). */
|
* layer visibility and use for postprocessing (compositor and sequencer). */
|
||||||
struct Depsgraph *pipeline_depsgraph;
|
struct Depsgraph *pipeline_depsgraph = nullptr;
|
||||||
Scene *pipeline_scene_eval;
|
Scene *pipeline_scene_eval = nullptr;
|
||||||
|
|
||||||
/* Realtime GPU Compositor. */
|
/* Realtime GPU Compositor. */
|
||||||
blender::render::RealtimeCompositor *gpu_compositor;
|
blender::render::RealtimeCompositor *gpu_compositor = nullptr;
|
||||||
ThreadMutex gpu_compositor_mutex;
|
ThreadMutex gpu_compositor_mutex = BLI_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
/* callbacks */
|
/* callbacks */
|
||||||
void (*display_init)(void *handle, RenderResult *rr);
|
void (*display_init)(void *handle, RenderResult *rr) = nullptr;
|
||||||
void *dih;
|
void *dih = nullptr;
|
||||||
void (*display_clear)(void *handle, RenderResult *rr);
|
void (*display_clear)(void *handle, RenderResult *rr) = nullptr;
|
||||||
void *dch;
|
void *dch = nullptr;
|
||||||
void (*display_update)(void *handle, RenderResult *rr, rcti *rect);
|
void (*display_update)(void *handle, RenderResult *rr, rcti *rect) = nullptr;
|
||||||
void *duh;
|
void *duh = nullptr;
|
||||||
void (*current_scene_update)(void *handle, struct Scene *scene);
|
void (*current_scene_update)(void *handle, struct Scene *scene) = nullptr;
|
||||||
void *suh;
|
void *suh = nullptr;
|
||||||
|
|
||||||
void (*stats_draw)(void *handle, RenderStats *ri);
|
void (*stats_draw)(void *handle, RenderStats *ri) = nullptr;
|
||||||
void *sdh;
|
void *sdh = nullptr;
|
||||||
void (*progress)(void *handle, float i);
|
void (*progress)(void *handle, float i) = nullptr;
|
||||||
void *prh;
|
void *prh = nullptr;
|
||||||
|
|
||||||
void (*draw_lock)(void *handle, bool lock);
|
void (*draw_lock)(void *handle, bool lock) = nullptr;
|
||||||
void *dlh;
|
void *dlh = nullptr;
|
||||||
bool (*test_break)(void *handle);
|
bool (*test_break)(void *handle) = nullptr;
|
||||||
void *tbh;
|
void *tbh = nullptr;
|
||||||
|
|
||||||
RenderStats i;
|
RenderStats i = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optional report list which may be null (borrowed memory).
|
* Optional report list which may be null (borrowed memory).
|
||||||
* Callers to rendering functions are responsible for setting can clearing, see: #RE_SetReports.
|
* Callers to rendering functions are responsible for setting can clearing, see: #RE_SetReports.
|
||||||
*/
|
*/
|
||||||
struct ReportList *reports;
|
struct ReportList *reports = nullptr;
|
||||||
|
|
||||||
void **movie_ctx_arr;
|
void **movie_ctx_arr = nullptr;
|
||||||
char viewname[MAX_NAME];
|
char viewname[MAX_NAME] = "";
|
||||||
|
|
||||||
/* TODO: replace by a whole draw manager. */
|
/* TODO: replace by a whole draw manager. */
|
||||||
void *system_gpu_context;
|
void *system_gpu_context = nullptr;
|
||||||
void *blender_gpu_context;
|
void *blender_gpu_context = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* **************** defines ********************* */
|
/* **************** defines ********************* */
|
||||||
|
|
|
@ -406,7 +406,7 @@ static bool wm_draw_region_stereo_set(Main *bmain,
|
||||||
View3D *v3d = area->spacedata.first;
|
View3D *v3d = area->spacedata.first;
|
||||||
if (v3d->camera && v3d->camera->type == OB_CAMERA) {
|
if (v3d->camera && v3d->camera->type == OB_CAMERA) {
|
||||||
RegionView3D *rv3d = region->regiondata;
|
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)) {
|
if (engine && !(engine->type->flag & RE_USE_STEREO_VIEWPORT)) {
|
||||||
return false;
|
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 */
|
/* tag region for redraw from render engine preview running inside of it */
|
||||||
if (area->spacetype == SPACE_VIEW3D && region->regiontype == RGN_TYPE_WINDOW) {
|
if (area->spacetype == SPACE_VIEW3D && region->regiontype == RGN_TYPE_WINDOW) {
|
||||||
RegionView3D *rv3d = region->regiondata;
|
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);
|
GPUViewport *viewport = WM_draw_region_get_viewport(region);
|
||||||
|
|
||||||
if (engine && (engine->flag & RE_ENGINE_DO_DRAW)) {
|
if (engine && (engine->flag & RE_ENGINE_DO_DRAW)) {
|
||||||
|
|
Loading…
Reference in New Issue