Merge branch 'master' into blender2.8
authorBastien Montagne <montagne29@wanadoo.fr>
Mon, 11 Jun 2018 14:02:46 +0000 (16:02 +0200)
committerBastien Montagne <montagne29@wanadoo.fr>
Mon, 11 Jun 2018 14:02:46 +0000 (16:02 +0200)
Conflicts:
source/blender/blenkernel/BKE_mesh.h
source/blender/blenkernel/intern/mesh_convert.c
source/blender/editors/interface/interface_eyedropper_color.c
source/blender/editors/object/object_add.c
source/blender/editors/space_image/image_ops.c
source/blender/makesrna/intern/rna_image.c
source/blender/windowmanager/intern/wm_draw.c

37 files changed:
1  2 
source/blender/blenkernel/BKE_mesh.h
source/blender/blenkernel/BKE_node.h
source/blender/blenkernel/intern/bpath.c
source/blender/blenkernel/intern/image.c
source/blender/blenkernel/intern/mesh_convert.c
source/blender/blenkernel/intern/node.c
source/blender/collada/DocumentImporter.cpp
source/blender/editors/include/ED_image.h
source/blender/editors/include/ED_node.h
source/blender/editors/interface/interface_eyedropper_color.c
source/blender/editors/object/object_add.c
source/blender/editors/render/render_internal.c
source/blender/editors/render/render_opengl.c
source/blender/editors/render/render_view.c
source/blender/editors/sculpt_paint/paint_image.c
source/blender/editors/sculpt_paint/paint_image_proj.c
source/blender/editors/space_image/image_edit.c
source/blender/editors/space_image/image_ops.c
source/blender/editors/space_node/drawnode.c
source/blender/editors/space_node/node_add.c
source/blender/editors/space_node/node_edit.c
source/blender/editors/space_node/node_manipulators.c
source/blender/makesrna/intern/rna_color.c
source/blender/makesrna/intern/rna_image.c
source/blender/makesrna/intern/rna_image_api.c
source/blender/makesrna/intern/rna_main_api.c
source/blender/makesrna/intern/rna_material.c
source/blender/makesrna/intern/rna_nodetree.c
source/blender/makesrna/intern/rna_scene.c
source/blender/makesrna/intern/rna_sculpt_paint.c
source/blender/makesrna/intern/rna_space.c
source/blender/nodes/composite/node_composite_tree.c
source/blender/nodes/shader/node_shader_tree.c
source/blender/nodes/texture/node_texture_tree.c
source/blender/render/intern/source/pipeline.c
source/blender/windowmanager/intern/wm_draw.c
source/blender/windowmanager/intern/wm_operators.c

   *  \ingroup bke
   */
  
 +/* defines BLI_INLINE */
 +#include "BLI_utildefines.h"
 +
 +/* defines CustomDataMask */
 +#include "BKE_customdata.h"
 +
  struct ID;
  struct BMeshCreateParams;
 +struct BMeshFromMeshParams;
 +struct BMeshToMeshParams;
  struct BoundBox;
 +struct Depsgraph;
  struct EdgeHash;
  struct ListBase;
  struct LinkNode;
  struct BLI_Stack;
  struct MemArena;
  struct BMesh;
 +struct KeyBlock;
  struct MLoopTri;
  struct Main;
  struct Mesh;
 +struct ModifierData;
  struct MPoly;
  struct MLoop;
  struct MFace;
  struct MEdge;
  struct MVert;
 +struct MVertTri;
  struct MDeformVert;
  struct MDisps;
  struct Object;
@@@ -82,16 -70,10 +82,16 @@@ extern "C" 
  
  /* *** mesh.c *** */
  
 +struct BMesh *BKE_mesh_to_bmesh_ex(
 +        struct Mesh *me,
 +        const struct BMeshCreateParams *create_params,
 +        const struct BMeshFromMeshParams *convert_params);
  struct BMesh *BKE_mesh_to_bmesh(
          struct Mesh *me, struct Object *ob,
          const bool add_key_index, const struct BMeshCreateParams *params);
  
 +struct Mesh *BKE_bmesh_to_mesh_nomain(struct BMesh *bm, const struct BMeshToMeshParams *params);
 +
  int poly_find_loop_from_vert(
          const struct MPoly *poly,
          const struct MLoop *loopstart, unsigned vert);
@@@ -110,21 -92,6 +110,21 @@@ struct Mesh *BKE_mesh_copy(struct Main 
  void BKE_mesh_update_customdata_pointers(struct Mesh *me, const bool do_ensure_tess_cd);
  void BKE_mesh_ensure_skin_customdata(struct Mesh *me);
  
 +struct Mesh *BKE_mesh_new_nomain(
 +        int verts_len, int edges_len, int tessface_len,
 +        int loops_len, int polys_len);
 +struct Mesh *BKE_mesh_new_nomain_from_template(
 +        const struct Mesh *me_src,
 +        int verts_len, int edges_len, int tessface_len,
 +        int loops_len, int polys_len);
 +
 +/* These functions construct a new Mesh, contrary to BKE_mesh_from_nurbs which modifies ob itself. */
 +struct Mesh *BKE_mesh_new_nomain_from_curve(struct Object *ob);
 +struct Mesh *BKE_mesh_new_nomain_from_curve_displist(struct Object *ob, struct ListBase *dispbase);
 +
 +bool BKE_mesh_ensure_facemap_customdata(struct Mesh *me);
 +bool BKE_mesh_clear_facemap_customdata(struct Mesh *me);
 +
  void BKE_mesh_make_local(struct Main *bmain, struct Mesh *me, const bool lib_local);
  void BKE_mesh_boundbox_calc(struct Mesh *me, float r_loc[3], float r_size[3]);
  void BKE_mesh_texspace_calc(struct Mesh *me);
@@@ -133,22 -100,6 +133,22 @@@ void   BKE_mesh_orco_verts_transform(st
  int test_index_face(struct MFace *mface, struct CustomData *mfdata, int mfindex, int nr);
  struct Mesh *BKE_mesh_from_object(struct Object *ob);
  void BKE_mesh_assign_object(struct Main *bmain, struct Object *ob, struct Mesh *me);
-         struct Object *ob, struct ListBase *dispbase, const bool use_orco_uv, const char *obdata_name, bool temporary);
- void BKE_mesh_from_nurbs(struct Object *ob);
 +void BKE_mesh_from_metaball(struct ListBase *lb, struct Mesh *me);
 +int  BKE_mesh_nurbs_to_mdata(
 +        struct Object *ob, struct MVert **r_allvert, int *r_totvert,
 +        struct MEdge **r_alledge, int *r_totedge, struct MLoop **r_allloop, struct MPoly **r_allpoly,
 +        int *r_totloop, int *r_totpoly);
 +int BKE_mesh_nurbs_displist_to_mdata(
 +        struct Object *ob, const struct ListBase *dispbase,
 +        struct MVert **r_allvert, int *r_totvert,
 +        struct MEdge **r_alledge, int *r_totedge,
 +        struct MLoop **r_allloop, struct MPoly **r_allpoly,
 +        struct MLoopUV **r_alluv, int *r_totloop, int *r_totpoly);
 +void BKE_mesh_from_nurbs_displist(
- void BKE_mesh_to_curve(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob);
++        struct Main *bmain, struct Object *ob, struct ListBase *dispbase, const bool use_orco_uv, const char *obdata_name, bool temporary);
++void BKE_mesh_from_nurbs(struct Main *bmain, struct Object *ob);
 +void BKE_mesh_to_curve_nurblist(const struct Mesh *me, struct ListBase *nurblist, const int edge_users_test);
++void BKE_mesh_to_curve(struct Main *bmain, struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob);
  void BKE_mesh_material_index_remove(struct Mesh *me, short index);
  void BKE_mesh_material_index_clear(struct Mesh *me);
  void BKE_mesh_material_remap(struct Mesh *me, const unsigned int *remap, unsigned int remap_len);
@@@ -158,31 -109,16 +158,31 @@@ const char *BKE_mesh_cmp(struct Mesh *m
  
  struct BoundBox *BKE_mesh_boundbox_get(struct Object *ob);
  void BKE_mesh_texspace_get(struct Mesh *me, float r_loc[3], float r_rot[3], float r_size[3]);
 +void BKE_mesh_texspace_get_reference(struct Mesh *me, short **r_texflag,  float **r_loc, float **r_rot, float **r_size);
  void BKE_mesh_texspace_copy_from_object(struct Mesh *me, struct Object *ob);
  
 -bool BKE_mesh_uv_cdlayer_rename_index(struct Mesh *me, const int poly_index, const int loop_index, const int face_index,
 -                                      const char *new_name, const bool do_tessface);
 +bool BKE_mesh_uv_cdlayer_rename_index(
 +        struct Mesh *me, const int loop_index, const int face_index,
 +        const char *new_name, const bool do_tessface);
  bool BKE_mesh_uv_cdlayer_rename(struct Mesh *me, const char *old_name, const char *new_name, bool do_tessface);
  
  float (*BKE_mesh_vertexCos_get(const struct Mesh *me, int *r_numVerts))[3];
  
  void BKE_mesh_split_faces(struct Mesh *mesh, bool free_loop_normals);
  
 +struct Mesh *BKE_mesh_new_from_object(
 +        struct Depsgraph *depsgraph, struct Main *bmain, struct Scene *sce, struct Object *ob,
 +        const bool apply_modifiers, const bool calc_tessface, const bool calc_undeformed);
 +struct Mesh *BKE_mesh_create_derived_for_modifier(
 +        struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob,
 +        struct ModifierData *md, int build_shapekey_layers);
 +
 +/* Copies a nomain-Mesh into an existing Mesh. */
 +void BKE_mesh_nomain_to_mesh(struct Mesh *mesh_src, struct Mesh *mesh_dst, struct Object *ob,
 +                             CustomDataMask mask, bool take_ownership);
 +void BKE_mesh_nomain_to_meshkey(struct Mesh *mesh_src, struct Mesh *mesh_dst, struct KeyBlock *kb);
 +
 +
  /* vertex level transformations & checks (no derived mesh) */
  
  bool BKE_mesh_minmax(const struct Mesh *me, float r_min[3], float r_max[3]);
@@@ -204,12 -140,31 +204,12 @@@ int  BKE_mesh_mselect_find(struct Mesh 
  int  BKE_mesh_mselect_active_get(struct Mesh *me, int type);
  void BKE_mesh_mselect_active_set(struct Mesh *me, int index, int type);
  
 -/* *** mesh_convert.c *** */
 -
 -void BKE_mesh_from_metaball(struct ListBase *lb, struct Mesh *me);
 -int  BKE_mesh_nurbs_to_mdata(
 -        struct Object *ob, struct MVert **r_allvert, int *r_totvert,
 -        struct MEdge **r_alledge, int *r_totedge, struct MLoop **r_allloop, struct MPoly **r_allpoly,
 -        int *r_totloop, int *r_totpoly);
 -int BKE_mesh_nurbs_displist_to_mdata(
 -        struct Object *ob, const struct ListBase *dispbase,
 -        struct MVert **r_allvert, int *r_totvert,
 -        struct MEdge **r_alledge, int *r_totedge,
 -        struct MLoop **r_allloop, struct MPoly **r_allpoly,
 -        struct MLoopUV **r_alluv, int *r_totloop, int *r_totpoly);
 -void BKE_mesh_from_nurbs_displist(
 -        struct Main *bmain, struct Object *ob, struct ListBase *dispbase, const bool use_orco_uv, const char *obdata_name);
 -void BKE_mesh_from_nurbs(struct Main *bmain, struct Object *ob);
 -void BKE_mesh_to_curve_nurblist(struct DerivedMesh *dm, struct ListBase *nurblist, const int edge_users_test);
 -void BKE_mesh_to_curve(struct Main *bmain, struct Scene *scene, struct Object *ob);
 +void BKE_mesh_apply_vert_coords(struct Mesh *mesh, float (*vertCoords)[3]);
  
 -struct Mesh *BKE_mesh_new_from_object(
 -        struct Main *bmain, struct Scene *sce, struct Object *ob,
 -        int apply_modifiers, int settings, int calc_tessface, int calc_undeformed);
  
  /* *** mesh_evaluate.c *** */
  
 +void BKE_mesh_calc_normals_mapping_simple(struct Mesh *me);
  void BKE_mesh_calc_normals_mapping(
          struct MVert *mverts, int numVerts,
          const struct MLoop *mloop, const struct MPoly *mpolys, int numLoops, int numPolys, float (*r_polyNors)[3],
@@@ -226,7 -181,6 +226,7 @@@ void BKE_mesh_calc_normals_poly
          int numLoops, int numPolys, float (*r_polyNors)[3],
          const bool only_face_normals);
  void BKE_mesh_calc_normals(struct Mesh *me);
 +void BKE_mesh_ensure_normals(struct Mesh *me);
  void BKE_mesh_calc_normals_tessface(
          struct MVert *mverts, int numVerts,
          const struct MFace *mfaces, int numFaces,
@@@ -378,7 -332,7 +378,7 @@@ void BKE_mesh_loops_to_mface_corners
          const int numTex, const int numCol,
          const bool hasPCol, const bool hasOrigSpace, const bool hasLNor);
  void BKE_mesh_loops_to_tessdata(
 -        struct CustomData *fdata, struct CustomData *ldata, struct CustomData *pdata, struct MFace *mface,
 +        struct CustomData *fdata, struct CustomData *ldata, struct MFace *mface,
          int *polyindices, unsigned int (*loopindices)[4], const int num_faces);
  void BKE_mesh_tangent_loops_to_tessdata(
          struct CustomData *fdata, struct CustomData *ldata, struct MFace *mface,
@@@ -414,19 -368,6 +414,19 @@@ void BKE_mesh_polygon_flip_ex
  void BKE_mesh_polygon_flip(struct MPoly *mpoly, struct MLoop *mloop, struct CustomData *ldata);
  void BKE_mesh_polygons_flip(struct MPoly *mpoly, struct MLoop *mloop, struct CustomData *ldata, int totpoly);
  
 +/* merge verts  */
 +/* Enum for merge_mode of CDDM_merge_verts.
 + * Refer to mesh.c for details. */
 +enum {
 +      MESH_MERGE_VERTS_DUMP_IF_MAPPED,
 +      MESH_MERGE_VERTS_DUMP_IF_EQUAL,
 +};
 +struct Mesh *BKE_mesh_merge_verts(
 +        struct Mesh *mesh,
 +        const int *vtargetmap, const int tot_vtargetmap,
 +        const int merge_mode);
 +
 +
  /* flush flags */
  void BKE_mesh_flush_hidden_from_verts_ex(
          const struct MVert *mvert,
@@@ -469,7 -410,7 +469,7 @@@ void BKE_mesh_calc_relative_deform
  /* *** mesh_validate.c *** */
  
  int BKE_mesh_validate(struct Mesh *me, const int do_verbose, const int cddata_check_mask);
 -void BKE_mesh_cd_validate(struct Mesh *me);
 +bool BKE_mesh_is_valid(struct Mesh *me);
  int BKE_mesh_validate_material_indices(struct Mesh *me);
  
  bool BKE_mesh_validate_arrays(
@@@ -499,34 -440,11 +499,34 @@@ void BKE_mesh_calc_edges(struct Mesh *m
  
  /* **** Depsgraph evaluation **** */
  
 -struct EvaluationContext;
 -
 -void BKE_mesh_eval_geometry(struct EvaluationContext *eval_ctx,
 +void BKE_mesh_eval_geometry(struct Depsgraph *depsgraph,
                              struct Mesh *mesh);
  
 +/* Draw Cache */
 +enum {
 +      BKE_MESH_BATCH_DIRTY_ALL = 0,
 +      BKE_MESH_BATCH_DIRTY_MAYBE_ALL,
 +      BKE_MESH_BATCH_DIRTY_SELECT,
 +      BKE_MESH_BATCH_DIRTY_SHADING,
 +      BKE_MESH_BATCH_DIRTY_SCULPT_COORDS,
 +};
 +void BKE_mesh_batch_cache_dirty(struct Mesh *me, int mode);
 +void BKE_mesh_batch_cache_free(struct Mesh *me);
 +
 +
 +/* Inlines */
 +
 +/* This is a copy of DM_origindex_mface_mpoly().
 + * Instead of -1 that function uses ORIGINDEX_NONE as defined in BKE_customdata.h,
 + * but I don't want to force every user of BKE_mesh.h to also include that file.
 + * ~~ Sybren */
 +BLI_INLINE int BKE_mesh_origindex_mface_mpoly(
 +        const int *index_mf_to_mpoly, const int *index_mp_to_orig, const int i)
 +{
 +      const int j = index_mf_to_mpoly[i];
 +      return (j != -1) ? (index_mp_to_orig ? index_mp_to_orig[j] : j) : -1;
 +}
 +
  #ifdef __cplusplus
  }
  #endif
@@@ -74,7 -74,6 +74,7 @@@ struct PointerRNA
  struct RenderData;
  struct Scene;
  struct Tex;
 +struct ViewRender;
  struct SpaceNode;
  struct ARegion;
  struct ColorManagedViewSettings;
@@@ -252,9 -251,8 +252,9 @@@ typedef struct bNodeType 
  #define NODE_CLASS_LAYOUT                     100
  
  /* nodetype->compatibility */
 -#define NODE_OLD_SHADING      1
 -#define NODE_NEW_SHADING      2
 +#define NODE_OLD_SHADING      (1 << 0)
 +#define NODE_NEW_SHADING      (1 << 1)
 +#define NODE_NEWER_SHADING    (1 << 2)
  
  /* node resize directions */
  #define NODE_RESIZE_TOP               1
@@@ -293,7 -291,7 +293,7 @@@ typedef struct bNodeTreeType 
        /* calls allowing threaded composite */
        void (*localize)(struct bNodeTree *localtree, struct bNodeTree *ntree);
        void (*local_sync)(struct bNodeTree *localtree, struct bNodeTree *ntree);
-       void (*local_merge)(struct bNodeTree *localtree, struct bNodeTree *ntree);
+       void (*local_merge)(struct Main *bmain, struct bNodeTree *localtree, struct bNodeTree *ntree);
  
        /* Tree update. Overrides nodetype->updatetreefunc! */
        void (*update)(struct bNodeTree *ntree);
@@@ -345,7 -343,7 +345,7 @@@ void              ntreeUserIncrefID(str
  void              ntreeUserDecrefID(struct bNodeTree *ntree);
  
  
 -struct bNodeTree *ntreeFromID(struct ID *id);
 +struct bNodeTree *ntreeFromID(const struct ID *id);
  
  void              ntreeMakeLocal(struct Main *bmain, struct bNodeTree *ntree, bool id_in_mainlist, const bool lib_local);
  struct bNode     *ntreeFindType(const struct bNodeTree *ntree, int type);
@@@ -371,7 -369,7 +371,7 @@@ int             ntreeOutputExists(struc
  void            ntreeNodeFlagSet(const bNodeTree *ntree, const int flag, const bool enable);
  struct bNodeTree *ntreeLocalize(struct bNodeTree *ntree);
  void            ntreeLocalSync(struct bNodeTree *localtree, struct bNodeTree *ntree);
- void            ntreeLocalMerge(struct bNodeTree *localtree, struct bNodeTree *ntree);
+ void            ntreeLocalMerge(struct Main *bmain, struct bNodeTree *localtree, struct bNodeTree *ntree);
  
  /** \} */
  
@@@ -498,6 -496,7 +498,6 @@@ struct bNode   *nodeGetActiveTexture(st
  void            nodeUpdate(struct bNodeTree *ntree, struct bNode *node);
  bool            nodeUpdateID(struct bNodeTree *ntree, struct ID *id);
  void            nodeUpdateInternalLinks(struct bNodeTree *ntree, struct bNode *node);
 -void            nodeSynchronizeID(struct bNode *node, bool copy_to_id);
  
  int             nodeSocketIsHidden(struct bNodeSocket *sock);
  void            ntreeTagUsedSockets(struct bNodeTree *ntree);
@@@ -691,33 -690,27 +691,33 @@@ bool BKE_node_tree_iter_step(struct Nod
  }
  /** \} */
  
 +
 +/* -------------------------------------------------------------------- */
 +/** \name Node Tree
 + */
 +
 +void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, const int layer_index);
 +
  /* -------------------------------------------------------------------- */
  /** \name Shader Nodes
   * \{ */
 -struct ShadeInput;
 -struct ShadeResult;
  
  /* note: types are needed to restore callbacks, don't change values */
  /* range 1 - 100 is reserved for common nodes */
  /* using toolbox, we add node groups by assuming the values below don't exceed NODE_GROUP_MENU for now */
  
 -#define SH_NODE_OUTPUT                1
 +//#define SH_NODE_OUTPUT              1
  
 -#define SH_NODE_MATERIAL      100
 +//#define SH_NODE_MATERIAL    100
  #define SH_NODE_RGB                   101
  #define SH_NODE_VALUE         102
  #define SH_NODE_MIX_RGB               103
  #define SH_NODE_VALTORGB      104
  #define SH_NODE_RGBTOBW               105
 -#define SH_NODE_TEXTURE               106
 +#define SH_NODE_SHADERTORGB   106
 +//#define SH_NODE_TEXTURE             106
  #define SH_NODE_NORMAL                107
 -#define SH_NODE_GEOMETRY      108
 +//#define SH_NODE_GEOMETRY    108
  #define SH_NODE_MAPPING               109
  #define SH_NODE_CURVE_VEC     110
  #define SH_NODE_CURVE_RGB     111
  #define SH_NODE_MATH          115
  #define SH_NODE_VECT_MATH     116
  #define SH_NODE_SQUEEZE               117
 -#define SH_NODE_MATERIAL_EXT  118
 +//#define SH_NODE_MATERIAL_EXT        118
  #define SH_NODE_INVERT                119
  #define SH_NODE_SEPRGB                120
  #define SH_NODE_COMBRGB               121
  #define SH_NODE_TEX_POINTDENSITY              192
  #define SH_NODE_BSDF_PRINCIPLED         193
  #define SH_NODE_TEX_IES                 194
 +#define SH_NODE_EEVEE_SPECULAR                        195
  #define SH_NODE_BEVEL                   197
  #define SH_NODE_DISPLACEMENT            198
  #define SH_NODE_VECTOR_DISPLACEMENT     199
  
  struct bNodeTreeExec *ntreeShaderBeginExecTree(struct bNodeTree *ntree);
  void            ntreeShaderEndExecTree(struct bNodeTreeExec *exec);
 -bool            ntreeShaderExecTree(struct bNodeTree *ntree, struct ShadeInput *shi, struct ShadeResult *shr);
 -void            ntreeShaderGetTexcoMode(struct bNodeTree *ntree, int osa, short *texco, int *mode);
 -
 -/* switch material render loop */
 -extern void (*node_shader_lamp_loop)(struct ShadeInput *, struct ShadeResult *);
 -void            set_node_shader_lamp_loop(void (*lamp_loop_func)(struct ShadeInput *, struct ShadeResult *));
 +bool            ntreeShaderExecTree(struct bNodeTree *ntree, int thread);
  
  void            ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMaterial *mat, short compatibility);
 +void            ntreeGPUMaterialDomain(struct bNodeTree *ntree, bool *has_surface_output, bool *has_volume_output);
  
  /** \} */
  
@@@ -986,7 -982,7 +986,7 @@@ void ntreeCompositTagRender(struct Scen
  int ntreeCompositTagAnimated(struct bNodeTree *ntree);
  void ntreeCompositTagGenerators(struct bNodeTree *ntree);
  void ntreeCompositUpdateRLayers(struct bNodeTree *ntree);
 -void ntreeCompositRegisterPass(struct bNodeTree *ntree, struct Scene *scene, struct SceneRenderLayer *srl, const char *name, int type);
 +void ntreeCompositRegisterPass(struct bNodeTree *ntree, struct Scene *scene, struct ViewLayer *view_layer, const char *name, int type);
  void ntreeCompositClearTags(struct bNodeTree *ntree);
  
  struct bNodeSocket *ntreeCompositOutputFileAddSocket(struct bNodeTree *ntree, struct bNode *node,
@@@ -1045,19 -1041,10 +1045,19 @@@ struct bNodeTreeExec *ntreeTexBeginExec
  void ntreeTexEndExecTree(struct bNodeTreeExec *exec);
  int ntreeTexExecTree(struct bNodeTree *ntree, struct TexResult *target,
                       float coord[3], float dxt[3], float dyt[3], int osatex, const short thread,
 -                     struct Tex *tex, short which_output, int cfra, int preview, struct ShadeInput *shi, struct MTex *mtex);
 +                     struct Tex *tex, short which_output, int cfra, int preview, struct MTex *mtex);
  /** \} */
  
  void init_nodesystem(void);
  void free_nodesystem(void);
  
 +/* -------------------------------------------------------------------- */
 +/* evaluation support, */
 +
 +struct Depsgraph;
 +
 +void BKE_nodetree_shading_params_eval(struct Depsgraph *depsgraph,
 +                                      struct bNodeTree *ntree_dst,
 +                                      const struct bNodeTree *ntree_src);
 +
  #endif  /* __BKE_NODE_H__ */
@@@ -442,7 -442,7 +442,7 @@@ void BKE_bpath_traverse_id(Main *bmain
                                                            /* image may have been painted onto (and not saved, T44543) */
                                                            !BKE_image_is_dirty(ima))
                                                        {
-                                                               BKE_image_signal(ima, NULL, IMA_SIGNAL_RELOAD);
+                                                               BKE_image_signal(bmain, ima, NULL, IMA_SIGNAL_RELOAD);
                                                                BKE_image_walk_all_users(bmain, ima, bpath_traverse_image_user_cb);
                                                        }
                                                }
                        }
                        break;
                }
 -              case ID_TE:
 -              {
 -                      Tex *tex = (Tex *)id;
 -                      if (tex->type == TEX_VOXELDATA && TEX_VD_IS_SOURCE_PATH(tex->vd->file_format)) {
 -                              rewrite_path_fixed(tex->vd->source_path, visit_cb, absbase, bpath_user_data);
 -                      }
 -                      break;
 -              }
                case ID_SCE:
                {
                        Scene *scene = (Scene *)id;
@@@ -82,7 -82,6 +82,7 @@@
  #include "BKE_scene.h"
  #include "BKE_node.h"
  #include "BKE_sequencer.h" /* seq_foreground_frame_get() */
 +#include "BKE_workspace.h"
  
  #include "BLF_api.h"
  
@@@ -370,6 -369,7 +370,6 @@@ static void image_init(Image *ima, shor
  
        ima->ok = IMA_OK;
  
 -      ima->xrep = ima->yrep = 1;
        ima->aspx = ima->aspy = 1.0;
        ima->gen_x = 1024; ima->gen_y = 1024;
        ima->gen_type = IMA_GENTYPE_GRID;
@@@ -472,10 -472,12 +472,10 @@@ void BKE_image_copy_data(Main *UNUSED(b
  
        BLI_listbase_clear(&ima_dst->anims);
  
 -      ima_dst->totbind = 0;
        for (int i = 0; i < TEXTARGET_COUNT; i++) {
                ima_dst->bindcode[i] = 0;
                ima_dst->gputexture[i] = NULL;
        }
 -      ima_dst->repbind = NULL;
  
        if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0) {
                BKE_previewimg_id_copy(&ima_dst->id, &ima_src->id);
@@@ -498,7 -500,7 +498,7 @@@ void BKE_image_make_local(Main *bmain, 
        BKE_id_make_local_generic(bmain, &ima->id, true, lib_local);
  }
  
- void BKE_image_merge(Image *dest, Image *source)
+ void BKE_image_merge(Main *bmain, Image *dest, Image *source)
  {
        /* sanity check */
        if (dest && source && dest != source) {
                }
                BLI_spin_unlock(&image_spin);
  
-               BKE_libblock_free(G.main, source);
+               BKE_libblock_free(bmain, source);
        }
  }
  
@@@ -615,7 -617,7 +615,7 @@@ Image *BKE_image_load(Main *bmain, cons
  /* otherwise creates new. */
  /* does not load ibuf itself */
  /* pass on optional frame for #name images */
- Image *BKE_image_load_exists_ex(const char *filepath, bool *r_exists)
+ Image *BKE_image_load_exists_ex(Main *bmain, const char *filepath, bool *r_exists)
  {
        Image *ima;
        char str[FILE_MAX], strtest[FILE_MAX];
        BLI_path_abs(str, BKE_main_blendfile_path_from_global());
  
        /* first search an identical filepath */
-       for (ima = G.main->image.first; ima; ima = ima->id.next) {
+       for (ima = bmain->image.first; ima; ima = ima->id.next) {
                if (ima->source != IMA_SRC_VIEWER && ima->source != IMA_SRC_GENERATED) {
                        STRNCPY(strtest, ima->name);
-                       BLI_path_abs(strtest, ID_BLEND_PATH(G.main, &ima->id));
+                       BLI_path_abs(strtest, ID_BLEND_PATH(bmain, &ima->id));
  
                        if (BLI_path_cmp(strtest, str) == 0) {
                                if ((BKE_image_has_anim(ima) == false) ||
  
        if (r_exists)
                *r_exists = false;
-       return BKE_image_load(G.main, filepath);
+       return BKE_image_load(bmain, filepath);
  }
  
- Image *BKE_image_load_exists(const char *filepath)
+ Image *BKE_image_load_exists(Main *bmain, const char *filepath)
  {
-       return BKE_image_load_exists_ex(filepath, NULL);
+       return BKE_image_load_exists_ex(bmain, filepath, NULL);
  }
  
  static ImBuf *add_ibuf_size(unsigned int width, unsigned int height, const char *name, int depth, int floatbuf, short gen_type,
@@@ -753,7 -755,7 +753,7 @@@ Image *BKE_image_add_generated
  /* Create an image image from ibuf. The refcount of ibuf is increased,
   * caller should take care to drop its reference by calling
   * IMB_freeImBuf if needed. */
- Image *BKE_image_add_from_imbuf(ImBuf *ibuf, const char *name)
+ Image *BKE_image_add_from_imbuf(Main *bmain, ImBuf *ibuf, const char *name)
  {
        /* on save, type is changed to FILE in editsima.c */
        Image *ima;
                name = BLI_path_basename(ibuf->name);
        }
  
-       ima = image_alloc(G.main, name, IMA_SRC_FILE, IMA_TYPE_IMAGE);
+       ima = image_alloc(bmain, name, IMA_SRC_FILE, IMA_TYPE_IMAGE);
  
        if (ima) {
                STRNCPY(ima->name, ibuf->name);
@@@ -931,12 -933,12 +931,12 @@@ void BKE_image_tag_time(Image *ima
  }
  
  #if 0
- static void tag_all_images_time()
+ static void tag_all_images_time(Main *bmain)
  {
        Image *ima;
        int ctime = PIL_check_seconds_timer_i();
  
-       ima = G.main->image.first;
+       ima = bmain->image.first;
        while (ima) {
                if (ima->bindcode || ima->repbind || ima->ibufs.first) {
                        ima->lastused = ctime;
@@@ -990,17 -992,17 +990,17 @@@ static uintptr_t image_mem_size(Image *
        return size;
  }
  
- void BKE_image_print_memlist(void)
+ void BKE_image_print_memlist(Main *bmain)
  {
        Image *ima;
        uintptr_t size, totsize = 0;
  
-       for (ima = G.main->image.first; ima; ima = ima->id.next)
+       for (ima = bmain->image.first; ima; ima = ima->id.next)
                totsize += image_mem_size(ima);
  
        printf("\ntotal image memory len: %.3f MB\n", (double)totsize / (double)(1024 * 1024));
  
-       for (ima = G.main->image.first; ima; ima = ima->id.next) {
+       for (ima = bmain->image.first; ima; ima = ima->id.next) {
                size = image_mem_size(ima);
  
                if (size)
@@@ -1013,7 -1015,7 +1013,7 @@@ static bool imagecache_check_dirty(ImBu
        return (ibuf->userflags & IB_BITMAPDIRTY) == 0;
  }
  
- void BKE_image_free_all_textures(void)
+ void BKE_image_free_all_textures(Main *bmain)
  {
  #undef CHECK_FREED_SIZE
  
        uintptr_t tot_freed_size = 0;
  #endif
  
-       for (ima = G.main->image.first; ima; ima = ima->id.next)
+       for (ima = bmain->image.first; ima; ima = ima->id.next)
                ima->id.tag &= ~LIB_TAG_DOIT;
  
-       for (tex = G.main->tex.first; tex; tex = tex->id.next)
+       for (tex = bmain->tex.first; tex; tex = tex->id.next)
                if (tex->ima)
                        tex->ima->id.tag |= LIB_TAG_DOIT;
  
-       for (ima = G.main->image.first; ima; ima = ima->id.next) {
+       for (ima = bmain->image.first; ima; ima = ima->id.next) {
                if (ima->cache && (ima->id.tag & LIB_TAG_DOIT)) {
  #ifdef CHECK_FREED_SIZE
                        uintptr_t old_size = image_mem_size(ima);
@@@ -1066,11 -1068,11 +1066,11 @@@ void BKE_image_free_anim_ibufs(Image *i
        BLI_spin_unlock(&image_spin);
  }
  
- void BKE_image_all_free_anim_ibufs(int cfra)
+ void BKE_image_all_free_anim_ibufs(Main *bmain, int cfra)
  {
        Image *ima;
  
-       for (ima = G.main->image.first; ima; ima = ima->id.next)
+       for (ima = bmain->image.first; ima; ima = ima->id.next)
                if (BKE_image_is_animated(ima))
                        BKE_image_free_anim_ibufs(ima, cfra);
  }
@@@ -1206,6 -1208,7 +1206,6 @@@ bool BKE_imtype_is_movie(const char imt
                case R_IMF_IMTYPE_H264:
                case R_IMF_IMTYPE_THEORA:
                case R_IMF_IMTYPE_XVID:
 -              case R_IMF_IMTYPE_FRAMESERVER:
                        return true;
        }
        return false;
@@@ -1346,6 -1349,7 +1346,6 @@@ char BKE_imtype_from_arg(const char *im
        else if (STREQ(imtype_arg, "MULTILAYER")) return R_IMF_IMTYPE_MULTILAYER;
  #endif
        else if (STREQ(imtype_arg, "FFMPEG")) return R_IMF_IMTYPE_FFMPEG;
 -      else if (STREQ(imtype_arg, "FRAMESERVER")) return R_IMF_IMTYPE_FRAMESERVER;
  #ifdef WITH_CINEON
        else if (STREQ(imtype_arg, "CINEON")) return R_IMF_IMTYPE_CINEON;
        else if (STREQ(imtype_arg, "DPX")) return R_IMF_IMTYPE_DPX;
@@@ -2548,17 -2552,17 +2548,17 @@@ struct anim *openanim(const char *name
  
  /* forces existence of 1 Image for renderout or nodes, returns Image */
  /* name is only for default, when making new one */
- Image *BKE_image_verify_viewer(int type, const char *name)
+ Image *BKE_image_verify_viewer(Main *bmain, int type, const char *name)
  {
        Image *ima;
  
-       for (ima = G.main->image.first; ima; ima = ima->id.next)
+       for (ima = bmain->image.first; ima; ima = ima->id.next)
                if (ima->source == IMA_SRC_VIEWER)
                        if (ima->type == type)
                                break;
  
        if (ima == NULL)
-               ima = image_alloc(G.main, name, IMA_SRC_VIEWER, type);
+               ima = image_alloc(bmain, name, IMA_SRC_VIEWER, type);
  
        /* happens on reload, imagewindow cannot be image user when hidden*/
        if (ima->id.us == 0)
@@@ -2650,19 -2654,19 +2650,19 @@@ void BKE_image_walk_all_users(const Mai
                }
        }
  
 +      for (Camera *cam = mainp->camera.first; cam; cam = cam->id.next) {
 +              for (CameraBGImage *bgpic = cam->bg_images.first; bgpic; bgpic = bgpic->next) {
 +                      callback(bgpic->ima, &bgpic->iuser, customdata);
 +              }
 +      }
 +
        /* image window, compo node users */
        for (wm = mainp->wm.first; wm; wm = wm->id.next) { /* only 1 wm */
                for (win = wm->windows.first; win; win = win->next) {
 -                      ScrArea *sa;
 -                      for (sa = win->screen->areabase.first; sa; sa = sa->next) {
 -                              if (sa->spacetype == SPACE_VIEW3D) {
 -                                      View3D *v3d = sa->spacedata.first;
 -                                      BGpic *bgpic;
 -                                      for (bgpic = v3d->bgpicbase.first; bgpic; bgpic = bgpic->next) {
 -                                              callback(bgpic->ima, &bgpic->iuser, customdata);
 -                                      }
 -                              }
 -                              else if (sa->spacetype == SPACE_IMAGE) {
 +                      const bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook);
 +
 +                      for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
 +                              if (sa->spacetype == SPACE_IMAGE) {
                                        SpaceImage *sima = sa->spacedata.first;
                                        callback(sima->image, &sima->iuser, customdata);
                                }
@@@ -2709,7 -2713,7 +2709,7 @@@ void BKE_image_init_imageuser(Image *im
        image_init_imageuser(ima, iuser);
  }
  
- void BKE_image_signal(Image *ima, ImageUser *iuser, int signal)
+ void BKE_image_signal(Main *bmain, Image *ima, ImageUser *iuser, int signal)
  {
        if (ima == NULL)
                return;
                        if (iuser)
                                iuser->ok = 1;
  
-                       BKE_image_walk_all_users(G.main, ima, image_tag_frame_recalc);
+                       BKE_image_walk_all_users(bmain, ima, image_tag_frame_recalc);
  
                        break;
  
                                if (totfiles != BLI_listbase_count_at_most(&ima->packedfiles, totfiles + 1)) {
                                        /* in case there are new available files to be loaded */
                                        image_free_packedfiles(ima);
-                                       BKE_image_packfiles(NULL, ima, ID_BLEND_PATH(G.main, &ima->id));
+                                       BKE_image_packfiles(NULL, ima, ID_BLEND_PATH(bmain, &ima->id));
                                }
                                else {
                                        ImagePackedFile *imapf;
                                        for (imapf = ima->packedfiles.first; imapf; imapf = imapf->next) {
                                                PackedFile *pf;
-                                               pf = newPackedFile(NULL, imapf->filepath, ID_BLEND_PATH(G.main, &ima->id));
+                                               pf = newPackedFile(NULL, imapf->filepath, ID_BLEND_PATH(bmain, &ima->id));
                                                if (pf) {
                                                        freePackedFile(imapf->packedfile);
                                                        imapf->packedfile = pf;
         * this also makes sure all scenes are accounted for. */
        {
                Scene *scene;
-               for (scene = G.main->scene.first; scene; scene = scene->id.next) {
+               for (scene = bmain->scene.first; scene; scene = scene->id.next) {
                        if (scene->nodetree) {
                                nodeUpdateID(scene->nodetree, &ima->id);
                        }
@@@ -3533,7 -3537,7 +3533,7 @@@ static ImBuf *load_image_single
                                BLI_addtail(&ima->packedfiles, imapf);
  
                                STRNCPY(imapf->filepath, filepath);
-                               imapf->packedfile = newPackedFile(NULL, filepath, ID_BLEND_PATH(G.main, &ima->id));
+                               imapf->packedfile = newPackedFile(NULL, filepath, ID_BLEND_PATH_FROM_GLOBAL(&ima->id));
                        }
                }
        }
@@@ -4371,7 -4375,7 +4371,7 @@@ void BKE_image_user_file_path(ImageUse
                BLI_stringenc(filepath, head, tail, numlen, frame);
        }
  
-       BLI_path_abs(filepath, ID_BLEND_PATH(G.main, &ima->id));
+       BLI_path_abs(filepath, ID_BLEND_PATH_FROM_GLOBAL(&ima->id));
  }
  
  bool BKE_image_has_alpha(struct Image *image)
   *  \ingroup bke
   */
  
 +
  #include "MEM_guardedalloc.h"
  
  #include "DNA_scene_types.h"
 +#include "DNA_key_types.h"
  #include "DNA_material_types.h"
  #include "DNA_meta_types.h"
  #include "DNA_object_types.h"
  #include "BKE_main.h"
  #include "BKE_DerivedMesh.h"
  #include "BKE_global.h"
 +#include "BKE_key.h"
  #include "BKE_mesh.h"
 +#include "BKE_mesh_runtime.h"
 +#include "BKE_modifier.h"
  #include "BKE_displist.h"
  #include "BKE_library.h"
  #include "BKE_material.h"
 -#include "BKE_modifier.h"
  #include "BKE_mball.h"
 -#include "BKE_depsgraph.h"
 +/* these 2 are only used by conversion functions */
  #include "BKE_curve.h"
  /* -- */
  #include "BKE_object.h"
  
  #include "DEG_depsgraph.h"
 +#include "DEG_depsgraph_query.h"
  
  /* Define for cases when you want extra validation of mesh
   * after certain modifications.
   */
  // #undef VALIDATE_MESH
  
 +#ifdef VALIDATE_MESH
 +#  define ASSERT_IS_VALID_MESH(mesh) (BLI_assert((mesh == NULL) || (BKE_mesh_is_valid(mesh) == true)))
 +#else
 +#  define ASSERT_IS_VALID_MESH(mesh)
 +#endif
 +
  void BKE_mesh_from_metaball(ListBase *lb, Mesh *me)
  {
        DispList *dl;
@@@ -490,63 -479,11 +490,63 @@@ int BKE_mesh_nurbs_displist_to_mdata
        return 0;
  }
  
 +Mesh *BKE_mesh_new_nomain_from_curve_displist(Object *ob, ListBase *dispbase)
 +{
 +      Curve *cu = ob->data;
 +      Mesh *mesh;
 +      MVert *allvert;
 +      MEdge *alledge;
 +      MLoop *allloop;
 +      MPoly *allpoly;
 +      MLoopUV *alluv = NULL;
 +      int totvert, totedge, totloop, totpoly;
 +      bool use_orco_uv = (cu->flag & CU_UV_ORCO) != 0;
 +
 +      if (BKE_mesh_nurbs_displist_to_mdata(
 +              ob, dispbase, &allvert, &totvert, &alledge,
 +              &totedge, &allloop, &allpoly, (use_orco_uv) ? &alluv : NULL,
 +              &totloop, &totpoly) != 0)
 +      {
 +              /* Error initializing mdata. This often happens when curve is empty */
 +              return BKE_mesh_new_nomain(0, 0, 0, 0, 0);
 +      }
 +
 +      mesh = BKE_mesh_new_nomain(totvert, totedge, 0, totloop, totpoly);
 +      mesh->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
 +
 +      memcpy(mesh->mvert, allvert, totvert * sizeof(MVert));
 +      memcpy(mesh->medge, alledge, totedge * sizeof(MEdge));
 +      memcpy(mesh->mloop, allloop, totloop * sizeof(MLoop));
 +      memcpy(mesh->mpoly, allpoly, totpoly * sizeof(MPoly));
 +
 +      if (alluv) {
 +              const char *uvname = "Orco";
 +              CustomData_add_layer_named(&mesh->ldata, CD_MLOOPUV, CD_ASSIGN, alluv, totloop, uvname);
 +      }
 +
 +      MEM_freeN(allvert);
 +      MEM_freeN(alledge);
 +      MEM_freeN(allloop);
 +      MEM_freeN(allpoly);
 +
 +      return mesh;
 +}
 +
 +Mesh *BKE_mesh_new_nomain_from_curve(Object *ob)
 +{
 +      ListBase disp = {NULL, NULL};
 +
 +      if (ob->curve_cache) {
 +              disp = ob->curve_cache->disp;
 +      }
 +
 +      return BKE_mesh_new_nomain_from_curve_displist(ob, &disp);
 +}
  
  /* this may fail replacing ob->data, be sure to check ob->type */
- void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, const bool use_orco_uv, const char *obdata_name, bool temporary)
+ void BKE_mesh_from_nurbs_displist(
 -        Main *bmain, Object *ob, ListBase *dispbase, const bool use_orco_uv, const char *obdata_name)
++        Main *bmain, Object *ob, ListBase *dispbase, const bool use_orco_uv, const char *obdata_name, bool temporary)
  {
-       Main *bmain = G.main;
        Object *ob1;
        DerivedMesh *dm = ob->derivedFinal;
        Mesh *me;
  
                if (alluv) {
                        const char *uvname = "Orco";
 -                      me->mtpoly = CustomData_add_layer_named(&me->pdata, CD_MTEXPOLY, CD_DEFAULT, NULL, me->totpoly, uvname);
                        me->mloopuv = CustomData_add_layer_named(&me->ldata, CD_MLOOPUV, CD_ASSIGN, alluv, me->totloop, uvname);
                }
  
                ob1 = ob1->id.next;
        }
  
 -      BKE_libblock_free_us(bmain, cu);
 +      if (temporary) {
 +              /* For temporary objects in BKE_mesh_new_from_object don't remap
 +               * the entire scene with associated depsgraph updates, which are
 +               * problematic for renderers exporting data. */
 +              id_us_min(&cu->id);
 +              BKE_libblock_free(bmain, cu);
 +      }
 +      else {
 +              BKE_libblock_free_us(bmain, cu);
 +      }
  }
  
- void BKE_mesh_from_nurbs(Object *ob)
+ void BKE_mesh_from_nurbs(Main *bmain, Object *ob)
  {
        Curve *cu = (Curve *) ob->data;
        bool use_orco_uv = (cu->flag & CU_UV_ORCO) != 0;
                disp = ob->curve_cache->disp;
        }
  
-       BKE_mesh_from_nurbs_displist(ob, &disp, use_orco_uv, cu->id.name, false);
 -      BKE_mesh_from_nurbs_displist(bmain, ob, &disp, use_orco_uv, cu->id.name);
++      BKE_mesh_from_nurbs_displist(bmain, ob, &disp, use_orco_uv, cu->id.name, false);
  }
  
  typedef struct EdgeLink {
@@@ -679,15 -608,15 +679,15 @@@ static void appendPolyLineVert(ListBas
        BLI_addtail(lb, vl);
  }
  
 -void BKE_mesh_to_curve_nurblist(DerivedMesh *dm, ListBase *nurblist, const int edge_users_test)
 +void BKE_mesh_to_curve_nurblist(const Mesh *me, ListBase *nurblist, const int edge_users_test)
  {
 -      MVert       *mvert = dm->getVertArray(dm);
 -      MEdge *med, *medge = dm->getEdgeArray(dm);
 -      MPoly *mp,  *mpoly = dm->getPolyArray(dm);
 -      MLoop       *mloop = dm->getLoopArray(dm);
 +      MVert       *mvert = me->mvert;
 +      MEdge *med, *medge = me->medge;
 +      MPoly *mp,  *mpoly = me->mpoly;
 +      MLoop       *mloop = me->mloop;
  
 -      int dm_totedge = dm->getNumEdges(dm);
 -      int dm_totpoly = dm->getNumPolys(dm);
 +      int medge_len = me->totedge;
 +      int mpoly_len = me->totpoly;
        int totedges = 0;
        int i;
  
        ListBase edges = {NULL, NULL};
  
        /* get boundary edges */
 -      edge_users = MEM_calloc_arrayN(dm_totedge, sizeof(int), __func__);
 -      for (i = 0, mp = mpoly; i < dm_totpoly; i++, mp++) {
 +      edge_users = MEM_calloc_arrayN(medge_len, sizeof(int), __func__);
 +      for (i = 0, mp = mpoly; i < mpoly_len; i++, mp++) {
                MLoop *ml = &mloop[mp->loopstart];
                int j;
                for (j = 0; j < mp->totloop; j++, ml++) {
  
        /* create edges from all faces (so as to find edges not in any faces) */
        med = medge;
 -      for (i = 0; i < dm_totedge; i++, med++) {
 +      for (i = 0; i < medge_len; i++, med++) {
                if (edge_users[i] == edge_users_test) {
                        EdgeLink *edl = MEM_callocN(sizeof(EdgeLink), "EdgeLink");
                        edl->edge = med;
        }
  }
  
- void BKE_mesh_to_curve(Depsgraph *depsgraph, Scene *scene, Object *ob)
 -void BKE_mesh_to_curve(Main *bmain, Scene *scene, Object *ob)
++void BKE_mesh_to_curve(Main *bmain, Depsgraph *depsgraph, Scene *scene, Object *ob)
  {
        /* make new mesh data from the original copy */
 -      DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_MESH);
 +      Mesh *me_eval = mesh_get_eval_final(depsgraph, scene, ob, CD_MASK_MESH);
        ListBase nurblist = {NULL, NULL};
        bool needsFree = false;
  
 -      BKE_mesh_to_curve_nurblist(dm, &nurblist, 0);
 -      BKE_mesh_to_curve_nurblist(dm, &nurblist, 1);
 +      BKE_mesh_to_curve_nurblist(me_eval, &nurblist, 0);
 +      BKE_mesh_to_curve_nurblist(me_eval, &nurblist, 1);
  
        if (nurblist.first) {
-               Curve *cu = BKE_curve_add(G.main, ob->id.name + 2, OB_CURVE);
+               Curve *cu = BKE_curve_add(bmain, ob->id.name + 2, OB_CURVE);
                cu->flag |= CU_3D;
  
                cu->nurb = nurblist;
                needsFree = true;
        }
  
 -      dm->needsFree = needsFree;
 -      dm->release(dm);
 +      /* Just to avoid dangling pointer, dm will be removed. */
 +      {
 +              DerivedMesh *dm = ob->derivedFinal;
 +              if (dm != NULL) {
 +                      dm->needsFree = needsFree;
 +                      dm->release(dm);
 +              }
 +      }
  
        if (needsFree) {
 +              BKE_mesh_free(me_eval);
 +
                ob->derivedFinal = NULL;
 +              ob->runtime.mesh_eval = NULL;
  
                /* curve object could have got bounding box only in special cases */
                if (ob->bb) {
  
  /* settings: 1 - preview, 2 - render */
  Mesh *BKE_mesh_new_from_object(
 -        Main *bmain, Scene *sce, Object *ob,
 -        int apply_modifiers, int settings, int calc_tessface, int calc_undeformed)
 +        Depsgraph *depsgraph, Main *bmain, Scene *sce, Object *ob,
 +        const bool apply_modifiers, const bool calc_tessface, const bool calc_undeformed)
  {
        Mesh *tmpmesh;
        Curve *tmpcu = NULL, *copycu;
        int i;
 -      const bool render = (settings == eModifierMode_Render);
 +      const bool render = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
        const bool cage = !apply_modifiers;
        bool do_mat_id_data_us = true;
  
                        /* copies object and modifiers (but not the data) */
                        Object *tmpobj;
                        /* TODO: make it temp copy outside bmain! */
 -                      BKE_id_copy_ex(bmain, &ob->id, (ID **)&tmpobj, LIB_ID_COPY_CACHES, false);
 +                      BKE_id_copy_ex(bmain, &ob->id, (ID **)&tmpobj, LIB_ID_COPY_CACHES | LIB_ID_CREATE_NO_DEG_TAG, false);
                        tmpcu = (Curve *)tmpobj->data;
 -                      id_us_min(&tmpcu->id);
  
                        /* Copy cached display list, it might be needed by the stack evaluation.
                         * Ideally stack should be able to use render-time display list, but doing
                                BKE_object_free_modifiers(tmpobj, 0);
  
                        /* copies the data */
 -                      copycu = tmpobj->data = BKE_curve_copy(bmain, (Curve *) ob->data);
 +                      BKE_id_copy_ex(bmain, ob->data, (ID **)&copycu, LIB_ID_CREATE_NO_DEG_TAG, false);
 +                      tmpobj->data = copycu;
  
                        /* make sure texture space is calculated for a copy of curve,
                         * it will be used for the final result.
                        copycu->editnurb = tmpcu->editnurb;
  
                        /* get updated display list, and convert to a mesh */
 -                      BKE_displist_make_curveTypes_forRender(sce, tmpobj, &dispbase, &derivedFinal, false, render);
 +                      BKE_displist_make_curveTypes_forRender(depsgraph, sce, tmpobj, &dispbase, &derivedFinal, false, render);
  
                        copycu->editfont = NULL;
                        copycu->editnurb = NULL;
  
                        /* convert object type to mesh */
                        uv_from_orco = (tmpcu->flag & CU_UV_ORCO) != 0;
-                       BKE_mesh_from_nurbs_displist(tmpobj, &dispbase, uv_from_orco, tmpcu->id.name + 2, true);
 -                      BKE_mesh_from_nurbs_displist(bmain, tmpobj, &dispbase, uv_from_orco, tmpcu->id.name + 2);
++                      BKE_mesh_from_nurbs_displist(bmain, tmpobj, &dispbase, uv_from_orco, tmpcu->id.name + 2, true);
  
                        tmpmesh = tmpobj->data;
  
                         * if it didn't the curve did not have any segments or otherwise
                         * would have generated an empty mesh */
                        if (tmpobj->type != OB_MESH) {
 -                              BKE_libblock_free_us(bmain, tmpobj);
 +                              BKE_libblock_free(bmain, tmpobj);
                                return NULL;
                        }
  
 -                      BKE_libblock_free_us(bmain, tmpobj);
 +                      BKE_libblock_free(bmain, tmpobj);
  
                        /* XXX The curve to mesh conversion is convoluted... But essentially, BKE_mesh_from_nurbs_displist()
                         *     already transfers the ownership of materials from the temp copy of the Curve ID to the new
                case OB_MBALL:
                {
                        /* metaballs don't have modifiers, so just convert to mesh */
 -                      Object *basis_ob = BKE_mball_basis_find(bmain, bmain->eval_ctx, sce, ob);
 +                      Object *basis_ob = BKE_mball_basis_find(sce, ob);
                        /* todo, re-generatre for render-res */
                        /* metaball_polygonize(scene, ob) */
  
  
                        if (render) {
                                ListBase disp = {NULL, NULL};
 -                              /* TODO(sergey): This is gonna to work for until EvaluationContext
 -                               *               only contains for_render flag. As soon as CoW is
 -                               *               implemented, this is to be rethought.
 -                               */
 -                              EvaluationContext eval_ctx;
 -                              DEG_evaluation_context_init(&eval_ctx, DAG_EVAL_RENDER);
 -                              BKE_displist_make_mball_forRender(bmain, &eval_ctx, sce, ob, &disp);
 +                              BKE_displist_make_mball_forRender(depsgraph, sce, ob, &disp);
                                BKE_mesh_from_metaball(&disp, tmpmesh);
                                BKE_displist_free(&disp);
                        }
  
                                /* Write the display mesh into the dummy mesh */
                                if (render)
 -                                      dm = mesh_create_derived_render(sce, ob, mask);
 +                                      dm = mesh_create_derived_render(depsgraph, sce, ob, mask);
                                else
 -                                      dm = mesh_create_derived_view(sce, ob, mask);
 +                                      dm = mesh_create_derived_view(depsgraph, sce, ob, mask);
  
                                tmpmesh = BKE_mesh_add(bmain, ((ID *)ob->data)->name + 2);
                                DM_to_mesh(dm, tmpmesh, ob, mask, true);
  
        return tmpmesh;
  }
 +
 +
 +static void add_shapekey_layers(Mesh *mesh_dest, Mesh *mesh_src)
 +{
 +      KeyBlock *kb;
 +      Key *key = mesh_src->key;
 +      int i;
 +
 +      if (!mesh_src->key)
 +              return;
 +
 +      /* ensure we can use mesh vertex count for derived mesh custom data */
 +      if (mesh_src->totvert != mesh_dest->totvert) {
 +              fprintf(stderr,
 +                      "%s: vertex size mismatch (mesh/dm) '%s' (%d != %d)\n",
 +                      __func__, mesh_src->id.name + 2, mesh_src->totvert, mesh_dest->totvert);
 +              return;
 +      }
 +
 +      for (i = 0, kb = key->block.first; kb; kb = kb->next, i++) {
 +              int ci;
 +              float *array;
 +
 +              if (mesh_src->totvert != kb->totelem) {
 +                      fprintf(stderr,
 +                              "%s: vertex size mismatch (Mesh '%s':%d != KeyBlock '%s':%d)\n",
 +                              __func__, mesh_src->id.name + 2, mesh_src->totvert, kb->name, kb->totelem);
 +                      array = MEM_calloc_arrayN((size_t)mesh_src->totvert, 3 * sizeof(float), __func__);
 +              }
 +              else {
 +                      array = MEM_malloc_arrayN((size_t)mesh_src->totvert, 3 * sizeof(float), __func__);
 +                      memcpy(array, kb->data, (size_t)mesh_src->totvert * 3 * sizeof(float));
 +              }
 +
 +              CustomData_add_layer_named(&mesh_dest->vdata, CD_SHAPEKEY, CD_ASSIGN, array, mesh_dest->totvert, kb->name);
 +              ci = CustomData_get_layer_index_n(&mesh_dest->vdata, CD_SHAPEKEY, i);
 +
 +              mesh_dest->vdata.layers[ci].uid = kb->uid;
 +      }
 +}
 +
 +
 +Mesh *BKE_mesh_create_derived_for_modifier(
 +        struct Depsgraph *depsgraph, Scene *scene, Object *ob,
 +        ModifierData *md, int build_shapekey_layers)
 +{
 +      Mesh *me = ob->data;
 +      const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
 +      Mesh *result;
 +      KeyBlock *kb;
 +      ModifierEvalContext mectx = {depsgraph, ob, 0};
 +
 +      md->scene = scene;
 +
 +      if (!(md->mode & eModifierMode_Realtime)) {
 +              return NULL;
 +      }
 +
 +      if (mti->isDisabled && mti->isDisabled(md, 0)) {
 +              return NULL;
 +      }
 +
 +      if (build_shapekey_layers && me->key && (kb = BLI_findlink(&me->key->block, ob->shapenr - 1))) {
 +              BKE_keyblock_convert_to_mesh(kb, me);
 +      }
 +
 +      if (mti->type == eModifierTypeType_OnlyDeform) {
 +              int numVerts;
 +              float (*deformedVerts)[3] = BKE_mesh_vertexCos_get(me, &numVerts);
 +
 +              modifier_deformVerts(md, &mectx, NULL, deformedVerts, numVerts);
 +              BKE_id_copy_ex(NULL, &me->id, (ID **)&result,
 +                             LIB_ID_CREATE_NO_MAIN |
 +                             LIB_ID_CREATE_NO_USER_REFCOUNT |
 +                             LIB_ID_CREATE_NO_DEG_TAG |
 +                             LIB_ID_COPY_NO_PREVIEW,
 +                             false);
 +              BKE_mesh_apply_vert_coords(result, deformedVerts);
 +
 +              if (build_shapekey_layers)
 +                      add_shapekey_layers(result, me);
 +
 +              MEM_freeN(deformedVerts);
 +      }
 +      else {
 +              Mesh *mesh_temp;
 +              BKE_id_copy_ex(NULL, &me->id, (ID **)&mesh_temp,
 +                             LIB_ID_CREATE_NO_MAIN |
 +                             LIB_ID_CREATE_NO_USER_REFCOUNT |
 +                             LIB_ID_CREATE_NO_DEG_TAG |
 +                             LIB_ID_COPY_NO_PREVIEW,
 +                             false);
 +
 +              if (build_shapekey_layers)
 +                      add_shapekey_layers(mesh_temp, me);
 +
 +              result = modifier_applyModifier(md, &mectx, mesh_temp);
 +              ASSERT_IS_VALID_MESH(result);
 +
 +              if (mesh_temp != result) {
 +                      BKE_id_free(NULL, mesh_temp);
 +              }
 +      }
 +
 +      return result;
 +}
 +
 +/* This is a Mesh-based copy of the same function in DerivedMesh.c */
 +static void shapekey_layers_to_keyblocks(Mesh *mesh_src, Mesh *mesh_dst, int actshape_uid)
 +{
 +      KeyBlock *kb;
 +      int i, j, tot;
 +
 +      if (!mesh_dst->key)
 +              return;
 +
 +      tot = CustomData_number_of_layers(&mesh_src->vdata, CD_SHAPEKEY);
 +      for (i = 0; i < tot; i++) {
 +              CustomDataLayer *layer = &mesh_src->vdata.layers[CustomData_get_layer_index_n(&mesh_src->vdata, CD_SHAPEKEY, i)];
 +              float (*cos)[3], (*kbcos)[3];
 +
 +              for (kb = mesh_dst->key->block.first; kb; kb = kb->next) {
 +                      if (kb->uid == layer->uid)
 +                              break;
 +              }
 +
 +              if (!kb) {
 +                      kb = BKE_keyblock_add(mesh_dst->key, layer->name);
 +                      kb->uid = layer->uid;
 +              }
 +
 +              if (kb->data)
 +                      MEM_freeN(kb->data);
 +
 +              cos = CustomData_get_layer_n(&mesh_src->vdata, CD_SHAPEKEY, i);
 +              kb->totelem = mesh_src->totvert;
 +
 +              kb->data = kbcos = MEM_malloc_arrayN(kb->totelem, 3 * sizeof(float), "kbcos DerivedMesh.c");
 +              if (kb->uid == actshape_uid) {
 +                      MVert *mvert = mesh_src->mvert;
 +
 +                      for (j = 0; j < mesh_src->totvert; j++, kbcos++, mvert++) {
 +                              copy_v3_v3(*kbcos, mvert->co);
 +                      }
 +              }
 +              else {
 +                      for (j = 0; j < kb->totelem; j++, cos++, kbcos++) {
 +                              copy_v3_v3(*kbcos, *cos);
 +                      }
 +              }
 +      }
 +
 +      for (kb = mesh_dst->key->block.first; kb; kb = kb->next) {
 +              if (kb->totelem != mesh_src->totvert) {
 +                      if (kb->data)
 +                              MEM_freeN(kb->data);
 +
 +                      kb->totelem = mesh_src->totvert;
 +                      kb->data = MEM_calloc_arrayN(kb->totelem, 3 * sizeof(float), "kb->data derivedmesh.c");
 +                      fprintf(stderr, "%s: lost a shapekey layer: '%s'! (bmesh internal error)\n", __func__, kb->name);
 +              }
 +      }
 +}
 +
 +
 +/* This is a Mesh-based copy of DM_to_mesh() */
 +void BKE_mesh_nomain_to_mesh(Mesh *mesh_src, Mesh *mesh_dst, Object *ob, CustomDataMask mask, bool take_ownership)
 +{
 +      /* mesh_src might depend on mesh_dst, so we need to do everything with a local copy */
 +      /* TODO(Sybren): the above claim came from DM_to_mesh(); check whether it is still true with Mesh */
 +      Mesh tmp = *mesh_dst;
 +      int totvert, totedge /*, totface */ /* UNUSED */, totloop, totpoly;
 +      int did_shapekeys = 0;
 +      eCDAllocType alloctype = CD_DUPLICATE;
 +
 +      if (take_ownership /* && dm->type == DM_TYPE_CDDM && dm->needsFree */) {
 +              bool has_any_referenced_layers =
 +                      CustomData_has_referenced(&mesh_src->vdata) ||
 +                      CustomData_has_referenced(&mesh_src->edata) ||
 +                      CustomData_has_referenced(&mesh_src->ldata) ||
 +                      CustomData_has_referenced(&mesh_src->fdata) ||
 +                      CustomData_has_referenced(&mesh_src->pdata);
 +              if (!has_any_referenced_layers) {
 +                      alloctype = CD_ASSIGN;
 +              }
 +      }
 +      CustomData_reset(&tmp.vdata);
 +      CustomData_reset(&tmp.edata);
 +      CustomData_reset(&tmp.fdata);
 +      CustomData_reset(&tmp.ldata);
 +      CustomData_reset(&tmp.pdata);
 +
 +      BKE_mesh_ensure_normals(mesh_src);
 +
 +      totvert = tmp.totvert = mesh_src->totvert;
 +      totedge = tmp.totedge = mesh_src->totedge;
 +      totloop = tmp.totloop = mesh_src->totloop;
 +      totpoly = tmp.totpoly = mesh_src->totpoly;
 +      tmp.totface = 0;
 +
 +      CustomData_copy(&mesh_src->vdata, &tmp.vdata, mask, alloctype, totvert);
 +      CustomData_copy(&mesh_src->edata, &tmp.edata, mask, alloctype, totedge);
 +      CustomData_copy(&mesh_src->ldata, &tmp.ldata, mask, alloctype, totloop);
 +      CustomData_copy(&mesh_src->pdata, &tmp.pdata, mask, alloctype, totpoly);
 +      tmp.cd_flag = mesh_src->cd_flag;
 +      tmp.runtime.deformed_only = mesh_src->runtime.deformed_only;
 +
 +      if (CustomData_has_layer(&mesh_src->vdata, CD_SHAPEKEY)) {
 +              KeyBlock *kb;
 +              int uid;
 +
 +              if (ob) {
 +                      kb = BLI_findlink(&mesh_dst->key->block, ob->shapenr - 1);
 +                      if (kb) {
 +                              uid = kb->uid;
 +                      }
 +                      else {
 +                              printf("%s: error - could not find active shapekey %d!\n",
 +                                     __func__, ob->shapenr - 1);
 +
 +                              uid = INT_MAX;
 +                      }
 +              }
 +              else {
 +                      /* if no object, set to INT_MAX so we don't mess up any shapekey layers */
 +                      uid = INT_MAX;
 +              }
 +
 +              shapekey_layers_to_keyblocks(mesh_src, mesh_dst, uid);
 +              did_shapekeys = 1;
 +      }
 +
 +      /* copy texture space */
 +      if (ob) {
 +              BKE_mesh_texspace_copy_from_object(&tmp, ob);
 +      }
 +
 +      /* not all DerivedMeshes store their verts/edges/faces in CustomData, so
 +       * we set them here in case they are missing */
 +      /* TODO(Sybren): we could probably replace CD_ASSIGN with alloctype and always directly pass mesh_src->mxxx,
 +       * instead of using a ternary operator. */
 +      if (!CustomData_has_layer(&tmp.vdata, CD_MVERT)) {
 +              CustomData_add_layer(&tmp.vdata, CD_MVERT, CD_ASSIGN,
 +                                   (alloctype == CD_ASSIGN) ? mesh_src->mvert : MEM_dupallocN(mesh_src->mvert),
 +                                   totvert);
 +      }
 +      if (!CustomData_has_layer(&tmp.edata, CD_MEDGE)) {
 +              CustomData_add_layer(&tmp.edata, CD_MEDGE, CD_ASSIGN,
 +                                   (alloctype == CD_ASSIGN) ? mesh_src->medge : MEM_dupallocN(mesh_src->medge),
 +                                   totedge);
 +      }
 +      if (!CustomData_has_layer(&tmp.pdata, CD_MPOLY)) {
 +              /* TODO(Sybren): assigment to tmp.mxxx is probably not necessary due to the
 +               * BKE_mesh_update_customdata_pointers() call below. */
 +              tmp.mloop = (alloctype == CD_ASSIGN) ? mesh_src->mloop : MEM_dupallocN(mesh_src->mloop);
 +              tmp.mpoly = (alloctype == CD_ASSIGN) ? mesh_src->mpoly : MEM_dupallocN(mesh_src->mpoly);
 +
 +              CustomData_add_layer(&tmp.ldata, CD_MLOOP, CD_ASSIGN, tmp.mloop, tmp.totloop);
 +              CustomData_add_layer(&tmp.pdata, CD_MPOLY, CD_ASSIGN, tmp.mpoly, tmp.totpoly);
 +      }
 +
 +      /* object had got displacement layer, should copy this layer to save sculpted data */
 +      /* NOTE: maybe some other layers should be copied? nazgul */
 +      if (CustomData_has_layer(&mesh_dst->ldata, CD_MDISPS)) {
 +              if (totloop == mesh_dst->totloop) {
 +                      MDisps *mdisps = CustomData_get_layer(&mesh_dst->ldata, CD_MDISPS);
 +                      CustomData_add_layer(&tmp.ldata, CD_MDISPS, alloctype, mdisps, totloop);
 +              }
 +      }
 +
 +      /* yes, must be before _and_ after tessellate */
 +      BKE_mesh_update_customdata_pointers(&tmp, false);
 +
 +      /* since 2.65 caller must do! */
 +      // BKE_mesh_tessface_calc(&tmp);
 +
 +      CustomData_free(&mesh_dst->vdata, mesh_dst->totvert);
 +      CustomData_free(&mesh_dst->edata, mesh_dst->totedge);
 +      CustomData_free(&mesh_dst->fdata, mesh_dst->totface);
 +      CustomData_free(&mesh_dst->ldata, mesh_dst->totloop);
 +      CustomData_free(&mesh_dst->pdata, mesh_dst->totpoly);
 +
 +      /* ok, this should now use new CD shapekey data,
 +       * which should be fed through the modifier
 +       * stack */
 +      if (tmp.totvert != mesh_dst->totvert && !did_shapekeys && mesh_dst->key) {
 +              printf("%s: YEEK! this should be recoded! Shape key loss!: ID '%s'\n", __func__, tmp.id.name);
 +              if (tmp.key && !(tmp.id.tag & LIB_TAG_NO_MAIN)) {
 +                      id_us_min(&tmp.key->id);
 +              }
 +              tmp.key = NULL;
 +      }
 +
 +      /* Clear selection history */
 +      MEM_SAFE_FREE(tmp.mselect);
 +      tmp.totselect = 0;
 +      BLI_assert(ELEM(tmp.bb, NULL, mesh_dst->bb));
 +      if (mesh_dst->bb) {
 +              MEM_freeN(mesh_dst->bb);
 +              tmp.bb = NULL;
 +      }
 +
 +      /* skip the listbase */
 +      MEMCPY_STRUCT_OFS(mesh_dst, &tmp, id.prev);
 +
 +      if (take_ownership) {
 +              if (alloctype == CD_ASSIGN) {
 +                      CustomData_free_typemask(&mesh_src->vdata, mesh_src->totvert, ~mask);
 +                      CustomData_free_typemask(&mesh_src->edata, mesh_src->totedge, ~mask);
 +                      CustomData_free_typemask(&mesh_src->ldata, mesh_src->totloop, ~mask);
 +                      CustomData_free_typemask(&mesh_src->pdata, mesh_src->totpoly, ~mask);
 +              }
 +              BKE_id_free(NULL, mesh_src);
 +      }
 +}
 +
 +/* This is a Mesh-based copy of DM_to_meshkey() */
 +void BKE_mesh_nomain_to_meshkey(Mesh *mesh_src, Mesh *mesh_dst, KeyBlock *kb)
 +{
 +      int a, totvert = mesh_src->totvert;
 +      float *fp;
 +      MVert *mvert;
 +
 +      if (totvert == 0 || mesh_dst->totvert == 0 || mesh_dst->totvert != totvert) {
 +              return;
 +      }
 +
 +      if (kb->data) MEM_freeN(kb->data);
 +      kb->data = MEM_malloc_arrayN(mesh_dst->key->elemsize, mesh_dst->totvert, "kb->data");
 +      kb->totelem = totvert;
 +
 +      fp = kb->data;
 +      mvert = mesh_src->mvert;
 +
 +      for (a = 0; a < kb->totelem; a++, fp += 3, mvert++) {
 +              copy_v3_v3(fp, mvert->co);
 +      }
 +}
@@@ -75,8 -75,6 +75,8 @@@
  #include "NOD_shader.h"
  #include "NOD_texture.h"
  
 +#include "DEG_depsgraph.h"
 +
  #define NODE_DEFAULT_MAX_WIDTH 700
  
  /* Fallback types for undefined tree, nodes, sockets */
@@@ -1933,15 -1931,15 +1933,15 @@@ void ntreeSetOutput(bNodeTree *ntree
         * might be different for editor or for "real" use... */
  }
  
 -bNodeTree *ntreeFromID(ID *id)
 +bNodeTree *ntreeFromID(const ID *id)
  {
        switch (GS(id->name)) {
 -              case ID_MA:  return ((Material *)id)->nodetree;
 -              case ID_LA:  return ((Lamp *)id)->nodetree;
 -              case ID_WO:  return ((World *)id)->nodetree;
 -              case ID_TE:  return ((Tex *)id)->nodetree;
 -              case ID_SCE: return ((Scene *)id)->nodetree;
 -              case ID_LS:  return ((FreestyleLineStyle *)id)->nodetree;
 +              case ID_MA:  return ((const Material *)id)->nodetree;
 +              case ID_LA:  return ((const Lamp *)id)->nodetree;
 +              case ID_WO:  return ((const World *)id)->nodetree;
 +              case ID_TE:  return ((const Tex *)id)->nodetree;
 +              case ID_SCE: return ((const Scene *)id)->nodetree;
 +              case ID_LS:  return ((const FreestyleLineStyle *)id)->nodetree;
                default: return NULL;
        }
  }
@@@ -1989,6 -1987,9 +1989,6 @@@ bNodeTree *ntreeLocalize(bNodeTree *ntr
        if (ntree) {
                bNodeTree *ltree;
                bNode *node;
 -              AnimData *adt;
 -
 -              bAction *action_backup = NULL, *tmpact_backup = NULL;
  
                BLI_spin_lock(&spin);
                if (!ntree->duplilock) {
  
                BLI_mutex_lock(ntree->duplilock);
  
 -              /* Workaround for copying an action on each render!
 -               * set action to NULL so animdata actions don't get copied */
 -              adt = BKE_animdata_from_id(&ntree->id);
 -
 -              if (adt) {
 -                      action_backup = adt->action;
 -                      tmpact_backup = adt->tmpact;
 -
 -                      adt->action = NULL;
 -                      adt->tmpact = NULL;
 -              }
 -
                /* Make full copy outside of Main database.
                 * Note: previews are not copied here.
                 */
 -              BKE_id_copy_ex(G.main, (ID *)ntree, (ID **)&ltree,
 -                             LIB_ID_CREATE_NO_MAIN | LIB_ID_CREATE_NO_USER_REFCOUNT | LIB_ID_COPY_NO_PREVIEW, false);
 +              BKE_id_copy_ex(
 +                      NULL, &ntree->id, (ID **)&ltree,
 +                      (LIB_ID_CREATE_NO_MAIN |
 +                       LIB_ID_CREATE_NO_USER_REFCOUNT |
 +                       LIB_ID_COPY_NO_PREVIEW |
 +                       LIB_ID_COPY_NO_ANIMDATA),
 +                      false);
                ltree->flag |= NTREE_IS_LOCALIZED;
  
                for (node = ltree->nodes.first; node; node = node->next) {
                        }
                }
  
 -              if (adt) {
 -                      AnimData *ladt = BKE_animdata_from_id(&ltree->id);
 -
 -                      adt->action = ladt->action = action_backup;
 -                      adt->tmpact = ladt->tmpact = tmpact_backup;
 -
 -                      if (action_backup)
 -                              id_us_plus(&action_backup->id);
 -                      if (tmpact_backup)
 -                              id_us_plus(&tmpact_backup->id);
 -
 -              }
 -              /* end animdata uglyness */
 -
                /* ensures only a single output node is enabled */
                ntreeSetOutput(ntree);
  
                for (node = ntree->nodes.first; node; node = node->next) {
                        /* store new_node pointer to original */
 -                      node->new_node->new_node = node;
 +                      node->new_node->original = node;
                }
  
                if (ntree->typeinfo->localize)
                        ntree->typeinfo->localize(ltree, ntree);
  
 +              ltree->id.tag |= LIB_TAG_LOCALIZED;
 +
                BLI_mutex_unlock(ntree->duplilock);
  
                return ltree;
@@@ -2050,11 -2070,11 +2050,11 @@@ void ntreeLocalSync(bNodeTree *localtre
  
  /* merge local tree results back, and free local tree */
  /* we have to assume the editor already changed completely */
- void ntreeLocalMerge(bNodeTree *localtree, bNodeTree *ntree)
+ void ntreeLocalMerge(Main *bmain, bNodeTree *localtree, bNodeTree *ntree)
  {
        if (ntree && localtree) {
                if (ntree->typeinfo->local_merge)
-                       ntree->typeinfo->local_merge(localtree, ntree);
+                       ntree->typeinfo->local_merge(bmain, localtree, ntree);
                
                ntreeFreeTree(localtree);
                MEM_freeN(localtree);
@@@ -3098,6 -3118,77 +3098,6 @@@ void nodeUpdateInternalLinks(bNodeTree 
  }
  
  
 -/* nodes that use ID data get synced with local data */
 -void nodeSynchronizeID(bNode *node, bool copy_to_id)
 -{
 -      if (node->id == NULL) return;
 -      
 -      if (ELEM(node->type, SH_NODE_MATERIAL, SH_NODE_MATERIAL_EXT)) {
 -              bNodeSocket *sock;
 -              Material *ma = (Material *)node->id;
 -              int a;
 -              short check_flags = SOCK_UNAVAIL;
 -
 -              if (!copy_to_id)
 -                      check_flags |= SOCK_HIDDEN;
 -              
 -              /* hrmf, case in loop isn't super fast, but we don't edit 100s of material at same time either! */
 -              for (a = 0, sock = node->inputs.first; sock; sock = sock->next, a++) {
 -                      if (!(sock->flag & check_flags)) {
 -                              if (copy_to_id) {
 -                                      switch (a) {
 -                                              case MAT_IN_COLOR:
 -                                                      copy_v3_v3(&ma->r, ((bNodeSocketValueRGBA *)sock->default_value)->value); break;
 -                                              case MAT_IN_SPEC:
 -                                                      copy_v3_v3(&ma->specr, ((bNodeSocketValueRGBA *)sock->default_value)->value); break;
 -                                              case MAT_IN_REFL:
 -                                                      ma->ref = ((bNodeSocketValueFloat *)sock->default_value)->value; break;
 -                                              case MAT_IN_MIR:
 -                                                      copy_v3_v3(&ma->mirr, ((bNodeSocketValueRGBA *)sock->default_value)->value); break;
 -                                              case MAT_IN_AMB:
 -                                                      ma->amb = ((bNodeSocketValueFloat *)sock->default_value)->value; break;
 -                                              case MAT_IN_EMIT:
 -                                                      ma->emit = ((bNodeSocketValueFloat *)sock->default_value)->value; break;
 -                                              case MAT_IN_SPECTRA:
 -                                                      ma->spectra = ((bNodeSocketValueFloat *)sock->default_value)->value; break;
 -                                              case MAT_IN_RAY_MIRROR:
 -                                                      ma->ray_mirror = ((bNodeSocketValueFloat *)sock->default_value)->value; break;
 -                                              case MAT_IN_ALPHA:
 -                                                      ma->alpha = ((bNodeSocketValueFloat *)sock->default_value)->value; break;
 -                                              case MAT_IN_TRANSLUCENCY:
 -                                                      ma->translucency = ((bNodeSocketValueFloat *)sock->default_value)->value; break;
 -                                      }
 -                              }
 -                              else {
 -                                      switch (a) {
 -                                              case MAT_IN_COLOR:
 -                                                      copy_v3_v3(((bNodeSocketValueRGBA *)sock->default_value)->value, &ma->r); break;
 -                                              case MAT_IN_SPEC:
 -                                                      copy_v3_v3(((bNodeSocketValueRGBA *)sock->default_value)->value, &ma->specr); break;
 -                                              case MAT_IN_REFL:
 -                                                      ((bNodeSocketValueFloat *)sock->default_value)->value = ma->ref; break;
 -                                              case MAT_IN_MIR:
 -                                                      copy_v3_v3(((bNodeSocketValueRGBA *)sock->default_value)->value, &ma->mirr); break;
 -                                              case MAT_IN_AMB:
 -                                                      ((bNodeSocketValueFloat *)sock->default_value)->value = ma->amb; break;
 -                                              case MAT_IN_EMIT:
 -                                                      ((bNodeSocketValueFloat *)sock->default_value)->value = ma->emit; break;
 -                                              case MAT_IN_SPECTRA:
 -                                                      ((bNodeSocketValueFloat *)sock->default_value)->value = ma->spectra; break;
 -                                              case MAT_IN_RAY_MIRROR:
 -                                                      ((bNodeSocketValueFloat *)sock->default_value)->value = ma->ray_mirror; break;
 -                                              case MAT_IN_ALPHA:
 -                                                      ((bNodeSocketValueFloat *)sock->default_value)->value = ma->alpha; break;
 -                                              case MAT_IN_TRANSLUCENCY:
 -                                                      ((bNodeSocketValueFloat *)sock->default_value)->value = ma->translucency; break;
 -                                      }
 -                              }
 -                      }
 -              }
 -      }
 -}
 -
 -
  /* ************* node type access ********** */
  
  void nodeLabel(bNodeTree *ntree, bNode *node, char *label, int maxlen)
@@@ -3462,7 -3553,10 +3462,7 @@@ static void registerShaderNodes(void
  {
        register_node_type_sh_group();
  
 -      register_node_type_sh_output();
 -      register_node_type_sh_material();
        register_node_type_sh_camera();
 -      register_node_type_sh_lamp();
        register_node_type_sh_gamma();
        register_node_type_sh_brightcontrast();
        register_node_type_sh_value();
        register_node_type_sh_mix_rgb();
        register_node_type_sh_valtorgb();
        register_node_type_sh_rgbtobw();
 -      register_node_type_sh_texture();
 +      register_node_type_sh_shadertorgb();
        register_node_type_sh_normal();
 -      register_node_type_sh_geom();
        register_node_type_sh_mapping();
        register_node_type_sh_curve_vec();
        register_node_type_sh_curve_rgb();
        register_node_type_sh_vect_math();
        register_node_type_sh_vect_transform();
        register_node_type_sh_squeeze();
 -      register_node_type_sh_material_ext();
        register_node_type_sh_invert();
        register_node_type_sh_seprgb();
        register_node_type_sh_combrgb();
        register_node_type_sh_add_shader();
        register_node_type_sh_uvmap();
        register_node_type_sh_uvalongstroke();
 +      register_node_type_sh_eevee_specular();
  
        register_node_type_sh_output_lamp();
        register_node_type_sh_output_material();
@@@ -3720,28 -3815,3 +3720,28 @@@ bool BKE_node_tree_iter_step(struct Nod
  
        return true;
  }
 +
 +/* -------------------------------------------------------------------- */
 +/* NodeTree kernel functions */
 +
 +void BKE_nodetree_remove_layer_n(bNodeTree *ntree, Scene *scene, const int layer_index)
 +{
 +      BLI_assert(layer_index != -1);
 +      for (bNode *node = ntree->nodes.first; node; node = node->next) {
 +              if (node->type == CMP_NODE_R_LAYERS && (Scene *)node->id == scene) {
 +                      if (node->custom1 == layer_index) {
 +                              node->custom1 = 0;
 +                      }
 +                      else if (node->custom1 > layer_index) {
 +                              node->custom1--;
 +                      }
 +              }
 +      }
 +}
 +
 +void BKE_nodetree_shading_params_eval(struct Depsgraph *depsgraph,
 +                                      bNodeTree *ntree_dst,
 +                                      const bNodeTree *ntree_src)
 +{
 +      DEG_debug_print_eval(depsgraph, __func__, ntree_src->id.name, ntree_dst);
 +}
@@@ -57,12 -57,12 +57,12 @@@ extern "C" 
  #include "BLI_fileops.h"
  
  #include "BKE_camera.h"
 +#include "BKE_collection.h"
  #include "BKE_main.h"
 +#include "BKE_layer.h"
  #include "BKE_lamp.h"
  #include "BKE_library.h"
 -#include "BKE_texture.h"
  #include "BKE_fcurve.h"
 -#include "BKE_depsgraph.h"
  #include "BKE_scene.h"
  #include "BKE_global.h"
  #include "BKE_material.h"
@@@ -82,9 -82,6 +82,9 @@@
  
  }
  
 +#include "DEG_depsgraph.h"
 +#include "DEG_depsgraph_build.h"
 +
  #include "ExtraHandler.h"
  #include "ErrorHandler.h"
  #include "DocumentImporter.h"
@@@ -107,9 -104,8 +107,9 @@@ DocumentImporter::DocumentImporter(bCon
        import_settings(import_settings),
        mImportStage(General),
        mContext(C),
 -      armature_importer(&unit_converter, &mesh_importer, CTX_data_scene(C), import_settings),
 -      mesh_importer(&unit_converter, &armature_importer, CTX_data_scene(C)),
 +      view_layer(CTX_data_view_layer(mContext)),
 +      armature_importer(&unit_converter, &mesh_importer, CTX_data_scene(C), view_layer, import_settings),
 +      mesh_importer(&unit_converter, &armature_importer, CTX_data_scene(C), view_layer),
        anim_importer(&unit_converter, &armature_importer, CTX_data_scene(C))
  {
  }
@@@ -134,7 -130,7 +134,7 @@@ bool DocumentImporter::import(
        loader.registerExtraDataCallbackHandler(ehandler);
  
        // deselect all to select new objects
 -      BKE_scene_base_deselect_all(CTX_data_scene(mContext));
 +      BKE_view_layer_base_deselect_all(view_layer);
  
        std::string mFilename = std::string(this->import_settings->filepath);
        const std::string encodedFilename = bc_url_encode(mFilename);
@@@ -234,7 -230,7 +234,7 @@@ void DocumentImporter::finish(
                }
  
                // update scene
 -              DAG_relations_tag_update(bmain);
 +              DEG_relations_tag_update(bmain);
                WM_event_add_notifier(mContext, NC_OBJECT | ND_TRANSFORM, NULL);
  
        }
        armature_importer.set_tags_map(this->uid_tags_map);
        armature_importer.make_armatures(mContext, *objects_to_scale);
        armature_importer.make_shape_keys();
 -      DAG_relations_tag_update(bmain);
 +      DEG_relations_tag_update(bmain);
  
  #if 0
        armature_importer.fix_animation();
  
                fprintf(stderr, "got %d library nodes to free\n", (int)libnode_ob.size());
                // free all library_nodes
 -              std::vector<Object *>::iterator lit;
 -              for (lit = libnode_ob.begin(); lit != libnode_ob.end(); lit++) {
 -                      Object *ob = *lit;
 -
 -                      Base *base = BKE_scene_base_find(sce, ob);
 -                      if (base) {
 -                              BLI_remlink(&sce->base, base);
 -                              BKE_libblock_free_us(G.main, base->object);
 -                              if (sce->basact == base)
 -                                      sce->basact = NULL;
 -                              MEM_freeN(base);
 -                      }
 +              std::vector<Object *>::iterator it;
 +              for (it = libnode_ob.begin(); it != libnode_ob.end(); it++) {
 +                      Object *ob = *it;
 +                      BKE_scene_collections_object_remove(G.main, sce, ob, true);
                }
                libnode_ob.clear();
  
 -              DAG_relations_tag_update(bmain);
 +              DEG_relations_tag_update(bmain);
        }
  
        bc_match_scale(objects_to_scale, unit_converter, !this->import_settings->import_units);
@@@ -379,7 -383,7 +379,7 @@@ Object *DocumentImporter::create_camera
                return NULL;
        }
  
 -      Object *ob = bc_add_object(sce, OB_CAMERA, NULL);
 +      Object *ob = bc_add_object(sce, view_layer, OB_CAMERA, NULL);
        Camera *cam = uid_camera_map[cam_uid];
        Camera *old_cam = (Camera *)ob->data;
        ob->data = cam;
@@@ -395,7 -399,7 +395,7 @@@ Object *DocumentImporter::create_lamp_o
                return NULL;
        }
  
 -      Object *ob = bc_add_object(sce, OB_LAMP, NULL);
 +      Object *ob = bc_add_object(sce, view_layer, OB_LAMP, NULL);
        Lamp *la = uid_lamp_map[lamp_uid];
        Lamp *old_lamp = (Lamp *)ob->data;
        ob->data = la;
@@@ -408,8 -412,8 +408,8 @@@ Object *DocumentImporter::create_instan
        fprintf(stderr, "create <instance_node> under node id=%s from node id=%s\n", instance_node ? instance_node->getOriginalId().c_str() : NULL, source_node ? source_node->getOriginalId().c_str() : NULL);
  
        Object *obn = BKE_object_copy(G.main, source_ob);
 -      DAG_id_tag_update(&obn->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
 -      BKE_scene_base_add(sce, obn);
 +      DEG_id_tag_update(&obn->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
 +      BKE_collection_object_add_from(G.main, sce, source_ob, obn);
  
        if (instance_node) {
                anim_importer.read_node_transform(instance_node, obn);
@@@ -511,7 -515,7 +511,7 @@@ std::vector<Object *> *DocumentImporter
                if (parent_node == NULL && !is_library_node) {
                        // A Joint on root level is a skeleton without root node.
                        // Here we add the armature "on the fly":
 -                      par = bc_add_object(sce, OB_ARMATURE, std::string("Armature").c_str());
 +                      par = bc_add_object(sce, view_layer, OB_ARMATURE, std::string("Armature").c_str());
                        objects_done->push_back(par);
                        root_objects->push_back(par);
                        object_map.insert(std::pair<COLLADAFW::UniqueId, Object *>(node->getUniqueId(), par));
                // maybe join multiple <instance_...> meshes into 1, and link object with it? not sure...
                // <instance_geometry>
                while (geom_done < geom.getCount()) {
 -                      ob = mesh_importer.create_mesh_object(node, geom[geom_done], false, uid_material_map,
 -                                                            material_texture_mapping_map);
 +                      ob = mesh_importer.create_mesh_object(node, geom[geom_done], false, uid_material_map);
                        if (ob == NULL) {
                                report_unknown_reference(*node, "instance_mesh");
                        }
                }
                while (controller_done < controller.getCount()) {
                        COLLADAFW::InstanceGeometry *geometry = (COLLADAFW::InstanceGeometry *)controller[controller_done];
 -                      ob = mesh_importer.create_mesh_object(node, geometry, true, uid_material_map, material_texture_mapping_map);
 +                      ob = mesh_importer.create_mesh_object(node, geometry, true, uid_material_map);
                        if (ob == NULL) {
                                report_unknown_reference(*node, "instance_controller");
                        }
                if ( (geom_done + camera_done + lamp_done + controller_done + inst_done) < 1) {
                        //Check if Object is armature, by checking if immediate child is a JOINT node.
                        if (is_armature(node)) {
 -                              ob = bc_add_object(sce, OB_ARMATURE, name.c_str());
 +                              ob = bc_add_object(sce, view_layer, OB_ARMATURE, name.c_str());
                        }
                        else {
 -                              ob = bc_add_object(sce, OB_EMPTY, NULL);
 +                              ob = bc_add_object(sce, view_layer, OB_EMPTY, NULL);
                        }
                        objects_done->push_back(ob);
                        if (parent_node == NULL) {
@@@ -763,74 -768,102 +763,74 @@@ bool DocumentImporter::writeMaterial(co
        return true;
  }
  
 -// create mtex, create texture, set texture image
 -MTex *DocumentImporter::create_texture(COLLADAFW::EffectCommon *ef, COLLADAFW::Texture &ctex, Material *ma,
 -                                       int i, TexIndexTextureArrayMap &texindex_texarray_map)
 -{
 -      COLLADAFW::SamplerPointerArray& samp_array = ef->getSamplerPointerArray();
 -      COLLADAFW::Sampler *sampler = samp_array[ctex.getSamplerId()];
 -
 -      const COLLADAFW::UniqueId& ima_uid = sampler->getSourceImage();
 -
 -      if (uid_image_map.find(ima_uid) == uid_image_map.end()) {
 -              fprintf(stderr, "Couldn't find an image by UID.\n");
 -              return NULL;
 -      }
 -
 -      ma->mtex[i] = BKE_texture_mtex_add();
 -      ma->mtex[i]->texco = TEXCO_UV;
 -      ma->mtex[i]->tex = BKE_texture_add(G.main, "Texture");
 -      ma->mtex[i]->tex->type = TEX_IMAGE;
 -      ma->mtex[i]->tex->ima = uid_image_map[ima_uid];
 -
 -      texindex_texarray_map[ctex.getTextureMapId()].push_back(ma->mtex[i]);
 -
 -      return ma->mtex[i];
 -}
 -
  void DocumentImporter::write_profile_COMMON(COLLADAFW::EffectCommon *ef, Material *ma)
  {
        COLLADAFW::EffectCommon::ShaderType shader = ef->getShaderType();
  
 +      // TODO: add back texture and extended material parameter support
 +
        // blinn
        if (shader == COLLADAFW::EffectCommon::SHADER_BLINN) {
 +#if 0
                ma->spec_shader = MA_SPEC_BLINN;
                ma->spec = ef->getShininess().getFloatValue();
 +#endif
        }
        // phong
        else if (shader == COLLADAFW::EffectCommon::SHADER_PHONG) {
 +#if 0
                ma->spec_shader = MA_SPEC_PHONG;
                ma->har = ef->getShininess().getFloatValue();
 +#endif
        }
        // lambert
        else if (shader == COLLADAFW::EffectCommon::SHADER_LAMBERT) {
 +#if 0
                ma->diff_shader = MA_DIFF_LAMBERT;
 +#endif
        }
        // default - lambert
        else {
 +#if 0
                ma->diff_shader = MA_DIFF_LAMBERT;
                fprintf(stderr, "Current shader type is not supported, default to lambert.\n");
 +#endif
        }
        // reflectivity
 -      ma->ray_mirror = ef->getReflectivity().getFloatValue();
 +      ma->metallic = ef->getReflectivity().getFloatValue();
        // index of refraction
 +#if 0
        ma->ang = ef->getIndexOfRefraction().getFloatValue();
 +#endif
  
 -      int i = 0;
        COLLADAFW::Color col;
 -      MTex *mtex = NULL;
 -      TexIndexTextureArrayMap texindex_texarray_map;
  
        // DIFFUSE
        // color
        if (ef->getDiffuse().isColor()) {
 -              /* too high intensity can create artefacts (fireflies)
 -                 So here we take care that intensity is set to 0.8 wherever possible
 -              */
                col = ef->getDiffuse().getColor();
 -              ma->ref = max_ffff(col.getRed(), col.getGreen(), col.getBlue(), 0.8);
 -              ma->r = col.getRed()   / ma->ref;
 -              ma->g = col.getGreen() / ma->ref;
 -              ma->b = col.getBlue()  / ma->ref;
 +              ma->r = col.getRed();
 +              ma->g = col.getGreen();
 +              ma->b = col.getBlue();
        }
        // texture
        else if (ef->getDiffuse().isTexture()) {
 +#if 0
                COLLADAFW::Texture ctex = ef->getDiffuse().getTexture();
 -              mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
 -              if (mtex != NULL) {
 -                      mtex->mapto = MAP_COL;
 -                      ma->texact = (int)i;
 -                      i++;
 -              }
 +#endif
        }
        // AMBIENT
        // color
        if (ef->getAmbient().isColor()) {
 +#if 0
                col = ef->getAmbient().getColor();
 -              ma->ambr = col.getRed();
 -              ma->ambg = col.getGreen();
 -              ma->ambb = col.getBlue();
 +#endif
        }
        // texture
        else if (ef->getAmbient().isTexture()) {
 +#if 0
                COLLADAFW::Texture ctex = ef->getAmbient().getTexture();
 -              mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
 -              if (mtex != NULL) {
 -                      mtex->mapto = MAP_AMB;
 -                      i++;
 -              }
 +#endif
        }
        // SPECULAR
        // color
        }
        // texture
        else if (ef->getSpecular().isTexture()) {
 +#if 0
                COLLADAFW::Texture ctex = ef->getSpecular().getTexture();
 -              mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
 -              if (mtex != NULL) {
 -                      mtex->mapto = MAP_SPEC;
 -                      i++;
 -              }
 +#endif
        }
        // REFLECTIVE
        // color
        if (ef->getReflective().isColor()) {
 +#if 0
                col = ef->getReflective().getColor();
 -              ma->mirr = col.getRed();
 -              ma->mirg = col.getGreen();
 -              ma->mirb = col.getBlue();
 +#endif
        }
        // texture
        else if (ef->getReflective().isTexture()) {
 +#if 0
                COLLADAFW::Texture ctex = ef->getReflective().getTexture();
 -              mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
 -              if (mtex != NULL) {
 -                      mtex->mapto = MAP_REF;
 -                      i++;
 -              }
 +#endif
        }
  
        // EMISSION
        }
        // texture
        else if (ef->getEmission().isTexture()) {
 +#if 0
                COLLADAFW::Texture ctex = ef->getEmission().getTexture();
 -              mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
 -              if (mtex != NULL) {
 -                      mtex->mapto = MAP_EMIT;
 -                      i++;
 -              }
 +#endif
        }
  
        // TRANSPARENT
        // color
        if (ef->getOpacity().isColor()) {
 +#if 0
                col = ef->getTransparent().getColor();
                float alpha = ef->getTransparency().getFloatValue();
                if (col.isValid()) {
                        alpha *= col.getAlpha(); // Assuming A_ONE opaque mode
                }
                if (col.isValid() || alpha < 1.0) {
 -                      ma->alpha = alpha;
 -                      ma->mode |= MA_ZTRANSP | MA_TRANSP;
 +                      ...
                }
 +#endif
        }
        // texture
        else if (ef->getOpacity().isTexture()) {
 +#if 0
                COLLADAFW::Texture ctex = ef->getOpacity().getTexture();
 -              mtex = create_texture(ef, ctex, ma, i, texindex_texarray_map);
 -              if (mtex != NULL) {
 -                      mtex->mapto = MAP_ALPHA;
 -                      i++;
 -                      ma->spectra = ma->alpha = 0;
 -                      ma->mode |= MA_ZTRANSP | MA_TRANSP;
 -              }
 +#endif
        }
 -
 -      material_texture_mapping_map[ma] = texindex_texarray_map;
  }
  
  /** When this method is called, the writer must write the effect.
@@@ -1085,7 -1134,7 +1085,7 @@@ bool DocumentImporter::writeImage(cons
                workpath = imagepath.c_str();
        }
  
-       Image *ima = BKE_image_load_exists(workpath);
+       Image *ima = BKE_image_load_exists(CTX_data_main(mContext), workpath);
        if (!ima) {
                fprintf(stderr, "Cannot create image: %s\n", workpath);
                return true;
@@@ -1139,6 -1188,7 +1139,6 @@@ bool DocumentImporter::writeLight(cons
                et->setData("spotsize", &(lamp->spotsize));
                lamp->spotsize = DEG2RADF(lamp->spotsize);
                et->setData("spotblend", &(lamp->spotblend));
 -              et->setData("halo_intensity", &(lamp->haint));
                et->setData("att1", &(lamp->att1));
                et->setData("att2", &(lamp->att2));
                et->setData("falloff_type", &(lamp->falloff_type));
                et->setData("clipend", &(lamp->clipend));
                et->setData("bias", &(lamp->bias));
                et->setData("soft", &(lamp->soft));
 -              et->setData("compressthresh", &(lamp->compressthresh));
                et->setData("bufsize", &(lamp->bufsize));
 -              et->setData("samp", &(lamp->samp));
                et->setData("buffers", &(lamp->buffers));
 -              et->setData("filtertype", &(lamp->filtertype));
 -              et->setData("bufflag", &(lamp->bufflag));
 -              et->setData("buftype", &(lamp->buftype));
 -              et->setData("ray_samp", &(lamp->ray_samp));
 -              et->setData("ray_sampy", &(lamp->ray_sampy));
 -              et->setData("ray_sampz", &(lamp->ray_sampz));
 -              et->setData("ray_samp_type", &(lamp->ray_samp_type));
                et->setData("area_shape", &(lamp->area_shape));
                et->setData("area_size", &(lamp->area_size));
                et->setData("area_sizey", &(lamp->area_sizey));
                et->setData("area_sizez", &(lamp->area_sizez));
 -              et->setData("adapt_thresh", &(lamp->adapt_thresh));
 -              et->setData("ray_samp_method", &(lamp->ray_samp_method));
 -              et->setData("shadhalostep", &(lamp->shadhalostep));
 -              et->setData("sun_effect_type", &(lamp->shadhalostep));
 -              et->setData("skyblendtype", &(lamp->skyblendtype));
 -              et->setData("horizon_brightness", &(lamp->horizon_brightness));
 -              et->setData("spread", &(lamp->spread));
 -              et->setData("sun_brightness", &(lamp->sun_brightness));
 -              et->setData("sun_size", &(lamp->sun_size));
 -              et->setData("backscattered_light", &(lamp->backscattered_light));
 -              et->setData("sun_intensity", &(lamp->sun_intensity));
 -              et->setData("atm_turbidity", &(lamp->atm_turbidity));
 -              et->setData("atm_extinction_factor", &(lamp->atm_extinction_factor));
 -              et->setData("atm_distance_factor", &(lamp->atm_distance_factor));
 -              et->setData("skyblendfac", &(lamp->skyblendfac));
 -              et->setData("sky_exposure", &(lamp->sky_exposure));
 -              et->setData("sky_colorspace", &(lamp->sky_colorspace));
        }
        else {
                float constatt = light->getConstantAttenuation().getValue();
                        {
                                /* our sun is very strong, so pick a smaller energy level */
                                lamp->type = LA_SUN;
 -                              lamp->mode |= LA_NO_SPEC;
                        }
                        break;
                        case COLLADAFW::Light::POINT_LIGHT:
@@@ -39,11 -39,11 +39,11 @@@ struct ToolSettings
  struct wmWindowManager;
  struct ARegion;
  struct Scene;
 +struct ViewLayer;
  
  /* image_edit.c, exported for transform */
  struct Image *ED_space_image(struct SpaceImage *sima);
- void          ED_space_image_set(struct SpaceImage *sima, struct Scene *scene, struct Object *obedit, struct Image *ima);
 -void          ED_space_image_set(
 -        struct Main *bmain, struct SpaceImage *sima, struct Scene *scene, struct Object *obedit, struct Image *ima);
++void          ED_space_image_set(struct Main *bmain, struct SpaceImage *sima, struct Scene *scene, struct Object *obedit, struct Image *ima);
  struct Mask  *ED_space_image_get_mask(struct SpaceImage *sima);
  void          ED_space_image_set_mask(struct bContext *C, struct SpaceImage *sima, struct Mask *mask);
  
@@@ -75,7 -75,7 +75,7 @@@ bool ED_space_image_show_uvedit(struct 
  
  bool ED_space_image_paint_curve(const struct bContext *C);
  
 -bool ED_space_image_check_show_maskedit(struct Scene *scene, struct SpaceImage *sima);
 +bool ED_space_image_check_show_maskedit(struct SpaceImage *sima, struct ViewLayer *view_layer);
  int ED_space_image_maskedit_poll(struct bContext *C);
  int ED_space_image_maskedit_mask_poll(struct bContext *C);
  
@@@ -75,7 -75,7 +75,7 @@@ void ED_init_custom_node_socket_type(st
  void ED_init_standard_node_socket_type(struct bNodeSocketType *stype);
  void ED_init_node_socket_type_virtual(struct bNodeSocketType *stype);
  void ED_node_sample_set(const float col[4]);
 -void ED_node_draw_snap(struct View2D *v2d, const float cent[2], float size, NodeBorder border);
 +void ED_node_draw_snap(struct View2D *v2d, const float cent[2], float size, NodeBorder border, unsigned pos);
  
  /* node_draw.c */
  void ED_node_tree_update(const struct bContext *C);
@@@ -107,7 -107,7 +107,7 @@@ void ED_node_composite_job(const struc
  void ED_operatormacros_node(void);
  
  /* node_view.c */
- bool ED_space_node_color_sample(struct SpaceNode *snode, struct ARegion *ar, int mval[2], float r_col[3]);
+ bool ED_space_node_color_sample(struct Main *bmain, struct SpaceNode *snode, struct ARegion *ar, int mval[2], float r_col[3]);
  
  #endif /* __ED_NODE_H__ */
  
@@@ -38,6 -38,7 +38,7 @@@
  #include "BLI_math_vector.h"
  
  #include "BKE_context.h"
+ #include "BKE_main.h"
  #include "BKE_screen.h"
  
  #include "RNA_access.h"
@@@ -131,8 -132,9 +132,9 @@@ static void eyedropper_exit(bContext *C
  void eyedropper_color_sample_fl(bContext *C, int mx, int my, float r_col[3])
  {
        /* we could use some clever */
 -      wmWindow *win = CTX_wm_window(C);
 -      ScrArea *sa = BKE_screen_find_area_xy(win->screen, SPACE_TYPE_ANY, mx, my);
+       Main *bmain = CTX_data_main(C);
 +      bScreen *screen = CTX_wm_screen(C);
 +      ScrArea *sa = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, mx, my);
        const char *display_device = CTX_data_scene(C)->display_settings.display_device;
        struct ColorManagedDisplay *display = IMB_colormanagement_display_get_named(display_device);
  
                                int mval[2] = {mx - ar->winrct.xmin,
                                               my - ar->winrct.ymin};
  
-                               if (ED_space_node_color_sample(snode, ar, mval, r_col)) {
+                               if (ED_space_node_color_sample(bmain, snode, ar, mval, r_col)) {
                                        return;
                                }
                        }
@@@ -45,9 -45,9 +45,9 @@@
  #include "DNA_object_fluidsim_types.h"
  #include "DNA_object_force_types.h"
  #include "DNA_object_types.h"
 +#include "DNA_lightprobe_types.h"
  #include "DNA_scene_types.h"
  #include "DNA_vfont_types.h"
 -#include "DNA_actuator_types.h"
  #include "DNA_gpencil_types.h"
  
  #include "BLI_utildefines.h"
  #include "BKE_animsys.h"
  #include "BKE_armature.h"
  #include "BKE_camera.h"
 +#include "BKE_collection.h"
  #include "BKE_context.h"
  #include "BKE_constraint.h"
  #include "BKE_curve.h"
 -#include "BKE_depsgraph.h"
  #include "BKE_DerivedMesh.h"
  #include "BKE_displist.h"
  #include "BKE_effect.h"
  #include "BKE_font.h"
 -#include "BKE_group.h"
  #include "BKE_lamp.h"
  #include "BKE_lattice.h"
 +#include "BKE_layer.h"
  #include "BKE_library.h"
  #include "BKE_library_query.h"
  #include "BKE_library_remap.h"
  #include "BKE_material.h"
  #include "BKE_mball.h"
  #include "BKE_mesh.h"
 +#include "BKE_mesh_runtime.h"
  #include "BKE_nla.h"
  #include "BKE_object.h"
  #include "BKE_particle.h"
  #include "BKE_report.h"
 -#include "BKE_sca.h"
  #include "BKE_scene.h"
  #include "BKE_screen.h"
  #include "BKE_speaker.h"
  
 +#include "DEG_depsgraph.h"
 +#include "DEG_depsgraph_build.h"
 +
  #include "RNA_access.h"
  #include "RNA_define.h"
  #include "RNA_enum_types.h"
  
  #include "UI_resources.h"
  
 -#include "GPU_material.h"
 -
  #include "object_intern.h"
  
  /* this is an exact copy of the define in rna_lamp.c
@@@ -147,16 -146,6 +147,16 @@@ static const EnumPropertyItem field_typ
        {0, NULL, 0, NULL, NULL}
  };
  
 +static EnumPropertyItem lightprobe_type_items[] = {
 +      {LIGHTPROBE_TYPE_CUBE, "CUBEMAP", ICON_LIGHTPROBE_CUBEMAP, "Reflection Cubemap",
 +     "Reflection probe with spherical or cubic attenuation"},
 +      {LIGHTPROBE_TYPE_PLANAR, "PLANAR", ICON_LIGHTPROBE_PLANAR, "Reflection Plane",
 +     "Planar reflection probe"},
 +      {LIGHTPROBE_TYPE_GRID, "GRID", ICON_LIGHTPROBE_GRID, "Irradiance Volume",
 +     "Irradiance probe to capture diffuse indirect lighting"},
 +      {0, NULL, 0, NULL, NULL}
 +};
 +
  /************************** Exported *****************************/
  
  void ED_object_location_from_view(bContext *C, float loc[3])
        Scene *scene = CTX_data_scene(C);
        const float *cursor;
  
 -      cursor = ED_view3d_cursor3d_get(scene, v3d);
 +      cursor = ED_view3d_cursor3d_get(scene, v3d)->location;
  
        copy_v3_v3(loc, cursor);
  }
@@@ -218,7 -207,6 +218,7 @@@ void ED_object_base_init_transform(bCon
  {
        Object *ob = base->object;
        Scene *scene = CTX_data_scene(C);
 +      Depsgraph *depsgraph = CTX_data_depsgraph(C);
  
        if (!scene) return;
  
        if (rot)
                copy_v3_v3(ob->rot, rot);
  
 -      BKE_object_where_is_calc(scene, ob);
 +      BKE_object_where_is_calc(depsgraph, scene, ob);
  }
  
  /* Uses context to figure out transform for primitive.
@@@ -306,7 -294,7 +306,7 @@@ void ED_object_add_generic_props(wmOper
  
  void ED_object_add_mesh_props(wmOperatorType *ot)
  {
 -      RNA_def_boolean(ot->srna, "calc_uvs", false, "Generate UVs", "Generate a default UV map");
 +      RNA_def_boolean(ot->srna, "calc_uvs", true, "Generate UVs", "Generate a default UV map");
  }
  
  bool ED_object_add_generic_get_opts(bContext *C, wmOperator *op, const char view_align_axis,
@@@ -416,11 -404,10 +416,11 @@@ Object *ED_object_add_type
          bContext *C,
          int type, const char *name,
          const float loc[3], const float rot[3],
 -        bool enter_editmode, unsigned int layer)
 +        bool enter_editmode, unsigned int UNUSED(layer))
  {
        Main *bmain = CTX_data_main(C);
        Scene *scene = CTX_data_scene(C);
 +      ViewLayer *view_layer = CTX_data_view_layer(C);
        Object *ob;
  
        /* for as long scene has editmode... */
        }
  
        /* deselects all, sets scene->basact */
 -      ob = BKE_object_add(bmain, scene, type, name);
 -      BASACT->lay = ob->lay = layer;
 +      ob = BKE_object_add(bmain, scene, view_layer, type, name);
        /* editor level activate, notifiers */
 -      ED_base_object_activate(C, BASACT);
 +      ED_object_base_activate(C, view_layer->basact);
  
        /* more editor stuff */
 -      ED_object_base_init_transform(C, BASACT, loc, rot);
 -
 -      /* Ignore collisions by default for non-mesh objects */
 -      if (type != OB_MESH) {
 -              ob->body_type = OB_BODY_TYPE_NO_COLLISION;
 -              ob->gameflag &= ~(OB_SENSOR | OB_RIGID_BODY | OB_SOFT_BODY | OB_COLLISION | OB_CHARACTER | OB_OCCLUDER | OB_DYNAMIC | OB_NAVMESH); /* copied from rna_object.c */
 -      }
 +      ED_object_base_init_transform(C, view_layer->basact, loc, rot);
  
 -      DAG_id_type_tag(bmain, ID_OB);
 -      DAG_relations_tag_update(bmain);
 -      if (ob->data) {
 -              ED_render_id_flush_update(bmain, ob->data);
 +      /* TODO(sergey): This is weird to manually tag objects for update, better to
 +       * use DEG_id_tag_update here perhaps.
 +       */
 +      DEG_id_type_tag(bmain, ID_OB);
 +      DEG_relations_tag_update(bmain);
 +      if (ob->data != NULL) {
 +              DEG_id_tag_update_ex(bmain, (ID *)ob->data, DEG_TAG_EDITORS_UPDATE);
        }
  
        if (enter_editmode)
  
        WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene);
  
 +      /* TODO(sergey): Use proper flag for tagging here. */
 +      DEG_id_tag_update(&scene->id, 0);
 +
        return ob;
  }
  
@@@ -504,79 -492,6 +504,79 @@@ void OBJECT_OT_add(wmOperatorType *ot
        ED_object_add_generic_props(ot, true);
  }
  
 +/********************** Add Probe Operator **********************/
 +
 +/* for object add operator */
 +static int lightprobe_add_exec(bContext *C, wmOperator *op)
 +{
 +      Object *ob;
 +      LightProbe *probe;
 +      int type;
 +      bool enter_editmode;
 +      unsigned int layer;
 +      float loc[3], rot[3];
 +      float radius;
 +
 +      WM_operator_view3d_unit_defaults(C, op);
 +      if (!ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, &enter_editmode, &layer, NULL))
 +              return OPERATOR_CANCELLED;
 +
 +      type = RNA_enum_get(op->ptr, "type");
 +      radius = RNA_float_get(op->ptr, "radius");
 +
 +      const char *name = CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Light Probe");
 +      ob = ED_object_add_type(C, OB_LIGHTPROBE, name, loc, rot, false, layer);
 +      BKE_object_obdata_size_init(ob, radius);
 +
 +      probe = (LightProbe *)ob->data;
 +      probe->type = type;
 +
 +      switch (type) {
 +              case LIGHTPROBE_TYPE_GRID:
 +                      probe->distinf = 0.3f;
 +                      probe->falloff = 1.0f;
 +                      probe->clipsta = 0.01f;
 +                      break;
 +              case LIGHTPROBE_TYPE_PLANAR:
 +                      probe->distinf = 0.1f;
 +                      probe->falloff = 0.5f;
 +                      probe->clipsta = 0.001f;
 +                      ob->empty_drawsize = 0.5f;
 +                      break;
 +              case LIGHTPROBE_TYPE_CUBE:
 +                      probe->attenuation_type = LIGHTPROBE_SHAPE_ELIPSOID;
 +                      break;
 +              default:
 +                      BLI_assert(!"Lightprobe type not configured.");
 +                      break;
 +      }
 +
 +      DEG_relations_tag_update(CTX_data_main(C));
 +
 +      return OPERATOR_FINISHED;
 +}
 +
 +void OBJECT_OT_lightprobe_add(wmOperatorType *ot)
 +{
 +      /* identifiers */
 +      ot->name = "Add Light Probe";
 +      ot->description = "Add a light probe object";
 +      ot->idname = "OBJECT_OT_lightprobe_add";
 +
 +      /* api callbacks */
 +      ot->exec = lightprobe_add_exec;
 +      ot->poll = ED_operator_objectmode;
 +
 +      /* flags */
 +      ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
 +
 +      /* properties */
 +      ot->prop = RNA_def_enum(ot->srna, "type", lightprobe_type_items, 0, "Type", "");
 +
 +      ED_object_add_unit_props(ot);
 +      ED_object_add_generic_props(ot, true);
 +}
 +
  /********************* Add Effector Operator ********************/
  
  /* for object add operator */
@@@ -620,7 -535,7 +620,7 @@@ static int effector_add_exec(bContext *
  
        ob->pd = object_add_collision_fields(type);
  
 -      DAG_relations_tag_update(CTX_data_main(C));
 +      DEG_relations_tag_update(CTX_data_main(C));
  
        return OPERATOR_FINISHED;
  }
@@@ -725,7 -640,7 +725,7 @@@ static int object_metaball_add_exec(bCo
                newob = true;
        }
        else {
 -              DAG_id_tag_update(&obedit->id, OB_RECALC_DATA);
 +              DEG_id_tag_update(&obedit->id, OB_RECALC_DATA);
        }
  
        ED_object_new_primitive_matrix(C, obedit, loc, rot, mat);
@@@ -829,7 -744,7 +829,7 @@@ static int object_armature_add_exec(bCo
                newob = true;
        }
        else {
 -              DAG_id_tag_update(&obedit->id, OB_RECALC_DATA);
 +              DEG_id_tag_update(&obedit->id, OB_RECALC_DATA);
        }
  
        if (obedit == NULL) {
@@@ -1017,7 -932,7 +1017,7 @@@ static int object_lamp_add_exec(bContex
        la = (Lamp *)ob->data;
        la->type = type;
  
 -      if (BKE_scene_use_new_shading_nodes(scene)) {
 +      if (BKE_scene_uses_cycles(scene)) {
                ED_node_shader_default(C, &la->id);
                la->use_nodes = true;
        }
@@@ -1048,12 -963,12 +1048,12 @@@ void OBJECT_OT_lamp_add(wmOperatorType 
        ED_object_add_generic_props(ot, false);
  }
  
 -/********************* Add Group Instance Operator ********************/
 +/********************* Add Collection Instance Operator ********************/
  
 -static int group_instance_add_exec(bContext *C, wmOperator *op)
 +static int collection_instance_add_exec(bContext *C, wmOperator *op)
  {
        Main *bmain = CTX_data_main(C);
 -      Group *group;
 +      Collection *collection;
        unsigned int layer;
        float loc[3], rot[3];
  
                char name[MAX_ID_NAME - 2];
  
                RNA_string_get(op->ptr, "name", name);
 -              group = (Group *)BKE_libblock_find_name(bmain, ID_GR, name);
 +              collection = (Collection *)BKE_libblock_find_name(bmain, ID_GR, name);
  
                if (0 == RNA_struct_property_is_set(op->ptr, "location")) {
                        const wmEvent *event = CTX_wm_window(C)->eventstate;
                }
        }
        else
 -              group = BLI_findlink(&CTX_data_main(C)->group, RNA_enum_get(op->ptr, "group"));
 +              collection = BLI_findlink(&CTX_data_main(C)->collection, RNA_enum_get(op->ptr, "collection"));
  
        if (!ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, NULL, &layer, NULL))
                return OPERATOR_CANCELLED;
  
 -      if (group) {
 +      if (collection) {
                Scene *scene = CTX_data_scene(C);
 -              Object *ob = ED_object_add_type(C, OB_EMPTY, group->id.name + 2, loc, rot, false, layer);
 -              ob->dup_group = group;
 -              ob->transflag |= OB_DUPLIGROUP;
 -              id_us_plus(&group->id);
 +              ViewLayer *view_layer = CTX_data_view_layer(C);
 +
 +              /* Avoid dependency cycles. */
 +              LayerCollection *active_lc = BKE_layer_collection_get_active(view_layer);
 +              while (BKE_collection_find_cycle(active_lc->collection, collection)) {
 +                      active_lc = BKE_layer_collection_activate_parent(view_layer, active_lc);
 +              }
 +
 +              Object *ob = ED_object_add_type(C, OB_EMPTY, collection->id.name + 2, loc, rot, false, layer);
 +              ob->dup_group = collection;
 +              ob->transflag |= OB_DUPLICOLLECTION;
 +              id_us_plus(&collection->id);
  
                /* works without this except if you try render right after, see: 22027 */
 -              DAG_relations_tag_update(bmain);
 +              DEG_relations_tag_update(bmain);
 +              DEG_id_tag_update(&collection->id, 0);
  
                WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
  
  }
  
  /* only used as menu */
 -void OBJECT_OT_group_instance_add(wmOperatorType *ot)
 +void OBJECT_OT_collection_instance_add(wmOperatorType *ot)
  {
        PropertyRNA *prop;
  
        /* identifiers */
 -      ot->name = "Add Group Instance";
 -      ot->description = "Add a dupligroup instance";
 -      ot->idname = "OBJECT_OT_group_instance_add";
 +      ot->name = "Add Collection Instance";
 +      ot->description = "Add a collection instance";
 +      ot->idname = "OBJECT_OT_collection_instance_add";
  
        /* api callbacks */
        ot->invoke = WM_enum_search_invoke;
 -      ot->exec = group_instance_add_exec;
 +      ot->exec = collection_instance_add_exec;
        ot->poll = ED_operator_objectmode;
  
        /* flags */
        ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
  
        /* properties */
 -      RNA_def_string(ot->srna, "name", "Group", MAX_ID_NAME - 2, "Name", "Group name to add");
 -      prop = RNA_def_enum(ot->srna, "group", DummyRNA_NULL_items, 0, "Group", "");
 -      RNA_def_enum_funcs(prop, RNA_group_itemf);
 +      RNA_def_string(ot->srna, "name", "Collection", MAX_ID_NAME - 2, "Name", "Collection name to add");
 +      prop = RNA_def_enum(ot->srna, "collection", DummyRNA_NULL_items, 0, "Collection", "");
 +      RNA_def_enum_funcs(prop, RNA_collection_itemf);
        RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
        ot->prop = prop;
        ED_object_add_generic_props(ot, false);
@@@ -1190,22 -1096,35 +1190,22 @@@ void OBJECT_OT_speaker_add(wmOperatorTy
  
  /**************************** Delete Object *************************/
  
 -static void object_delete_check_glsl_update(Object *ob)
 -{
 -      /* some objects could affect on GLSL shading, make sure GLSL settings
 -       * are being tagged to be updated when object is removing from scene
 -       */
 -      if (ob->type == OB_LAMP) {
 -              if (ob->gpulamp.first)
 -                      GPU_lamp_free(ob);
 -      }
 -}
 -
  /* remove base from a specific scene */
  /* note: now unlinks constraints as well */
 -void ED_base_object_free_and_unlink(Main *bmain, Scene *scene, Base *base)
 +void ED_object_base_free_and_unlink(Main *bmain, Scene *scene, Object *ob)
  {
 -      if (BKE_library_ID_is_indirectly_used(bmain, base->object) &&
 -          ID_REAL_USERS(base->object) <= 1 && ID_EXTRA_USERS(base->object) == 0)
 +      if (BKE_library_ID_is_indirectly_used(bmain, ob) &&
 +          ID_REAL_USERS(ob) <= 1 && ID_EXTRA_USERS(ob) == 0)
        {
                /* We cannot delete indirectly used object... */
                printf("WARNING, undeletable object '%s', should have been catched before reaching this function!",
 -                     base->object->id.name + 2);
 +                     ob->id.name + 2);
                return;
        }
  
 -      BKE_scene_base_unlink(scene, base);
 -      object_delete_check_glsl_update(base->object);
 -      BKE_libblock_free_us(bmain, base->object);
 -      MEM_freeN(base);
 -      DAG_id_type_tag(bmain, ID_OB);
 +      DEG_id_tag_update_ex(bmain, &ob->id, DEG_TAG_BASE_FLAGS_UPDATE);
 +
 +      BKE_scene_collections_object_remove(bmain, scene, ob, true);
  }
  
  static int object_delete_exec(bContext *C, wmOperator *op)
        if (CTX_data_edit_object(C))
                return OPERATOR_CANCELLED;
  
 -      CTX_DATA_BEGIN (C, Base *, base, selected_bases)
 +      CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
        {
 -              const bool is_indirectly_used = BKE_library_ID_is_indirectly_used(bmain, base->object);
 -              if (base->object->id.tag & LIB_TAG_INDIRECT) {
 +              const bool is_indirectly_used = BKE_library_ID_is_indirectly_used(bmain, ob);
 +              if (ob->id.tag & LIB_TAG_INDIRECT) {
                        /* Can this case ever happen? */
 -                      BKE_reportf(op->reports, RPT_WARNING, "Cannot delete indirectly linked object '%s'", base->object->id.name + 2);
 +                      BKE_reportf(op->reports, RPT_WARNING, "Cannot delete indirectly linked object '%s'", ob->id.name + 2);
                        continue;
                }
 -              else if (is_indirectly_used && ID_REAL_USERS(base->object) <= 1 && ID_EXTRA_USERS(base->object) == 0) {
 +              else if (is_indirectly_used && ID_REAL_USERS(ob) <= 1 && ID_EXTRA_USERS(ob) == 0) {
                        BKE_reportf(op->reports, RPT_WARNING,
                                "Cannot delete object '%s' from scene '%s', indirectly used objects need at least one user",
 -                              base->object->id.name + 2, scene->id.name + 2);
 +                              ob->id.name + 2, scene->id.name + 2);
                        continue;
                }
  
                 * custom scene/object/base handling, and use generic lib remap/query for that.
                 * But this is for later (aka 2.8, once layers & co are settled and working).
                 */
 -              if (use_global && base->object->id.lib == NULL) {
 +              if (use_global && ob->id.lib == NULL) {
                        /* We want to nuke the object, let's nuke it the easy way (not for linked data though)... */
 -                      BKE_libblock_delete(bmain, &base->object->id);
 +                      BKE_libblock_delete(bmain, &ob->id);
                        changed = true;
                        continue;
                }
                for (bGPdata *gpd = bmain->gpencil.first; gpd; gpd = gpd->id.next) {
                        for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
                                if (gpl->parent != NULL) {
 -                                      Object *ob = gpl->parent;
 -                                      Object *curob = base->object;
 -                                      if (ob == curob) {
 +                                      if (gpl->parent == ob) {
                                                gpl->parent = NULL;
                                        }
                                }
                        }
                }
  
 -              /* deselect object -- it could be used in other scenes */
 -              base->object->flag &= ~SELECT;
 -
                /* remove from current scene only */
 -              ED_base_object_free_and_unlink(bmain, scene, base);
 +              ED_object_base_free_and_unlink(bmain, scene, ob);
                changed = true;
  
                if (use_global) {
                        Scene *scene_iter;
 -                      Base *base_other;
 -
                        for (scene_iter = bmain->scene.first; scene_iter; scene_iter = scene_iter->id.next) {
                                if (scene_iter != scene && !ID_IS_LINKED(scene_iter)) {
 -                                      base_other = BKE_scene_base_find(scene_iter, base->object);
 -                                      if (base_other) {
 -                                              if (is_indirectly_used && ID_REAL_USERS(base->object) <= 1 && ID_EXTRA_USERS(base->object) == 0) {
 -                                                      BKE_reportf(op->reports, RPT_WARNING,
 -                                                                  "Cannot delete object '%s' from scene '%s', indirectly used objects need at least one user",
 -                                                                  base->object->id.name + 2, scene_iter->id.name + 2);
 -                                                      break;
 -                                              }
 -                                              ED_base_object_free_and_unlink(bmain, scene_iter, base_other);
 +                                      if (is_indirectly_used && ID_REAL_USERS(ob) <= 1 && ID_EXTRA_USERS(ob) == 0) {
 +                                              BKE_reportf(op->reports, RPT_WARNING,
 +                                                          "Cannot delete object '%s' from scene '%s', indirectly used objects need at least one user",
 +                                                          ob->id.name + 2, scene_iter->id.name + 2);
 +                                              break;
                                        }
 +                                      ED_object_base_free_and_unlink(bmain, scene_iter, ob);
                                }
                        }
                }
        /* delete has to handle all open scenes */
        BKE_main_id_tag_listbase(&bmain->scene, LIB_TAG_DOIT, true);
        for (win = wm->windows.first; win; win = win->next) {
 -              scene = win->screen->scene;
 +              scene = WM_window_get_active_scene(win);
  
                if (scene->id.tag & LIB_TAG_DOIT) {
                        scene->id.tag &= ~LIB_TAG_DOIT;
  
 -                      DAG_relations_tag_update(bmain);
 +                      DEG_relations_tag_update(bmain);
  
                        WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
                        WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene);
@@@ -1333,13 -1262,15 +1333,13 @@@ static void copy_object_set_idnew(bCont
        }
        CTX_DATA_END;
  
 -      set_sca_new_poins();
 -
        BKE_main_id_clear_newpoins(bmain);
  }
  
  /********************* Make Duplicates Real ************************/
  
  /**
 - * \note regarding hashing dupli-objects when using OB_DUPLIGROUP, skip the first member of #DupliObject.persistent_id
 + * \note regarding hashing dupli-objects when using OB_DUPLICOLLECTION, skip the first member of #DupliObject.persistent_id
   * since its a unique index and we only want to know if the group objects are from the same dupli-group instance.
   */
  static unsigned int dupliobject_group_hash(const void *ptr)
  }
  
  /**
 - * \note regarding hashing dupli-objects when NOT using OB_DUPLIGROUP, include the first member of #DupliObject.persistent_id
 + * \note regarding hashing dupli-objects when NOT using OB_DUPLICOLLECTION, include the first member of #DupliObject.persistent_id
   * since its the index of the vertex/face the object is instantiated on and we want to identify objects on the same vertex/face.
   */
  static unsigned int dupliobject_hash(const void *ptr)
@@@ -1412,8 -1343,6 +1412,8 @@@ static void make_object_duplilist_real(
                                         const bool use_hierarchy)
  {
        Main *bmain = CTX_data_main(C);
 +      ViewLayer *view_layer = CTX_data_view_layer(C);
 +      Depsgraph *depsgraph = CTX_data_depsgraph(C);
        ListBase *lb_duplis;
        DupliObject *dob;
        GHash *dupli_gh, *parent_gh = NULL;
                return;
        }
  
 -      lb_duplis = object_duplilist(bmain, bmain->eval_ctx, scene, base->object);
 +      lb_duplis = object_duplilist(depsgraph, scene, base->object);
  
        dupli_gh = BLI_ghash_ptr_new(__func__);
        if (use_hierarchy) {
 -              if (base->object->transflag & OB_DUPLIGROUP) {
 +              if (base->object->transflag & OB_DUPLICOLLECTION) {
                        parent_gh = BLI_ghash_new(dupliobject_group_hash, dupliobject_group_cmp, __func__);
                }
                else {
                        ob_dst->totcol = 0;
                }
  
 -              base_dst = MEM_dupallocN(base);
 -              base_dst->flag &= ~(OB_FROMDUPLI | OB_FROMGROUP);
 -              ob_dst->flag = base_dst->flag;
 -              base_dst->lay = base->lay;
 -              BLI_addhead(&scene->base, base_dst);   /* addhead: othwise eternal loop */
 -              base_dst->object = ob_dst;
 +              BKE_collection_object_add_from(bmain, scene, base->object, ob_dst);
 +              base_dst = BKE_view_layer_base_find(view_layer, ob_dst);
 +              BLI_assert(base_dst != NULL);
 +
 +              BKE_scene_object_base_flag_sync_from_base(base_dst);
  
                /* make sure apply works */
                BKE_animdata_free(&ob_dst->id, true);
                BKE_constraints_free(&ob_dst->constraints);
                ob_dst->curve_cache = NULL;
                ob_dst->transflag &= ~OB_DUPLI;
 -              ob_dst->lay = base->lay;
  
                copy_m4_m4(ob_dst->obmat, dob->mat);
                BKE_object_apply_mat4(ob_dst, ob_dst->obmat, false, false);
  
                /* Remap new object to itself, and clear again newid pointer of orig object. */
                BKE_libblock_relink_to_newid(&ob_dst->id);
 -              set_sca_new_poins_ob(ob_dst);
  
 -              DAG_id_tag_update(&ob_dst->id, OB_RECALC_DATA);
 +              DEG_id_tag_update(&ob_dst->id, OB_RECALC_DATA);
  
                if (use_hierarchy) {
                        /* original parents */
                                 * they won't be read, this is simply for a hash lookup. */
                                DupliObject dob_key;
                                dob_key.ob = ob_src_par;
 -                              if (base->object->transflag & OB_DUPLIGROUP) {
 +                              if (base->object->transflag & OB_DUPLICOLLECTION) {
                                        memcpy(&dob_key.persistent_id[1],
                                               &dob->persistent_id[1],
                                               sizeof(dob->persistent_id[1]) * (MAX_DUPLI_RECUR - 1));
                        BKE_object_apply_mat4(ob_dst, dob->mat, false, true);
  
                        /* to set ob_dst->orig and in case theres any other discrepicies */
 -                      DAG_id_tag_update(&ob_dst->id, OB_RECALC_OB);
 +                      DEG_id_tag_update(&ob_dst->id, OB_RECALC_OB);
                }
        }
  
 -      if (base->object->transflag & OB_DUPLIGROUP && base->object->dup_group) {
 +      if (base->object->transflag & OB_DUPLICOLLECTION && base->object->dup_group) {
                for (Object *ob = bmain->object.first; ob; ob = ob->id.next) {
                        if (ob->proxy_group == base->object) {
                                ob->proxy = NULL;
                                ob->proxy_from = NULL;
 -                              DAG_id_tag_update(&ob->id, OB_RECALC_OB);
 +                              DEG_id_tag_update(&ob->id, OB_RECALC_OB);
                        }
                }
        }
@@@ -1586,7 -1518,7 +1586,7 @@@ static int object_duplicates_make_real_
        }
        CTX_DATA_END;
  
 -      DAG_relations_tag_update(bmain);
 +      DEG_relations_tag_update(bmain);
        WM_event_add_notifier(C, NC_SCENE, scene);
        WM_main_add_notifier(NC_OBJECT | ND_DRAW, NULL);
  
@@@ -1620,43 -1552,46 +1620,43 @@@ static const EnumPropertyItem convert_t
        {0, NULL, 0, NULL, NULL}
  };
  
 -static void convert_ensure_curve_cache(Main *bmain, Scene *scene, Object *ob)
 +static void convert_ensure_curve_cache(Depsgraph *depsgraph, Scene *scene, Object *ob)
  {
        if (ob->curve_cache == NULL) {
                /* Force creation. This is normally not needed but on operator
                 * redo we might end up with an object which isn't evaluated yet.
                 */
                if (ELEM(ob->type, OB_SURF, OB_CURVE, OB_FONT)) {
 -                      BKE_displist_make_curveTypes(scene, ob, false);
 +                      BKE_displist_make_curveTypes(depsgraph, scene, ob, false);
                }
                else if (ob->type == OB_MBALL) {
 -                      BKE_displist_make_mball(bmain, bmain->eval_ctx, scene, ob);
 +                      BKE_displist_make_mball(depsgraph, scene, ob);
                }
        }
  }
  
- static void curvetomesh(Depsgraph *depsgraph, Scene *scene, Object *ob)
 -static void curvetomesh(Main *bmain, Scene *scene, Object *ob)
++static void curvetomesh(Main *bmain, Depsgraph *depsgraph, Scene *scene, Object *ob)
  {
 -      convert_ensure_curve_cache(bmain, scene, ob);
 +      convert_ensure_curve_cache(depsgraph, scene, ob);
-       BKE_mesh_from_nurbs(ob); /* also does users */
+       BKE_mesh_from_nurbs(bmain, ob); /* also does users */
  
        if (ob->type == OB_MESH) {
                BKE_object_free_modifiers(ob, 0);
 -
 -              /* Game engine defaults for mesh objects */
 -              ob->body_type = OB_BODY_TYPE_STATIC;
 -              ob->gameflag = OB_PROP | OB_COLLISION;
        }
  }
  
  static int convert_poll(bContext *C)
  {
 -      Object *obact = CTX_data_active_object(C);
        Scene *scene = CTX_data_scene(C);
 +      Base *base_act = CTX_data_active_base(C);
 +      Object *obact = base_act ? base_act->object : NULL;
  
 -      return (!ID_IS_LINKED(scene) && obact && scene->obedit != obact &&
 -              (obact->flag & SELECT) && !ID_IS_LINKED(obact));
 +      return (!ID_IS_LINKED(scene) && obact && (BKE_object_is_in_editmode(obact) == false) &&
 +              (base_act->flag & BASE_SELECTED) && !ID_IS_LINKED(obact));
  }
  
  /* Helper for convert_exec */
 -static Base *duplibase_for_convert(Main *bmain, Scene *scene, Base *base, Object *ob)
 +static Base *duplibase_for_convert(Main *bmain, Scene *scene, ViewLayer *view_layer, Base *base, Object *ob)
  {
        Object *obn;
        Base *basen;
        }
  
        obn = BKE_object_copy(bmain, ob);
 -      DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
 -
 -      basen = MEM_mallocN(sizeof(Base), "duplibase");
 -      *basen = *base;
 -      BLI_addhead(&scene->base, basen);   /* addhead: otherwise eternal loop */
 -      basen->object = obn;
 -      basen->flag |= SELECT;
 -      obn->flag |= SELECT;
 -      base->flag &= ~SELECT;
 -      ob->flag &= ~SELECT;
 +      DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
 +      BKE_collection_object_add_from(bmain, scene, ob, obn);
  
 +      basen = BKE_view_layer_base_find(view_layer, obn);
 +      ED_object_base_select(basen, BA_SELECT);
 +      ED_object_base_select(basen, BA_DESELECT);
        return basen;
  }
  
  static int convert_exec(bContext *C, wmOperator *op)
  {
        Main *bmain = CTX_data_main(C);
 +      Depsgraph *depsgraph = CTX_data_depsgraph(C);
        Scene *scene = CTX_data_scene(C);
 +      ViewLayer *view_layer = CTX_data_view_layer(C);
        Base *basen = NULL, *basact = NULL;
 -      Object *ob, *ob1, *newob, *obact = CTX_data_active_object(C);
 +      Object *ob1, *newob, *obact = CTX_data_active_object(C);
        DerivedMesh *dm;
        Curve *cu;
        Nurb *nu;
        /* don't forget multiple users! */
  
        {
 -              Base *base;
 -
 -              for (base = scene->base.first; base; base = base->next) {
 -                      ob = base->object;
 +              FOREACH_SCENE_OBJECT_BEGIN(scene, ob)
 +              {
                        ob->flag &= ~OB_DONE;
  
                        /* flag data thats not been edited (only needed for !keep_original) */
                        if (ob->type == OB_MBALL && target == OB_MESH) {
                                if (BKE_mball_is_basis(ob) == false) {
                                        Object *ob_basis;
 -                                      ob_basis = BKE_mball_basis_find(bmain, bmain->eval_ctx, scene, ob);
 +                                      ob_basis = BKE_mball_basis_find(scene, ob);
                                        if (ob_basis) {
                                                ob_basis->flag &= ~OB_DONE;
                                        }
                                }
                        }
                }
 +              FOREACH_SCENE_OBJECT_END;
        }
  
        ListBase selected_editable_bases = CTX_data_collection_get(C, "selected_editable_bases");
        {
                for (CollectionPointerLink *link = selected_editable_bases.first; link; link = link->next) {
                        Base *base = link->ptr.data;
 -                      ob = base->object;
 +                      Object *ob = base->object;
  
                        /* The way object type conversion works currently (enforcing conversion of *all* objetcs using converted
                         * obdata, even some un-selected/hidden/inother scene ones, sounds totally bad to me.
                                            "Converting some linked object/object data, enforcing 'Keep Original' option to True");
                        }
  
 -                      DAG_id_tag_update(&base->object->id, OB_RECALC_DATA);
 +                      DEG_id_tag_update(&base->object->id, OB_RECALC_DATA);
                }
  
                uint64_t customdata_mask_prev = scene->customdata_mask;
                scene->customdata_mask |= CD_MASK_MESH;
 -              BKE_scene_update_tagged(bmain->eval_ctx, bmain, scene);
 +              BKE_scene_graph_update_tagged(depsgraph, bmain);
                scene->customdata_mask = customdata_mask_prev;
        }
  
        for (CollectionPointerLink *link = selected_editable_bases.first; link; link = link->next) {
                Base *base = link->ptr.data;
 -              ob = base->object;
 +              Object *ob = base->object;
  
                if (ob->flag & OB_DONE || !IS_TAGGED(ob->data)) {
                        if (ob->type != target) {
                        ob->flag |= OB_DONE;
  
                        if (keep_original) {
 -                              basen = duplibase_for_convert(bmain, scene, base, NULL);
 +                              basen = duplibase_for_convert(bmain, scene, view_layer, base, NULL);
                                newob = basen->object;
  
                                /* decrement original mesh's usage count  */
                                newob = ob;
                        }
  
-                       BKE_mesh_to_curve(depsgraph, scene, newob);
 -                      BKE_mesh_to_curve(bmain, scene, newob);
++                      BKE_mesh_to_curve(bmain, depsgraph, scene, newob);
  
                        if (newob->type == OB_CURVE) {
                                BKE_object_free_modifiers(newob, 0);   /* after derivedmesh calls! */
                        ob->flag |= OB_DONE;
  
                        if (keep_original) {
 -                              basen = duplibase_for_convert(bmain, scene, base, NULL);
 +                              basen = duplibase_for_convert(bmain, scene, view_layer, base, NULL);
                                newob = basen->object;
  
                                /* decrement original mesh's usage count  */
                        }
                        else {
                                newob = ob;
 -                              DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
 +                              DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
                        }
  
                        /* make new mesh data from the original copy */
                        /* note: get the mesh from the original, not from the copy in some
                         * cases this doesnt give correct results (when MDEF is used for eg)
                         */
 -                      dm = mesh_get_derived_final(scene, newob, CD_MASK_MESH);
 +                      dm = mesh_get_derived_final(depsgraph, scene, newob, CD_MASK_MESH);
  
                        DM_to_mesh(dm, newob->data, newob, CD_MASK_MESH, true);
  
                        ob->flag |= OB_DONE;
  
                        if (keep_original) {
 -                              basen = duplibase_for_convert(bmain, scene, base, NULL);
 +                              basen = duplibase_for_convert(bmain, scene, view_layer, base, NULL);
                                newob = basen->object;
  
                                /* decrement original curve's usage count  */
                                        for (ob1 = bmain->object.first; ob1; ob1 = ob1->id.next) {
                                                if (ob1->data == ob->data) {
                                                        ob1->type = OB_CURVE;
 -                                                      DAG_id_tag_update(&ob1->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
 +                                                      DEG_id_tag_update(&ob1->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
                                                }
                                        }
                                }
                        BKE_curve_curve_dimension_update(cu);
  
                        if (target == OB_MESH) {
-                               curvetomesh(depsgraph, scene, newob);
 -                              curvetomesh(bmain, scene, newob);
++                              curvetomesh(bmain, depsgraph, scene, newob);
  
                                /* meshes doesn't use displist */
                                BKE_object_free_curve_cache(newob);
  
                        if (target == OB_MESH) {
                                if (keep_original) {
 -                                      basen = duplibase_for_convert(bmain, scene, base, NULL);
 +                                      basen = duplibase_for_convert(bmain, scene, view_layer, base, NULL);
                                        newob = basen->object;
  
                                        /* decrement original curve's usage count  */
                                        newob = ob;
                                }
  
-                               curvetomesh(depsgraph, scene, newob);
 -                              curvetomesh(bmain, scene, newob);
++                              curvetomesh(bmain, depsgraph, scene, newob);
  
                                /* meshes doesn't use displist */
                                BKE_object_free_curve_cache(newob);
                else if (ob->type == OB_MBALL && target == OB_MESH) {
                        Object *baseob;
  
 -                      base->flag &= ~SELECT;
 -                      ob->flag &= ~SELECT;
 +                      base->flag &= ~BASE_SELECTED;
 +                      ob->base_flag &= ~BASE_SELECTED;
  
 -                      baseob = BKE_mball_basis_find(bmain, bmain->eval_ctx, scene, ob);
 +                      baseob = BKE_mball_basis_find(scene, ob);
  
                        if (ob != baseob) {
                                /* if motherball is converting it would be marked as done later */
                        if (!(baseob->flag & OB_DONE)) {
                                baseob->flag |= OB_DONE;
  
 -                              basen = duplibase_for_convert(bmain, scene, base, baseob);
 +                              basen = duplibase_for_convert(bmain, scene, view_layer, base, baseob);
                                newob = basen->object;
  
                                mb = newob->data;
                                        for (a = 0; a < newob->totcol; a++) id_us_plus((ID *)me->mat[a]);
                                }
  
 -                              convert_ensure_curve_cache(bmain, scene, baseob);
 +                              convert_ensure_curve_cache(depsgraph, scene, baseob);
                                BKE_mesh_from_metaball(&baseob->curve_cache->disp, newob->data);
  
                                if (obact->type == OB_MBALL) {
                }
  
                if (!keep_original && (ob->flag & OB_DONE)) {
 -                      DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
 +                      DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
                        ((ID *)ob->data)->tag &= ~LIB_TAG_DOIT; /* flag not to convert this datablock again */
                }
        }
  
        if (!keep_original) {
                if (mballConverted) {
 -                      Base *base, *base_next;
 -
 -                      for (base = scene->base.first; base; base = base_next) {
 -                              base_next = base->next;
 -
 -                              ob = base->object;
 -                              if (ob->type == OB_MBALL) {
 -                                      if (ob->flag & OB_DONE) {
 +                      FOREACH_SCENE_OBJECT_BEGIN(scene, ob_mball)
 +                      {
 +                              if (ob_mball->type == OB_MBALL) {
 +                                      if (ob_mball->flag & OB_DONE) {
                                                Object *ob_basis = NULL;
 -                                              if (BKE_mball_is_basis(ob) ||
 -                                                  ((ob_basis = BKE_mball_basis_find(bmain, bmain->eval_ctx, scene, ob)) && (ob_basis->flag & OB_DONE)))
 +                                              if (BKE_mball_is_basis(ob_mball) ||
 +                                                  ((ob_basis = BKE_mball_basis_find(scene, ob_mball)) && (ob_basis->flag & OB_DONE)))
                                                {
 -                                                      ED_base_object_free_and_unlink(bmain, scene, base);
 +                                                      ED_object_base_free_and_unlink(bmain, scene, ob_mball);
                                                }
                                        }
                                }
                        }
 +                      FOREACH_SCENE_OBJECT_END;
                }
  
                /* delete object should renew depsgraph */
 -              DAG_relations_tag_update(bmain);
 +              DEG_relations_tag_update(bmain);
        }
  
  // XXX        ED_object_editmode_enter(C, 0);
  
        if (basact) {
                /* active base was changed */
 -              ED_base_object_activate(C, basact);
 -              BASACT = basact;
 +              ED_object_base_activate(C, basact);
 +              BASACT(view_layer) = basact;
        }
 -      else if (BASACT->object->flag & OB_DONE) {
 -              WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, BASACT->object);
 -              WM_event_add_notifier(C, NC_OBJECT | ND_DATA, BASACT->object);
 +      else if (BASACT(view_layer)->object->flag & OB_DONE) {
 +              WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, BASACT(view_layer)->object);
 +              WM_event_add_notifier(C, NC_OBJECT | ND_DATA, BASACT(view_layer)->object);
        }
  
 -      DAG_relations_tag_update(bmain);
 +      DEG_relations_tag_update(bmain);
        WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, scene);
        WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
  
@@@ -2056,43 -1998,39 +2056,43 @@@ void OBJECT_OT_convert(wmOperatorType *
  /* used below, assumes id.new is correct */
  /* leaves selection of base/object unaltered */
  /* Does set ID->newid pointers. */
 -static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base, int dupflag)
 +static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, ViewLayer *view_layer, Object *ob, int dupflag)
  {
  #define ID_NEW_REMAP_US(a)    if (      (a)->id.newid) { (a) = (void *)(a)->id.newid;       (a)->id.us++; }
  #define ID_NEW_REMAP_US2(a)   if (((ID *)a)->newid)    { (a) = ((ID  *)a)->newid;     ((ID *)a)->us++;    }
  
 -      Base *basen = NULL;
 +      Base *base, *basen = NULL;
        Material ***matarar;
 -      Object *ob, *obn;
 +      Object *obn;
        ID *id;
        int a, didit;
  
 -      ob = base->object;
        if (ob->mode & OB_MODE_POSE) {
                ; /* nothing? */
        }
        else {
                obn = ID_NEW_SET(ob, BKE_object_copy(bmain, ob));
 -              DAG_id_tag_update(&obn->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
 +              DEG_id_tag_update(&obn->id, OB_RECALC_OB | OB_RECALC_DATA);
  
 -              basen = MEM_mallocN(sizeof(Base), "duplibase");
 -              *basen = *base;
 -              BLI_addhead(&scene->base, basen);   /* addhead: prevent eternal loop */
 -              basen->object = obn;
 +              base = BKE_view_layer_base_find(view_layer, ob);
 +              if ((base != NULL) && (base->flag & BASE_VISIBLED)) {
 +                      BKE_collection_object_add_from(bmain, scene, ob, obn);
 +              }
 +              else {
 +                      LayerCollection *layer_collection = BKE_layer_collection_get_active(view_layer);
 +                      BKE_collection_object_add(bmain, layer_collection->collection, obn);
 +              }
 +              basen = BKE_view_layer_base_find(view_layer, obn);
  
 -              /* 1) duplis should end up in same group as the original
 -               * 2) Rigid Body sim participants MUST always be part of a group...
 +              /* 1) duplis should end up in same collection as the original
 +               * 2) Rigid Body sim participants MUST always be part of a collection...
                 */
                // XXX: is 2) really a good measure here?
 -              if ((basen->flag & OB_FROMGROUP) || ob->rigidbody_object || ob->rigidbody_constraint) {
 -                      Group *group;
 -                      for (group = bmain->group.first; group; group = group->id.next) {
 -                              if (BKE_group_object_exists(group, ob))
 -                                      BKE_group_object_add(group, obn, scene, basen);
 +              if (ob->rigidbody_object || ob->rigidbody_constraint) {
 +                      Collection *collection;
 +                      for (collection = bmain->collection.first; collection; collection = collection->id.next) {
 +                              if (BKE_collection_has_object(collection, ob))
 +                                      BKE_collection_object_add(bmain, collection, obn);
                        }
                }
  
                                }
                                break;
                        case OB_ARMATURE:
 -                              DAG_id_tag_update(&obn->id, OB_RECALC_DATA);
 +                              DEG_id_tag_update(&obn->id, OB_RECALC_DATA);
                                if (obn->pose)
                                        BKE_pose_tag_recalc(bmain, obn->pose);
                                if (dupflag & USER_DUP_ARM) {
                        }
  
                        if (dupflag & USER_DUP_ACT) {
 -                              bActuator *act;
 -
                                BKE_animdata_copy_id_action((ID *)obn->data, true);
                                if (key) {
                                        BKE_animdata_copy_id_action((ID *)key, true);
                                }
 -
 -                              /* Update the duplicated action in the action actuators */
 -                              /* XXX TODO this code is all wrong! actact->act is user-refcounted (see readfile.c),
 -                               * and what about other ID pointers of other BGE logic bricks,
 -                               * and since this is object-level, why is it only ran if obdata was duplicated??? -mont29 */
 -                              for (act = obn->actuators.first; act; act = act->next) {
 -                                      if (act->type == ACT_ACTION) {
 -                                              bActionActuator *actact = (bActionActuator *) act->data;
 -                                              if (ob->adt && actact->act == ob->adt->action) {
 -                                                      actact->act = obn->adt->action;
 -                                              }
 -                                      }
 -                              }
                        }
  
                        if (dupflag & USER_DUP_MAT) {
   * note: don't call this within a loop since clear_* funcs loop over the entire database.
   * note: caller must do DAG_relations_tag_update(bmain);
   *       this is not done automatic since we may duplicate many objects in a batch */
 -Base *ED_object_add_duplicate(Main *bmain, Scene *scene, Base *base, int dupflag)
 +Base *ED_object_add_duplicate(Main *bmain, Scene *scene, ViewLayer *view_layer, Base *base, int dupflag)
  {
        Base *basen;
        Object *ob;
  
 -      clear_sca_new_poins();  /* BGE logic */
 -
 -      basen = object_add_duplicate_internal(bmain, scene, base, dupflag);
 +      basen = object_add_duplicate_internal(bmain, scene, view_layer, base->object, dupflag);
        if (basen == NULL) {
                return NULL;
        }
  
        /* link own references to the newly duplicated data [#26816] */
        BKE_libblock_relink_to_newid(&ob->id);
 -      set_sca_new_poins_ob(ob);
  
        /* DAG_relations_tag_update(bmain); */ /* caller must do */
  
 -      if (ob->data) {
 -              ED_render_id_flush_update(bmain, ob->data);
 +      if (ob->data != NULL) {
 +              DEG_id_tag_update_ex(bmain, (ID *)ob->data, DEG_TAG_EDITORS_UPDATE);
        }
  
        BKE_main_id_clear_newpoins(bmain);
@@@ -2321,29 -2277,29 +2321,29 @@@ static int duplicate_exec(bContext *C, 
  {
        Main *bmain = CTX_data_main(C);
        Scene *scene = CTX_data_scene(C);
 +      ViewLayer *view_layer = CTX_data_view_layer(C);
        const bool linked = RNA_boolean_get(op->ptr, "linked");
        int dupflag = (linked) ? 0 : U.dupflag;
  
 -      clear_sca_new_poins();  /* BGE logic */
 -
        CTX_DATA_BEGIN (C, Base *, base, selected_bases)
        {
 -              Base *basen = object_add_duplicate_internal(bmain, scene, base, dupflag);
 +              Base *basen = object_add_duplicate_internal(bmain, scene, view_layer, base->object, dupflag);
  
                /* note that this is safe to do with this context iterator,
                 * the list is made in advance */
 -              ED_base_object_select(base, BA_DESELECT);
 +              ED_object_base_select(base, BA_DESELECT);
 +              ED_object_base_select(basen, BA_SELECT);
  
                if (basen == NULL) {
                        continue;
                }
  
                /* new object becomes active */
 -              if (BASACT == base)
 -                      ED_base_object_activate(C, basen);
 +              if (BASACT(view_layer) == base)
 +                      ED_object_base_activate(C, basen);
  
                if (basen->object->data) {
 -                      DAG_id_tag_update(basen->object->data, 0);
 +                      DEG_id_tag_update(basen->object->data, 0);
                }
        }
        CTX_DATA_END;
  
        BKE_main_id_clear_newpoins(bmain);
  
 -      DAG_relations_tag_update(bmain);
 +      DEG_relations_tag_update(bmain);
 +      /* TODO(sergey): Use proper flag for tagging here. */
 +      DEG_id_tag_update(&scene->id, 0);
  
        WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
  
@@@ -2390,9 -2344,9 +2390,9 @@@ static int add_named_exec(bContext *C, 
        wmWindow *win = CTX_wm_window(C);
        const wmEvent *event = win ? win->eventstate : NULL;
        Main *bmain = CTX_data_main(C);
 -      View3D *v3d = CTX_wm_view3d(C);  /* may be NULL */
        Scene *scene = CTX_data_scene(C);
 -      Base *basen, *base;
 +      ViewLayer *view_layer = CTX_data_view_layer(C);
 +      Base *basen;
        Object *ob;
        const bool linked = RNA_boolean_get(op->ptr, "linked");
        int dupflag = (linked) ? 0 : U.dupflag;
                return OPERATOR_CANCELLED;
        }
  
 -      base = MEM_callocN(sizeof(Base), "duplibase");
 -      base->object = ob;
 -      base->flag = ob->flag;
 -
        /* prepare dupli */
 -      clear_sca_new_poins();  /* BGE logic */
 -
 -      basen = object_add_duplicate_internal(bmain, scene, base, dupflag);
 +      basen = object_add_duplicate_internal(bmain, scene, view_layer, ob, dupflag);
  
        if (basen == NULL) {
 -              MEM_freeN(base);
                BKE_report(op->reports, RPT_ERROR, "Object could not be duplicated");
                return OPERATOR_CANCELLED;
        }
  
 -      basen->lay = basen->object->lay = BKE_screen_view3d_layer_active(v3d, scene);
 +      BKE_scene_object_base_flag_sync_from_object(basen);
        basen->object->restrictflag &= ~OB_RESTRICT_VIEW;
  
        if (event) {
                ED_view3d_cursor3d_position(C, basen->object->loc, mval);
        }
  
 -      ED_base_object_select(basen, BA_SELECT);
 -      ED_base_object_activate(C, basen);
 +      ED_object_base_select(basen, BA_SELECT);
 +      ED_object_base_activate(C, basen);
  
        copy_object_set_idnew(C);
  
        BKE_main_id_clear_newpoins(bmain);
  
 -      DAG_relations_tag_update(bmain);
 -
 -      MEM_freeN(base);
 +      /* TODO(sergey): Only update relations for the current scene. */
 +      DEG_relations_tag_update(bmain);
  
        WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
        WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
@@@ -2476,9 -2438,10 +2476,9 @@@ static int join_poll(bContext *C
  
  static int join_exec(bContext *C, wmOperator *op)
  {
 -      Scene *scene = CTX_data_scene(C);
        Object *ob = CTX_data_active_object(C);
  
 -      if (scene->obedit) {
 +      if (ob->mode & OB_MODE_EDIT) {
                BKE_report(op->reports, RPT_ERROR, "This data does not support joining in edit mode");
                return OPERATOR_CANCELLED;
        }
@@@ -2529,9 -2492,10 +2529,9 @@@ static int join_shapes_poll(bContext *C
  
  static int join_shapes_exec(bContext *C, wmOperator *op)
  {
 -      Scene *scene = CTX_data_scene(C);
        Object *ob = CTX_data_active_object(C);
  
 -      if (scene->obedit) {
 +      if (ob->mode & OB_MODE_EDIT) {
                BKE_report(op->reports, RPT_ERROR, "This data does not support joining in edit mode");
                return OPERATOR_CANCELLED;
        }
@@@ -54,9 -54,9 +54,9 @@@
  #include "BKE_camera.h"
  #include "BKE_context.h"
  #include "BKE_colortools.h"
 -#include "BKE_depsgraph.h"
  #include "BKE_global.h"
  #include "BKE_image.h"
 +#include "BKE_layer.h"
  #include "BKE_library.h"
  #include "BKE_main.h"
  #include "BKE_node.h"
@@@ -66,9 -66,6 +66,9 @@@
  #include "BKE_screen.h"
  #include "BKE_scene.h"
  #include "BKE_undo_system.h"
 +#include "BKE_workspace.h"
 +
 +#include "DEG_depsgraph.h"
  
  #include "WM_api.h"
  #include "WM_types.h"
@@@ -86,7 -83,6 +86,7 @@@
  #include "IMB_colormanagement.h"
  #include "IMB_imbuf_types.h"
  
 +#include "GPU_shader.h"
  
  #include "BIF_gl.h"
  #include "BIF_glutil.h"
@@@ -104,13 -100,9 +104,13 @@@ static int render_break(void *rjv)
  typedef struct RenderJob {
        Main *main;
        Scene *scene;
 +      ViewLayer *single_layer;
        Scene *current_scene;
 +      /* TODO(sergey): Should not be needed once engine will have own
 +       * depsgraph and copy-on-write will be implemented.
 +       */
 +      Depsgraph *depsgraph;
        Render *re;
 -      SceneRenderLayer *srl;
        struct Object *camera_override;
        int lay_override;
        bool v3d_override;
@@@ -263,7 -255,7 +263,7 @@@ static void image_buffer_rect_update(Re
  /* set callbacks, exported to sequence render too.
   * Only call in foreground (UI) renders. */
  
 -static void screen_render_scene_layer_set(wmOperator *op, Main *mainp, Scene **scene, SceneRenderLayer **srl)
 +static void screen_render_single_layer_set(wmOperator *op, Main *mainp, WorkSpace *workspace, Scene **scene, ViewLayer **single_layer)
  {
        /* single layer re-render */
        if (RNA_struct_property_is_set(op->ptr, "scene")) {
        }
  
        if (RNA_struct_property_is_set(op->ptr, "layer")) {
 -              SceneRenderLayer *rl;
 +              ViewLayer *rl;
                char rl_name[RE_MAXNAME];
  
                RNA_string_get(op->ptr, "layer", rl_name);
 -              rl = (SceneRenderLayer *)BLI_findstring(&(*scene)->r.layers, rl_name, offsetof(SceneRenderLayer, name));
 +              rl = (ViewLayer *)BLI_findstring(&(*scene)->view_layers, rl_name, offsetof(ViewLayer, name));
  
                if (rl)
 -                      *srl = rl;
 +                      *single_layer = rl;
 +      }
 +      else if (((*scene)->r.scemode & R_SINGLE_LAYER) && workspace) {
 +              *single_layer = BKE_view_layer_from_workspace_get(*scene, workspace);
        }
  }
  
  static int screen_render_exec(bContext *C, wmOperator *op)
  {
        Scene *scene = CTX_data_scene(C);
 -      SceneRenderLayer *srl = NULL;
 +      RenderEngineType *re_type = RE_engines_find(scene->r.engine);
 +      ViewLayer *single_layer = NULL;
        Render *re;
        Image *ima;
        View3D *v3d = CTX_wm_view3d(C);
        Main *mainp = CTX_data_main(C);
 +      WorkSpace *workspace = CTX_wm_workspace(C);
        unsigned int lay_override;
        const bool is_animation = RNA_boolean_get(op->ptr, "animation");
        const bool is_write_still = RNA_boolean_get(op->ptr, "write_still");
        struct Object *camera_override = v3d ? V3D_CAMERA_LOCAL(v3d) : NULL;
  
 +      /* Cannot do render if there is not this function. */
 +      if (re_type->render == NULL) {
 +              return OPERATOR_CANCELLED;
 +      }
 +
        /* custom scene and single layer re-render */
 -      screen_render_scene_layer_set(op, mainp, &scene, &srl);
 +      screen_render_single_layer_set(op, mainp, workspace, &scene, &single_layer);
  
        if (!is_animation && is_write_still && BKE_imtype_is_movie(scene->r.im_format.imtype)) {
                BKE_report(op->reports, RPT_ERROR, "Cannot write a single file with an animation format selected");
        G.is_break = false;
        RE_test_break_cb(re, NULL, render_break);
  
-       ima = BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result");
-       BKE_image_signal(ima, NULL, IMA_SIGNAL_FREE);
+       ima = BKE_image_verify_viewer(mainp, IMA_TYPE_R_RESULT, "Render Result");
+       BKE_image_signal(mainp, ima, NULL, IMA_SIGNAL_FREE);
        BKE_image_backup_render(scene, ima, true);
  
        /* cleanup sequencer caches before starting user triggered render.
        if (is_animation)
                RE_BlenderAnim(re, mainp, scene, camera_override, lay_override, scene->r.sfra, scene->r.efra, scene->r.frame_step);
        else
 -              RE_BlenderFrame(re, mainp, scene, srl, camera_override, lay_override, scene->r.cfra, is_write_still);
 +              RE_BlenderFrame(re, mainp, scene, single_layer, camera_override, lay_override, scene->r.cfra, is_write_still);
        BLI_threaded_malloc_end();
  
        RE_SetReports(re, NULL);
  
        // no redraw needed, we leave state as we entered it
 -      ED_update_for_newframe(mainp, scene, 1);
 +      ED_update_for_newframe(mainp, CTX_data_depsgraph(C));
  
        WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, scene);
  
@@@ -510,9 -492,8 +510,9 @@@ static void render_image_update_pass_an
        for (wm = rj->main->wm.first; wm && matched_sa == NULL; wm = wm->id.next) { /* only 1 wm */
                wmWindow *win;
                for (win = wm->windows.first; win && matched_sa == NULL; win = win->next) {
 -                      ScrArea *sa;
 -                      for (sa = win->screen->areabase.first; sa; sa = sa->next) {
 +                      const bScreen *screen = WM_window_get_active_screen(win);
 +
 +                      for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
                                if (sa->spacetype == SPACE_IMAGE) {
                                        SpaceImage *sima = sa->spacedata.first;
                                        // sa->spacedata might be empty when toggling fullscreen mode.
@@@ -570,7 -551,7 +570,7 @@@ static void image_rect_update(void *rjv
        else if (rj->image_outdated) {
                /* update entire render */
                rj->image_outdated = false;
-               BKE_image_signal(ima, NULL, IMA_SIGNAL_COLORMANAGE);
+               BKE_image_signal(rj->main, ima, NULL, IMA_SIGNAL_COLORMANAGE);
                *(rj->do_update) = true;
                return;
        }
@@@ -623,7 -604,7 +623,7 @@@ static void render_startjob(void *rjv, 
        if (rj->anim)
                RE_BlenderAnim(rj->re, rj->main, rj->scene, rj->camera_override, rj->lay_override, rj->scene->r.sfra, rj->scene->r.efra, rj->scene->r.frame_step);
        else
 -              RE_BlenderFrame(rj->re, rj->main, rj->scene, rj->srl, rj->camera_override, rj->lay_override, rj->scene->r.cfra, rj->write_still);
 +              RE_BlenderFrame(rj->re, rj->main, rj->scene, rj->single_layer, rj->camera_override, rj->lay_override, rj->scene->r.cfra, rj->write_still);
  
        RE_SetReports(rj->re, NULL);
  }
@@@ -636,9 -617,8 +636,9 @@@ static void render_image_restore_layer(
        for (wm = rj->main->wm.first; wm; wm = wm->id.next) { /* only 1 wm */
                wmWindow *win;
                for (win = wm->windows.first; win; win = win->next) {
 -                      ScrArea *sa;
 -                      for (sa = win->screen->areabase.first; sa; sa = sa->next) {
 +                      const bScreen *screen = WM_window_get_active_screen(win);
 +
 +                      for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
                                if (sa == rj->sa) {
                                        if (sa->spacetype == SPACE_IMAGE) {
                                                SpaceImage *sima = sa->spacedata.first;
@@@ -680,7 -660,7 +680,7 @@@ static void render_endjob(void *rjv
        if (rj->anim && !(rj->scene->r.scemode & R_NO_FRAME_UPDATE)) {
                /* possible this fails of loading new file while rendering */
                if (G.main->wm.first) {
 -                      ED_update_for_newframe(G.main, rj->scene, 1);
 +                      ED_update_for_newframe(G.main, rj->depsgraph);
                }
        }
  
        /* potentially set by caller */
        rj->scene->r.scemode &= ~R_NO_FRAME_UPDATE;
  
 -      if (rj->srl) {
 +      if (rj->single_layer) {
                nodeUpdateID(rj->scene->nodetree, &rj->scene->id);
                WM_main_add_notifier(NC_NODE | NA_EDITED, rj->scene);
        }
         * engine API, so lets use simple and robust way for now
         *                                          - sergey -
         */
 -      if (rj->scene->r.layers.first != rj->scene->r.layers.last ||
 +      if (rj->scene->view_layers.first != rj->scene->view_layers.last ||
            rj->image_outdated)
        {
                void *lock;
                        scene->lay_updated = 0;
                }
  
 -              DAG_on_visible_update(G.main, false);
 +              DEG_on_visible_update(G.main, false);
        }
  }
  
@@@ -817,46 -797,33 +817,46 @@@ static void screen_render_cancel(bConte
        WM_jobs_kill_type(wm, scene, WM_JOB_TYPE_RENDER);
  }
  
 -static void clean_viewport_memory(Main *bmain, Scene *scene, int renderlay)
 +static void clean_viewport_memory_base(Base *base)
  {
 -      Object *object;
 -      Scene *sce_iter;
 -      Base *base;
 +      if ((base->flag & BASE_VISIBLED) == 0) {
 +              return;
 +      }
 +
 +      Object *object = base->object;
  
 -      for (object = bmain->object.first; object; object = object->id.next) {
 -              object->id.tag |= LIB_TAG_DOIT;
 +      if (object->id.tag & LIB_TAG_DOIT) {
 +              return;
        }
  
 -      for (SETLOOPER(scene, sce_iter, base)) {
 -              if ((base->lay & renderlay) == 0) {
 -                      continue;
 -              }
 -              if (RE_allow_render_generic_object(base->object)) {
 -                      base->object->id.tag &= ~LIB_TAG_DOIT;
 -              }
 +      object->id.tag &= ~LIB_TAG_DOIT;
 +      if (RE_allow_render_generic_object(object)) {
 +              BKE_object_free_derived_caches(object);
        }
 +}
 +
 +static void clean_viewport_memory(Main *bmain, Scene *scene)
 +{
 +      Scene *sce_iter;
 +      Base *base;
  
 -      for (SETLOOPER(scene, sce_iter, base)) {
 -              object = base->object;
 -              if ((object->id.tag & LIB_TAG_DOIT) == 0) {
 -                      continue;
 +      /* Tag all the available objects. */
 +      BKE_main_id_tag_listbase(&bmain->object, LIB_TAG_DOIT, true);
 +
 +      /* Go over all the visible objects. */
 +      for (wmWindowManager *wm = bmain->wm.first; wm; wm = wm->id.next) {
 +              for (wmWindow *win = wm->windows.first; win; win = win->next) {
 +                      WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook);
 +                      ViewLayer *view_layer = BKE_view_layer_from_workspace_get(scene, workspace);
 +
 +                      for (base = view_layer->object_bases.first; base; base = base->next) {
 +                              clean_viewport_memory_base(base);
 +                      }
                }
 -              object->id.tag &= ~LIB_TAG_DOIT;
 +      }
  
 -              BKE_object_free_derived_caches(object);
 +      for (SETLOOPER_SET_ONLY(scene, sce_iter, base)) {
 +              clean_viewport_memory_base(base);
        }
  }
  
  static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *event)
  {
        /* new render clears all callbacks */
 -      Main *mainp;
 +      Main *bmain = CTX_data_main(C);
 +      ViewLayer *single_layer = NULL;
        Scene *scene = CTX_data_scene(C);
 -      SceneRenderLayer *srl = NULL;
 +      RenderEngineType *re_type = RE_engines_find(scene->r.engine);
        Render *re;
        wmJob *wm_job;
        RenderJob *rj;
        const bool is_write_still = RNA_boolean_get(op->ptr, "write_still");
        const bool use_viewport = RNA_boolean_get(op->ptr, "use_viewport");
        View3D *v3d = use_viewport ? CTX_wm_view3d(C) : NULL;
 +      WorkSpace *workspace = CTX_wm_workspace(C);
        struct Object *camera_override = v3d ? V3D_CAMERA_LOCAL(v3d) : NULL;
        const char *name;
        ScrArea *sa;
  
 +      /* Cannot do render if there is not this function. */
 +      if (re_type->render == NULL) {
 +              return OPERATOR_CANCELLED;
 +      }
 +
 +      /* custom scene and single layer re-render */
 +      screen_render_single_layer_set(op, bmain, workspace, &scene, &single_layer);
 +
        /* only one render job at a time */
        if (WM_jobs_test(CTX_wm_manager(C), scene, WM_JOB_TYPE_RENDER))
                return OPERATOR_CANCELLED;
  
 -      if (RE_force_single_renderlayer(scene))
 -              WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, NULL);
 -
 -      if (!RE_is_rendering_allowed(scene, camera_override, op->reports)) {
 +      if (!RE_is_rendering_allowed(scene, single_layer, camera_override, op->reports)) {
                return OPERATOR_CANCELLED;
        }
  
        /* stop all running jobs, except screen one. currently previews frustrate Render */
        WM_jobs_kill_all_except(CTX_wm_manager(C), CTX_wm_screen(C));
  
 -      /* get main */
 -      if (G.debug_value == 101) {
 -              /* thread-safety experiment, copy main from the undo buffer */
 -              struct MemFile *memfile = ED_undosys_stack_memfile_get_active(CTX_wm_manager(C)->undo_stack);
 -              mainp = BLO_memfile_main_get(memfile, CTX_data_main(C), &scene);
 -      }
 -      else
 -              mainp = CTX_data_main(C);
 -
        /* cancel animation playback */
        if (ED_screen_animation_playing(CTX_wm_manager(C)))
                ED_screen_animation_play(C, 0, 0);
  
        jobflag = WM_JOB_EXCL_RENDER | WM_JOB_PRIORITY | WM_JOB_PROGRESS;
  
 -      /* custom scene and single layer re-render */
 -      screen_render_scene_layer_set(op, mainp, &scene, &srl);
 -
        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 = mainp;
 +      rj->main = bmain;
        rj->scene = scene;
        rj->current_scene = rj->scene;
 -      rj->srl = srl;
 +      rj->single_layer = single_layer;
 +      /* TODO(sergey): Render engine should be using own depsgraph. */
 +      rj->depsgraph = CTX_data_depsgraph(C);
        rj->camera_override = camera_override;
        rj->lay_override = 0;
        rj->anim = is_animation;
  
        /* Lock the user interface depending on render settings. */
        if (scene->r.use_lock_interface) {
 -              int renderlay = rj->lay_override ? rj->lay_override : scene->lay;
 -
                WM_set_locked_interface(CTX_wm_manager(C), true);
  
                /* Set flag interface need to be unlocked.
                rj->interface_locked = true;
  
                /* Clean memory used by viewport? */
 -              clean_viewport_memory(rj->main, scene, renderlay);
 +              clean_viewport_memory(rj->main, scene);
        }
  
        /* setup job */
        WM_jobs_callbacks(wm_job, render_startjob, NULL, NULL, render_endjob);
  
        /* get a render result image, and make sure it is empty */
-       ima = BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result");
-       BKE_image_signal(ima, NULL, IMA_SIGNAL_FREE);
 -      ima = BKE_image_verify_viewer(mainp, IMA_TYPE_R_RESULT, "Render Result");
++      ima = BKE_image_verify_viewer(bmain, IMA_TYPE_R_RESULT, "Render Result");
+       BKE_image_signal(rj->main, ima, NULL, IMA_SIGNAL_FREE);
        BKE_image_backup_render(rj->scene, ima, true);
        rj->image = ima;
  
        RE_current_scene_update_cb(re, rj, current_scene_update);
        RE_stats_draw_cb(re, rj, image_renderinfo_cb);
        RE_progress_cb(re, rj, render_progress_update);
 +      RE_gl_context_create(re);
  
        rj->re = re;
        G.is_break = false;
@@@ -1072,6 -1043,615 +1072,6 @@@ void RENDER_OT_render(wmOperatorType *o
  }
  
  
 -/* ************** preview for 3d viewport ***************** */
 -
 -#define PR_UPDATE_VIEW                                1
 -#define PR_UPDATE_RENDERSIZE          2
 -#define PR_UPDATE_MATERIAL                    4
 -#define PR_UPDATE_DATABASE                    8
 -
 -typedef struct RenderPreview {
 -      /* from wmJob */
 -      void *owner;
 -      short *stop, *do_update;
 -      wmJob *job;
 -
 -      Scene *scene;
 -      ScrArea *sa;
 -      ARegion *ar;
 -      View3D *v3d;
 -      RegionView3D *rv3d;
 -      Main *bmain;
 -      RenderEngine *engine;
 -
 -      float viewmat[4][4];
 -
 -      int start_resolution_divider;
 -      int resolution_divider;
 -      bool has_freestyle;
 -} RenderPreview;
 -
 -static int render_view3d_disprect(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, rcti *disprect)
 -{
 -      /* copied code from view3d_draw.c */
 -      rctf viewborder;
 -      int draw_border;
 -
 -      if (rv3d->persp == RV3D_CAMOB)
 -              draw_border = (scene->r.mode & R_BORDER) != 0;
 -      else
 -              draw_border = (v3d->flag2 & V3D_RENDER_BORDER) != 0;
 -
 -      if (draw_border) {
 -              if (rv3d->persp == RV3D_CAMOB) {
 -                      ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &viewborder, false);
 -
 -                      disprect->xmin = viewborder.xmin + scene->r.border.xmin * BLI_rctf_size_x(&viewborder);
 -                      disprect->ymin = viewborder.ymin + scene->r.border.ymin * BLI_rctf_size_y(&viewborder);
 -                      disprect->xmax = viewborder.xmin + scene->r.border.xmax * BLI_rctf_size_x(&viewborder);
 -                      disprect->ymax = viewborder.ymin + scene->r.border.ymax * BLI_rctf_size_y(&viewborder);
 -              }
 -              else {
 -                      disprect->xmin = v3d->render_border.xmin * ar->winx;
 -                      disprect->xmax = v3d->render_border.xmax * ar->winx;
 -                      disprect->ymin = v3d->render_border.ymin * ar->winy;
 -                      disprect->ymax = v3d->render_border.ymax * ar->winy;
 -              }
 -
 -              return 1;
 -      }
 -
 -      BLI_rcti_init(disprect, 0, 0, 0, 0);
 -      return 0;
 -}
 -
 -/* returns true if OK  */
 -static bool render_view3d_get_rects(ARegion *ar, View3D *v3d, RegionView3D *rv3d, rctf *viewplane, RenderEngine *engine,
 -                                    float *r_clipsta, float *r_clipend, float *r_pixsize, bool *r_ortho)
 -{
 -
 -      if (ar->winx < 4 || ar->winy < 4) return false;
 -
 -      *r_ortho = ED_view3d_viewplane_get(v3d, rv3d, ar->winx, ar->winy, viewplane, r_clipsta, r_clipend, r_pixsize);
 -
 -      engine->resolution_x = ar->winx;
 -      engine->resolution_y = ar->winy;
 -
 -      return true;
 -}
 -
 -static bool render_view3d_is_valid(RenderPreview *rp)
 -{
 -      return (rp->rv3d->render_engine != NULL);
 -}
 -
 -/* called by renderer, checks job value */
 -static int render_view3d_break(void *rpv)
 -{
 -      RenderPreview *rp = rpv;
 -
 -      if (G.is_break)
 -              return 1;
 -
 -      /* during render, rv3d->engine can get freed */
 -      if (render_view3d_is_valid(rp) == false) {
 -              *rp->stop = 1;
 -      }
 -
 -      return *(rp->stop);
 -}
 -
 -static void render_view3d_display_update(void *rpv, RenderResult *UNUSED(rr), volatile struct rcti *UNUSED(rect))
 -{
 -      RenderPreview *rp = rpv;
 -
 -      *(rp->do_update) = true;
 -}
 -
 -static void render_view3d_renderinfo_cb(void *rjp, RenderStats *rs)
 -{
 -      RenderPreview *rp = rjp;
 -
 -      /* during render, rv3d->engine can get freed */
 -      if (rp->rv3d->render_engine == NULL) {
 -              *rp->stop = 1;
 -      }
 -      else {
 -              make_renderinfo_string(rs, rp->scene, false, NULL, rp->engine->text);
 -
 -              /* make jobs timer to send notifier */
 -              *(rp->do_update) = true;
 -      }
 -}
 -
 -BLI_INLINE void rcti_scale_coords(rcti *scaled_rect, const rcti *rect,
 -                                  const float scale)
 -{
 -      scaled_rect->xmin = rect->xmin * scale;
 -      scaled_rect->ymin = rect->ymin * scale;
 -      scaled_rect->xmax = rect->xmax * scale;
 -      scaled_rect->ymax = rect->ymax * scale;
 -}
 -
 -static void render_update_resolution(Render *re, const RenderPreview *rp,
 -                                     bool use_border, const rcti *clip_rect)
 -{
 -      int winx = rp->ar->winx / rp->resolution_divider;
 -      int winy = rp->ar->winy / rp->resolution_divider;
 -      if (use_border) {
 -              rcti scaled_cliprct;
 -              rcti_scale_coords(&scaled_cliprct, clip_rect,
 -                                1.0f / rp->resolution_divider);
 -              RE_ChangeResolution(re, winx, winy, &scaled_cliprct);
 -      }
 -      else {
 -              RE_ChangeResolution(re, winx, winy, NULL);
 -      }
 -
 -      if (rp->has_freestyle) {
 -              if (rp->resolution_divider == BKE_render_preview_pixel_size(&rp->scene->r)) {
 -                      RE_ChangeModeFlag(re, R_EDGE_FRS, false);
 -              }
 -              else {
 -                      RE_ChangeModeFlag(re, R_EDGE_FRS, true);
 -              }
 -      }
 -}
 -
 -static void render_view3d_startjob(void *customdata, short *stop, short *do_update, float *UNUSED(progress))
 -{
 -      RenderPreview *rp = customdata;
 -      Render *re;
 -      RenderStats *rstats;
 -      rctf viewplane;
 -      rcti cliprct;
 -      float clipsta, clipend, pixsize;
 -      bool orth, restore = 0;
 -      char name[32];
 -      int update_flag;
 -      bool use_border;
 -      int ob_inst_update_flag = 0;
 -
 -      update_flag = rp->engine->job_update_flag;
 -      rp->engine->job_update_flag = 0;
 -
 -      //printf("ma %d res %d view %d db %d\n", update_flag & PR_UPDATE_MATERIAL, update_flag & PR_UPDATE_RENDERSIZE, update_flag & PR_UPDATE_VIEW, update_flag & PR_UPDATE_DATABASE);
 -
 -      G.is_break = false;
 -
 -      if (false == render_view3d_get_rects(rp->ar, rp->v3d, rp->rv3d, &viewplane, rp->engine, &clipsta, &clipend, &pixsize, &orth))
 -              return;
 -
 -      rp->stop = stop;
 -      rp->do_update = do_update;
 -
 -      // printf("Enter previewrender\n");
 -
 -      /* ok, are we rendering all over? */
 -      sprintf(name, "View3dPreview %p", (void *)rp->ar);
 -      re = rp->engine->re = RE_GetRender(name);
 -
 -      /* set this always, rp is different for each job */
 -      RE_test_break_cb(re, rp, render_view3d_break);
 -      RE_display_update_cb(re, rp, render_view3d_display_update);
 -      RE_stats_draw_cb(re, rp, render_view3d_renderinfo_cb);
 -
 -      rstats = RE_GetStats(re);
 -
 -      if (update_flag & PR_UPDATE_VIEW) {
 -              Object *object;
 -              rp->resolution_divider = rp->start_resolution_divider;
 -
 -              /* Same as database_init_objects(), loop over all objects.
 -               * We might consider de-duplicating the code between this two cases.
 -               */
 -              for (object = rp->bmain->object.first; object; object = object->id.next) {
 -                      float mat[4][4];
 -                      mul_m4_m4m4(mat, rp->viewmat, object->obmat);
 -                      invert_m4_m4(object->imat_ren, mat);
 -              }
 -      }
 -
 -      use_border = render_view3d_disprect(rp->scene, rp->ar, rp->v3d,
 -                                          rp->rv3d, &cliprct);
 -
 -      if ((update_flag & (PR_UPDATE_RENDERSIZE | PR_UPDATE_DATABASE | PR_UPDATE_VIEW)) || rstats->convertdone == 0) {
 -              RenderData rdata;
 -
 -              /* no osa, blur, seq, layers, savebuffer etc for preview render */
 -              rdata = rp->scene->r;
 -              rdata.mode &= ~(R_OSA | R_MBLUR | R_BORDER | R_PANORAMA);
 -              rdata.scemode &= ~(R_DOSEQ | R_DOCOMP | R_FREE_IMAGE | R_EXR_TILE_FILE | R_FULL_SAMPLE);
 -              rdata.scemode |= R_VIEWPORT_PREVIEW;
 -
 -              /* we do use layers, but only active */
 -              rdata.scemode |= R_SINGLE_LAYER;
 -
 -              /* initalize always */
 -              if (use_border) {
 -                      rdata.mode |= R_BORDER;
 -                      RE_InitState(re, NULL, &rdata, NULL, rp->ar->winx, rp->ar->winy, &cliprct);
 -              }
 -              else
 -                      RE_InitState(re, NULL, &rdata, NULL, rp->ar->winx, rp->ar->winy, NULL);
 -      }
 -
 -      if (orth)
 -              RE_SetOrtho(re, &viewplane, clipsta, clipend);
 -      else
 -              RE_SetWindow(re, &viewplane, clipsta, clipend);
 -
 -      RE_SetPixelSize(re, pixsize);
 -
 -      if ((update_flag & PR_UPDATE_DATABASE) || rstats->convertdone == 0) {
 -              unsigned int lay = rp->scene->lay;
 -
 -              /* allow localview render for objects with lights in normal layers */
 -              if (rp->v3d->lay & 0xFF000000)
 -                      lay |= rp->v3d->lay;
 -              else lay = rp->v3d->lay;
 -
 -              RE_SetView(re, rp->viewmat);
 -
 -              /* copying blender data while main thread is locked, to avoid crashes */
 -              WM_job_main_thread_lock_acquire(rp->job);
 -              RE_Database_Free(re);
 -              RE_Database_FromScene(re, rp->bmain, rp->scene, lay, 0);                // 0= dont use camera view
 -              WM_job_main_thread_lock_release(rp->job);
 -
 -              /* do preprocessing like building raytree, shadows, volumes, SSS */
 -              RE_Database_Preprocess(re);
 -
 -              /* conversion not completed, need to do it again */
 -              if (!rstats->convertdone) {
 -                      if (render_view3d_is_valid(rp)) {
 -                              rp->engine->job_update_flag |= PR_UPDATE_DATABASE;
 -                      }
 -              }
 -
 -              // printf("dbase update\n");
 -      }
 -      else {
 -              // printf("dbase rotate\n");
 -              RE_DataBase_IncrementalView(re, rp->viewmat, 0);
 -              restore = 1;
 -      }
 -
 -      RE_DataBase_ApplyWindow(re);
 -
 -      /* OK, can we enter render code? */
 -      if (rstats->convertdone) {
 -              bool first_time = true;
 -
 -              if (update_flag & PR_UPDATE_VIEW) {
 -                      ob_inst_update_flag |= RE_OBJECT_INSTANCES_UPDATE_VIEW;
 -              }
 -
 -              RE_updateRenderInstances(re, ob_inst_update_flag);
 -
 -              for (;;) {
 -                      int pixel_size = BKE_render_preview_pixel_size(&rp->scene->r);
 -                      if (first_time == false) {
 -                              if (restore)
 -                                      RE_DataBase_IncrementalView(re, rp->viewmat, 1);
 -
 -                              rp->resolution_divider = MAX2(rp->resolution_divider / 2, pixel_size);
 -                              *do_update = 1;
 -
 -                              render_update_resolution(re, rp, use_border, &cliprct);
 -
 -                              RE_DataBase_IncrementalView(re, rp->viewmat, 0);
 -                              RE_DataBase_ApplyWindow(re);
 -                              restore = 1;
 -                      }
 -                      else {
 -                              render_update_resolution(re, rp, use_border, &cliprct);
 -                      }
 -
 -                      RE_TileProcessor(re);
 -
 -                      first_time = false;
 -
 -                      if (*stop || rp->resolution_divider == pixel_size) {
 -                              break;
 -                      }
 -              }
 -
 -              /* always rotate back */
 -              if (restore)
 -                      RE_DataBase_IncrementalView(re, rp->viewmat, 1);
 -      }
 -}
 -
 -static void render_view3d_free(void *customdata)
 -{
 -      RenderPreview *rp = customdata;
 -
 -      MEM_freeN(rp);
 -}
 -
 -static bool render_view3d_flag_changed(RenderEngine *engine, const bContext *C)
 -{
 -      Main *bmain = CTX_data_main(C);
 -      RegionView3D *rv3d = CTX_wm_region_view3d(C);
 -      View3D *v3d = CTX_wm_view3d(C);
 -      ARegion *ar = CTX_wm_region(C);
 -      Scene *scene = CTX_data_scene(C);
 -      Render *re;
 -      rctf viewplane;
 -      rcti disprect;
 -      float clipsta, clipend;
 -      bool orth;
 -      int job_update_flag = 0;
 -      char name[32];
 -
 -      /* ensure render engine exists */
 -      re = engine->re;
 -
 -      if (!re) {
 -              sprintf(name, "View3dPreview %p", (void *)ar);
 -              re = engine->re = RE_GetRender(name);
 -              if (!re)
 -                      re = engine->re = RE_NewRender(name);
 -
 -              engine->update_flag |= RE_ENGINE_UPDATE_DATABASE;
 -      }
 -
 -      /* check update_flag */
 -      if (engine->update_flag & RE_ENGINE_UPDATE_MA)
 -              job_update_flag |= PR_UPDATE_MATERIAL;
 -
 -      if (engine->update_flag & RE_ENGINE_UPDATE_OTHER)
 -              job_update_flag |= PR_UPDATE_MATERIAL;
 -
 -      if (engine->update_flag & RE_ENGINE_UPDATE_DATABASE) {
 -              job_update_flag |= PR_UPDATE_DATABASE;
 -
 -              /* load editmesh */
 -              if (scene->obedit)
 -                      ED_object_editmode_load(bmain, scene->obedit);
 -      }
 -
 -      engine->update_flag = 0;
 -
 -      /* check if viewport changed */
 -      if (engine->last_winx != ar->winx || engine->last_winy != ar->winy) {
 -              engine->last_winx = ar->winx;
 -              engine->last_winy = ar->winy;
 -              job_update_flag |= PR_UPDATE_RENDERSIZE;
 -      }
 -
 -      if (compare_m4m4(engine->last_viewmat, rv3d->viewmat, 0.00001f) == 0) {
 -              copy_m4_m4(engine->last_viewmat, rv3d->viewmat);
 -              job_update_flag |= PR_UPDATE_VIEW;
 -      }
 -
 -      render_view3d_get_rects(ar, v3d, rv3d, &viewplane, engine, &clipsta, &clipend, NULL, &orth);
 -
 -      if (BLI_rctf_compare(&viewplane, &engine->last_viewplane, 0.00001f) == 0) {
 -              engine->last_viewplane = viewplane;
 -              job_update_flag |= PR_UPDATE_VIEW;
 -      }
 -
 -      render_view3d_disprect(scene, ar, v3d, rv3d, &disprect);
 -      if (BLI_rcti_compare(&disprect, &engine->last_disprect) == 0) {
 -              engine->last_disprect = disprect;
 -              job_update_flag |= PR_UPDATE_RENDERSIZE;
 -      }
 -
 -      /* any changes? go ahead and rerender */
 -      if (job_update_flag) {
 -              engine->job_update_flag |= job_update_flag;
 -              return true;
 -      }
 -
 -      return false;
 -}
 -
 -static void render_view3d_do(RenderEngine *engine, const bContext *C)
 -{
 -      wmJob *wm_job;
 -      RenderPreview *rp;
 -      Scene *scene = CTX_data_scene(C);
 -      ARegion *ar = CTX_wm_region(C);
 -      int width = ar->winx, height = ar->winy;
 -      int divider = BKE_render_preview_pixel_size(&scene->r);
 -      int resolution_threshold = scene->r.preview_start_resolution *
 -                                 scene->r.preview_start_resolution;
 -
 -      if (CTX_wm_window(C) == NULL)
 -              return;
 -      if (!render_view3d_flag_changed(engine, C))
 -              return;
 -
 -      wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), CTX_wm_region(C), "Render Preview",
 -                           WM_JOB_EXCL_RENDER, WM_JOB_TYPE_RENDER_PREVIEW);
 -      rp = MEM_callocN(sizeof(RenderPreview), "render preview");
 -      rp->job = wm_job;
 -
 -      while (width * height > resolution_threshold) {
 -              width = max_ii(1, width / 2);
 -              height = max_ii(1, height / 2);
 -              divider *= 2;
 -      }
 -
 -      /* customdata for preview thread */
 -      rp->scene = scene;
 -      rp->engine = engine;
 -      rp->sa = CTX_wm_area(C);
 -      rp->ar = CTX_wm_region(C);
 -      rp->v3d = rp->sa->spacedata.first;
 -      rp->rv3d = CTX_wm_region_view3d(C);
 -      rp->bmain = CTX_data_main(C);
 -      rp->resolution_divider = divider;
 -      rp->start_resolution_divider = divider;
 -      rp->has_freestyle = (scene->r.mode & R_EDGE_FRS) != 0;
 -      copy_m4_m4(rp->viewmat, rp->rv3d->viewmat);
 -
 -      /* clear info text */
 -      engine->text[0] = '\0';
 -
 -      /* setup job */
 -      WM_jobs_customdata_set(wm_job, rp, render_view3d_free);
 -      WM_jobs_timer(wm_job, 0.1, NC_SPACE | ND_SPACE_VIEW3D, NC_SPACE | ND_SPACE_VIEW3D);
 -      WM_jobs_callbacks(wm_job, render_view3d_startjob, NULL, NULL, NULL);
 -
 -      WM_jobs_start(CTX_wm_manager(C), wm_job);
 -
 -      engine->flag &= ~RE_ENGINE_DO_UPDATE;
 -}
 -
 -/* callback for render engine, on changes */
 -void render_view3d_update(RenderEngine *engine, const bContext *C)
 -{
 -      /* this shouldn't be needed and causes too many database rebuilds, but we
 -       * aren't actually tracking updates for all relevant datablocks so this is
 -       * a catch-all for updates */
 -      engine->update_flag |= RE_ENGINE_UPDATE_DATABASE;
 -
 -      render_view3d_do(engine, C);
 -}
 -
 -void render_view3d_draw(RenderEngine *engine, const bContext *C)
 -{
 -      Render *re = engine->re;
 -      RenderResult rres;
 -      char name[32];
 -
 -      render_view3d_do(engine, C);
 -
 -      if (re == NULL) {
 -              sprintf(name, "View3dPreview %p", (void *)CTX_wm_region(C));
 -              re = RE_GetRender(name);
 -
 -              if (re == NULL) return;
 -      }
 -
 -      /* Viewport render preview doesn't support multiview, view hardcoded to 0 */
 -      RE_AcquireResultImage(re, &rres, 0);
 -
 -      if (rres.rectf) {
 -              RegionView3D *rv3d = CTX_wm_region_view3d(C);
 -              View3D *v3d = CTX_wm_view3d(C);
 -              Scene *scene = CTX_data_scene(C);
 -              ARegion *ar = CTX_wm_region(C);
 -              bool force_fallback = false;
 -              bool need_fallback = true;
 -              float dither = scene->r.dither_intensity;
 -              float scale_x, scale_y;
 -              rcti clip_rect;
 -              int xof, yof;
 -
 -              if (render_view3d_disprect(scene, ar, v3d, rv3d, &clip_rect)) {
 -                      scale_x = (float) BLI_rcti_size_x(&clip_rect) / rres.rectx;
 -                      scale_y = (float) BLI_rcti_size_y(&clip_rect) / rres.recty;
 -                      xof = clip_rect.xmin;
 -                      yof = clip_rect.ymin;
 -              }
 -              else {
 -                      scale_x = (float) ar->winx / rres.rectx;
 -                      scale_y = (float) ar->winy / rres.recty;
 -                      xof = rres.xof;
 -                      yof = rres.yof;
 -              }
 -
 -              /* If user decided not to use GLSL, fallback to glaDrawPixelsAuto */
 -              force_fallback |= (U.image_draw_method != IMAGE_DRAW_METHOD_GLSL);
 -
 -              /* Try using GLSL display transform. */
 -              if (force_fallback == false) {
 -                      if (IMB_colormanagement_setup_glsl_draw(&scene->view_settings, &scene->display_settings, dither, true)) {
 -                              glEnable(GL_BLEND);
 -                              glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
 -                              glPixelZoom(scale_x, scale_y);
 -                              glaDrawPixelsTex(xof, yof, rres.rectx, rres.recty,
 -                                               GL_RGBA, GL_FLOAT, GL_NEAREST, rres.rectf);
 -                              glPixelZoom(1.0f, 1.0f);
 -                              glDisable(GL_BLEND);
 -
 -                              IMB_colormanagement_finish_glsl_draw();
 -                              need_fallback = false;
 -                      }
 -              }
 -
 -              /* If GLSL failed, use old-school CPU-based transform. */
 -              if (need_fallback) {
 -                      unsigned char *display_buffer = MEM_mallocN(4 * rres.rectx * rres.recty * sizeof(char),
 -                                                                  "render_view3d_draw");
 -
 -                      IMB_colormanagement_buffer_make_display_space(rres.rectf, display_buffer, rres.rectx, rres.recty,
 -                                                                    4, dither, &scene->view_settings, &scene->display_settings);
 -
 -                      glEnable(GL_BLEND);
 -                      glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
 -                      glPixelZoom(scale_x, scale_y);
 -                      glaDrawPixelsAuto(xof, yof, rres.rectx, rres.recty,
 -                                        GL_RGBA, GL_UNSIGNED_BYTE,
 -                                        GL_NEAREST, display_buffer);
 -                      glPixelZoom(1.0f, 1.0f);
 -                      glDisable(GL_BLEND);
 -
 -                      MEM_freeN(display_buffer);
 -              }
 -      }
 -
 -      RE_ReleaseResultImage(re);
 -}
 -
 -void ED_viewport_render_kill_jobs(wmWindowManager *wm,
 -                                  Main *bmain,
 -                                  bool free_database)
 -{
 -      bScreen *sc;
 -      ScrArea *sa;
 -      ARegion *ar;
 -
 -      if (!wm)
 -              return;
 -
 -      /* kill all actively running jobs */
 -      WM_jobs_kill(wm, NULL, render_view3d_startjob);
 -
 -      /* loop over 3D view render engines */
 -      for (sc = bmain->screen.first; sc; sc = sc->id.next) {
 -              for (sa = sc->areabase.first; sa; sa = sa->next) {
 -                      if (sa->spacetype != SPACE_VIEW3D)
 -                              continue;
 -
 -                      for (ar = sa->regionbase.first; ar; ar = ar->next) {
 -                              RegionView3D *rv3d;
 -
 -                              if (ar->regiontype != RGN_TYPE_WINDOW)
 -                                      continue;
 -
 -                              rv3d = ar->regiondata;
 -
 -                              if (rv3d->render_engine) {
 -                                      /* free render database now before we change data, because
 -                                       * RE_Database_Free will also loop over blender data */
 -                                      if (free_database) {
 -                                              char name[32];
 -                                              Render *re;
 -
 -                                              sprintf(name, "View3dPreview %p", (void *)ar);
 -                                              re = RE_GetRender(name);
 -
 -                                              if (re)
 -                                                      RE_Database_Free(re);
 -
 -                                              /* tag render engine to update entire database */
 -                                              rv3d->render_engine->update_flag |= RE_ENGINE_UPDATE_DATABASE;
 -                                      }
 -                                      else {
 -                                              /* quick shader update */
 -                                              rv3d->render_engine->update_flag |= RE_ENGINE_UPDATE_MA;
 -                                      }
 -                              }
 -                      }
 -              }
 -      }
 -}
 -
  Scene *ED_render_job_get_scene(const bContext *C)
  {
        wmWindowManager *wm = CTX_wm_manager(C);
@@@ -1093,7 -1673,6 +1093,7 @@@ Scene *ED_render_job_get_current_scene(
        return NULL;
  }
  
 +
  /* Motion blur curve preset */
  
  static int render_shutter_curve_preset_exec(bContext *C, wmOperator *op)
  #include "BKE_sequencer.h"
  #include "BKE_writeavi.h"
  
 +#include "DEG_depsgraph.h"
 +
 +#include "DRW_engine.h"
 +
  #include "WM_api.h"
  #include "WM_types.h"
  
@@@ -74,9 -70,9 +74,9 @@@
  #include "RNA_access.h"
  #include "RNA_define.h"
  
 -#include "GPU_glew.h"
 -#include "GPU_compositing.h"
  #include "GPU_framebuffer.h"
 +#include "GPU_glew.h"
 +#include "GPU_matrix.h"
  
  #include "render_intern.h"
  
@@@ -95,9 -91,6 +95,9 @@@ typedef struct OGLRender 
        Main *bmain;
        Render *re;
        Scene *scene;
 +      WorkSpace *workspace;
 +      ViewLayer *view_layer;
 +      Depsgraph *depsgraph;
  
        View3D *v3d;
        RegionView3D *rv3d;
        GPUOffScreen *ofs;
        int ofs_samples;
        bool ofs_full_samples;
 -      GPUFX *fx;
        int sizex, sizey;
        int write_still;
  
  #endif
  } OGLRender;
  
 -/* added because v3d is not always valid */
 -static unsigned int screen_opengl_layers(OGLRender *oglrender)
 -{
 -      if (oglrender->v3d) {
 -              return oglrender->scene->lay | oglrender->v3d->lay;
 -      }
 -      else {
 -              return oglrender->scene->lay;
 -      }
 -}
 -
  static bool screen_opengl_is_multiview(OGLRender *oglrender)
  {
        View3D *v3d = oglrender->v3d;
@@@ -266,9 -271,8 +266,9 @@@ static void screen_opengl_views_setup(O
        RE_ReleaseResult(oglrender->re);
  }
  
 -static void screen_opengl_render_doit(OGLRender *oglrender, RenderResult *rr)
 +static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, RenderResult *rr)
  {
 +      Depsgraph *depsgraph = CTX_data_depsgraph(C);
        Scene *scene = oglrender->scene;
        ARegion *ar = oglrender->ar;
        View3D *v3d = oglrender->v3d;
        int sizex = oglrender->sizex;
        int sizey = oglrender->sizey;
        const short view_context = (v3d != NULL);
 -      bool draw_bgpic = true;
        bool draw_sky = (scene->r.alphamode == R_ADDSKY);
 -      unsigned char *rect = NULL;
 +      float *rectf = NULL;
        const char *viewname = RE_GetActiveRenderView(oglrender->re);
        ImBuf *ibuf_result = NULL;
  
                        unsigned char *gp_rect;
                        unsigned char *render_rect = (unsigned char *)RE_RenderViewGetById(rr, oglrender->view_id)->rect32;
  
 +                      DRW_opengl_context_enable();
                        GPU_offscreen_bind(oglrender->ofs, true);
  
                        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
                        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  
                        wmOrtho2(0, sizex, 0, sizey);
 -                      glTranslatef(sizex / 2, sizey / 2, 0.0f);
 +                      gpuTranslate2f(sizex / 2, sizey / 2);
  
                        G.f |= G_RENDER_OGL;
                        ED_gpencil_draw_ex(scene, gpd, sizex, sizey, scene->r.cfra, SPACE_SEQ);
                                blend_color_mix_byte(&render_rect[i], &render_rect[i], &gp_rect[i]);
                        }
                        GPU_offscreen_unbind(oglrender->ofs, true);
 +                      DRW_opengl_context_disable();
  
                        MEM_freeN(gp_rect);
                }
                draw_flags |= (oglrender->ofs_full_samples) ? V3D_OFSDRAW_USE_FULL_SAMPLE : 0;
  
                if (view_context) {
 -                      draw_flags |= (draw_bgpic) ? V3D_OFSDRAW_USE_BACKGROUND : 0;
 -
                        ibuf_view = ED_view3d_draw_offscreen_imbuf(
 -                             oglrender->bmain, scene, v3d, ar, sizex, sizey,
 -                             IB_rect, draw_flags, alpha_mode, oglrender->ofs_samples, viewname,
 -                             oglrender->fx, oglrender->ofs, err_out);
 +                             depsgraph, scene, v3d->drawtype,
 +                             v3d, ar, sizex, sizey,
 +                             IB_rectfloat, draw_flags, alpha_mode, oglrender->ofs_samples, viewname,
 +                             oglrender->ofs, err_out);
  
                        /* for stamp only */
                        if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
                        }
                }
                else {
 -                      draw_flags |= (V3D_OFSDRAW_USE_GPENCIL | V3D_OFSDRAW_USE_BACKGROUND);
 +                      draw_flags |= V3D_OFSDRAW_USE_GPENCIL;
                        ibuf_view = ED_view3d_draw_offscreen_imbuf_simple(
 -                              oglrender->bmain, scene, scene->camera, oglrender->sizex, oglrender->sizey,
 -                              IB_rect, draw_flags, OB_SOLID,
 +                              depsgraph, scene, OB_SOLID,
 +                              scene->camera, oglrender->sizex, oglrender->sizey,
 +                              IB_rectfloat, draw_flags,
                                alpha_mode, oglrender->ofs_samples, viewname,
 -                              oglrender->fx, oglrender->ofs, err_out);
 +                              oglrender->ofs, err_out);
                        camera = scene->camera;
                }
  
                if (ibuf_view) {
                        ibuf_result = ibuf_view;
 -                      rect = (unsigned char *)ibuf_view->rect;
 +                      rectf = (float *)ibuf_view->rect_float;
                }
                else {
                        fprintf(stderr, "%s: failed to get buffer, %s\n", __func__, err_out);
  
        if (ibuf_result != NULL) {
                if ((scene->r.stamp & R_STAMP_ALL) && (scene->r.stamp & R_STAMP_DRAW)) {
 -                      BKE_image_stamp_buf(scene, camera, NULL, rect, NULL, rr->rectx, rr->recty, 4);
 +                      BKE_image_stamp_buf(scene, camera, NULL, NULL, rectf, rr->rectx, rr->recty, 4);
                }
                RE_render_result_rect_from_ibuf(rr, &scene->r, ibuf_result, oglrender->view_id);
                IMB_freeImBuf(ibuf_result);
@@@ -432,7 -435,7 +432,7 @@@ static void addAlphaOverFloat(float des
  }
  
  /* add renderlayer and renderpass for each grease pencil layer for using in composition */
 -static void add_gpencil_renderpass(OGLRender *oglrender, RenderResult *rr, RenderView *rv)
 +static void add_gpencil_renderpass(const bContext *C, OGLRender *oglrender, RenderResult *rr, RenderView *rv)
  {
        bGPdata *gpd = oglrender->scene->gpd;
        Scene *scene = oglrender->scene;
                }
  
                /* render this gp layer */
 -              screen_opengl_render_doit(oglrender, rr);
 +              screen_opengl_render_doit(C, oglrender, rr);
  
                /* add RendePass composite */
                RenderPass *rp = RE_create_gp_pass(rr, gpl->info, rv->name);
        scene->r.alphamode = oldalphamode;
  }
  
 -static void screen_opengl_render_apply(OGLRender *oglrender)
 +static void screen_opengl_render_apply(const bContext *C, OGLRender *oglrender)
  {
        RenderResult *rr;
        RenderView *rv;
                int chanshown = sseq ? sseq->chanshown : 0;
  
                BKE_sequencer_new_render_data(
 -                      oglrender->bmain->eval_ctx, oglrender->bmain, scene,
 -                      oglrender->sizex, oglrender->sizey, 100.0f,
 +                      oglrender->bmain, oglrender->depsgraph, scene,
 +                      oglrender->sizex, oglrender->sizey, 100.0f, false,
                        &context);
  
                for (view_id = 0; view_id < oglrender->views_len; view_id++) {
                        context.view_id = view_id;
                        context.gpu_offscreen = oglrender->ofs;
 -                      context.gpu_fx = oglrender->fx;
                        context.gpu_full_samples = oglrender->ofs_full_samples;
  
                        oglrender->seq_data.ibufs_arr[view_id] = BKE_sequencer_give_ibuf(&context, CFRA, chanshown);
                /* add grease pencil passes. For sequencer, the render does not include renderpasses
                 * TODO: The sequencer render of grease pencil should be rethought */
                if (!oglrender->is_sequencer) {
 -                      add_gpencil_renderpass(oglrender, rr, rv);
 +                      add_gpencil_renderpass(C, oglrender, rr, rv);
                }
                /* render composite */
 -              screen_opengl_render_doit(oglrender, rr);
 +              screen_opengl_render_doit(C, oglrender, rr);
        }
  
        RE_ReleaseResult(oglrender->re);
        }
  }
  
 +static bool screen_opengl_fullsample_enabled(Scene *scene)
 +{
 +      if (scene->r.scemode & R_FULL_SAMPLE) {
 +              return true;
 +      }
 +      else {
 +              /* XXX TODO:
 +               * Technically if the hardware supports MSAA we could keep using Blender 2.7x approach.
 +               * However anti-aliasing without full_sample is not playing well even in 2.7x.
 +               *
 +               * For example, if you enable depth of field, there is aliasing, even if the viewport is fine.
 +               * For 2.8x this is more complicated because so many things rely on shader.
 +               * So until we fix the gpu_framebuffer anti-aliasing suupport we need to force full sample.
 +               */
 +              return true;
 +      }
 +}
 +
  static bool screen_opengl_render_init(bContext *C, wmOperator *op)
  {
        /* new render clears all callbacks */
        wmWindowManager *wm = CTX_wm_manager(C);
        wmWindow *win = CTX_wm_window(C);
 +      WorkSpace *workspace = CTX_wm_workspace(C);
  
        Scene *scene = CTX_data_scene(C);
        ScrArea *prevsa = CTX_wm_area(C);
        OGLRender *oglrender;
        int sizex, sizey;
        const int samples = (scene->r.mode & R_OSA) ? scene->r.osa : 0;
 -      const bool full_samples = (samples != 0) && (scene->r.scemode & R_FULL_SAMPLE);
 +      const bool full_samples = (samples != 0) && screen_opengl_fullsample_enabled(scene);
        bool is_view_context = RNA_boolean_get(op->ptr, "view_context");
        const bool is_animation = RNA_boolean_get(op->ptr, "animation");
        const bool is_sequencer = RNA_boolean_get(op->ptr, "sequencer");
        sizey = (scene->r.size * scene->r.ysch) / 100;
  
        /* corrects render size with actual size, not every card supports non-power-of-two dimensions */
 -      ofs = GPU_offscreen_create(sizex, sizey, full_samples ? 0 : samples, err_out);
 +      DRW_opengl_context_enable(); /* Offscreen creation needs to be done in DRW context. */
 +      ofs = GPU_offscreen_create(sizex, sizey, full_samples ? 0 : samples, true, true, err_out);
 +      DRW_opengl_context_disable();
  
        if (!ofs) {
                BKE_reportf(op->reports, RPT_ERROR, "Failed to create OpenGL off-screen buffer, %s", err_out);
        oglrender->sizey = sizey;
        oglrender->bmain = CTX_data_main(C);
        oglrender->scene = scene;
 +      oglrender->workspace = workspace;
 +      oglrender->view_layer = CTX_data_view_layer(C);
 +      oglrender->depsgraph = CTX_data_depsgraph(C);
        oglrender->cfrao = scene->r.cfra;
  
        oglrender->write_still = is_write_still && !is_animation;
                /* apply immediately in case we're rendering from a script,
                 * running notifiers again will overwrite */
                oglrender->scene->customdata_mask |= oglrender->scene->customdata_mask_modal;
 -
 -              if (oglrender->v3d->fx_settings.fx_flag & (GPU_FX_FLAG_DOF | GPU_FX_FLAG_SSAO)) {
 -                      oglrender->fx = GPU_fx_compositor_create();
 -              }
 -      }
 -      else if (is_sequencer) {
 -              /* NOTE: We allow animation of DoF setting for flexibility in edits, so
 -               * we can't check in advance whether we need FX compositor or not.
 -               * We just always allocated it and make sure it doesn't add extra
 -               * overhead rather than memory allocation here if it's not really
 -               * needed.
 -               */
 -              oglrender->fx = GPU_fx_compositor_create();
        }
  
        /* create render */
        oglrender->re = RE_NewSceneRender(scene);
  
        /* create image and image user */
-       oglrender->ima = BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result");
-       BKE_image_signal(oglrender->ima, NULL, IMA_SIGNAL_FREE);
+       oglrender->ima = BKE_image_verify_viewer(oglrender->bmain, IMA_TYPE_R_RESULT, "Render Result");
+       BKE_image_signal(oglrender->bmain, oglrender->ima, NULL, IMA_SIGNAL_FREE);
        BKE_image_backup_render(oglrender->scene, oglrender->ima, true);
  
        oglrender->iuser.scene = scene;
        oglrender->iuser.ok = 1;
  
        /* create render result */
 -      RE_InitState(oglrender->re, NULL, &scene->r, NULL, sizex, sizey, NULL);
 +      RE_InitState(oglrender->re, NULL, &scene->r, &scene->view_layers, NULL, sizex, sizey, NULL);
  
        /* create render views */
        screen_opengl_views_setup(oglrender);
@@@ -810,9 -803,8 +810,9 @@@ static void screen_opengl_render_end(bC
        }
  
        if (oglrender->timer) { /* exec will not have a timer */
 +              Depsgraph *depsgraph = oglrender->depsgraph;
                scene->r.cfra = oglrender->cfrao;
 -              BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, screen_opengl_layers(oglrender));
 +              BKE_scene_graph_update_for_newframe(depsgraph, bmain);
  
                WM_event_remove_timer(oglrender->wm, oglrender->win, oglrender->timer);
        }
  
        WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, oglrender->scene);
  
 -      if (oglrender->fx)
 -              GPU_fx_compositor_destroy(oglrender->fx);
 -
 +      DRW_opengl_context_enable();
        GPU_offscreen_free(oglrender->ofs);
 +      DRW_opengl_context_disable();
  
        if (oglrender->is_sequencer) {
                MEM_freeN(oglrender->seq_data.ibufs_arr);
@@@ -1011,7 -1004,6 +1011,7 @@@ static bool screen_opengl_render_anim_s
        Main *bmain = CTX_data_main(C);
        OGLRender *oglrender = op->customdata;
        Scene *scene = oglrender->scene;
 +      Depsgraph *depsgraph = oglrender->depsgraph;
        char name[FILE_MAX];
        bool ok = false;
        const bool view_context = (oglrender->v3d != NULL);
        if (CFRA < oglrender->nfra)
                CFRA++;
        while (CFRA < oglrender->nfra) {
 -              unsigned int lay = screen_opengl_layers(oglrender);
 -
 -              if (lay & 0xFF000000)
 -                      lay &= 0xFF000000;
 -
 -              BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, lay);
 +              BKE_scene_graph_update_for_newframe(depsgraph, bmain);
                CFRA++;
        }
  
  
        WM_cursor_time(oglrender->win, scene->r.cfra);
  
 -      BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, screen_opengl_layers(oglrender));
 +      BKE_scene_graph_update_for_newframe(depsgraph, bmain);
  
        if (view_context) {
                if (oglrender->rv3d->persp == RV3D_CAMOB && oglrender->v3d->camera && oglrender->v3d->scenelock) {
 -                      /* since BKE_scene_update_for_newframe() is used rather
 +                      /* since BKE_scene_graph_update_for_newframe() is used rather
                         * then ED_update_for_newframe() the camera needs to be set */
                        if (BKE_scene_camera_switch_update(scene)) {
                                oglrender->v3d->camera = scene->camera;
        }
  
        /* render into offscreen buffer */
 -      screen_opengl_render_apply(oglrender);
 +      screen_opengl_render_apply(C, oglrender);
  
        /* save to disk */
        rr = RE_AcquireResultRead(oglrender->re);
@@@ -1110,7 -1107,7 +1110,7 @@@ static int screen_opengl_render_modal(b
        WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, oglrender->scene);
  
        if (anim == 0) {
 -              screen_opengl_render_apply(op->customdata);
 +              screen_opengl_render_apply(C, op->customdata);
                screen_opengl_render_end(C, op->customdata);
                return OPERATOR_FINISHED;
        }
@@@ -1161,7 -1158,7 +1161,7 @@@ static int screen_opengl_render_exec(bC
  
        if (!is_animation) { /* same as invoke */
                /* render image */
 -              screen_opengl_render_apply(op->customdata);
 +              screen_opengl_render_apply(C, op->customdata);
                screen_opengl_render_end(C, op->customdata);
  
                return OPERATOR_FINISHED;
        }
  
        /* no redraw needed, we leave state as we entered it */
 -//    ED_update_for_newframe(C, 1);
 +//    ED_update_for_newframe(C);
        WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, CTX_data_scene(C));
  
        return OPERATOR_FINISHED;
@@@ -37,6 -37,7 +37,7 @@@
  #include "BKE_context.h"
  #include "BKE_image.h"
  #include "BKE_global.h"
+ #include "BKE_main.h"
  #include "BKE_screen.h"
  #include "BKE_report.h"
  
@@@ -90,10 -91,8 +91,10 @@@ static ScrArea *find_area_showing_r_res
  
        /* find an imagewindow showing render result */
        for (*win = wm->windows.first; *win; *win = (*win)->next) {
 -              if ((*win)->screen->scene == scene) {
 -                      for (sa = (*win)->screen->areabase.first; sa; sa = sa->next) {
 +              if (WM_window_get_active_scene(*win) == scene) {
 +                      const bScreen *screen = WM_window_get_active_screen(*win);
 +
 +                      for (sa = screen->areabase.first; sa; sa = sa->next) {
                                if (sa->spacetype == SPACE_IMAGE) {
                                        sima = sa->spacedata.first;
                                        if (sima->image && sima->image->type == IMA_TYPE_R_RESULT)
@@@ -131,6 -130,7 +132,7 @@@ static ScrArea *find_area_image_empty(b
  /* new window uses x,y to set position */
  ScrArea *render_view_open(bContext *C, int mx, int my, ReportList *reports)
  {
+       Main *bmain = CTX_data_main(C);
        Scene *scene = CTX_data_scene(C);
        wmWindow *win = NULL;
        ScrArea *sa = NULL;
        sima = sa->spacedata.first;
  
        /* get the correct image, and scale it */
-       sima->image = BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result");
+       sima->image = BKE_image_verify_viewer(bmain, IMA_TYPE_R_RESULT, "Render Result");
  
  
        /* if we're rendering to full screen, set appropriate hints on image editor
@@@ -248,7 -248,7 +250,7 @@@ static int render_view_cancel_exec(bCon
        }
  
        /* test if we have a temp screen in front */
 -      if (win->screen->temp) {
 +      if (WM_window_is_temp_screen(win)) {
                wm_window_lower(win);
                return OPERATOR_FINISHED;
        }
@@@ -294,7 -294,7 +296,7 @@@ static int render_view_show_invoke(bCon
        wmWindow *wincur = CTX_wm_window(C);
  
        /* test if we have currently a temp screen active */
 -      if (wincur->screen->temp) {
 +      if (WM_window_is_temp_screen(wincur)) {
                wm_window_lower(wincur);
        }
        else {
  
                /* is there another window on current scene showing result? */
                for (win = CTX_wm_manager(C)->windows.first; win; win = win->next) {
 -                      bScreen *sc = win->screen;
 -                      if ((sc->temp && ((ScrArea *)sc->areabase.first)->spacetype == SPACE_IMAGE) ||
 +                      const bScreen *sc = WM_window_get_active_screen(win);
 +
 +                      if ((WM_window_is_temp_screen(win) && ((ScrArea *)sc->areabase.first)->spacetype == SPACE_IMAGE) ||
                            (win == winshow && winshow != wincur))
                        {
                                wm_window_raise(win);
@@@ -51,6 -51,7 +51,6 @@@
  
  #include "BKE_colorband.h"
  #include "BKE_context.h"
 -#include "BKE_depsgraph.h"
  #include "BKE_DerivedMesh.h"
  #include "BKE_brush.h"
  #include "BKE_main.h"
@@@ -60,8 -61,6 +60,8 @@@
  #include "BKE_undo_system.h"
  
  
 +#include "DEG_depsgraph.h"
 +
  #include "UI_interface.h"
  #include "UI_view2d.h"
  
  
  #include "WM_api.h"
  #include "WM_types.h"
 +#include "WM_message.h"
 +#include "WM_toolsystem.h"
  
  #include "RNA_access.h"
  #include "RNA_define.h"
  
  #include "GPU_draw.h"
 -#include "GPU_buffers.h"
 +#include "GPU_immediate.h"
  
  #include "BIF_gl.h"
 -#include "BIF_glutil.h"
  
  #include "IMB_colormanagement.h"
  
@@@ -266,7 -264,7 +266,7 @@@ static Brush *image_paint_brush(bContex
        return BKE_paint_brush(&settings->imapaint.paint);
  }
  
 -static int image_paint_poll(bContext *C)
 +static int image_paint_poll_ex(bContext *C, bool check_tool)
  {
        Object *obact;
  
  
        obact = CTX_data_active_object(C);
        if ((obact && obact->mode & OB_MODE_TEXTURE_PAINT) && CTX_wm_region_view3d(C)) {
 -              return 1;
 +              if (!check_tool || WM_toolsystem_active_tool_is_brush(C)) {
 +                      return 1;
 +              }
        }
        else {
                SpaceImage *sima = CTX_wm_space_image(C);
        return 0;
  }
  
 +static int image_paint_poll(bContext *C)
 +{
 +      return image_paint_poll_ex(C, true);
 +}
 +
 +static int image_paint_ignore_tool_poll(bContext *C)
 +{
 +      return image_paint_poll_ex(C, false);
 +}
 +
  static int image_paint_2d_clone_poll(bContext *C)
  {
        Brush *brush = image_paint_brush(C);
@@@ -415,28 -401,12 +415,28 @@@ static void gradient_draw_line(bContex
                glEnable(GL_LINE_SMOOTH);
                glEnable(GL_BLEND);
  
 +              Gwn_VertFormat *format = immVertexFormat();
 +              unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
 +
 +              immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
 +
                glLineWidth(4.0);
 -              glColor4ub(0, 0, 0, 255);
 -              sdrawline(x, y, pop->startmouse[0], pop->startmouse[1]);
 +              immUniformColor4ub(0, 0, 0, 255);
 +
 +              immBegin(GWN_PRIM_LINES, 2);
 +              immVertex2i(pos, x, y);
 +              immVertex2i(pos, pop->startmouse[0], pop->startmouse[1]);
 +              immEnd();
 +
                glLineWidth(2.0);
 -              glColor4ub(255, 255, 255, 255);
 -              sdrawline(x, y, pop->startmouse[0], pop->startmouse[1]);
 +              immUniformColor4ub(255, 255, 255, 255);
 +
 +              immBegin(GWN_PRIM_LINES, 2);
 +              immVertex2i(pos, x, y);
 +              immVertex2i(pos, pop->startmouse[0], pop->startmouse[1]);
 +              immEnd();
 +
 +              immUnbindProgram();
  
                glDisable(GL_BLEND);
                glDisable(GL_LINE_SMOOTH);
@@@ -458,8 -428,7 +458,8 @@@ static PaintOperation *texture_paint_in
  
        /* initialize from context */
        if (CTX_wm_region_view3d(C)) {
 -              Object *ob = OBACT;
 +              ViewLayer *view_layer = CTX_data_view_layer(C);
 +              Object *ob = OBACT(view_layer);
                bool uvs, mat, tex, stencil;
                if (!BKE_paint_proj_mesh_data_check(scene, ob, &uvs, &mat, &tex, &stencil)) {
                        BKE_paint_data_warning(op->reports, uvs, mat, tex, stencil);
@@@ -742,20 -711,16 +742,20 @@@ static void toggle_paint_cursor(bContex
  void ED_space_image_paint_update(Main *bmain, wmWindowManager *wm, Scene *scene)
  {
        ToolSettings *settings = scene->toolsettings;
 -      wmWindow *win;
 -      ScrArea *sa;
        ImagePaintSettings *imapaint = &settings->imapaint;
        bool enabled = false;
  
 -      for (win = wm->windows.first; win; win = win->next)
 -              for (sa = win->screen->areabase.first; sa; sa = sa->next)
 -                      if (sa->spacetype == SPACE_IMAGE)
 -                              if (((SpaceImage *)sa->spacedata.first)->mode == SI_MODE_PAINT)
 +      for (wmWindow *win = wm->windows.first; win; win = win->next) {
 +              bScreen *screen = WM_window_get_active_screen(win);
 +
 +              for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
 +                      if (sa->spacetype == SPACE_IMAGE) {
 +                              if (((SpaceImage *)sa->spacedata.first)->mode == SI_MODE_PAINT) {
                                        enabled = true;
 +                              }
 +                      }
 +              }
 +      }
  
        if (enabled) {
                BKE_paint_init(bmain, scene, ePaintTexture2D, PAINT_CURSOR_TEXTURE_PAINT);
@@@ -1011,6 -976,11 +1011,6 @@@ static int sample_color_modal(bContext 
        return OPERATOR_RUNNING_MODAL;
  }
  
 -static int sample_color_poll(bContext *C)
 -{
 -      return (image_paint_poll(C) || vertex_paint_poll(C));
 -}
 -
  void PAINT_OT_sample_color(wmOperatorType *ot)
  {
        /* identifiers */
        ot->exec = sample_color_exec;
        ot->invoke = sample_color_invoke;
        ot->modal = sample_color_modal;
 -      ot->poll = sample_color_poll;
 +      ot->poll = image_paint_ignore_tool_poll;
  
        /* flags */
        ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@@ -1054,7 -1024,6 +1054,7 @@@ static int texture_paint_toggle_poll(bC
  
  static int texture_paint_toggle_exec(bContext *C, wmOperator *op)
  {
 +      struct wmMsgBus *mbus = CTX_wm_message_bus(C);
        Scene *scene = CTX_data_scene(C);
        Object *ob = CTX_data_active_object(C);
        const int mode_flag = OB_MODE_TEXTURE_PAINT;
                                                if (sl->spacetype == SPACE_IMAGE) {
                                                        SpaceImage *sima = (SpaceImage *)sl;
  
 -                                                      if (!sima->pin)
 -                                                              ED_space_image_set(bmain, sima, scene, scene->obedit, ima);
 +                                                      if (!sima->pin) {
 +                                                              Object *obedit = CTX_data_edit_object(C);
-                                                               ED_space_image_set(sima, scene, obedit, ima);
++                                                              ED_space_image_set(bmain, sima, scene, obedit, ima);
 +                                                      }
                                                }
                                        }
                                }
                toggle_paint_cursor(C, 1);
        }
  
 -      GPU_drawobject_free(ob->derivedFinal);
        WM_event_add_notifier(C, NC_SCENE | ND_MODE, scene);
  
 +      WM_msg_publish_rna_prop(mbus, &ob->id, ob, Object, mode);
 +
 +      WM_toolsystem_update_from_context_view3d(C);
 +
        return OPERATOR_FINISHED;
  }
  
@@@ -1157,8 -1121,8 +1157,8 @@@ static int brush_colors_flip_exec(bCont
  {
        UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings;
  
 -      Brush *br;
        Object *ob = CTX_data_active_object(C);
 +      Brush *br;
        if (!(ob && (ob->mode & OB_MODE_VERTEX_PAINT))) {
                br = image_paint_brush(C);
        }
@@@ -1227,7 -1191,7 +1227,7 @@@ void ED_imapaint_bucket_fill(struct bCo
  
        BKE_undosys_step_push(wm->undo_stack, C, op->type->name);
  
 -      DAG_id_tag_update(&ima->id, 0);
 +      DEG_id_tag_update(&ima->id, 0);
  }
  
  
@@@ -65,6 -65,7 +65,6 @@@
  #include "BKE_colorband.h"
  #include "BKE_context.h"
  #include "BKE_colortools.h"
 -#include "BKE_depsgraph.h"
  #include "BKE_DerivedMesh.h"
  #include "BKE_idprop.h"
  #include "BKE_brush.h"
  #include "BKE_material.h"
  #include "BKE_mesh.h"
  #include "BKE_mesh_mapping.h"
 +#include "BKE_mesh_runtime.h"
  #include "BKE_node.h"
  #include "BKE_paint.h"
  #include "BKE_report.h"
  #include "BKE_scene.h"
  #include "BKE_texture.h"
  
 +#include "DEG_depsgraph.h"
 +#include "DEG_depsgraph_query.h"
 +
  #include "UI_interface.h"
  
  #include "ED_object.h"
@@@ -230,7 -227,6 +230,7 @@@ typedef struct ProjPaintState 
        View3D *v3d;
        RegionView3D *rv3d;
        ARegion *ar;
 +      Depsgraph *depsgraph;
        Scene *scene;
        int source; /* PROJ_SRC_**** */
  
        bool  do_backfacecull;          /* ignore faces with normals pointing away, skips a lot of raycasts if your normals are correctly flipped */
        bool  do_mask_normal;           /* mask out pixels based on their normals */
        bool  do_mask_cavity;           /* mask out pixels based on cavity */
 -      bool  do_new_shading_nodes;     /* cache BKE_scene_use_new_shading_nodes value */
        float normal_angle;             /* what angle to mask at */
        float normal_angle__cos;         /* cos(normal_angle), faster to compare */
        float normal_angle_inner;
@@@ -2494,7 -2491,8 +2494,7 @@@ static bool IsectPoly2Df_twoside(const 
  static void project_paint_face_init(
          const ProjPaintState *ps,
          const int thread_index, const int bucket_index, const int tri_index, const int image_index,
 -        const rctf *clip_rect, const rctf *bucket_bounds, ImBuf *ibuf, ImBuf **tmpibuf,
 -        const bool clamp_u, const bool clamp_v)
 +        const rctf *clip_rect, const rctf *bucket_bounds, ImBuf *ibuf, ImBuf **tmpibuf)
  {
        /* Projection vars, to get the 3D locations into screen space  */
        MemArena *arena = ps->arena_mt[thread_index];
  #endif
  
                if (pixel_bounds_array(uv_clip, &bounds_px, ibuf->x, ibuf->y, uv_clip_tot)) {
 -
 -                      if (clamp_u) {
 -                              CLAMP(bounds_px.xmin, 0, ibuf->x);
 -                              CLAMP(bounds_px.xmax, 0, ibuf->x);
 -                      }
 -
 -                      if (clamp_v) {
 -                              CLAMP(bounds_px.ymin, 0, ibuf->y);
 -                              CLAMP(bounds_px.ymax, 0, ibuf->y);
 -                      }
 -
  #if 0
                        project_paint_undo_tiles_init(&bounds_px, ps->projImages + image_index, tmpibuf,
                                                      tile_width, threaded, ps->do_masking);
@@@ -2917,16 -2926,19 +2917,16 @@@ static void project_bucket_init
        int tri_index, image_index = 0;
        ImBuf *ibuf = NULL;
        Image *tpage_last = NULL, *tpage;
 -      Image *ima = NULL;
        ImBuf *tmpibuf = NULL;
  
        if (ps->image_tot == 1) {
                /* Simple loop, no context switching */
                ibuf = ps->projImages[0].ibuf;
 -              ima = ps->projImages[0].ima;
  
                for (node = ps->bucketFaces[bucket_index]; node; node = node->next) {
                        project_paint_face_init(
                                ps, thread_index, bucket_index, GET_INT_FROM_POINTER(node->link), 0,
 -                              clip_rect, bucket_bounds, ibuf, &tmpibuf,
 -                              (ima->tpageflag & IMA_CLAMP_U) != 0, (ima->tpageflag & IMA_CLAMP_V) != 0);
 +                              clip_rect, bucket_bounds, ibuf, &tmpibuf);
                }
        }
        else {
                                for (image_index = 0; image_index < ps->image_tot; image_index++) {
                                        if (ps->projImages[image_index].ima == tpage_last) {
                                                ibuf = ps->projImages[image_index].ibuf;
 -                                              ima = ps->projImages[image_index].ima;
                                                break;
                                        }
                                }
  
                        project_paint_face_init(
                                ps, thread_index, bucket_index, tri_index, image_index,
 -                              clip_rect, bucket_bounds, ibuf, &tmpibuf,
 -                              (ima->tpageflag & IMA_CLAMP_U) != 0, (ima->tpageflag & IMA_CLAMP_V) != 0);
 +                              clip_rect, bucket_bounds, ibuf, &tmpibuf);
                }
        }
  
@@@ -3086,7 -3100,7 +3086,7 @@@ static void proj_paint_state_non_cddm_i
  }
  
  static void proj_paint_state_viewport_init(
 -        ProjPaintState *ps, const char symmetry_flag)
 +        ProjPaintState *ps, const Depsgraph *depsgraph, const char symmetry_flag)
  {
        float mat[3][3];
        float viewmat[4][4];
  
                ED_view3d_ob_project_mat_get_from_obmat(ps->rv3d, ps->obmat, ps->projectMat);
  
 -              ps->is_ortho = ED_view3d_clip_range_get(ps->v3d, ps->rv3d, &ps->clipsta, &ps->clipend, true);
 +              ps->is_ortho = ED_view3d_clip_range_get(ps->depsgraph, ps->v3d, ps->rv3d, &ps->clipsta, &ps->clipend, true);
        }
        else {
                /* re-projection */
                        invert_m4_m4(viewinv, viewmat);
                }
                else if (ps->source == PROJ_SRC_IMAGE_CAM) {
 -                      Object *cam_ob = ps->scene->camera;
 +                      Object *cam_ob_eval = DEG_get_evaluated_object(depsgraph, ps->scene->camera);
                        CameraParams params;
  
                        /* viewmat & viewinv */
 -                      copy_m4_m4(viewinv, cam_ob->obmat);
 +                      copy_m4_m4(viewinv, cam_ob_eval->obmat);
                        normalize_m4(viewinv);
                        invert_m4_m4(viewmat, viewinv);
  
                        /* window matrix, clipping and ortho */
                        BKE_camera_params_init(&params);
 -                      BKE_camera_params_from_object(&params, cam_ob);
 +                      BKE_camera_params_from_object(&params, cam_ob_eval);
                        BKE_camera_params_compute_viewplane(&params, ps->winx, ps->winy, 1.0f, 1.0f);
                        BKE_camera_params_compute_matrix(&params);
  
@@@ -3409,14 -3423,12 +3409,14 @@@ static void project_paint_bleed_add_fac
  #endif
  
  /* Return true if DM can be painted on, false otherwise */
 -static bool proj_paint_state_dm_init(ProjPaintState *ps)
 +static bool proj_paint_state_dm_init(const bContext *C, ProjPaintState *ps)
  {
 +      Depsgraph *depsgraph = CTX_data_depsgraph(C);
 +
        /* Workaround for subsurf selection, try the display mesh first */
        if (ps->source == PROJ_SRC_IMAGE_CAM) {
                /* using render mesh, assume only camera was rendered from */
 -              ps->dm = mesh_create_derived_render(ps->scene, ps->ob, ps->scene->customdata_mask | CD_MASK_MTFACE);
 +              ps->dm = mesh_create_derived_render(depsgraph, ps->scene, ps->ob, ps->scene->customdata_mask | CD_MASK_MTFACE);
                ps->dm_release = true;
        }
        else if (ps->ob->derivedFinal &&
        }
        else {
                ps->dm = mesh_get_derived_final(
 -                      ps->scene, ps->ob,
 +                      depsgraph, ps->scene, ps->ob,
                        ps->scene->customdata_mask | CD_MASK_MTFACE | (ps->do_face_sel ? CD_ORIGINDEX : 0));
                ps->dm_release = true;
        }
@@@ -3478,7 -3490,7 +3478,7 @@@ static void proj_paint_layer_clone_init
  
        /* use clone mtface? */
        if (ps->do_layer_clone) {
 -              const int layer_num = CustomData_get_clone_layer(&((Mesh *)ps->ob->data)->pdata, CD_MTEXPOLY);
 +              const int layer_num = CustomData_get_clone_layer(&((Mesh *)ps->ob->data)->ldata, CD_MLOOPUV);
  
                ps->dm_mloopuv_clone = MEM_mallocN(ps->dm_totpoly * sizeof(MLoopUV *), "proj_paint_mtfaces");
  
@@@ -3808,7 -3820,7 +3808,7 @@@ static void project_paint_prepare_all_f
  
  /* run once per stroke before projection painting */
  static void project_paint_begin(
 -        ProjPaintState *ps,
 +        const bContext *C, ProjPaintState *ps,
          const bool is_multi_view, const char symmetry_flag)
  {
        ProjPaintLayerClone layer_clone;
  
        /* paint onto the derived mesh */
        if (ps->is_shared_user == false) {
 -              if (!proj_paint_state_dm_init(ps)) {
 +              if (!proj_paint_state_dm_init(C, ps)) {
                        return;
                }
        }
  
        if (ps->do_layer_stencil || ps->do_stencil_brush) {
                //int layer_num = CustomData_get_stencil_layer(&ps->dm->loopData, CD_MLOOPUV);
 -              int layer_num = CustomData_get_stencil_layer(&((Mesh *)ps->ob->data)->pdata, CD_MTEXPOLY);
 +              int layer_num = CustomData_get_stencil_layer(&((Mesh *)ps->ob->data)->ldata, CD_MLOOPUV);
                if (layer_num != -1)
                        ps->dm_mloopuv_stencil = CustomData_get_layer_n(&ps->dm->loopData, CD_MLOOPUV, layer_num);
  
                proj_paint_state_cavity_init(ps);
        }
  
 -      proj_paint_state_viewport_init(ps, symmetry_flag);
 +      proj_paint_state_viewport_init(ps, CTX_data_depsgraph(C), symmetry_flag);
  
        /* calculate vert screen coords
         * run this early so we can calculate the x/y resolution of our bucket rect */
@@@ -3908,7 -3920,7 +3908,7 @@@ static void paint_proj_begin_clone(Proj
        /* setup clone offset */
        if (ps->tool == PAINT_TOOL_CLONE) {
                float projCo[4];
 -              copy_v3_v3(projCo, ED_view3d_cursor3d_get(ps->scene, ps->v3d));
 +              copy_v3_v3(projCo, ED_view3d_cursor3d_get(ps->scene, ps->v3d)->location);
                mul_m4_v3(ps->obmat_imat, projCo);
  
                projCo[3] = 1.0f;
@@@ -3929,7 -3941,7 +3929,7 @@@ static void project_paint_end(ProjPaint
                ProjPaintImage *projIma;
                for (a = 0, projIma = ps->projImages; a < ps->image_tot; a++, projIma++) {
                        BKE_image_release_ibuf(projIma->ima, projIma->ibuf, NULL);
 -                      DAG_id_tag_update(&projIma->ima->id, 0);
 +                      DEG_id_tag_update(&projIma->ima->id, 0);
                }
        }
  
@@@ -5014,18 -5026,17 +5014,18 @@@ void paint_proj_stroke
  
        /* clone gets special treatment here to avoid going through image initialization */
        if (ps_handle->is_clone_cursor_pick) {
 -              Main *bmain = CTX_data_main(C);
                Scene *scene = ps_handle->scene;
 +              struct Depsgraph *depsgraph = CTX_data_depsgraph(C);
                View3D *v3d = CTX_wm_view3d(C);
                ARegion *ar = CTX_wm_region(C);
 -              float *cursor = ED_view3d_cursor3d_get(scene, v3d);
 +              float *cursor = ED_view3d_cursor3d_get(scene, v3d)->location;
                int mval_i[2] = {(int)pos[0], (int)pos[1]};
  
                view3d_operator_needs_opengl(C);
  
 -              if (!ED_view3d_autodist(bmain, scene, ar, v3d, mval_i, cursor, false, NULL))
 +              if (!ED_view3d_autodist(depsgraph, ar, v3d, mval_i, cursor, false, NULL)) {
                        return;
 +              }
  
                ED_region_tag_redraw(ar);
  
@@@ -5081,7 -5092,6 +5081,7 @@@ static void project_state_init(bContex
        ps->rv3d = CTX_wm_region_view3d(C);
        ps->ar = CTX_wm_region(C);
  
 +      ps->depsgraph = CTX_data_depsgraph(C);
        ps->scene = scene;
        ps->ob = ob; /* allow override of active object */
  
        else {
                ps->do_backfacecull = ps->do_occlude = ps->do_mask_normal = 0;
        }
 -      ps->do_new_shading_nodes = BKE_scene_use_new_shading_nodes(scene); /* only cache the value */
  
        if (ps->tool == PAINT_TOOL_CLONE)
                ps->do_layer_clone = (settings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_CLONE) ? 1 : 0;
@@@ -5203,7 -5214,7 +5203,7 @@@ void *paint_proj_new_stroke(bContext *C
  
                project_state_init(C, ob, ps, mode);
  
 -              if (ps->ob == NULL || !(ps->ob->lay & ps->v3d->lay)) {
 +              if (ps->ob == NULL) {
                        ps_handle->ps_views_tot = i + 1;
                        goto fail;
                }
                        PROJ_PAINT_STATE_SHARED_MEMCPY(ps, ps_handle->ps_views[0]);
                }
  
 -              project_paint_begin(ps, is_multi_view, symmetry_flag_views[i]);
 +              project_paint_begin(C, ps, is_multi_view, symmetry_flag_views[i]);
  
                paint_proj_begin_clone(ps, mouse);
  
@@@ -5305,12 -5316,11 +5305,12 @@@ static int texture_paint_camera_project
  {
        Image *image = BLI_findlink(&CTX_data_main(C)->image, RNA_enum_get(op->ptr, "image"));
        Scene *scene = CTX_data_scene(C);
 +      ViewLayer *view_layer = CTX_data_view_layer(C);
        ProjPaintState ps = {NULL};
        int orig_brush_size;
        IDProperty *idgroup;
        IDProperty *view_data = NULL;
 -      Object *ob = OBACT;
 +      Object *ob = OBACT(view_layer);
        bool uvs, mat, tex;
  
        if (ob == NULL || ob->type != OB_MESH) {
        ED_image_undo_push_begin(op->type->name);
  
        /* allocate and initialize spatial data structures */
 -      project_paint_begin(&ps, false, 0);
 +      project_paint_begin(C, &ps, false, 0);
  
        if (ps.dm == NULL) {
                BKE_brush_size_set(scene, ps.brush, orig_brush_size);
@@@ -5437,11 -5447,9 +5437,12 @@@ static int texture_paint_image_from_vie
        ImBuf *ibuf;
        char filename[FILE_MAX];
  
+       Main *bmain = CTX_data_main(C);
 +      Depsgraph *depsgraph = CTX_data_depsgraph(C);
        Scene *scene = CTX_data_scene(C);
        ToolSettings *settings = scene->toolsettings;
 +      View3D *v3d = CTX_wm_view3d(C);
 +      RegionView3D *rv3d = CTX_wm_region_view3d(C);
        int w = settings->imapaint.screen_grab_size[0];
        int h = settings->imapaint.screen_grab_size[1];
        int maxsize;
        if (h > maxsize) h = maxsize;
  
        ibuf = ED_view3d_draw_offscreen_imbuf(
 -              bmain, scene, CTX_wm_view3d(C), CTX_wm_region(C),
 +              depsgraph, scene, v3d->drawtype,
 +              v3d, CTX_wm_region(C),
                w, h, IB_rect, V3D_OFSDRAW_NONE, R_ALPHAPREMUL, 0, NULL,
 -              NULL, NULL, err_out);
 +              NULL, err_out);
        if (!ibuf) {
                /* Mostly happens when OpenGL offscreen buffer was failed to create, */
                /* but could be other reasons. Should be handled in the future. nazgul */
                return OPERATOR_CANCELLED;
        }
  
-       image = BKE_image_add_from_imbuf(ibuf, "image_view");
+       image = BKE_image_add_from_imbuf(bmain, ibuf, "image_view");
  
        /* Drop reference to ibuf so that the image owns it */
        IMB_freeImBuf(ibuf);
        if (image) {
                /* now for the trickiness. store the view projection here!
                 * re-projection will reuse this */
 -              View3D *v3d = CTX_wm_view3d(C);
 -              RegionView3D *rv3d = CTX_wm_region_view3d(C);
 -
                IDPropertyTemplate val;
                IDProperty *idgroup = IDP_GetProperties(&image->id, 1);
                IDProperty *view_data;
                array = (float *)IDP_Array(view_data);
                memcpy(array, rv3d->winmat, sizeof(rv3d->winmat)); array += sizeof(rv3d->winmat) / sizeof(float);
                memcpy(array, rv3d->viewmat, sizeof(rv3d->viewmat)); array += sizeof(rv3d->viewmat) / sizeof(float);
 -              is_ortho = ED_view3d_clip_range_get(v3d, rv3d, &array[0], &array[1], true);
 +              is_ortho = ED_view3d_clip_range_get(CTX_data_depsgraph(C), v3d, rv3d, &array[0], &array[1], true);
                /* using float for a bool is dodgy but since its an extra member in the array...
                 * easier then adding a single bool prop */
                array[2] = is_ortho ? 1.0f : 0.0f;
@@@ -5587,7 -5597,7 +5588,7 @@@ bool BKE_paint_proj_mesh_data_check(Sce
        }
  
        me = BKE_mesh_from_object(ob);
 -      layernum = CustomData_number_of_layers(&me->pdata, CD_MTEXPOLY);
 +      layernum = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV);
  
        if (layernum == 0) {
                hasuvs = false;