Merge branch 'master' into blender2.8
authorBastien Montagne <montagne29@wanadoo.fr>
Wed, 24 Jan 2018 11:14:59 +0000 (12:14 +0100)
committerBastien Montagne <montagne29@wanadoo.fr>
Wed, 24 Jan 2018 11:14:59 +0000 (12:14 +0100)
Conflicts:
source/blender/modifiers/intern/MOD_wireframe.c

1  2 
source/blender/blenkernel/intern/modifier.c
source/blender/blenkernel/intern/subsurf_ccg.c
source/blender/modifiers/intern/MOD_wireframe.c
source/blender/nodes/shader/nodes/node_shader_bump.c
source/blender/render/intern/source/pipeline.c

index 8eb1a7733c1b2f5d7e8b8fd1d27ab7f270d15749,d7a24f90dbe565a002d4d7aaab24520153585009..8bfeacd256cdcfefa4e2cf1af94f7efadc341c81
@@@ -434,6 -434,11 +434,11 @@@ bool modifiers_isParticleEnabled(Objec
        return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render));
  }
  
+ /**
+  * Check whether is enabled.
+  *
+  * \param scene Current scene, may be NULL, in which case isDisabled callback of the modifier is never called.
+  */
  bool modifier_isEnabled(struct Scene *scene, ModifierData *md, int required_mode)
  {
        const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
        md->scene = scene;
  
        if ((md->mode & required_mode) != required_mode) return false;
-       if (mti->isDisabled && mti->isDisabled(md, required_mode == eModifierMode_Render)) return false;
+       if (scene != NULL && mti->isDisabled && mti->isDisabled(md, required_mode == eModifierMode_Render)) return false;
        if (md->mode & eModifierMode_DisableTemporary) return false;
        if ((required_mode & eModifierMode_Editmode) && !(mti->flags & eModifierTypeFlag_SupportsEditmode)) return false;
        
@@@ -757,8 -762,8 +762,8 @@@ void modifier_path_init(char *path, in
  /* wrapper around ModifierTypeInfo.applyModifier that ensures valid normals */
  
  struct DerivedMesh *modwrap_applyModifier(
 -        ModifierData *md, Object *ob,
 -        struct DerivedMesh *dm,
 +        ModifierData *md, const struct EvaluationContext *eval_ctx,
 +        Object *ob, struct DerivedMesh *dm,
          ModifierApplyFlag flag)
  {
        const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
        if (mti->dependsOnNormals && mti->dependsOnNormals(md)) {
                DM_ensure_normals(dm);
        }
 -      return mti->applyModifier(md, ob, dm, flag);
 +      return mti->applyModifier(md, eval_ctx, ob, dm, flag);
  }
  
  struct DerivedMesh *modwrap_applyModifierEM(
 -        ModifierData *md, Object *ob,
 -        struct BMEditMesh *em,
 +        ModifierData *md, const struct EvaluationContext *eval_ctx,
 +        Object *ob, struct BMEditMesh *em,
          DerivedMesh *dm,
          ModifierApplyFlag flag)
  {
        if (mti->dependsOnNormals && mti->dependsOnNormals(md)) {
                DM_ensure_normals(dm);
        }
 -      return mti->applyModifierEM(md, ob, em, dm, flag);
 +      return mti->applyModifierEM(md, eval_ctx, ob, em, dm, flag);
  }
  
  void modwrap_deformVerts(
 -        ModifierData *md, Object *ob,
 -        DerivedMesh *dm,
 +        ModifierData *md, const struct EvaluationContext *eval_ctx,
 +        Object *ob, DerivedMesh *dm,
          float (*vertexCos)[3], int numVerts,
          ModifierApplyFlag flag)
  {
        if (dm && mti->dependsOnNormals && mti->dependsOnNormals(md)) {
                DM_ensure_normals(dm);
        }
 -      mti->deformVerts(md, ob, dm, vertexCos, numVerts, flag);
 +      mti->deformVerts(md, eval_ctx, ob, dm, vertexCos, numVerts, flag);
  }
  
  void modwrap_deformVertsEM(
 -        ModifierData *md, Object *ob,
 +        ModifierData *md, const struct EvaluationContext *eval_ctx, Object *ob,
          struct BMEditMesh *em, DerivedMesh *dm,
          float (*vertexCos)[3], int numVerts)
  {
        if (dm && mti->dependsOnNormals && mti->dependsOnNormals(md)) {
                DM_ensure_normals(dm);
        }
 -      mti->deformVertsEM(md, ob, em, dm, vertexCos, numVerts);
 +      mti->deformVertsEM(md, eval_ctx, ob, em, dm, vertexCos, numVerts);
  }
  /* end modifier callback wrappers */
index fa83567c3b9f42684de7ab94cea2312b72ecde0d,84b97f2812a0e14a711bdf53277d18936081c380..1c3ff3521265c6f860b14fc2130402dbfb6537ce
@@@ -67,6 -67,7 +67,7 @@@
  #include "BKE_global.h"
  #include "BKE_mesh.h"
  #include "BKE_mesh_mapping.h"
+ #include "BKE_modifier.h"
  #include "BKE_multires.h"
  #include "BKE_paint.h"
  #include "BKE_scene.h"
@@@ -1931,8 -1932,7 +1932,8 @@@ static void ccgDM_glNormalFast(float *a
        no[1] = b_dZ * a_cX - b_dX * a_cZ;
        no[2] = b_dX * a_cY - b_dY * a_cX;
  
 -      /* don't normalize, GL_NORMALIZE is enabled */
 +      normalize_v3(no); /* we no longer rely on GL_NORMALIZE */
 +
        glNormal3fv(no);
  }
  
@@@ -3440,6 -3440,261 +3441,6 @@@ static void ccgDM_drawMappedFacesMat(De
  #undef PASSATTRIB
  }
  
 -static void ccgDM_drawFacesTex_common(DerivedMesh *dm,
 -                                      DMSetDrawOptionsTex drawParams,
 -                                      DMSetDrawOptionsMappedTex drawParamsMapped,
 -                                      DMCompareDrawOptions compareDrawOptions,
 -                                      void *userData, DMDrawFlag flag)
 -{
 -      CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
 -      CCGSubSurf *ss = ccgdm->ss;
 -      CCGKey key;
 -      int colType;
 -      const MLoopCol *mloopcol = NULL;
 -      MTexPoly *mtexpoly = DM_get_poly_data_layer(dm, CD_MTEXPOLY);
 -      DMFlagMat *faceFlags = ccgdm->faceFlags;
 -      DMDrawOption draw_option;
 -      int i, totpoly;
 -      bool flush;
 -      const bool use_tface = (flag & DM_DRAW_USE_ACTIVE_UV) != 0;
 -      const bool use_colors = (flag & DM_DRAW_USE_COLORS) != 0;
 -      unsigned int next_actualFace;
 -      unsigned int gridFaces = ccgSubSurf_getGridSize(ss) - 1;
 -      int mat_index;
 -      int tot_element, start_element, tot_drawn;
 -
 -      if (use_colors) {
 -              colType = CD_TEXTURE_MLOOPCOL;
 -              mloopcol = dm->getLoopDataArray(dm, colType);
 -              if (!mloopcol) {
 -                      colType = CD_PREVIEW_MLOOPCOL;
 -                      mloopcol = dm->getLoopDataArray(dm, colType);
 -              }
 -              if (!mloopcol) {
 -                      colType = CD_MLOOPCOL;
 -                      mloopcol = dm->getLoopDataArray(dm, colType);
 -              }
 -      }
 -
 -#ifdef WITH_OPENSUBDIV
 -      if (ccgdm->useGpuBackend) {
 -              const int active_uv_layer = CustomData_get_active_layer_index(&dm->loopData, CD_MLOOPUV);
 -              if (UNLIKELY(ccgSubSurf_prepareGLMesh(ss, true, active_uv_layer) == false)) {
 -                      return;
 -              }
 -              if (drawParams == NULL) {
 -                      ccgSubSurf_drawGLMesh(ss, true, -1, -1);
 -                      return;
 -              }
 -              const int level = ccgSubSurf_getSubdivisionLevels(ss);
 -              const int face_side = 1 << level;
 -              const int grid_side = 1 << (level - 1);
 -              const int face_patches = face_side * face_side;
 -              const int grid_patches = grid_side * grid_side;
 -              const int num_base_faces = ccgSubSurf_getNumGLMeshBaseFaces(ss);
 -              int current_patch = 0;
 -              int mat_nr = -1;
 -              int start_draw_patch = 0, num_draw_patches = 0;
 -              bool draw_smooth = false;
 -              for (i = 0; i < num_base_faces; ++i) {
 -                      const int num_face_verts = ccgSubSurf_getNumGLMeshBaseFaceVerts(ss, i);
 -                      const int num_patches = (num_face_verts == 4) ? face_patches
 -                                                                    : num_face_verts * grid_patches;
 -                      if (faceFlags) {
 -                              mat_nr = faceFlags[i].mat_nr;
 -                              draw_smooth = (faceFlags[i].flag & ME_SMOOTH);
 -                      }
 -                      else {
 -                              mat_nr = 0;
 -                              draw_smooth = false;
 -                      }
 -
 -                      if (drawParams != NULL) {
 -                              MTexPoly *tp = (use_tface && mtexpoly) ? &mtexpoly[i] : NULL;
 -                              draw_option = drawParams(tp, (mloopcol != NULL), mat_nr);
 -                      }
 -                      else {
 -                              draw_option = (drawParamsMapped)
 -                                                ? drawParamsMapped(userData, i, mat_nr)
 -                                                : DM_DRAW_OPTION_NORMAL;
 -                      }
 -
 -                      flush = (draw_option == DM_DRAW_OPTION_SKIP) || (i == num_base_faces - 1);
 -
 -                      const int next_face = min_ii(i + 1, num_base_faces - 1);
 -                      if (!flush && compareDrawOptions) {
 -                              flush |= compareDrawOptions(userData, i, next_face) == 0;
 -                      }
 -                      if (!flush && faceFlags) {
 -                              bool new_draw_smooth = (faceFlags[next_face].flag & ME_SMOOTH);
 -                              flush |= (new_draw_smooth != draw_smooth);
 -                      }
 -
 -                      current_patch += num_patches;
 -
 -                      if (flush) {
 -                              if (draw_option != DM_DRAW_OPTION_SKIP) {
 -                                      num_draw_patches += num_patches;
 -                              }
 -                              if (num_draw_patches != 0) {
 -                                      glShadeModel(draw_smooth ? GL_SMOOTH : GL_FLAT);
 -                                      ccgSubSurf_drawGLMesh(ss,
 -                                                            true,
 -                                                            start_draw_patch,
 -                                                            num_draw_patches);
 -                              }
 -                              start_draw_patch = current_patch;
 -                              num_draw_patches = 0;
 -                      }
 -                      else {
 -                              num_draw_patches += num_patches;
 -                      }
 -              }
 -              glShadeModel(GL_SMOOTH);
 -              return;
 -      }
 -#endif
 -
 -      CCG_key_top_level(&key, ss);
 -      ccgdm_pbvh_update(ccgdm);
 -
 -      GPU_vertex_setup(dm);
 -      GPU_normal_setup(dm);
 -      GPU_triangle_setup(dm);
 -      if (flag & DM_DRAW_USE_TEXPAINT_UV)
 -              GPU_texpaint_uv_setup(dm);
 -      else
 -              GPU_uv_setup(dm);
 -      if (mloopcol) {
 -              GPU_color_setup(dm, colType);
 -      }
 -
 -      next_actualFace = 0;
 -
 -      /* lastFlag = 0; */ /* UNUSED */
 -      for (mat_index = 0; mat_index < dm->drawObject->totmaterial; mat_index++) {
 -              GPUBufferMaterial *bufmat = dm->drawObject->materials + mat_index;
 -              next_actualFace = bufmat->polys[0];
 -              totpoly = bufmat->totpolys;
 -
 -              tot_element = 0;
 -              tot_drawn = 0;
 -              start_element = 0;
 -
 -              for (i = 0; i < totpoly; i++) {
 -                      int polyindex = bufmat->polys[i];
 -                      CCGFace *f = ccgdm->faceMap[polyindex].face;
 -                      int numVerts = ccgSubSurf_getFaceNumVerts(f);
 -                      int index = ccgDM_getFaceMapIndex(ss, f);
 -                      int orig_index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
 -                      int mat_nr;
 -                      int facequads = numVerts * gridFaces * gridFaces;
 -                      int actualFace = ccgdm->faceMap[polyindex].startFace;
 -
 -                      if (i != totpoly - 1) {
 -                              polyindex = bufmat->polys[i + 1];
 -                              next_actualFace = ccgdm->faceMap[polyindex].startFace;
 -                      }
 -
 -                      if (faceFlags) {
 -                              mat_nr = faceFlags[orig_index].mat_nr;
 -                      }
 -                      else {
 -                              mat_nr = 0;
 -                      }
 -
 -                      if (drawParams) {
 -                              MTexPoly *tp = (use_tface && mtexpoly) ? &mtexpoly[actualFace] : NULL;
 -                              draw_option = drawParams(tp, (mloopcol != NULL), mat_nr);
 -                      }
 -                      else if (index != ORIGINDEX_NONE)
 -                              draw_option = (drawParamsMapped) ? drawParamsMapped(userData, index, mat_nr) : DM_DRAW_OPTION_NORMAL;
 -                      else
 -                              draw_option = DM_DRAW_OPTION_NORMAL;
 -
 -                      /* flush buffer if current triangle isn't drawable or it's last triangle */
 -                      flush = (draw_option == DM_DRAW_OPTION_SKIP) || (i == totpoly - 1);
 -
 -                      if (!flush && compareDrawOptions) {
 -                              /* also compare draw options and flush buffer if they're different
 -                               * need for face selection highlight in edit mode */
 -                              flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0;
 -                      }
 -
 -                      tot_element += facequads * 6;
 -
 -                      if (flush) {
 -                              if (draw_option != DM_DRAW_OPTION_SKIP)
 -                                      tot_drawn += facequads * 6;
 -
 -                              if (tot_drawn) {
 -                                      if (mloopcol && draw_option != DM_DRAW_OPTION_NO_MCOL)
 -                                              GPU_color_switch(1);
 -                                      else
 -                                              GPU_color_switch(0);
 -
 -                                      GPU_buffer_draw_elements(dm->drawObject->triangles, GL_TRIANGLES, bufmat->start + start_element, tot_drawn);
 -                                      tot_drawn = 0;
 -                              }
 -
 -                              start_element = tot_element;
 -                      }
 -                      else {
 -                              tot_drawn += facequads * 6;
 -                      }
 -              }
 -      }
 -
 -
 -      GPU_buffers_unbind();
 -}
 -
 -static void ccgDM_drawFacesTex(DerivedMesh *dm,
 -                               DMSetDrawOptionsTex setDrawOptions,
 -                               DMCompareDrawOptions compareDrawOptions,
 -                               void *userData, DMDrawFlag flag)
 -{
 -      ccgDM_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions, userData, flag);
 -}
 -
 -static void ccgDM_drawMappedFacesTex(DerivedMesh *dm,
 -                                     DMSetDrawOptionsMappedTex setDrawOptions,
 -                                     DMCompareDrawOptions compareDrawOptions,
 -                                     void *userData, DMDrawFlag flag)
 -{
 -      ccgDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData, flag);
 -}
 -
 -/* same as cdDM_drawUVEdges */
 -static void ccgDM_drawUVEdges(DerivedMesh *dm)
 -{
 -      MPoly *mpoly = dm->getPolyArray(dm);
 -      int totpoly = dm->getNumPolys(dm);
 -      int prevstart = 0;
 -      bool prevdraw = true;
 -      int curpos = 0;
 -      int i;
 -
 -      GPU_uvedge_setup(dm);
 -      for (i = 0; i < totpoly; i++, mpoly++) {
 -              const bool draw = (mpoly->flag & ME_HIDE) == 0;
 -
 -              if (prevdraw != draw) {
 -                      if (prevdraw && (curpos != prevstart)) {
 -                              glDrawArrays(GL_LINES, prevstart, curpos - prevstart);
 -                      }
 -                      prevstart = curpos;
 -              }
 -
 -              curpos += 2 * mpoly->totloop;
 -              prevdraw = draw;
 -      }
 -      if (prevdraw && (curpos != prevstart)) {
 -              glDrawArrays(GL_LINES, prevstart, curpos - prevstart);
 -      }
 -      GPU_buffers_unbind();
 -}
 -
  static void ccgDM_drawMappedFaces(DerivedMesh *dm,
                                    DMSetDrawOptions setDrawOptions,
                                    DMSetMaterial setMaterial,
@@@ -4190,7 -4445,7 +4191,7 @@@ static struct PBVH *ccgDM_getPBVH(Objec
  {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
        CCGKey key;
-       int numGrids, grid_pbvh;
+       int numGrids;
  
        CCG_key_top_level(&key, ccgdm->ss);
  
        if (!ob->sculpt)
                return NULL;
  
-       /* In vwpaint, we always use a grid_pbvh for multires/subsurf */
-       grid_pbvh = (!(ob->mode & OB_MODE_SCULPT) || ccgDM_use_grid_pbvh(ccgdm));
+       bool grid_pbvh = ccgDM_use_grid_pbvh(ccgdm);
+       if ((ob->mode & OB_MODE_SCULPT) == 0) {
+               /* In vwpaint, we may use a grid_pbvh for multires/subsurf, under certain conditions.
+                * More complex cases break 'history' trail back to original vertices, in that case we fall back to
+                * deformed cage only (i.e. original deformed mesh). */
+               VirtualModifierData virtualModifierData;
+               ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
+               grid_pbvh = true;
+               bool has_one_ccg_modifier = false;
+               for (; md; md = md->next) {
+                       /* We can only accept to use this ccgdm if:
+                        *   - it's the only active ccgdm in the stack.
+                        *   - there is no topology-modifying modifier in the stack.
+                        * Otherwise, there is no way to map back to original geometry from grid-generated PBVH.
+                        */
+                       const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+                       if (!modifier_isEnabled(NULL, md, eModifierMode_Realtime)) {
+                               continue;
+                       }
+                       if (ELEM(mti->type, eModifierTypeType_OnlyDeform, eModifierTypeType_NonGeometrical)) {
+                               continue;
+                       }
+                       if (ELEM(md->type, eModifierType_Subsurf, eModifierType_Multires)) {
+                               if (has_one_ccg_modifier) {
+                                       /* We only allow a single active ccg modifier in the stack. */
+                                       grid_pbvh = false;
+                                       break;
+                               }
+                               has_one_ccg_modifier = true;
+                               continue;
+                       }
+                       /* Any other non-deforming modifier makes it impossible to use grid pbvh. */
+                       grid_pbvh = false;
+                       break;
+               }
+       }
  
        if (ob->sculpt->pbvh) {
+               /* Note that we have to clean up exisitng pbvh instead of updating it in case it does not match current
+                * grid_pbvh status. */
                if (grid_pbvh) {
-                       /* pbvh's grids, gridadj and gridfaces points to data inside ccgdm
-                        * but this can be freed on ccgdm release, this updates the pointers
-                        * when the ccgdm gets remade, the assumption is that the topology
-                        * does not change. */
-                       ccgdm_create_grids(dm);
-                       BKE_pbvh_grids_update(ob->sculpt->pbvh, ccgdm->gridData, (void **)ccgdm->gridFaces,
-                                             ccgdm->gridFlagMats, ccgdm->gridHidden);
+                       if (BKE_pbvh_get_ccgdm(ob->sculpt->pbvh) != NULL) {
+                               /* pbvh's grids, gridadj and gridfaces points to data inside ccgdm
+                                * but this can be freed on ccgdm release, this updates the pointers
+                                * when the ccgdm gets remade, the assumption is that the topology
+                                * does not change. */
+                               ccgdm_create_grids(dm);
+                               BKE_pbvh_grids_update(ob->sculpt->pbvh, ccgdm->gridData, (void **)ccgdm->gridFaces,
+                                                     ccgdm->gridFlagMats, ccgdm->gridHidden);
+                       }
+                       else {
+                               BKE_pbvh_free(ob->sculpt->pbvh);
+                               ob->sculpt->pbvh = NULL;
+                       }
+               }
+               else if (BKE_pbvh_get_ccgdm(ob->sculpt->pbvh) != NULL) {
+                       BKE_pbvh_free(ob->sculpt->pbvh);
+                       ob->sculpt->pbvh = NULL;
                }
  
                ccgdm->pbvh = ob->sculpt->pbvh;
        }
  
        if (ccgdm->pbvh) {
-               /* For vertex paint, keep track of ccgdm */
-               if (!(ob->mode & OB_MODE_SCULPT)) {
+               /* For grid pbvh, keep track of ccgdm */
+               if (grid_pbvh) {
                        BKE_pbvh_set_ccgdm(ccgdm->pbvh, ccgdm);
                }
                return ccgdm->pbvh;
        }
  
-       /* no pbvh exists yet, we need to create one. only in case of multires
+       /* No pbvh exists yet, we need to create one. only in case of multires
         * we build a pbvh over the modified mesh, in other cases the base mesh
         * is being sculpted, so we build a pbvh from that. */
-       /* Note: vwpaint always builds a pbvh over the modified mesh. */
+       /* Note: vwpaint tries to always build a pbvh over the modified mesh. */
        if (grid_pbvh) {
                ccgdm_create_grids(dm);
  
                ob->sculpt->pbvh = ccgdm->pbvh = BKE_pbvh_new();
                BKE_pbvh_build_mesh(ccgdm->pbvh, me->mpoly, me->mloop, me->mvert, me->totvert, &me->vdata,
                                    looptri, looptris_num);
+               if (ob->sculpt->modifiers_active && ob->derivedDeform != NULL) {
+                       DerivedMesh *deformdm = ob->derivedDeform;
+                       float (*vertCos)[3];
+                       int totvert;
+                       totvert = deformdm->getNumVerts(deformdm);
+                       vertCos = MEM_malloc_arrayN(totvert, sizeof(float[3]), "ccgDM_getPBVH vertCos");
+                       deformdm->getVertCos(deformdm, vertCos);
+                       BKE_pbvh_apply_vertCos(ccgdm->pbvh, vertCos);
+                       MEM_freeN(vertCos);
+               }
        }
  
        if (ccgdm->pbvh != NULL) {
                pbvh_show_mask_set(ccgdm->pbvh, ob->sculpt->show_mask);
        }
  
-       /* For vertex paint, keep track of ccgdm */
-       if (!(ob->mode & OB_MODE_SCULPT) && ccgdm->pbvh) {
+       /* For grid pbvh, keep track of ccgdm. */
+       if (grid_pbvh && ccgdm->pbvh) {
                BKE_pbvh_set_ccgdm(ccgdm->pbvh, ccgdm);
        }
        return ccgdm->pbvh;
@@@ -4374,10 -4691,13 +4437,10 @@@ static void set_default_ccgdm_callbacks
        ccgdm->dm.drawEdges = ccgDM_drawEdges;
        ccgdm->dm.drawLooseEdges = ccgDM_drawLooseEdges;
        ccgdm->dm.drawFacesSolid = ccgDM_drawFacesSolid;
 -      ccgdm->dm.drawFacesTex = ccgDM_drawFacesTex;
        ccgdm->dm.drawFacesGLSL = ccgDM_drawFacesGLSL;
        ccgdm->dm.drawMappedFaces = ccgDM_drawMappedFaces;
 -      ccgdm->dm.drawMappedFacesTex = ccgDM_drawMappedFacesTex;
        ccgdm->dm.drawMappedFacesGLSL = ccgDM_drawMappedFacesGLSL;
        ccgdm->dm.drawMappedFacesMat = ccgDM_drawMappedFacesMat;
 -      ccgdm->dm.drawUVEdges = ccgDM_drawUVEdges;
  
        ccgdm->dm.drawMappedEdgesInterp = ccgDM_drawMappedEdgesInterp;
        ccgdm->dm.drawMappedEdges = ccgDM_drawMappedEdges;
@@@ -4835,7 -5155,8 +4898,7 @@@ static bool subsurf_use_gpu_backend(Sub
         */
        return
                (flags & SUBSURF_USE_GPU_BACKEND) != 0 &&
 -              (U.opensubdiv_compute_type != USER_OPENSUBDIV_COMPUTE_NONE) &&
 -              (openSubdiv_supportGPUDisplay());
 +              (U.opensubdiv_compute_type != USER_OPENSUBDIV_COMPUTE_NONE);
  #else
        (void)flags;
        return false;
index 6fc1907ba0ae6cd34f9733a8e2a411f5956803e8,15f8b185a3d2ddc1ba04d70285ea934b76a65bf2..3cb35286114b7e44827167485da982c218a7d45f
@@@ -52,11 -52,6 +52,6 @@@ static void copyData(ModifierData *md, 
        modifier_copyData_generic(md, target);
  }
  
- static bool isDisabled(ModifierData *UNUSED(md), int UNUSED(useRenderParams))
- {
-       return false;
- }
  static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
  {
        WireframeModifierData *wmd = (WireframeModifierData *)md;
@@@ -107,8 -102,7 +102,8 @@@ static DerivedMesh *WireframeModifier_d
  
  }
  
 -static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *dm, ModifierApplyFlag UNUSED(flag))
 +static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx), Object *ob,
 +                                  DerivedMesh *dm, ModifierApplyFlag UNUSED(flag))
  {
        return WireframeModifier_do((WireframeModifierData *)md, ob, dm);
  }
@@@ -132,8 -126,9 +127,8 @@@ ModifierTypeInfo modifierType_Wirefram
        /* initData */          initData,
        /* requiredDataMask */  requiredDataMask,
        /* freeData */          NULL,
-       /* isDisabled */        isDisabled,
-       /* updateDepsgraph */   NULL,
+       /* isDisabled */        NULL,
+       /* updateDepgraph */    NULL,
 -      /* updateDepsgraph */   NULL,
        /* dependsOnTime */     NULL,
        /* dependsOnNormals */  dependsOnNormals,
        /* foreachObjectLink */ NULL,
index 15a8c47db7a08a450a450f8e783dd5729c1219d2,122f02eda8a69416cc2b888486806829c1f491ce..84481a50993085bba714b27f365171124e348df3
@@@ -34,7 -34,7 +34,7 @@@
  /* **************** BUMP ******************** */ 
  static bNodeSocketTemplate sh_node_bump_in[] = {
        { SOCK_FLOAT, 1, N_("Strength"),        1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
-       { SOCK_FLOAT, 1, N_("Distance"),        0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f},
+       { SOCK_FLOAT, 1, N_("Distance"),        1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f},
        { SOCK_FLOAT, 1, N_("Height"),          1.0f, 1.0f, 1.0f, 1.0f, -1000.0f, 1000.0f, PROP_NONE, SOCK_HIDE_VALUE},
        { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
        { -1, 0, "" }
@@@ -52,7 -52,7 +52,7 @@@ static int gpu_shader_bump(GPUMaterial 
        else
                GPU_link(mat, "direction_transform_m4v3", in[3].link, GPU_builtin(GPU_VIEW_MATRIX), &in[3].link);
        float invert = node->custom1;
 -      GPU_stack_link(mat, "node_bump", in, out, GPU_builtin(GPU_VIEW_POSITION), GPU_uniform(&invert));
 +      GPU_stack_link(mat, node, "node_bump", in, out, GPU_builtin(GPU_VIEW_POSITION), GPU_uniform(&invert));
        /* Other nodes are applying view matrix if the input Normal has a link.
         * We don't want normal to have view matrix applied twice, so we cancel it here.
         *
index 999e0f7f70e39065ac3d8df9c79e60a32696037a,5a1a15d0266a5fcda4a55ac6b34f94d87427c2a1..ea3939cfd9991f43a686c50aaed7ac30f1dcf5fc
@@@ -37,7 -37,6 +37,7 @@@
  #include <errno.h>
  
  #include "DNA_anim_types.h"
 +#include "DNA_group_types.h"
  #include "DNA_image_types.h"
  #include "DNA_node_types.h"
  #include "DNA_object_types.h"
@@@ -63,9 -62,9 +63,9 @@@
  #include "BKE_animsys.h"  /* <------ should this be here?, needed for sequencer update */
  #include "BKE_camera.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_library_remap.h"
  #include "BKE_main.h"
@@@ -79,8 -78,6 +79,8 @@@
  #include "BKE_writeavi.h"  /* <------ should be replaced once with generic movie module */
  #include "BKE_object.h"
  
 +#include "DEG_depsgraph.h"
 +
  #include "PIL_time.h"
  #include "IMB_colormanagement.h"
  #include "IMB_imbuf.h"
@@@ -265,7 -262,7 +265,7 @@@ RenderResult *RE_MultilayerConvert(voi
  
  RenderLayer *render_get_active_layer(Render *re, RenderResult *rr)
  {
 -      RenderLayer *rl = BLI_findlink(&rr->layers, re->r.actlay);
 +      RenderLayer *rl = BLI_findlink(&rr->layers, re->active_view_layer);
        
        if (rl)
                return rl;
  
  static int render_scene_needs_vector(Render *re)
  {
 -      SceneRenderLayer *srl;
 -      
 -      for (srl = re->r.layers.first; srl; srl = srl->next)
 -              if (!(srl->layflag & SCE_LAY_DISABLE))
 -                      if (srl->passflag & SCE_PASS_VECTOR)
 +      ViewLayer *view_layer;
 +      for (view_layer = re->view_layers.first; view_layer; view_layer = view_layer->next)
 +              if (view_layer->flag & VIEW_LAYER_RENDER) {
 +                      if (view_layer->passflag & SCE_PASS_VECTOR) {
                                return 1;
 -
 +                      }
 +              }
        return 0;
  }
  
  static bool render_scene_has_layers_to_render(Scene *scene)
  {
 -      SceneRenderLayer *srl;
 -      for (srl = scene->r.layers.first; srl; srl = srl->next) {
 -              if (!(srl->layflag & SCE_LAY_DISABLE)) {
 +      ViewLayer *view_layer;
 +      for (view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) {
 +              if (view_layer->flag & VIEW_LAYER_RENDER) {
                        return true;
                }
        }
@@@ -354,15 -351,6 +354,15 @@@ Scene *RE_GetScene(Render *re
        return NULL;
  }
  
 +EvaluationContext *RE_GetEvalCtx(Render *re)
 +{
 +      if (re) {
 +              return re->eval_ctx;
 +      }
 +
 +      return NULL;
 +}
 +
  /**
   * Same as #RE_AcquireResultImage but creating the necessary views to store the result
   * fill provided result struct with a copy of thew views of what is done so far the
@@@ -585,7 -573,7 +585,7 @@@ void RE_FreeRender(Render *re
        BLI_rw_mutex_end(&re->resultmutex);
        BLI_rw_mutex_end(&re->partsmutex);
  
 -      BLI_freelistN(&re->r.layers);
 +      BLI_freelistN(&re->view_layers);
        BLI_freelistN(&re->r.views);
  
        curvemapping_free_data(&re->r.mblur_shutter_curve);
        /* main dbase can already be invalid now, some database-free code checks it */
        re->main = NULL;
        re->scene = NULL;
 +      re->depsgraph = NULL;
        
        RE_Database_Free(re);   /* view render can still have full database */
        free_sample_tables(re);
@@@ -663,13 -650,12 +663,13 @@@ void RE_FreePersistentData(void
  /* ********* initialize state ******** */
  
  /* clear full sample and tile flags if needed */
 -static int check_mode_full_sample(RenderData *rd)
 +static int check_mode_full_sample(RenderData *rd, ViewRender *view_render)
  {
 +      const char *engine_id = view_render->engine_id;
        int scemode = rd->scemode;
  
 -      if (!STREQ(rd->engine, RE_engine_id_BLENDER_RENDER) &&
 -          !STREQ(rd->engine, RE_engine_id_BLENDER_GAME))
 +      if (!STREQ(engine_id, RE_engine_id_BLENDER_RENDER) &&
 +          !STREQ(engine_id, RE_engine_id_BLENDER_GAME))
        {
                scemode &= ~R_FULL_SAMPLE;
        }
@@@ -731,25 -717,21 +731,25 @@@ static void re_init_resolution(Render *
  
  void render_copy_renderdata(RenderData *to, RenderData *from)
  {
 -      BLI_freelistN(&to->layers);
        BLI_freelistN(&to->views);
        curvemapping_free_data(&to->mblur_shutter_curve);
  
        *to = *from;
  
 -      BLI_duplicatelist(&to->layers, &from->layers);
        BLI_duplicatelist(&to->views, &from->views);
        curvemapping_copy_data(&to->mblur_shutter_curve, &from->mblur_shutter_curve);
  }
  
 +void render_copy_viewrender(ViewRender *to, ViewRender *from)
 +{
 +      BKE_viewrender_copy(to, from);
 +}
 +
  /* what doesn't change during entire render sequence */
  /* disprect is optional, if NULL it assumes full window render */
  void RE_InitState(Render *re, Render *source, RenderData *rd,
 -                  SceneRenderLayer *srl,
 +                  ListBase *render_layers, const int active_layer,
 +                  ViewRender *view_render, ViewLayer *view_layer,
                    int winx, int winy, rcti *disprect)
  {
        bool had_freestyle = (re->r.mode & R_EDGE_FRS) != 0;
  
        /* copy render data and render layers for thread safety */
        render_copy_renderdata(&re->r, rd);
 +      render_copy_viewrender(&re->view_render, view_render);
 +      BLI_freelistN(&re->view_layers);
 +      BLI_duplicatelist(&re->view_layers, render_layers);
 +      re->active_view_layer = active_layer;
  
        if (source) {
                /* reuse border flags from source renderer */
                return;
        }
  
 -      re->r.scemode = check_mode_full_sample(&re->r);
 +      re->r.scemode = check_mode_full_sample(&re->r, &re->view_render);
        
        /* fullsample wants uniform osa levels */
        if (source && (re->r.scemode & R_FULL_SAMPLE)) {
                else re->osa = 0;
        }
        
 -      if (srl) {
 -              int index = BLI_findindex(&rd->layers, srl);
 +      if (view_layer) {
 +              int index = BLI_findindex(render_layers, view_layer);
                if (index != -1) {
 -                      re->r.actlay = index;
 +                      re->active_view_layer = index;
                        re->r.scemode |= R_SINGLE_LAYER;
                }
        }
                        re->result = NULL;
                }
                else if (re->result) {
 -                      SceneRenderLayer *actsrl = BLI_findlink(&re->r.layers, re->r.actlay);
 +                      ViewLayer *active_render_layer = BLI_findlink(&re->view_layers, re->active_view_layer);
                        RenderLayer *rl;
                        bool have_layer = false;
  
                        for (rl = re->result->layers.first; rl; rl = rl->next)
 -                              if (STREQ(rl->name, actsrl->name))
 +                              if (STREQ(rl->name, active_render_layer->name))
                                        have_layer = true;
  
                        if (re->result->rectx == re->rectx && re->result->recty == re->recty &&
@@@ -963,7 -941,7 +963,7 @@@ void RE_ChangeModeFlag(Render *re, int 
  
  /* update some variables that can be animated, and otherwise wouldn't be due to
   * RenderData getting copied once at the start of animation render */
 -void render_update_anim_renderdata(Render *re, RenderData *rd)
 +void render_update_anim_renderdata(Render *re, RenderData *rd, ListBase *render_layers)
  {
        /* filter */
        re->r.gauss = rd->gauss;
        re->r.unit_line_thickness = rd->unit_line_thickness;
  
        /* render layers */
 -      BLI_freelistN(&re->r.layers);
 -      BLI_duplicatelist(&re->r.layers, &rd->layers);
 +      BLI_freelistN(&re->view_layers);
 +      BLI_duplicatelist(&re->view_layers, render_layers);
  
        /* render views */
        BLI_freelistN(&re->r.views);
@@@ -1751,7 -1729,7 +1751,7 @@@ static void do_render_blur_3d(Render *r
        
        /* make sure motion blur changes get reset to current frame */
        if ((re->r.scemode & (R_NO_FRAME_UPDATE|R_BUTS_PREVIEW|R_VIEWPORT_PREVIEW))==0) {
 -              BKE_scene_update_for_newframe(re->eval_ctx, re->main, re->scene, re->lay);
 +              BKE_scene_graph_update_for_newframe(re->eval_ctx, re->depsgraph, re->main, re->scene, NULL);
        }
        
        /* weak... the display callback wants an active renderlayer pointer... */
@@@ -1980,14 -1958,13 +1980,14 @@@ static void render_scene(Render *re, Sc
        }
        
        /* initial setup */
 -      RE_InitState(resc, re, &sce->r, NULL, winx, winy, &re->disprect);
 +      RE_InitState(resc, re, &sce->r, &sce->view_layers, sce->active_view_layer, &sce->view_render, NULL, winx, winy, &re->disprect);
  
        /* We still want to use 'rendercache' setting from org (main) scene... */
        resc->r.scemode = (resc->r.scemode & ~R_EXR_CACHE_FILE) | (re->r.scemode & R_EXR_CACHE_FILE);
  
        /* still unsure entity this... */
        resc->main = re->main;
 +      resc->depsgraph = re->depsgraph;
        resc->scene = sce;
        resc->lay = sce->lay;
        resc->scene_color_manage = BKE_scene_check_color_management_enabled(sce);
@@@ -2068,10 -2045,17 +2068,10 @@@ bool RE_allow_render_generic_object(Obj
  #define DEPSGRAPH_WORKAROUND_HACK
  
  #ifdef DEPSGRAPH_WORKAROUND_HACK
 -static void tag_dependend_objects_for_render(Scene *scene, int renderlay)
 +static void tag_dependend_objects_for_render(Scene *scene, int UNUSED(renderlay))
  {
 -      Scene *sce_iter;
 -      Base *base;
 -      for (SETLOOPER(scene, sce_iter, base)) {
 -              Object *object = base->object;
 -
 -              if ((base->lay & renderlay) == 0) {
 -                      continue;
 -              }
 -
 +      FOREACH_OBJECT_RENDERABLE(scene, object)
 +      {
                if (object->type == OB_MESH) {
                        if (RE_allow_render_generic_object(object)) {
                                ModifierData *md;
                                        if (md->type == eModifierType_Boolean) {
                                                BooleanModifierData *bmd = (BooleanModifierData *)md;
                                                if (bmd->object && bmd->object->type == OB_MESH) {
 -                                                      DAG_id_tag_update(&bmd->object->id, OB_RECALC_DATA);
 +                                                      DEG_id_tag_update(&bmd->object->id, OB_RECALC_DATA);
                                                }
                                        }
                                        else if (md->type == eModifierType_Array) {
                                                ArrayModifierData *amd = (ArrayModifierData *)md;
                                                if (amd->start_cap && amd->start_cap->type == OB_MESH) {
 -                                                      DAG_id_tag_update(&amd->start_cap->id, OB_RECALC_DATA);
 +                                                      DEG_id_tag_update(&amd->start_cap->id, OB_RECALC_DATA);
                                                }
                                                if (amd->end_cap && amd->end_cap->type == OB_MESH) {
 -                                                      DAG_id_tag_update(&amd->end_cap->id, OB_RECALC_DATA);
 +                                                      DEG_id_tag_update(&amd->end_cap->id, OB_RECALC_DATA);
                                                }
                                        }
                                        else if (md->type == eModifierType_Shrinkwrap) {
                                                ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md;
                                                if (smd->target  && smd->target->type == OB_MESH) {
 -                                                      DAG_id_tag_update(&smd->target->id, OB_RECALC_DATA);
 +                                                      DEG_id_tag_update(&smd->target->id, OB_RECALC_DATA);
                                                }
                                        }
                                }
                        }
                }
        }
 +      FOREACH_OBJECT_RENDERABLE_END
 +}
 +#endif
 +
 +#define DEPSGRAPH_WORKAROUND_GROUP_HACK
 +
 +#ifdef DEPSGRAPH_WORKAROUND_GROUP_HACK
 +/**
 + * Make sure the COLLECTION_VIEWPORT / COLLECTION_RENDER is considered
 + * for the collections visibility.
 + *
 + * This won't be needed anymore once we have depsgraph per render engine.
 + */
 +static void tag_groups_for_render(Render *re)
 +{
 +      for (Group *group = re->main->group.first; group; group = group->id.next) {
 +              DEG_id_tag_update(&group->id, 0);
 +      }
 +
 +#ifdef WITH_FREESTYLE
 +      if (re->freestyle_bmain) {
 +              for (Group *group = re->freestyle_bmain->group.first; group; group = group->id.next) {
 +                      DEG_id_tag_update(&group->id, 0);
 +              }
 +      }
 +#endif
  }
  #endif
  
@@@ -2222,10 -2180,6 +2222,10 @@@ static void ntree_render_scenes(Render 
        if (re->scene->nodetree == NULL) return;
        
        tag_scenes_for_render(re);
 +
 +#ifdef DEPSGRAPH_WORKAROUND_GROUP_HACK
 +      tag_groups_for_render(re);
 +#endif
        
        /* now foreach render-result node tagged we do a full render */
        /* results are stored in a way compisitor will find it */
@@@ -2280,24 -2234,24 +2280,24 @@@ static void init_freestyle(Render *re
  /* invokes Freestyle stroke rendering */
  static void add_freestyle(Render *re, int render)
  {
 -      SceneRenderLayer *srl, *actsrl;
 +      ViewLayer *view_layer, *active_view_layer;
        LinkData *link;
        Render *r;
        const bool do_link = (re->r.mode & R_MBLUR) == 0 || re->i.curblur == re->r.mblur_samples;
  
 -      actsrl = BLI_findlink(&re->r.layers, re->r.actlay);
 +      active_view_layer = BLI_findlink(&re->view_layers, re->active_view_layer);
  
        FRS_begin_stroke_rendering(re);
  
 -      for (srl = (SceneRenderLayer *)re->r.layers.first; srl; srl = srl->next) {
 +      for (view_layer = (ViewLayer *)re->view_layers.first; view_layer; view_layer = view_layer->next) {
                if (do_link) {
                        link = (LinkData *)MEM_callocN(sizeof(LinkData), "LinkData to Freestyle render");
                        BLI_addtail(&re->freestyle_renders, link);
                }
 -              if ((re->r.scemode & R_SINGLE_LAYER) && srl != actsrl)
 +              if ((re->r.scemode & R_SINGLE_LAYER) && view_layer != active_view_layer)
                        continue;
 -              if (FRS_is_freestyle_enabled(srl)) {
 -                      r = FRS_do_stroke_rendering(re, srl, render);
 +              if (FRS_is_freestyle_enabled(view_layer)) {
 +                      r = FRS_do_stroke_rendering(re, view_layer, render);
                        if (do_link)
                                link->data = (void *)r;
                }
@@@ -2314,25 -2268,25 +2314,25 @@@ static void composite_freestyle_renders
  {
        Render *freestyle_render;
        RenderView *rv;
 -      SceneRenderLayer *srl, *actsrl;
 +      ViewLayer *view_layer, *active_view_layer;
        LinkData *link;
  
 -      actsrl = BLI_findlink(&re->r.layers, re->r.actlay);
 +      active_view_layer = BLI_findlink(&re->view_layers, re->active_view_layer);
  
        link = (LinkData *)re->freestyle_renders.first;
  
        for (rv = re->result->views.first; rv; rv = rv->next) {
 -              for (srl = (SceneRenderLayer *)re->r.layers.first; srl; srl = srl->next) {
 -                      if ((re->r.scemode & R_SINGLE_LAYER) && srl != actsrl)
 +              for (view_layer = (ViewLayer *)re->view_layers.first; view_layer; view_layer = view_layer->next) {
 +                      if ((re->r.scemode & R_SINGLE_LAYER) && view_layer != active_view_layer)
                                continue;
  
 -                      if (FRS_is_freestyle_enabled(srl)) {
 +                      if (FRS_is_freestyle_enabled(view_layer)) {
                                freestyle_render = (Render *)link->data;
  
                                /* may be NULL in case of empty render layer */
                                if (freestyle_render) {
                                        render_result_exr_file_read_sample(freestyle_render, sample);
 -                                      FRS_composite_result(re, srl, freestyle_render);
 +                                      FRS_composite_result(re, view_layer, freestyle_render);
                                        RE_FreeRenderResult(freestyle_render->result);
                                        freestyle_render->result = NULL;
                                }
@@@ -2443,10 -2397,6 +2443,10 @@@ static void do_merge_fullsample(Render 
                        }
                }
                
 +#ifdef DEPSGRAPH_WORKAROUND_GROUP_HACK
 +              tag_groups_for_render(re);
 +#endif
 +
                /* composite */
                if (ntree) {
                        ntreeCompositTagRender(re->scene);
@@@ -2598,11 -2548,6 +2598,11 @@@ void RE_MergeFullSample(Render *re, Mai
  #ifdef WITH_FREESTYLE
        free_all_freestyle_renders();
  #endif
 +
 +#ifdef DEPSGRAPH_WORKAROUND_GROUP_HACK
 +      /* Restore their visibility based on the viewport visibility flags. */
 +      tag_groups_for_render(re);
 +#endif
  }
  
  /* returns fully composited render-result on given time step (in RenderData) */
@@@ -2676,7 -2621,7 +2676,7 @@@ static void do_render_composite_fields_
                                R.i.cfra = re->i.cfra;
                                
                                if (update_newframe)
 -                                      BKE_scene_update_for_newframe(re->eval_ctx, re->main, re->scene, re->lay);
 +                                      BKE_scene_graph_update_for_newframe(re->eval_ctx, re->depsgraph, re->main, re->scene, NULL);
                                
                                if (re->r.scemode & R_FULL_SAMPLE)
                                        do_merge_fullsample(re, ntree);
        free_all_freestyle_renders();
  #endif
  
 +#ifdef DEPSGRAPH_WORKAROUND_GROUP_HACK
 +      /* Restore their visibility based on the viewport visibility flags. */
 +      tag_groups_for_render(re);
 +#endif
 +
        /* weak... the display callback wants an active renderlayer pointer... */
        if (re->result != NULL) {
                re->result->renlay = render_get_active_layer(re, re->result);
@@@ -2924,12 -2864,12 +2924,12 @@@ static void do_render_all_options(Rende
  
  bool RE_force_single_renderlayer(Scene *scene)
  {
 -      int scemode = check_mode_full_sample(&scene->r);
 +      int scemode = check_mode_full_sample(&scene->r, &scene->view_render);
        if (scemode & R_SINGLE_LAYER) {
 -              SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
 +              ViewLayer *view_layer = BLI_findlink(&scene->view_layers, scene->active_view_layer);
                /* force layer to be enabled */
 -              if (srl->layflag & SCE_LAY_DISABLE) {
 -                      srl->layflag &= ~SCE_LAY_DISABLE;
 +              if ((view_layer->flag & VIEW_LAYER_RENDER) == 0) {
 +                      view_layer->flag |= VIEW_LAYER_RENDER;
                        return true;
                }
        }
@@@ -2945,7 -2885,7 +2945,7 @@@ static bool check_valid_compositing_cam
                        if (node->type == CMP_NODE_R_LAYERS && (node->flag & NODE_MUTED) == 0) {
                                Scene *sce = node->id ? (Scene *)node->id : scene;
                                if (sce->camera == NULL) {
 -                                      sce->camera = BKE_scene_camera_find(sce);
 +                                      sce->camera = BKE_view_layer_camera_find(BKE_view_layer_from_scene_get(sce));
                                }
                                if (sce->camera == NULL) {
                                        /* all render layers nodes need camera */
@@@ -3003,7 -2943,7 +3003,7 @@@ static int check_valid_camera(Scene *sc
        const char *err_msg = "No camera found in scene \"%s\"";
  
        if (camera_override == NULL && scene->camera == NULL)
 -              scene->camera = BKE_scene_camera_find(scene);
 +              scene->camera = BKE_view_layer_camera_find(BKE_view_layer_from_scene_get(scene));
  
        if (!check_valid_camera_multiview(scene, scene->camera, reports))
                return false;
                                    (seq->scene != NULL))
                                {
                                        if (!seq->scene_camera) {
 -                                              if (!seq->scene->camera && !BKE_scene_camera_find(seq->scene)) {
 +                                              if (!seq->scene->camera &&
 +                                                  !BKE_view_layer_camera_find(BKE_view_layer_from_scene_get(seq->scene)))
 +                                              {
                                                        /* camera could be unneeded due to composite nodes */
                                                        Object *override = (seq->scene == scene) ? camera_override : NULL;
  
@@@ -3073,7 -3011,7 +3073,7 @@@ static int check_composite_output(Scen
  
  bool RE_is_rendering_allowed(Scene *scene, Object *camera_override, ReportList *reports)
  {
 -      int scemode = check_mode_full_sample(&scene->r);
 +      int scemode = check_mode_full_sample(&scene->r, &scene->view_render);
        
        if (scene->r.mode & R_BORDER) {
                if (scene->r.border.xmax <= scene->r.border.xmin ||
@@@ -3186,15 -3124,13 +3186,15 @@@ static void validate_render_settings(Re
        }
  }
  
 -static void update_physics_cache(Render *re, Scene *scene, int UNUSED(anim_init))
 +static void update_physics_cache(Render *re, Scene *scene, ViewLayer *view_layer, int UNUSED(anim_init))
  {
        PTCacheBaker baker;
  
        memset(&baker, 0, sizeof(baker));
        baker.main = re->main;
        baker.scene = scene;
 +      baker.view_layer = view_layer;
 +      baker.depsgraph = BKE_scene_get_depsgraph(scene, view_layer, true);
        baker.bake = 0;
        baker.render = 1;
        baker.anim_init = 1;
@@@ -3213,15 -3149,9 +3213,15 @@@ const char *RE_GetActiveRenderView(Rend
        return re->viewname;
  }
  
 +void RE_SetEngineByID(Render *re, const char *engine_id)
 +{
 +      BLI_strncpy(re->view_render.engine_id, engine_id, sizeof(re->view_render.engine_id));
 +}
 +
  /* evaluating scene options for general Blender render */
 -static int render_initialize_from_main(Render *re, RenderData *rd, Main *bmain, Scene *scene, SceneRenderLayer *srl,
 -                                       Object *camera_override, unsigned int lay_override, int anim, int anim_init)
 +static int render_initialize_from_main(Render *re, RenderData *rd, Main *bmain, Scene *scene, ViewRender *view_render,
 +                                       ViewLayer *view_layer, Object *camera_override, unsigned int lay_override,
 +                                       int anim, int anim_init)
  {
        int winx, winy;
        rcti disprect;
        re->layer_override = lay_override;
        re->i.localview = (re->lay & 0xFF000000) != 0;
        re->viewname[0] = '\0';
 +      RE_SetEngineByID(re, view_render->engine_id);
  
        /* not too nice, but it survives anim-border render */
        if (anim) {
 -              render_update_anim_renderdata(re, &scene->r);
 +              render_update_anim_renderdata(re, &scene->r, &scene->view_layers);
                re->disprect = disprect;
                return 1;
        }
        /* check all scenes involved */
        tag_scenes_for_render(re);
  
 +#ifdef DEPSGRAPH_WORKAROUND_GROUP_HACK
 +      /* Update group collections visibility. */
 +      tag_groups_for_render(re);
 +#endif
 +
        /*
         * Disabled completely for now,
         * can be later set as render profile option
         */
        if (0) {
                /* make sure dynamics are up to date */
 -              update_physics_cache(re, scene, anim_init);
 +              view_layer = BKE_view_layer_from_scene_get(scene);
 +              update_physics_cache(re, scene, view_layer, anim_init);
        }
        
 -      if (srl || scene->r.scemode & R_SINGLE_LAYER) {
 +      if (view_layer || scene->r.scemode & R_SINGLE_LAYER) {
                BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
                render_result_single_layer_begin(re);
                BLI_rw_mutex_unlock(&re->resultmutex);
        }
        
 -      RE_InitState(re, NULL, &scene->r, srl, winx, winy, &disprect);
 +      RE_InitState(re, NULL, &scene->r, &scene->view_layers, scene->active_view_layer, &scene->view_render, view_layer, winx, winy, &disprect);
        if (!re->ok)  /* if an error was printed, abort */
                return 0;
        
@@@ -3310,7 -3233,7 +3310,7 @@@ void RE_SetReports(Render *re, ReportLi
  }
  
  /* general Blender frame render call */
 -void RE_BlenderFrame(Render *re, Main *bmain, Scene *scene, SceneRenderLayer *srl, Object *camera_override,
 +void RE_BlenderFrame(Render *re, Main *bmain, Scene *scene, ViewLayer *view_layer, Object *camera_override,
                       unsigned int lay_override, int frame, const bool write_still)
  {
        BLI_callback_exec(re->main, (ID *)scene, BLI_CB_EVT_RENDER_INIT);
        
        scene->r.cfra = frame;
        
 -      if (render_initialize_from_main(re, &scene->r, bmain, scene, srl, camera_override, lay_override, 0, 0)) {
 +      if (render_initialize_from_main(re, &scene->r, bmain, scene, &scene->view_render, view_layer,
 +                                      camera_override, lay_override, 0, 0))
 +      {
                MEM_reset_peak_memory();
  
                BLI_callback_exec(re->main, (ID *)scene, BLI_CB_EVT_RENDER_PRE);
  void RE_RenderFreestyleStrokes(Render *re, Main *bmain, Scene *scene, int render)
  {
        re->result_ok= 0;
 -      if (render_initialize_from_main(re, &scene->r, bmain, scene, NULL, NULL, scene->lay, 0, 0)) {
 +      if (render_initialize_from_main(re, &scene->r, bmain, scene, &scene->view_render, NULL, NULL, scene->lay, 0, 0)) {
                if (render)
                        do_render_fields_blur_3d(re);
        }
@@@ -3413,11 -3334,14 +3413,14 @@@ bool RE_WriteRenderViewsImage(ReportLis
                BLI_strncpy(filepath, name, sizeof(filepath));
  
                for (view_id = 0, rv = rr->views.first; rv; rv = rv->next, view_id++) {
+                       /* Sequencer and OpenGL render can't save multiple EXR layers. */
+                       bool is_float = rv->rect32 == NULL;
                        if (!is_mono) {
                                BKE_scene_multiview_view_filepath_get(&scene->r, filepath, rv->name, name);
                        }
  
-                       if (is_exr_rr) {
+                       if (is_exr_rr && is_float) {
                                ok = RE_WriteRenderResult(reports, rr, name, &rd->im_format, rv->name, -1);
                                render_print_save_message(reports, name, ok, errno);
  
@@@ -3656,7 -3580,7 +3659,7 @@@ void RE_BlenderAnim(Render *re, Main *b
        BLI_callback_exec(re->main, (ID *)scene, BLI_CB_EVT_RENDER_INIT);
  
        /* do not fully call for each frame, it initializes & pops output window */
 -      if (!render_initialize_from_main(re, &rd, bmain, scene, NULL, camera_override, lay_override, 0, 1))
 +      if (!render_initialize_from_main(re, &rd, bmain, scene, &scene->view_render, NULL, camera_override, lay_override, 0, 1))
                return;
  
        /* MULTIVIEW_TODO:
                        }
  
                        /* only border now, todo: camera lens. (ton) */
 -                      render_initialize_from_main(re, &rd, bmain, scene, NULL, camera_override, lay_override, 1, 0);
 +                      render_initialize_from_main(re, &rd, bmain, scene, &scene->view_render,
 +                                                  NULL, camera_override, lay_override, 1, 0);
  
                        if (nfra != scene->r.cfra) {
 -                              /*
 -                               * Skip this frame, but update for physics and particles system.
 -                               * From convertblender.c:
 -                               * in localview, lamps are using normal layers, objects only local bits.
 -                               */
 -                              unsigned int updatelay;
 -
 -                              if (re->lay & 0xFF000000)
 -                                      updatelay = re->lay & 0xFF000000;
 -                              else
 -                                      updatelay = re->lay;
 -
 -                              BKE_scene_update_for_newframe(re->eval_ctx, bmain, scene, updatelay);
 +                              /* Skip this frame, but update for physics and particles system. */
 +                              BKE_scene_graph_update_for_newframe(re->eval_ctx, re->depsgraph, bmain, scene, NULL);
                                continue;
                        }
                        else
        G.is_rendering = false;
  }
  
 -void RE_PreviewRender(Render *re, Main *bmain, Scene *sce)
 +void RE_PreviewRender(Render *re, Main *bmain, Scene *sce, ViewRender *view_render)
  {
        Object *camera;
 +      ViewLayer *view_layer = BKE_view_layer_from_scene_get(sce);
        int winx, winy;
  
        winx = (sce->r.size * sce->r.xsch) / 100;
        winy = (sce->r.size * sce->r.ysch) / 100;
  
 -      RE_InitState(re, NULL, &sce->r, NULL, winx, winy, NULL);
 +      RE_InitState(re, NULL, &sce->r, &sce->view_layers, sce->active_view_layer, view_render, NULL, winx, winy, NULL);
  
        re->pool = BKE_image_pool_new();
  
        re->scene = sce;
        re->scene_color_manage = BKE_scene_check_color_management_enabled(sce);
        re->lay = sce->lay;
 +      re->depsgraph = BKE_scene_get_depsgraph(sce, view_layer, false);
 +      re->eval_ctx->view_layer = view_layer;
  
        camera = RE_GetCamera(re);
        RE_SetCamera(re, camera);
@@@ -3961,7 -3892,7 +3964,7 @@@ bool RE_ReadRenderResult(Scene *scene, 
        re = RE_GetSceneRender(scene);
        if (re == NULL)
                re = RE_NewSceneRender(scene);
 -      RE_InitState(re, NULL, &scene->r, NULL, winx, winy, &disprect);
 +      RE_InitState(re, NULL, &scene->r, &scene->view_layers, scene->active_view_layer, &scene->view_render, NULL, winx, winy, &disprect);
        re->scene = scene;
        re->scene_color_manage = BKE_scene_check_color_management_enabled(scene);
        
@@@ -4194,6 -4125,7 +4197,6 @@@ RenderPass *RE_create_gp_pass(RenderRes
                rl = MEM_callocN(sizeof(RenderLayer), layername);
                BLI_addtail(&rr->layers, rl);
                BLI_strncpy(rl->name, layername, sizeof(rl->name));
 -              rl->lay = 0;
                rl->layflag = SCE_LAY_SOLID;
                rl->passflag = SCE_PASS_COMBINED;
                rl->rectx = rr->rectx;