Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2018-06-14 17:20:23 +0300
committerClément Foucault <foucault.clem@gmail.com>2018-06-14 19:17:28 +0300
commitdc856be8399242f4ee3a2ce0450b7ac5a20b35f6 (patch)
tree7c795bcb2d94bfc1af489efe7142911b618a72e3 /source
parenta8e8808d586f89145cc18352a0beef4a4ef7f289 (diff)
Preview: Add own opengl context to render preview images.
Diffstat (limited to 'source')
-rw-r--r--source/blender/editors/render/render_preview.c48
-rw-r--r--source/blender/render/extern/include/RE_pipeline.h2
-rw-r--r--source/blender/render/intern/include/render_types.h1
-rw-r--r--source/blender/render/intern/source/pipeline.c19
-rw-r--r--source/blender/windowmanager/intern/wm_window.c5
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);
}