Refactor: WM: Suspend new jobs based on same job type, not callback

The callback-based identification was introduced before job types were added in
7b60529517. The job type should be a more predictable/sane way to identify jobs
that should be exclusive. Using anything else is confusing and non-obvious from
the API usage side. In fact it really confused me when working on #123027.

Checked all existing jobs to make sure behavior is unchanged. Found
two issues:
- `WM_JOB_TYPE_OBJECT_SIM_FLUID` is used for both
  `fluid_bake_startjob()` and `fluid_free_startjob()`. It makes sense to
  me that they would be exclusive though, so leaving it this way
  (meaning they are exclusive now).
- Alembic and USD job types were reused, split them up now to not change
  behavior.

Pull Request: https://projects.blender.org/blender/blender/pulls/123033
This commit is contained in:
Julian Eisel 2024-06-21 13:27:23 +02:00 committed by Julian Eisel
parent dbd04310c7
commit 6887dea786
6 changed files with 28 additions and 12 deletions

@ -230,8 +230,12 @@ bool ABC_export(Scene *scene,
bool export_ok = false;
if (as_background_job) {
wmJob *wm_job = WM_jobs_get(
job->wm, CTX_wm_window(C), scene, "Alembic Export", WM_JOB_PROGRESS, WM_JOB_TYPE_ALEMBIC);
wmJob *wm_job = WM_jobs_get(job->wm,
CTX_wm_window(C),
scene,
"Alembic Export",
WM_JOB_PROGRESS,
WM_JOB_TYPE_ALEMBIC_EXPORT);
/* setup job */
WM_jobs_customdata_set(wm_job, job, MEM_freeN);

@ -746,7 +746,7 @@ bool ABC_import(bContext *C, const AlembicImportParams *params, bool as_backgrou
job->scene,
"Alembic Import",
WM_JOB_PROGRESS,
WM_JOB_TYPE_ALEMBIC);
WM_JOB_TYPE_ALEMBIC_IMPORT);
/* setup job */
WM_jobs_customdata_set(wm_job, job, import_freejob);

@ -641,7 +641,7 @@ bool USD_export(bContext *C,
bool export_ok = false;
if (as_background_job) {
wmJob *wm_job = WM_jobs_get(
job->wm, CTX_wm_window(C), scene, "USD Export", WM_JOB_PROGRESS, WM_JOB_TYPE_ALEMBIC);
job->wm, CTX_wm_window(C), scene, "USD Export", WM_JOB_PROGRESS, WM_JOB_TYPE_USD_EXPORT);
/* setup job */
WM_jobs_customdata_set(wm_job, job, MEM_freeN);

@ -521,7 +521,7 @@ bool USD_import(bContext *C,
job->scene,
"USD Import",
WM_JOB_PROGRESS,
WM_JOB_TYPE_ALEMBIC);
WM_JOB_TYPE_USD_IMPORT);
/* setup job */
WM_jobs_customdata_set(wm_job, job, import_freejob);

@ -1589,7 +1589,10 @@ enum eWM_JobType {
WM_JOB_TYPE_SEQ_BUILD_PREVIEW,
WM_JOB_TYPE_POINTCACHE,
WM_JOB_TYPE_DPAINT_BAKE,
WM_JOB_TYPE_ALEMBIC,
WM_JOB_TYPE_ALEMBIC_IMPORT,
WM_JOB_TYPE_ALEMBIC_EXPORT,
WM_JOB_TYPE_USD_IMPORT,
WM_JOB_TYPE_USD_EXPORT,
WM_JOB_TYPE_SHADER_COMPILATION,
WM_JOB_TYPE_STUDIOLIGHT,
WM_JOB_TYPE_LIGHT_BAKE,
@ -1609,8 +1612,8 @@ enum eWM_JobType {
/**
* \return current job or adds new job, but doesn't run it.
*
* \note every owner only gets a single job,
* adding a new one will stop running job and when stopped it starts the new one.
* \note every owner only gets a single running job of the same \a job_type (or with the
* #WM_JOB_EXCL_RENDER flag). Adding a new one will wait for the running job to finish.
*/
wmJob *WM_jobs_get(wmWindowManager *wm,
wmWindow *win,
@ -1654,8 +1657,17 @@ void WM_jobs_callbacks_ex(wmJob *wm_job,
void (*canceled)(void *));
/**
* If job running, the same owner gave it a new job.
* if different owner starts existing #wmJob::startjob, it suspends itself.
* Register the given \a wm_job and try to start it immediately.
*
* The new \a wm_job will not start immediately and wait for other blocking jobs
* to end in some way if:
* - the new job is flagged with #WM_JOB_EXCL_RENDER and another job with the same flag is already
* running (blocks it), or...
* - the new job is __not__ flagged with #WM_JOB_EXCL_RENDER and a job of the same #eWM_JobType is
* already running (blocks it).
*
* If the new \a wm_job is flagged with #WM_JOB_PRIORITY, it will request other blocking jobs to
* stop (using #WM_jobs_stop(), so this doesn't take immediate effect) rather than finish its work.
*/
void WM_jobs_start(wmWindowManager *wm, wmJob *wm_job);
/**

@ -419,9 +419,9 @@ static void wm_jobs_test_suspend_stop(wmWindowManager *wm, wmJob *test)
continue;
}
/* If new job is not render, then check for same startjob. */
/* If new job is not render, then check for same job type. */
if (0 == (test->flag & WM_JOB_EXCL_RENDER)) {
if (wm_job->startjob != test->startjob) {
if (wm_job->job_type != test->job_type) {
continue;
}
}