Fix T66262: slow preview icon loading
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 *),
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user