Render: Create a separate gl context for rendering.
This should take care of all the threading stability issues some people are reporting.
This commit is contained in:
@@ -1464,8 +1464,24 @@ void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph)
|
||||
WM_init_opengl();
|
||||
}
|
||||
|
||||
void *re_gl_context = RE_gl_context_get(render);
|
||||
void *re_gwn_context = NULL;
|
||||
|
||||
/* Changing Context */
|
||||
DRW_opengl_context_enable();
|
||||
if (re_gl_context != NULL) {
|
||||
/* TODO get rid of the blocking. Only here because of the static global DST. */
|
||||
BLI_mutex_lock(&DST.gl_context_mutex);
|
||||
WM_opengl_context_activate(re_gl_context);
|
||||
re_gwn_context = RE_gwn_context_get(render);
|
||||
if (GWN_context_active_get() == NULL) {
|
||||
GWN_context_active_set(re_gwn_context);
|
||||
}
|
||||
DRW_shape_cache_reset(); /* XXX fix that too. */
|
||||
}
|
||||
else {
|
||||
DRW_opengl_context_enable();
|
||||
}
|
||||
|
||||
/* IMPORTANT: We dont support immediate mode in render mode!
|
||||
* This shall remain in effect until immediate mode supports
|
||||
* multiple threads. */
|
||||
@@ -1533,7 +1549,17 @@ void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph)
|
||||
GPU_framebuffer_restore();
|
||||
|
||||
/* Changing Context */
|
||||
DRW_opengl_context_disable();
|
||||
if (re_gl_context != NULL) {
|
||||
DRW_shape_cache_reset(); /* XXX fix that too. */
|
||||
glFlush();
|
||||
GWN_context_active_set(NULL);
|
||||
WM_opengl_context_release(re_gl_context);
|
||||
/* TODO get rid of the blocking. */
|
||||
BLI_mutex_unlock(&DST.gl_context_mutex);
|
||||
}
|
||||
else {
|
||||
DRW_opengl_context_disable();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
/* Avoid accidental reuse. */
|
||||
|
||||
@@ -1015,6 +1015,7 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even
|
||||
RE_current_scene_update_cb(re, rj, current_scene_update);
|
||||
RE_stats_draw_cb(re, rj, image_renderinfo_cb);
|
||||
RE_progress_cb(re, rj, render_progress_update);
|
||||
RE_gl_context_create(re);
|
||||
|
||||
rj->re = re;
|
||||
G.is_break = false;
|
||||
|
||||
@@ -311,6 +311,11 @@ void RE_draw_lock_cb (struct Render *re, void *handle, void (*f)(void *handle,
|
||||
void RE_test_break_cb (struct Render *re, void *handle, int (*f)(void *handle));
|
||||
void RE_current_scene_update_cb(struct Render *re, void *handle, void (*f)(void *handle, struct Scene *scene));
|
||||
|
||||
void RE_gl_context_create(Render *re);
|
||||
void RE_gl_context_destroy(Render *re);
|
||||
void *RE_gl_context_get(Render *re);
|
||||
void *RE_gwn_context_get(Render *re);
|
||||
|
||||
/* should move to kernel once... still unsure on how/where */
|
||||
float RE_filter_value(int type, float x);
|
||||
|
||||
|
||||
@@ -157,6 +157,10 @@ struct Render {
|
||||
|
||||
void **movie_ctx_arr;
|
||||
char viewname[MAX_NAME];
|
||||
|
||||
/* TODO replace by a whole draw manager. */
|
||||
void *gl_context;
|
||||
void *gwn_context;
|
||||
};
|
||||
|
||||
/* **************** defines ********************* */
|
||||
|
||||
@@ -94,6 +94,9 @@
|
||||
#include "RE_pipeline.h"
|
||||
#include "RE_render_ext.h"
|
||||
|
||||
#include "../../../windowmanager/WM_api.h" /* XXX */
|
||||
#include "../../../intern/gawain/gawain/gwn_context.h"
|
||||
|
||||
#ifdef WITH_FREESTYLE
|
||||
# include "FRS_freestyle.h"
|
||||
#endif
|
||||
@@ -1020,6 +1023,40 @@ void RE_test_break_cb(Render *re, void *handle, int (*f)(void *handle))
|
||||
re->tbh = handle;
|
||||
}
|
||||
|
||||
/* ********* GL Context ******** */
|
||||
|
||||
void RE_gl_context_create(Render *re)
|
||||
{
|
||||
/* Needs to be created in the main ogl thread. */
|
||||
re->gl_context = WM_opengl_context_create();
|
||||
}
|
||||
|
||||
void RE_gl_context_destroy(Render *re)
|
||||
{
|
||||
/* Needs to be called from the thread which used the ogl context for rendering. */
|
||||
if (re->gwn_context) {
|
||||
GWN_context_active_set(re->gwn_context);
|
||||
GWN_context_discard(re->gwn_context);
|
||||
re->gwn_context = NULL;
|
||||
}
|
||||
if (re->gl_context) {
|
||||
WM_opengl_context_dispose(re->gl_context);
|
||||
re->gl_context = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void *RE_gl_context_get(Render *re)
|
||||
{
|
||||
return re->gl_context;
|
||||
}
|
||||
|
||||
void *RE_gwn_context_get(Render *re)
|
||||
{
|
||||
if (re->gwn_context == NULL) {
|
||||
re->gwn_context = GWN_context_create();
|
||||
}
|
||||
return re->gwn_context;
|
||||
}
|
||||
|
||||
/* ********* add object data (later) ******** */
|
||||
|
||||
@@ -2224,6 +2261,9 @@ void RE_BlenderFrame(Render *re, Main *bmain, Scene *scene, ViewLayer *single_la
|
||||
|
||||
BLI_callback_exec(re->main, (ID *)scene, G.is_break ? BLI_CB_EVT_RENDER_CANCEL : BLI_CB_EVT_RENDER_COMPLETE);
|
||||
|
||||
/* Destroy the opengl context in the correct thread. */
|
||||
RE_gl_context_destroy(re);
|
||||
|
||||
/* UGLY WARNING */
|
||||
G.is_rendering = false;
|
||||
}
|
||||
@@ -2779,6 +2819,9 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri
|
||||
BLI_callback_exec(re->main, (ID *)scene, G.is_break ? BLI_CB_EVT_RENDER_CANCEL : BLI_CB_EVT_RENDER_COMPLETE);
|
||||
BKE_sound_reset_scene_specs(scene);
|
||||
|
||||
/* Destroy the opengl context in the correct thread. */
|
||||
RE_gl_context_destroy(re);
|
||||
|
||||
/* UGLY WARNING */
|
||||
G.is_rendering = false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user