OpenSubdiv: Completely avoid possible access to non-existing CPU data
authorSergey Sharybin <sergey.vfx@gmail.com>
Wed, 5 Aug 2015 13:11:50 +0000 (15:11 +0200)
committerSergey Sharybin <sergey.vfx@gmail.com>
Wed, 5 Aug 2015 13:11:50 +0000 (15:11 +0200)
Make it so CCGDM reports 0 number of geometry when it uses GPU backend for
drawing. This screws up a bit statistics in info header and requires to have
some special handle of CCGDM in the drawing code, but makes it so non of the
areas will try to access non-existing geometry.

source/blender/blenkernel/BKE_subsurf.h
source/blender/blenkernel/intern/CCGSubSurf.c
source/blender/blenkernel/intern/subsurf_ccg.c
source/blender/editors/space_view3d/drawobject.c

index 93baca3710091174303f4bf19b49af2fc1f71c68..161ab2f2fbd104aa4051aec32819a6e025103550 100644 (file)
@@ -85,6 +85,9 @@ void subsurf_copy_grid_paint_mask(struct DerivedMesh *dm,
                                   const struct MPoly *mpoly, float *paint_mask,
                                   const struct GridPaintMask *grid_paint_mask);
 
+bool subsurf_has_edges(struct DerivedMesh *dm);
+bool subsurf_has_faces(struct DerivedMesh *dm);
+
 typedef enum MultiresModifiedFlags {
        /* indicates the grids have been sculpted on, so MDisps
         * have to be updated */
index bd5ddba9590f7d745dada3d8217981e7eb48df80..95ddb9d5498158d3875f4bb1cbf87cfe9dc46429 100644 (file)
@@ -1515,6 +1515,12 @@ int ccgSubSurf_getNumFinalVerts(const CCGSubSurf *ss)
                             ss->fMap->numEntries +
                             ss->numGrids * ((gridSize - 2) + ((gridSize - 2) * (gridSize - 2))));
 
+#ifdef WITH_OPENSUBDIV
+       if (ss->skip_grids) {
+               return 0;
+       }
+#endif
+
        return numFinalVerts;
 }
 int ccgSubSurf_getNumFinalEdges(const CCGSubSurf *ss)
@@ -1523,13 +1529,22 @@ int ccgSubSurf_getNumFinalEdges(const CCGSubSurf *ss)
        int gridSize = ccg_gridsize(ss->subdivLevels);
        int numFinalEdges = (ss->eMap->numEntries * (edgeSize - 1) +
                             ss->numGrids * ((gridSize - 1) + 2 * ((gridSize - 2) * (gridSize - 1))));
-
+#ifdef WITH_OPENSUBDIV
+       if (ss->skip_grids) {
+               return 0;
+       }
+#endif
        return numFinalEdges;
 }
 int ccgSubSurf_getNumFinalFaces(const CCGSubSurf *ss)
 {
        int gridSize = ccg_gridsize(ss->subdivLevels);
        int numFinalFaces = ss->numGrids * ((gridSize - 1) * (gridSize - 1));
+#ifdef WITH_OPENSUBDIV
+       if (ss->skip_grids) {
+               return 0;
+       }
+#endif
        return numFinalFaces;
 }
 
index 617bf70c08150ed428cc96870e6425ed768bbc57..9971a9ef141515ec509a214943d54ccab086e874 100644 (file)
@@ -4850,3 +4850,25 @@ void subsurf_calculate_limit_positions(Mesh *me, float (*r_positions)[3])
 
        dm->release(dm);
 }
+
+bool subsurf_has_edges(DerivedMesh *dm)
+{
+       CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
+#ifdef WITH_OPENSUBDIV
+       if (ccgdm->useGpuBackend) {
+               return true;
+       }
+#endif
+       return dm->getNumEdges(dm) != 0;
+}
+
+bool subsurf_has_faces(DerivedMesh *dm)
+{
+       CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
+#ifdef WITH_OPENSUBDIV
+       if (ccgdm->useGpuBackend) {
+               return true;
+       }
+#endif
+       return dm->getNumPolys(dm) != 0;
+}
index 82acc5863c4848d97abed3977cd6bbf71a9e1bda..f8af238de14211c8ff768cae4649d51c0114f11f 100644 (file)
@@ -74,6 +74,7 @@
 #include "BKE_particle.h"
 #include "BKE_pointcache.h"
 #include "BKE_scene.h"
+#include "BKE_subsurf.h"
 #include "BKE_unit.h"
 #include "BKE_tracking.h"
 
@@ -4027,9 +4028,15 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D
        }
        
        /* check polys instead of tessfaces because of dyntopo where tessfaces don't exist */
-       no_edges = (dm->getNumEdges(dm) == 0);
-       no_faces = (dm->getNumPolys(dm) == 0);
-       
+       if (dm->type == DM_TYPE_CCGDM) {
+               no_edges = !subsurf_has_edges(dm);
+               no_faces = !subsurf_has_faces(dm);
+       }
+       else {
+               no_edges = (dm->getNumEdges(dm) == 0);
+               no_faces = (dm->getNumPolys(dm) == 0);
+       }
+
        /* vertexpaint, faceselect wants this, but it doesnt work for shaded? */
        glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);