Workspace: Fix crash on preview, and sanitize placeholder functions

This commit effectively makes workspace switching useless as far as the
active scene layer goes.

The functions from the scene layer API to get the correct scene layer
from "context" were a placeholder to be addressed by the workspace
commit.

When workspace was merged, however G.main was used as a replacement to pass the
correct argument for the functions. As it turned out (surprise!) this
leads to crash on render preview.

We need to get rid of:
* BKE_scene_layer_context_active_ex_PLACEHOLDER
* BKE_scene_layer_context_active_PLACEHOLDER

And either use SceneLayer explicitly or replace it by:
* BKE_scene_layer_from_workspace_get
This commit is contained in:
Dalai Felinto 2017-07-14 11:16:25 +02:00
parent 018df5a49a
commit b48694639a
Notes: blender-bot 2023-06-12 00:52:52 +02:00
Referenced by issue #52062, Blender 2.8 Crashes When Opening the Material Tab in the Properties Panel
Referenced by issue #52052, Back to Desktop if klick on Material Tab
24 changed files with 57 additions and 62 deletions

View File

@ -56,14 +56,19 @@ struct RenderEngine;
struct Scene;
struct SceneCollection;
struct SceneLayer;
struct WorkSpace;
void BKE_layer_exit(void);
struct SceneLayer *BKE_scene_layer_render_active(const struct Scene *scene);
struct SceneLayer *BKE_scene_layer_context_active_ex(const struct Main *bmain, const struct Scene *scene);
struct SceneLayer *BKE_scene_layer_context_active(const struct Scene *scene);
struct SceneLayer *BKE_scene_layer_from_scene_get(const struct Scene *scene);
struct SceneLayer *BKE_scene_layer_from_workspace_get(const struct WorkSpace *workspace);
struct SceneLayer *BKE_scene_layer_add(struct Scene *scene, const char *name);
/* DEPRECATED */
struct SceneLayer *BKE_scene_layer_context_active_ex_PLACEHOLDER(const struct Main *bmain, const struct Scene *scene);
/* DEPRECATED */
struct SceneLayer *BKE_scene_layer_context_active_PLACEHOLDER(const struct Scene *scene);
void BKE_scene_layer_free(struct SceneLayer *sl);
void BKE_scene_layer_engine_set(struct SceneLayer *sl, const char *engine);

View File

@ -2683,7 +2683,7 @@ static void editbmesh_build_data(Scene *scene, Object *obedit, BMEditMesh *em, C
static CustomDataMask object_get_datamask(const Scene *scene, Object *ob, bool *r_need_mapping)
{
/* TODO(sergey): Avoid this linear list lookup. */
SceneLayer *sl = BKE_scene_layer_context_active(scene);
SceneLayer *sl = BKE_scene_layer_context_active_PLACEHOLDER(scene);
Object *actob = sl->basact ? sl->basact->object : NULL;
CustomDataMask mask = ob->customdata_mask;

View File

@ -193,7 +193,7 @@ static void setup_app_data(
}
if (cur_render_layer == NULL) {
/* fallback to scene layer */
cur_render_layer = BKE_scene_layer_render_active(curscene);
cur_render_layer = BKE_scene_layer_from_scene_get(curscene);
}
if (track_undo_scene) {
@ -335,7 +335,8 @@ static void setup_app_data(
if (mode == LOAD_UI_OFF && BLI_listbase_is_empty(&G.main->wm)) {
/* XXX prevent crash in pdInitEffectors called through DEG_scene_relations_rebuild (see T51794).
* Can be removed once BKE_scene_layer_context_active_ex gets workspace passed. */
* Can be removed once BKE_scene_layer_context_active_ex_PLACEHOLDER gets
* replaced by BKE_scene_layer_from_workspace_get. */
BLI_addhead(&G.main->wm, CTX_wm_manager(C));
BKE_scene_set_background(G.main, curscene);
BLI_listbase_clear(&G.main->wm);

View File

@ -916,7 +916,7 @@ SceneLayer *CTX_data_scene_layer(const bContext *C)
return sl;
}
else {
return BKE_scene_layer_context_active_ex(CTX_data_main(C), CTX_data_scene(C));
return BKE_scene_layer_context_active_ex_PLACEHOLDER(CTX_data_main(C), CTX_data_scene(C));
}
}

View File

@ -210,7 +210,7 @@ static void add_particles_to_effectors(ListBase **effectors, Scene *scene, Effec
ListBase *pdInitEffectors(Scene *scene, Object *ob_src, ParticleSystem *psys_src,
EffectorWeights *weights, bool for_simulation)
{
SceneLayer *sl = BKE_scene_layer_context_active(scene); /* Can't get sl from the calling modifiers yet */
SceneLayer *sl = BKE_scene_layer_context_active_PLACEHOLDER(scene); /* Can't get sl from the calling modifiers yet */
Base *base;
unsigned int layer= ob_src->lay;
ListBase *effectors = NULL;

View File

@ -69,9 +69,9 @@ static void object_bases_iterator_next(BLI_Iterator *iter, const int flag);
/**
* Returns the SceneLayer to be used for rendering
* Most of the time BKE_scene_layer_context_active should be used instead
* Most of the time BKE_scene_layer_from_workspace_get should be used instead
*/
SceneLayer *BKE_scene_layer_render_active(const Scene *scene)
SceneLayer *BKE_scene_layer_from_scene_get(const Scene *scene)
{
SceneLayer *sl = BLI_findlink(&scene->render_layers, scene->active_layer);
BLI_assert(sl);
@ -81,37 +81,27 @@ SceneLayer *BKE_scene_layer_render_active(const Scene *scene)
/**
* Returns the SceneLayer to be used for drawing, outliner, and other context related areas.
*/
SceneLayer *BKE_scene_layer_context_active_ex(const Main *bmain, const Scene *scene)
SceneLayer *BKE_scene_layer_from_workspace_get(const struct WorkSpace *workspace)
{
/* XXX We should really pass the workspace as argument, but would require
* some bigger changes since it's often not available where we call this.
* Just working around this by getting active window from WM for now */
for (wmWindowManager *wm = bmain->wm.first; wm; wm = wm->id.next) {
/* Called on startup, so 'winactive' may not be set, in that case fall back to first window. */
wmWindow *win = wm->winactive ? wm->winactive : wm->windows.first;
const WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook);
SceneLayer *scene_layer = BKE_workspace_render_layer_get(workspace);
if (scene_layer != NULL) {
/* NOTE: We never have copy-on-written main database, but we might
* be passing copy-on-write version of scene here. For that case
* we always ensure we are returning copy-on-write version of scene
* layer as well.
*/
/* TODO(sergey): This will make an extra lookup for case when we
* pass original scene, but this function is to be rewritten
* anyway.
*/
scene_layer = BLI_findstring(&scene->render_layers, scene_layer->name, offsetof(SceneLayer, name));
}
return scene_layer;
}
return NULL;
return BKE_workspace_render_layer_get(workspace);
}
SceneLayer *BKE_scene_layer_context_active(const Scene *scene)
/**
* This is a placeholder to know which areas of the code need to be addressed for the Workspace changes.
* Never use this, you should either use BKE_scene_layer_workspace_active or get SceneLayer explicitly.
*/
SceneLayer *BKE_scene_layer_context_active_ex_PLACEHOLDER(const Main *UNUSED(bmain), const Scene *scene)
{
return BKE_scene_layer_context_active_ex(G.main, scene);
return BKE_scene_layer_from_scene_get(scene);
}
/**
* This is a placeholder to know which areas of the code need to be addressed for the Workspace changes.
* Never use this, you should either use BKE_scene_layer_workspace_active or get SceneLayer explicitly.
*/
SceneLayer *BKE_scene_layer_context_active_PLACEHOLDER(const Scene *scene)
{
return BKE_scene_layer_from_scene_get(scene);
}
/**

View File

@ -1774,7 +1774,7 @@ Base *_setlooper_base_step(Scene **sce_iter, Base *base)
/* first time looping, return the scenes first base */
/* for the first loop we should get the layer from context */
SceneLayer *sl = BKE_scene_layer_context_active((*sce_iter));
SceneLayer *sl = BKE_scene_layer_context_active_PLACEHOLDER((*sce_iter));
/* TODO For first scene (non-background set), we should pass the render layer as argument.
* In some cases we want it to be the workspace one, in other the scene one. */
TODO_LAYER;
@ -1789,7 +1789,7 @@ Base *_setlooper_base_step(Scene **sce_iter, Base *base)
next_set:
/* reached the end, get the next base in the set */
while ((*sce_iter = (*sce_iter)->set)) {
SceneLayer *sl = BKE_scene_layer_render_active((*sce_iter));
SceneLayer *sl = BKE_scene_layer_from_scene_get((*sce_iter));
base = (Base *)sl->object_bases.first;
if (base) {

View File

@ -3306,7 +3306,7 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, Sequence *seq
BKE_scene_update_for_newframe(context->eval_ctx, context->bmain, scene);
ibuf = sequencer_view3d_cb(
/* set for OpenGL render (NULL when scrubbing) */
scene, BKE_scene_layer_render_active(scene), camera, width, height, IB_rect,
scene, BKE_scene_layer_from_scene_get(scene), camera, width, height, IB_rect,
context->scene->r.seq_prev_type,
(context->scene->r.seq_flag & R_SEQ_SOLID_TEX) != 0,
use_gpencil, use_background, scene->r.alphamode,

View File

@ -85,7 +85,7 @@ static void do_version_workspaces_create_from_screens(Main *bmain)
for (bScreen *screen = bmain->screen.first; screen; screen = screen->id.next) {
const bScreen *screen_parent = screen_parent_find(screen);
WorkSpace *workspace;
SceneLayer *layer = BKE_scene_layer_render_active(screen->scene);
SceneLayer *layer = BKE_scene_layer_from_scene_get(screen->scene);
ListBase *transform_orientations;
if (screen_parent) {
@ -287,7 +287,7 @@ void do_versions_after_linking_280(Main *main)
if (!MAIN_VERSION_ATLEAST(main, 280, 0)) {
for (bScreen *screen = main->screen.first; screen; screen = screen->id.next) {
/* same render-layer as do_version_workspaces_after_lib_link will activate,
* so same layer as BKE_scene_layer_context_active would return */
* so same layer as BKE_scene_layer_from_workspace_get would return */
SceneLayer *layer = screen->scene->render_layers.first;
for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {

View File

@ -93,7 +93,7 @@ SceneLayer *DEG_get_evaluated_scene_layer(Depsgraph *graph)
Scene *scene = DEG_get_evaluated_scene(graph);
if (scene != NULL) {
DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph);
return BKE_scene_layer_context_active_ex(deg_graph->bmain, scene);
return BKE_scene_layer_context_active_ex_PLACEHOLDER(deg_graph->bmain, scene);
}
return NULL;
}
@ -240,7 +240,7 @@ void DEG_objects_iterator_next(BLI_Iterator *iter)
data->base_flag = ~(BASE_SELECTED | BASE_SELECTABLED);
/* For the sets we use the layer used for rendering. */
scene_layer = BKE_scene_layer_render_active(data->scene);
scene_layer = BKE_scene_layer_from_scene_get(data->scene);
/* TODO(sergey): It's really confusing to store pointer to a local data. */
Base base = {(Base *)scene_layer->object_bases.first, NULL};

View File

@ -329,7 +329,7 @@ static Scene *preview_prepare_scene(Main *bmain, Scene *scene, ID *id, int id_ty
sce = preview_get_scene(pr_main);
if (sce) {
SceneLayer *scene_layer = BKE_scene_layer_render_active(sce);
SceneLayer *scene_layer = BKE_scene_layer_from_scene_get(sce);
/* this flag tells render to not execute depsgraph or ipos etc */
sce->r.scemode |= R_BUTS_PREVIEW;

View File

@ -656,7 +656,7 @@ static int render_layer_remove_exec(bContext *C, wmOperator *UNUSED(op))
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
SceneLayer *sl = BKE_scene_layer_context_active(scene);
SceneLayer *sl = BKE_scene_layer_context_active_PLACEHOLDER(scene);
if (!ED_scene_render_layer_delete(bmain, scene, sl, NULL)) {
return OPERATOR_CANCELLED;

View File

@ -87,9 +87,8 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
bScreen *sc = CTX_wm_screen(C);
ScrArea *sa = CTX_wm_area(C);
Scene *scene = WM_window_get_active_scene(win);
/* can't call BKE_scene_layer_context_active here, it uses G.main->wm which might be NULL on file read. */
WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook);
SceneLayer *sl = BKE_workspace_render_layer_get(workspace);
SceneLayer *sl = BKE_scene_layer_from_workspace_get(workspace);
Object *obedit = scene->obedit;
Object *obact = sl->basact ? sl->basact->object : NULL;

View File

@ -182,7 +182,7 @@ static int buttons_context_path_object(ButsContextPath *path)
else if (buttons_context_path_scene(path)) {
scene = path->ptr[path->len - 1].data;
SceneLayer *sl = BKE_scene_layer_context_active(scene);
SceneLayer *sl = BKE_scene_layer_context_active_PLACEHOLDER(scene);
ob = (sl->basact) ? sl->basact->object : NULL;
if (ob) {

View File

@ -536,7 +536,7 @@ static void image_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, co
case ND_TRANSFORM:
case ND_MODIFIER:
{
SceneLayer *sl = BKE_scene_layer_context_active(scene);
SceneLayer *sl = BKE_scene_layer_context_active_PLACEHOLDER(scene);
Object *ob = OBACT_NEW;
if (ob && (ob == wmn->reference) && (ob->mode & OB_MODE_EDIT)) {
if (sima->lock && (sima->flag & SI_DRAWSHADOW)) {

View File

@ -1944,7 +1944,7 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SceneLayer *sl, SpaceOops
outliner_add_orphaned_datablocks(mainvar, soops);
}
else if (soops->outlinevis == SO_ACT_LAYER) {
outliner_add_collections_act_layer(soops, BKE_scene_layer_context_active(scene));
outliner_add_collections_act_layer(soops, BKE_scene_layer_context_active_PLACEHOLDER(scene));
}
else if (soops->outlinevis == SO_COLLECTIONS) {
outliner_add_collections_master(soops, scene);

View File

@ -1198,7 +1198,7 @@ void ED_view3d_draw_depth_gpencil(Scene *scene, ARegion *ar, View3D *v3d)
void ED_view3d_draw_depth_loop(Scene *scene, ARegion *ar, View3D *v3d)
{
Base *base;
SceneLayer *sl = BKE_scene_layer_context_active(scene);
SceneLayer *sl = BKE_scene_layer_context_active_PLACEHOLDER(scene);
/* no need for color when drawing depth buffer */
const short dflag_depth = DRAW_CONSTCOLOR;
@ -1422,7 +1422,7 @@ static void gpu_update_lamps_shadows_world(Scene *scene, View3D *v3d)
/* no need to call ED_view3d_draw_offscreen_init since shadow buffers were already updated */
ED_view3d_draw_offscreen(
scene, BKE_scene_layer_context_active(scene), v3d, &ar, winsize, winsize, viewmat, winmat,
scene, BKE_scene_layer_context_active_PLACEHOLDER(scene), v3d, &ar, winsize, winsize, viewmat, winmat,
false, false, true,
NULL, NULL, NULL, NULL);
GPU_lamp_shadow_buffer_unbind(shadow->lamp);
@ -1499,7 +1499,7 @@ static void view3d_draw_objects(
const char **grid_unit,
const bool do_bgpic, const bool draw_offscreen, GPUFX *fx)
{
SceneLayer *sl = C ? CTX_data_scene_layer(C) : BKE_scene_layer_render_active(scene);
SceneLayer *sl = C ? CTX_data_scene_layer(C) : BKE_scene_layer_from_scene_get(scene);
RegionView3D *rv3d = ar->regiondata;
Base *base;
const bool do_camera_frame = !draw_offscreen;

View File

@ -1791,7 +1791,7 @@ static void rna_Physics_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Pointe
static void rna_Scene_editmesh_select_mode_set(PointerRNA *ptr, const int *value)
{
Scene *scene = (Scene *)ptr->id.data;
SceneLayer *sl = BKE_scene_layer_context_active(scene);
SceneLayer *sl = BKE_scene_layer_context_active_PLACEHOLDER(scene);
ToolSettings *ts = (ToolSettings *)ptr->data;
int flag = (value[0] ? SCE_SELECT_VERTEX : 0) | (value[1] ? SCE_SELECT_EDGE : 0) | (value[2] ? SCE_SELECT_FACE : 0);

View File

@ -852,7 +852,7 @@ static int rna_SpaceImageEditor_show_maskedit_get(PointerRNA *ptr)
SpaceImage *sima = (SpaceImage *)(ptr->data);
bScreen *sc = (bScreen *)ptr->id.data;
Scene *scene = ED_screen_scene_find(sc, G.main->wm.first);
SceneLayer *sl = BKE_scene_layer_context_active(scene);
SceneLayer *sl = BKE_scene_layer_context_active_PLACEHOLDER(scene);
return ED_space_image_check_show_maskedit(sl, sima);
}

View File

@ -119,7 +119,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
/* dont apply dynamic paint on orco dm stack */
if (!(flag & MOD_APPLY_ORCO)) {
return dynamicPaint_Modifier_do(pmd, md->scene, BKE_scene_layer_context_active(md->scene), ob, dm);
return dynamicPaint_Modifier_do(pmd, md->scene, BKE_scene_layer_context_active_PLACEHOLDER(md->scene), ob, dm);
}
return dm;
}

View File

@ -109,7 +109,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
if (flag & MOD_APPLY_ORCO)
return dm;
return smokeModifier_do(smd, md->scene, BKE_scene_layer_context_active(md->scene), ob, dm);
return smokeModifier_do(smd, md->scene, BKE_scene_layer_context_active_PLACEHOLDER(md->scene), ob, dm);
}
static bool dependsOnTime(ModifierData *UNUSED(md))

View File

@ -54,7 +54,7 @@ static void deformVerts(ModifierData *md, Object *ob,
int numVerts,
ModifierApplyFlag UNUSED(flag))
{
sbObjectStep(md->scene, BKE_scene_layer_context_active(md->scene), ob, (float)md->scene->r.cfra, vertexCos, numVerts);
sbObjectStep(md->scene, BKE_scene_layer_context_active_PLACEHOLDER(md->scene), ob, (float)md->scene->r.cfra, vertexCos, numVerts);
}
static bool dependsOnTime(ModifierData *UNUSED(md))

View File

@ -3797,7 +3797,7 @@ void RE_PreviewRender(Render *re, Main *bmain, Scene *sce)
{
Object *camera;
/* TODO(sergey): Get proper scene layer here. */
SceneLayer *scene_layer = BKE_scene_layer_context_active_ex(bmain, sce);
SceneLayer *scene_layer = BKE_scene_layer_context_active_ex_PLACEHOLDER(bmain, sce);
int winx, winy;
winx = (sce->r.size * sce->r.xsch) / 100;

View File

@ -335,7 +335,7 @@ void wm_event_do_notifiers(bContext *C)
}
}
if (ELEM(note->category, NC_SCENE, NC_OBJECT, NC_GEOM, NC_WM)) {
SceneLayer *sl = BKE_scene_layer_context_active(scene);
SceneLayer *sl = BKE_scene_layer_context_active_PLACEHOLDER(scene);
ED_info_stats_clear(sl);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_INFO, NULL);
}