diff options
author | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2019-07-01 16:23:42 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2019-07-01 16:36:02 +0300 |
commit | 2698544db2a19436155191608e4ef13c001b8209 (patch) | |
tree | 2d369a6ac5610fef85f2cabe94029b3699913acb /source/blender | |
parent | 3c6260d42de007c223c4bdb1bc8ed5431f2f2963 (diff) |
Fix T66262: slow preview icon loading
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/draw/intern/draw_manager_shader.c | 17 | ||||
-rw-r--r-- | source/blender/editors/include/ED_render.h | 3 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_icons.c | 4 | ||||
-rw-r--r-- | source/blender/editors/render/render_internal.c | 19 | ||||
-rw-r--r-- | source/blender/editors/render/render_preview.c | 14 | ||||
-rw-r--r-- | source/blender/windowmanager/WM_api.h | 2 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_jobs.c | 19 |
7 files changed, 47 insertions, 31 deletions
diff --git a/source/blender/draw/intern/draw_manager_shader.c b/source/blender/draw/intern/draw_manager_shader.c index 5c3b5aa8a8e..d0aa6d55c03 100644 --- a/source/blender/draw/intern/draw_manager_shader.c +++ b/source/blender/draw/intern/draw_manager_shader.c @@ -202,12 +202,8 @@ static void drw_deferred_shader_add(GPUMaterial *mat, bool deferred) /* Get the running job or a new one if none is running. Can only have one job per type & owner. */ - wmJob *wm_job = WM_jobs_get(wm, - win, - scene, - "Shaders Compilation", - WM_JOB_PROGRESS | WM_JOB_SUSPEND, - WM_JOB_TYPE_SHADER_COMPILATION); + wmJob *wm_job = WM_jobs_get( + wm, win, scene, "Shaders Compilation", WM_JOB_PROGRESS, WM_JOB_TYPE_SHADER_COMPILATION); DRWShaderCompiler *old_comp = (DRWShaderCompiler *)WM_jobs_customdata_get(wm_job); @@ -238,6 +234,7 @@ static void drw_deferred_shader_add(GPUMaterial *mat, bool deferred) WM_jobs_customdata_set(wm_job, comp, drw_deferred_shader_compilation_free); WM_jobs_timer(wm_job, 0.1, NC_MATERIAL | ND_SHADING_DRAW, 0); + WM_jobs_delay_start(wm_job, 0.1); WM_jobs_callbacks(wm_job, drw_deferred_shader_compilation_exec, NULL, NULL, NULL); WM_jobs_start(wm, wm_job); } @@ -252,12 +249,8 @@ void DRW_deferred_shader_remove(GPUMaterial *mat) continue; } for (wmWindow *win = wm->windows.first; win; win = win->next) { - wmJob *wm_job = WM_jobs_get(wm, - win, - scene, - "Shaders Compilation", - WM_JOB_PROGRESS | WM_JOB_SUSPEND, - WM_JOB_TYPE_SHADER_COMPILATION); + wmJob *wm_job = WM_jobs_get( + wm, win, scene, "Shaders Compilation", WM_JOB_PROGRESS, WM_JOB_TYPE_SHADER_COMPILATION); DRWShaderCompiler *comp = (DRWShaderCompiler *)WM_jobs_customdata_get(wm_job); if (comp != NULL) { diff --git a/source/blender/editors/include/ED_render.h b/source/blender/editors/include/ED_render.h index 7689a9f97cd..d36d2559f26 100644 --- a/source/blender/editors/include/ED_render.h +++ b/source/blender/editors/include/ED_render.h @@ -93,7 +93,8 @@ void ED_preview_icon_job(const struct bContext *C, struct ID *id, unsigned int *rect, int sizex, - int sizey); + int sizey, + const bool delay); void ED_preview_kill_jobs(struct wmWindowManager *wm, struct Main *bmain); void ED_preview_draw(const struct bContext *C, void *idp, void *parentp, void *slot, rcti *rect); diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index 6f1f4dde1ab..59889e74230 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -1417,11 +1417,13 @@ static void icon_set_image(const bContext *C, return; } + const bool delay = prv_img->rect[size] != NULL; icon_create_rect(prv_img, size); if (use_job) { /* Job (background) version */ - ED_preview_icon_job(C, prv_img, id, prv_img->rect[size], prv_img->w[size], prv_img->h[size]); + ED_preview_icon_job( + C, prv_img, id, prv_img->rect[size], prv_img->w[size], prv_img->h[size], delay); } else { if (!scene) { diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index 352593a15ad..9ac93f07300 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -914,7 +914,6 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even wmJob *wm_job; RenderJob *rj; Image *ima; - int jobflag; const bool is_animation = RNA_boolean_get(op->ptr, "animation"); const bool is_write_still = RNA_boolean_get(op->ptr, "write_still"); const bool use_viewport = RNA_boolean_get(op->ptr, "use_viewport"); @@ -973,12 +972,6 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even /* ensure at least 1 area shows result */ sa = render_view_open(C, event->x, event->y, op->reports); - jobflag = WM_JOB_EXCL_RENDER | WM_JOB_PRIORITY | WM_JOB_PROGRESS; - - if (RNA_struct_property_is_set(op->ptr, "layer")) { - jobflag |= WM_JOB_SUSPEND; - } - /* job custom data */ rj = MEM_callocN(sizeof(RenderJob), "render job"); rj->main = bmain; @@ -1038,12 +1031,20 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even name = "Render"; } - wm_job = WM_jobs_get( - CTX_wm_manager(C), CTX_wm_window(C), scene, name, jobflag, WM_JOB_TYPE_RENDER); + wm_job = WM_jobs_get(CTX_wm_manager(C), + CTX_wm_window(C), + scene, + name, + WM_JOB_EXCL_RENDER | WM_JOB_PRIORITY | WM_JOB_PROGRESS, + WM_JOB_TYPE_RENDER); WM_jobs_customdata_set(wm_job, rj, render_freejob); WM_jobs_timer(wm_job, 0.2, NC_SCENE | ND_RENDER_RESULT, 0); WM_jobs_callbacks(wm_job, render_startjob, NULL, NULL, render_endjob); + if (RNA_struct_property_is_set(op->ptr, "layer")) { + WM_jobs_delay_start(wm_job, 0.2); + } + /* get a render result image, and make sure it is empty */ ima = BKE_image_verify_viewer(bmain, IMA_TYPE_R_RESULT, "Render Result"); BKE_image_signal(rj->main, ima, NULL, IMA_SIGNAL_FREE); diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index c6b1acfbd94..fbabdc2f3c1 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -1340,8 +1340,13 @@ void ED_preview_icon_render( BLI_freelistN(&ip.sizes); } -void ED_preview_icon_job( - const bContext *C, void *owner, ID *id, unsigned int *rect, int sizex, int sizey) +void ED_preview_icon_job(const bContext *C, + void *owner, + ID *id, + unsigned int *rect, + int sizex, + int sizey, + const bool delay) { wmJob *wm_job; IconPreview *ip, *old_ip; @@ -1353,7 +1358,7 @@ void ED_preview_icon_job( CTX_wm_window(C), owner, "Icon Preview", - WM_JOB_EXCL_RENDER | WM_JOB_SUSPEND, + WM_JOB_EXCL_RENDER, WM_JOB_TYPE_RENDER_PREVIEW); ip = MEM_callocN(sizeof(IconPreview), "icon preview"); @@ -1385,10 +1390,11 @@ void ED_preview_icon_job( /* setup job */ WM_jobs_customdata_set(wm_job, ip, icon_preview_free); + WM_jobs_timer(wm_job, 0.1, NC_WINDOW, NC_WINDOW); /* Wait 2s to start rendering icon previews, to not bog down user interaction. * Particularly important for heavy scenes and Eevee using OpenGL that blocks * the user interface drawing. */ - WM_jobs_timer(wm_job, 2.0, NC_WINDOW, NC_WINDOW); + WM_jobs_delay_start(wm_job, (delay) ? 2.0 : 0.0); WM_jobs_callbacks(wm_job, icon_preview_startjob_all_sizes, NULL, NULL, icon_preview_endjob); WM_jobs_start(CTX_wm_manager(C), wm_job); diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index d4fbbd1ecff..d3c1e5f146d 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -649,7 +649,6 @@ enum { WM_JOB_PRIORITY = (1 << 0), WM_JOB_EXCL_RENDER = (1 << 1), WM_JOB_PROGRESS = (1 << 2), - WM_JOB_SUSPEND = (1 << 3), }; /** Identifying jobs by owner alone is unreliable, this isnt saved, @@ -700,6 +699,7 @@ bool WM_jobs_is_stopped(wmWindowManager *wm, void *owner); void *WM_jobs_customdata_get(struct wmJob *); void WM_jobs_customdata_set(struct wmJob *, void *customdata, void (*free)(void *)); void WM_jobs_timer(struct wmJob *, double timestep, unsigned int note, unsigned int endnote); +void WM_jobs_delay_start(struct wmJob *, double delay_time); void WM_jobs_callbacks(struct wmJob *, void (*startjob)(void *, short *, short *, float *), void (*initjob)(void *), diff --git a/source/blender/windowmanager/intern/wm_jobs.c b/source/blender/windowmanager/intern/wm_jobs.c index a63592f7b60..a417d80a9a9 100644 --- a/source/blender/windowmanager/intern/wm_jobs.c +++ b/source/blender/windowmanager/intern/wm_jobs.c @@ -92,6 +92,8 @@ struct wmJob { /** Running jobs each have own timer */ double timestep; wmTimer *wt; + /** Only start job after specified time delay */ + double start_delay_time; /** The notifier event timers should send */ unsigned int note, endnote; @@ -356,6 +358,11 @@ void WM_jobs_timer(wmJob *wm_job, double timestep, unsigned int note, unsigned i wm_job->endnote = endnote; } +void WM_jobs_delay_start(wmJob *wm_job, double delay_time) +{ + wm_job->start_delay_time = delay_time; +} + void WM_jobs_callbacks(wmJob *wm_job, void (*startjob)(void *, short *, short *, float *), void (*initjob)(void *), @@ -386,9 +393,9 @@ static void wm_jobs_test_suspend_stop(wmWindowManager *wm, wmJob *test) bool suspend = false; /* job added with suspend flag, we wait 1 timer step before activating it */ - if (test->flag & WM_JOB_SUSPEND) { + if (test->start_delay_time > 0.0) { suspend = true; - test->flag &= ~WM_JOB_SUSPEND; + test->start_delay_time = 0.0; } else { /* check other jobs */ @@ -441,6 +448,8 @@ void WM_jobs_start(wmWindowManager *wm, wmJob *wm_job) else { if (wm_job->customdata && wm_job->startjob) { + const double timestep = (wm_job->start_delay_time > 0.0) ? wm_job->start_delay_time : + wm_job->timestep; wm_jobs_test_suspend_stop(wm, wm_job); @@ -467,8 +476,12 @@ void WM_jobs_start(wmWindowManager *wm, wmJob *wm_job) } /* restarted job has timer already */ + if (wm_job->wt && (wm_job->wt->timestep > timestep)) { + WM_event_remove_timer(wm, wm_job->win, wm_job->wt); + wm_job->wt = WM_event_add_timer(wm, wm_job->win, TIMERJOBS, timestep); + } if (wm_job->wt == NULL) { - wm_job->wt = WM_event_add_timer(wm, wm_job->win, TIMERJOBS, wm_job->timestep); + wm_job->wt = WM_event_add_timer(wm, wm_job->win, TIMERJOBS, timestep); } wm_job->start_time = PIL_check_seconds_timer(); |