diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2018-06-14 17:20:23 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2018-06-14 19:17:28 +0300 |
commit | dc856be8399242f4ee3a2ce0450b7ac5a20b35f6 (patch) | |
tree | 7c795bcb2d94bfc1af489efe7142911b618a72e3 | |
parent | a8e8808d586f89145cc18352a0beef4a4ef7f289 (diff) |
Preview: Add own opengl context to render preview images.
-rw-r--r-- | source/blender/editors/render/render_preview.c | 48 | ||||
-rw-r--r-- | source/blender/render/extern/include/RE_pipeline.h | 2 | ||||
-rw-r--r-- | source/blender/render/intern/include/render_types.h | 1 | ||||
-rw-r--r-- | source/blender/render/intern/source/pipeline.c | 19 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_window.c | 5 |
5 files changed, 70 insertions, 5 deletions
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 4a3c7a3fd4b..cdd79f43a72 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -176,6 +176,9 @@ typedef struct ShaderPreview { Main *bmain; Main *pr_main; + + void *gl_context; + bool gl_context_owner; } ShaderPreview; typedef struct IconPreviewSize { @@ -191,6 +194,8 @@ typedef struct IconPreview { void *owner; ID *id; ListBase sizes; + + void *gl_context; } IconPreview; /* *************************** Preview for buttons *********************** */ @@ -741,6 +746,10 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs /* set this for all previews, default is react to G.is_break still */ RE_test_break_cb(re, sp, shader_preview_break); + if (sp->gl_context) { + RE_gl_context_set(re, sp->gl_context); + } + /* lens adjust */ oldlens = ((Camera *)sce->camera->data)->lens; if (sizex > sp->sizey) @@ -860,6 +869,10 @@ static void shader_preview_free(void *customdata) } MEM_freeN(sp->lampcopy); } + if (sp->gl_context_owner && sp->gl_context) { + WM_opengl_context_dispose(sp->gl_context); + sp->gl_context = NULL; + } MEM_freeN(sp); } @@ -1075,6 +1088,8 @@ static void icon_preview_startjob_all_sizes(void *customdata, short *stop, short sp->pr_rect = cur_size->rect; sp->id = ip->id; sp->bmain = ip->bmain; + sp->gl_context = ip->gl_context; + sp->gl_context_owner = false; if (is_render) { BLI_assert(ip->id); @@ -1091,6 +1106,11 @@ static void icon_preview_startjob_all_sizes(void *customdata, short *stop, short common_preview_startjob(sp, stop, do_update, progress); shader_preview_free(sp); } + + if (ip->gl_context) { + WM_opengl_context_dispose(ip->gl_context); + ip->gl_context = NULL; + } } static void icon_preview_endjob(void *customdata) @@ -1174,8 +1194,17 @@ void ED_preview_icon_job(const bContext *C, void *owner, ID *id, unsigned int *r /* render all resolutions from suspended job too */ old_ip = WM_jobs_customdata_get(wm_job); - if (old_ip) + if (old_ip) { BLI_movelisttolist(&ip->sizes, &old_ip->sizes); + /* NOTE: This assumes that it will be the same thread + * that will be used when resuming the job. */ + ip->gl_context = old_ip->gl_context; + } + + if (ip->gl_context == NULL) { + /* Create context in the main thread. */ + ip->gl_context = WM_opengl_context_create(); + } /* customdata for preview thread */ ip->bmain = CTX_data_main(C); @@ -1206,7 +1235,7 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, M { Object *ob = CTX_data_active_object(C); wmJob *wm_job; - ShaderPreview *sp; + ShaderPreview *sp, *old_sp; Scene *scene = CTX_data_scene(C); short id_type = GS(id->name); @@ -1223,6 +1252,21 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, M WM_JOB_EXCL_RENDER, WM_JOB_TYPE_RENDER_PREVIEW); sp = MEM_callocN(sizeof(ShaderPreview), "shader preview"); + /* Reuse previous gl context. */ + old_sp = WM_jobs_customdata_get(wm_job); + if (old_sp) { + /* NOTE: This assumes that it will be the same thread + * that will be used when resuming the job. */ + old_sp->gl_context_owner = false; /* Don't free it */ + sp->gl_context = old_sp->gl_context; + } + + if (sp->gl_context == NULL) { + /* Create context in the main thread. */ + sp->gl_context = WM_opengl_context_create(); + } + sp->gl_context_owner = true; + /* customdata for preview thread */ sp->scene = scene; sp->depsgraph = CTX_data_depsgraph(C); diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h index 55638471883..5cb14df8308 100644 --- a/source/blender/render/extern/include/RE_pipeline.h +++ b/source/blender/render/extern/include/RE_pipeline.h @@ -311,8 +311,10 @@ 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)); +/* TODO replace by a simple set and get draw manager. */ void RE_gl_context_create(Render *re); void RE_gl_context_destroy(Render *re); +void RE_gl_context_set(Render *re, void *gl_context); void *RE_gl_context_get(Render *re); void *RE_gwn_context_get(Render *re); diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index 34535fba1e0..134fa56f01c 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -161,6 +161,7 @@ struct Render { /* TODO replace by a whole draw manager. */ void *gl_context; void *gwn_context; + bool gl_context_ownership; }; /* **************** defines ********************* */ diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 809faeb87a4..62257caa43b 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -1021,10 +1021,13 @@ void RE_test_break_cb(Render *re, void *handle, int (*f)(void *handle)) /* ********* GL Context ******** */ +/* Create the gl context of the Render. + * It will be free by the render itself. */ void RE_gl_context_create(Render *re) { /* Needs to be created in the main ogl thread. */ re->gl_context = WM_opengl_context_create(); + re->gl_context_ownership = true; } void RE_gl_context_destroy(Render *re) @@ -1036,11 +1039,22 @@ void RE_gl_context_destroy(Render *re) re->gwn_context = NULL; } if (re->gl_context) { - WM_opengl_context_dispose(re->gl_context); + if (re->gl_context_ownership) { + WM_opengl_context_dispose(re->gl_context); + } re->gl_context = NULL; } } +/* Manually set the gl context of the Render. + * It won't be free by the render itself. */ +void RE_gl_context_set(Render *re, void *gl_context) +{ + BLI_assert(gl_context); /* Cannot set NULL */ + re->gl_context = gl_context; + re->gl_context_ownership = false; +} + void *RE_gl_context_get(Render *re) { return re->gl_context; @@ -2622,6 +2636,9 @@ void RE_PreviewRender(Render *re, Main *bmain, Scene *sce) RE_SetCamera(re, camera); do_render_3d(re); + + /* Destroy the opengl context in the correct thread. */ + RE_gl_context_destroy(re); } /* note; repeated win/disprect calc... solve that nicer, also in compo */ diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 30f4e5981a1..076514cd73f 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -2318,13 +2318,14 @@ void *WM_opengl_context_create(void) * So we should call this function only on the main thread. */ BLI_assert(BLI_thread_is_main()); - BLI_assert(GPU_framebuffer_current_get() == 0); + // BLI_assert(GPU_framebuffer_current_get() == 0); return GHOST_CreateOpenGLContext(g_system); } void WM_opengl_context_dispose(void *context) { - BLI_assert(GPU_framebuffer_current_get() == 0); + // BLI_assert(BLI_thread_is_main()); + // BLI_assert(GPU_framebuffer_current_get() == 0); GHOST_DisposeOpenGLContext(g_system, (GHOST_ContextHandle)context); } |