DRW / Render: Add support for render pipeline in drawmanager.
For simplicity we choose to execute the rendering of Opengl engines in the main thread and block the interface. This might be addressed in the future at least for video rendering. A drawmanager wrapper (DRW_render_to_image) is called by the render pipeline to set up the Opengl state and then call the specific draw_engine->render_to_image function.
This commit is contained in:
parent
01a62515cb
commit
b6dbd8723c
|
@ -46,6 +46,7 @@ struct View3D;
|
|||
struct rcti;
|
||||
struct GPUOffScreen;
|
||||
struct GPUViewport;
|
||||
struct RenderEngine;
|
||||
struct RenderEngineType;
|
||||
struct WorkSpace;
|
||||
|
||||
|
@ -67,6 +68,7 @@ typedef struct DefaultTextureList {
|
|||
void DRW_engines_register(void);
|
||||
void DRW_engines_free(void);
|
||||
|
||||
bool DRW_engine_render_support(struct DrawEngineType *draw_engine_type);
|
||||
void DRW_engine_register(struct DrawEngineType *draw_engine_type);
|
||||
void DRW_engine_viewport_data_size_get(
|
||||
const void *engine_type,
|
||||
|
|
|
@ -264,6 +264,7 @@ DrawEngineType draw_engine_basic_type = {
|
|||
&basic_draw_scene,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
||||
/* Note: currently unused, we may want to register so we can see this when debugging the view. */
|
||||
|
|
|
@ -949,6 +949,7 @@ DrawEngineType draw_engine_clay_type = {
|
|||
&clay_draw_scene,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
||||
RenderEngineType DRW_engine_viewport_clay_type = {
|
||||
|
|
|
@ -218,6 +218,7 @@ DrawEngineType draw_engine_external_type = {
|
|||
&external_draw_scene,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
||||
/* Note: currently unused, we should not register unless we want to see this when debugging the view. */
|
||||
|
|
|
@ -139,6 +139,8 @@ typedef struct DrawEngineType {
|
|||
|
||||
void (*view_update)(void *vedata);
|
||||
void (*id_update)(void *vedata, struct ID *id);
|
||||
|
||||
void (*render_to_image)(void *vedata, struct RenderEngine *engine, struct Depsgraph *graph);
|
||||
} DrawEngineType;
|
||||
|
||||
#ifndef __DRW_ENGINE_H__
|
||||
|
@ -386,6 +388,11 @@ struct DefaultTextureList *DRW_viewport_texture_list_get(void);
|
|||
|
||||
void DRW_viewport_request_redraw(void);
|
||||
|
||||
void DRW_render_to_image(struct RenderEngine *re, struct Depsgraph *depsgraph);
|
||||
void DRW_render_object_iter(
|
||||
void *vedata, struct RenderEngine *engine, struct Depsgraph *graph,
|
||||
void (*callback)(void *vedata, struct Object *ob, struct RenderEngine *engine, struct Depsgraph *graph));
|
||||
|
||||
/* ViewLayers */
|
||||
void *DRW_view_layer_engine_data_get(DrawEngineType *engine_type);
|
||||
void **DRW_view_layer_engine_data_ensure(DrawEngineType *engine_type, void (*callback)(void *storage));
|
||||
|
|
|
@ -2365,7 +2365,9 @@ void DRW_framebuffer_init(
|
|||
}
|
||||
}
|
||||
|
||||
GPU_framebuffer_bind(DST.default_framebuffer);
|
||||
if (DST.default_framebuffer != NULL) {
|
||||
GPU_framebuffer_bind(DST.default_framebuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2626,14 +2628,17 @@ static void drw_viewport_var_init(void)
|
|||
DST.default_framebuffer = NULL;
|
||||
DST.vmempool = NULL;
|
||||
}
|
||||
/* Refresh DST.screenvecs */
|
||||
copy_v3_v3(DST.screenvecs[0], rv3d->viewinv[0]);
|
||||
copy_v3_v3(DST.screenvecs[1], rv3d->viewinv[1]);
|
||||
normalize_v3(DST.screenvecs[0]);
|
||||
normalize_v3(DST.screenvecs[1]);
|
||||
|
||||
/* Refresh DST.pixelsize */
|
||||
DST.pixsize = rv3d->pixsize;
|
||||
if (rv3d != NULL) {
|
||||
/* Refresh DST.screenvecs */
|
||||
copy_v3_v3(DST.screenvecs[0], rv3d->viewinv[0]);
|
||||
copy_v3_v3(DST.screenvecs[1], rv3d->viewinv[1]);
|
||||
normalize_v3(DST.screenvecs[0]);
|
||||
normalize_v3(DST.screenvecs[1]);
|
||||
|
||||
/* Refresh DST.pixelsize */
|
||||
DST.pixsize = rv3d->pixsize;
|
||||
}
|
||||
|
||||
/* Reset facing */
|
||||
DST.frontface = GL_CCW;
|
||||
|
@ -2664,6 +2669,7 @@ void DRW_viewport_matrix_get(float mat[4][4], DRWViewportMatrixType type)
|
|||
copy_m4_m4(mat, viewport_matrix_override.mat[type]);
|
||||
}
|
||||
else {
|
||||
BLI_assert(rv3d != NULL); /* Can't use this in render mode. */
|
||||
switch (type) {
|
||||
case DRW_MAT_PERS:
|
||||
copy_m4_m4(mat, rv3d->persmat);
|
||||
|
@ -2704,6 +2710,7 @@ void DRW_viewport_matrix_override_unset(DRWViewportMatrixType type)
|
|||
bool DRW_viewport_is_persp_get(void)
|
||||
{
|
||||
RegionView3D *rv3d = DST.draw_ctx.rv3d;
|
||||
BLI_assert(rv3d);
|
||||
return rv3d->is_persp;
|
||||
}
|
||||
|
||||
|
@ -3422,9 +3429,7 @@ void DRW_draw_render_loop_ex(
|
|||
/* Init engines */
|
||||
drw_engines_init();
|
||||
|
||||
/* TODO : tag to refresh by the dependency graph */
|
||||
/* ideally only refresh when objects are added/removed */
|
||||
/* or render properties / materials change */
|
||||
/* Cache filling */
|
||||
{
|
||||
PROFILE_START(stime);
|
||||
drw_engines_cache_init();
|
||||
|
@ -3569,6 +3574,70 @@ void DRW_draw_render_loop_offscreen(
|
|||
GPU_offscreen_bind(ofs, false);
|
||||
}
|
||||
|
||||
void DRW_render_to_image(RenderEngine *re, struct Depsgraph *depsgraph)
|
||||
{
|
||||
Scene *scene = DEG_get_evaluated_scene(depsgraph);
|
||||
ViewLayer *view_layer = DEG_get_evaluated_view_layer(depsgraph);
|
||||
RenderEngineType *engine_type = re->type;
|
||||
DrawEngineType *draw_engine_type = engine_type->draw_engine;
|
||||
RenderData *r = &scene->r;
|
||||
|
||||
/* Reset before using it. */
|
||||
memset(&DST, 0x0, sizeof(DST));
|
||||
DST.options.is_image_render = true;
|
||||
|
||||
DST.draw_ctx = (DRWContextState){
|
||||
NULL, NULL, NULL, scene, view_layer, OBACT(view_layer), engine_type, depsgraph, NULL
|
||||
};
|
||||
|
||||
DST.viewport = GPU_viewport_create();
|
||||
const int size[2] = {(r->size * r->xsch) / 100, (r->size * r->ysch) / 100};
|
||||
GPU_viewport_size_set(DST.viewport, size);
|
||||
|
||||
drw_viewport_var_init();
|
||||
|
||||
ViewportEngineData *data = DRW_viewport_engine_data_ensure(draw_engine_type);
|
||||
|
||||
/* set default viewport */
|
||||
gpuPushAttrib(GPU_ENABLE_BIT | GPU_VIEWPORT_BIT);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glViewport(0, 0, size[0], size[1]);
|
||||
|
||||
engine_type->draw_engine->render_to_image(data, re, depsgraph);
|
||||
|
||||
/* TODO grease pencil */
|
||||
|
||||
GPU_viewport_free(DST.viewport);
|
||||
MEM_freeN(DST.viewport);
|
||||
|
||||
DRW_state_reset();
|
||||
/* FIXME GL_DEPTH_TEST is enabled by default but it seems
|
||||
* to trigger some bad behaviour / artifacts if it's turned
|
||||
* on at this point. */
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
/* Restore Drawing area. */
|
||||
gpuPopAttrib();
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
GPU_framebuffer_restore();
|
||||
|
||||
#ifdef DEBUG
|
||||
/* Avoid accidental reuse. */
|
||||
memset(&DST, 0xFF, sizeof(DST));
|
||||
#endif
|
||||
}
|
||||
|
||||
void DRW_render_object_iter(
|
||||
void *vedata, RenderEngine *engine, struct Depsgraph *depsgraph,
|
||||
void (*callback)(void *vedata, Object *ob, RenderEngine *engine, struct Depsgraph *depsgraph))
|
||||
{
|
||||
DEG_OBJECT_ITER_FOR_RENDER_ENGINE(depsgraph, ob, DRW_iterator_mode_get())
|
||||
{
|
||||
callback(vedata, ob, engine, depsgraph);
|
||||
}
|
||||
DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END
|
||||
}
|
||||
|
||||
/**
|
||||
* object mode select-loop, see: ED_view3d_draw_select_loop (legacy drawing).
|
||||
*/
|
||||
|
@ -3796,7 +3865,7 @@ void DRW_state_dfdy_factors_get(float dfdyfac[2])
|
|||
*/
|
||||
bool DRW_state_is_fbo(void)
|
||||
{
|
||||
return (DST.default_framebuffer != NULL);
|
||||
return ((DST.default_framebuffer != NULL) || DST.options.is_image_render);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3894,6 +3963,11 @@ const DRWContextState *DRW_context_state_get(void)
|
|||
/** \name Init/Exit (DRW_engines)
|
||||
* \{ */
|
||||
|
||||
bool DRW_engine_render_support(DrawEngineType *draw_engine_type)
|
||||
{
|
||||
return draw_engine_type->render_to_image;
|
||||
}
|
||||
|
||||
void DRW_engine_register(DrawEngineType *draw_engine_type)
|
||||
{
|
||||
BLI_addtail(&DRW_engines, draw_engine_type);
|
||||
|
|
|
@ -154,4 +154,5 @@ DrawEngineType draw_engine_edit_armature_type = {
|
|||
NULL,
|
||||
&EDIT_ARMATURE_draw_scene,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
|
|
@ -347,4 +347,5 @@ DrawEngineType draw_engine_edit_curve_type = {
|
|||
NULL, /* draw_background but not needed by mode engines */
|
||||
&EDIT_CURVE_draw_scene,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
|
|
@ -294,4 +294,5 @@ DrawEngineType draw_engine_edit_lattice_type = {
|
|||
NULL, /* draw_background but not needed by mode engines */
|
||||
&EDIT_LATTICE_draw_scene,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
|
|
@ -610,4 +610,5 @@ DrawEngineType draw_engine_edit_mesh_type = {
|
|||
NULL,
|
||||
&EDIT_MESH_draw_scene,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
|
|
@ -248,4 +248,5 @@ DrawEngineType draw_engine_edit_metaball_type = {
|
|||
NULL, /* draw_background but not needed by mode engines */
|
||||
&EDIT_METABALL_draw_scene,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
|
|
@ -266,4 +266,5 @@ DrawEngineType draw_engine_edit_surface_type = {
|
|||
NULL, /* draw_background but not needed by mode engines */
|
||||
&EDIT_SURFACE_draw_scene,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
|
|
@ -309,4 +309,5 @@ DrawEngineType draw_engine_edit_text_type = {
|
|||
NULL, /* draw_background but not needed by mode engines */
|
||||
&EDIT_TEXT_draw_scene,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
|
|
@ -2044,4 +2044,5 @@ DrawEngineType draw_engine_object_type = {
|
|||
NULL,
|
||||
&OBJECT_draw_scene,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
|
|
@ -414,4 +414,5 @@ DrawEngineType draw_engine_paint_texture_type = {
|
|||
NULL, /* draw_background but not needed by mode engines */
|
||||
&PAINT_TEXTURE_draw_scene,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
|
|
@ -213,4 +213,5 @@ DrawEngineType draw_engine_paint_vertex_type = {
|
|||
NULL,
|
||||
&PAINT_VERTEX_draw_scene,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
|
|
@ -251,4 +251,5 @@ DrawEngineType draw_engine_paint_weight_type = {
|
|||
NULL,
|
||||
&PAINT_WEIGHT_draw_scene,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
|
|
@ -261,4 +261,5 @@ DrawEngineType draw_engine_particle_type = {
|
|||
NULL, /* draw_background but not needed by mode engines */
|
||||
&PARTICLE_draw_scene,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
|
|
@ -195,4 +195,5 @@ DrawEngineType draw_engine_pose_type = {
|
|||
NULL,
|
||||
&POSE_draw_scene,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
|
|
@ -302,4 +302,5 @@ DrawEngineType draw_engine_sculpt_type = {
|
|||
NULL, /* draw_background but not needed by mode engines */
|
||||
&SCULPT_draw_scene,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
|
|
@ -844,6 +844,7 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even
|
|||
Main *mainp;
|
||||
ViewLayer *view_layer = NULL;
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
RenderEngineType *re_type = RE_engines_find(scene->view_render.engine_id);
|
||||
Render *re;
|
||||
wmJob *wm_job;
|
||||
RenderJob *rj;
|
||||
|
@ -856,6 +857,13 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even
|
|||
struct Object *camera_override = v3d ? V3D_CAMERA_LOCAL(v3d) : NULL;
|
||||
const char *name;
|
||||
ScrArea *sa;
|
||||
|
||||
/* XXX FIXME If engine is an OpenGL engine do not run modal.
|
||||
* This is a problem for animation rendering since you cannot abort them.
|
||||
* This also does not open an image editor space. */
|
||||
if (RE_engine_is_opengl(re_type)) {
|
||||
return screen_render_exec(C, op);
|
||||
}
|
||||
|
||||
/* only one render job at a time */
|
||||
if (WM_jobs_test(CTX_wm_manager(C), scene, WM_JOB_TYPE_RENDER))
|
||||
|
|
|
@ -183,6 +183,8 @@ void RE_engines_init(void);
|
|||
void RE_engines_exit(void);
|
||||
void RE_engines_register(struct Main *bmain, RenderEngineType *render_type);
|
||||
|
||||
bool RE_engine_is_opengl(RenderEngineType *render_type);
|
||||
|
||||
RenderEngineType *RE_engines_find(const char *idname);
|
||||
|
||||
rcti* RE_engine_get_current_tiles(struct Render *re, int *r_total_tiles, bool *r_needs_free);
|
||||
|
|
|
@ -155,6 +155,13 @@ bool RE_engine_is_external(Render *re)
|
|||
return (re->engine && re->engine->type && re->engine->type->render_to_image);
|
||||
}
|
||||
|
||||
bool RE_engine_is_opengl(RenderEngineType *render_type)
|
||||
{
|
||||
/* TODO refine? Can we have ogl render engine without ogl render pipeline? */
|
||||
return (render_type->draw_engine != NULL) &&
|
||||
DRW_engine_render_support(render_type->draw_engine);
|
||||
}
|
||||
|
||||
/* Create, Free */
|
||||
|
||||
RenderEngine *RE_engine_create(RenderEngineType *type)
|
||||
|
|
Loading…
Reference in New Issue