Mesh drawing optimization and fixes:
authorSergey Sharybin <sergey.vfx@gmail.com>
Fri, 9 Dec 2011 11:46:48 +0000 (11:46 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Fri, 9 Dec 2011 11:46:48 +0000 (11:46 +0000)
- Pass MFace, MTface and OrigIndex arrays via userData to compareDrawParams callback
  rather than looking up for this layers for each face
- This allowed to avoid massing DM to compare callback which seems like a bad-level pass
- Fixed crashes on some video cards when assigning different materials to different
  faces in edit mode. Both of intel and nvidia cards in my laptop were affected by
  this error

source/blender/blenkernel/intern/editderivedmesh.c
source/blender/editors/space_view3d/drawmesh.c
source/blender/editors/space_view3d/drawobject.c

index 8eccfd4d3f0a62d6a3aba8c463a6906eb47be460..bb1d20f0187a6fa55a57edbee275d8baa5324b9a 100644 (file)
@@ -273,7 +273,7 @@ static void emDM_drawMappedFaces(
 {
        EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
        EditFace *efa;
-       int i, draw;
+       int i, draw, flush;
        const int skip_normals= !glIsEnabled(GL_LIGHTING); /* could be passed as an arg */
 
        /* GL_ZERO is used to detect if drawing has started or not */
@@ -352,7 +352,11 @@ static void emDM_drawMappedFaces(
                                        }
                                }
 
-                               if (draw==2) {
+                               flush= (draw==2);
+                               if (!skip_normals && !flush && efa->next)
+                                       flush|= efa->mat_nr != efa->next->mat_nr;
+
+                               if (flush) {
                                        glEnd();
                                        poly_prev= GL_ZERO; /* force glBegin */
 
@@ -419,8 +423,11 @@ static void emDM_drawMappedFaces(
                                        }
                                }
 
+                               flush= (draw==2);
+                               if (!skip_normals && !flush && efa->next)
+                                       flush|= efa->mat_nr != efa->next->mat_nr;
 
-                               if (draw==2) {
+                               if (flush) {
                                        glEnd();
                                        poly_prev= GL_ZERO; /* force glBegin */
 
index e83591b73f567203a5056380341025cba4e2fc86..6dd362b827f6ec57508e048c54b05526368de512 100644 (file)
@@ -513,7 +513,7 @@ static int draw_tface_mapped__set_draw(void *userData, int index)
 
 static int draw_em_tf_mapped__set_draw(void *userData, int index)
 {
-       struct {DerivedMesh *dm; EditMesh *em; short has_mcol; short has_mtface;} *data = userData;
+       struct {EditMesh *em; short has_mcol; short has_mtface; MFace *mf; MTFace *tf;} *data = userData;
        EditMesh *em = data->em;
        EditFace *efa= EM_get_face_for_index(index);
        MTFace *tface;
@@ -631,14 +631,12 @@ static void draw_mesh_text(Scene *scene, Object *ob, int glsl)
 
 static int compareDrawOptions(void *userData, int cur_index, int next_index)
 {
-       DerivedMesh *dm= (DerivedMesh*) userData;
-       MFace *mf = DM_get_face_data_layer(dm, CD_MFACE);
-       MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE);
+       struct { MFace *mf; MTFace *tf; } *data = userData;
 
-       if(mf && mf[cur_index].mat_nr != mf[next_index].mat_nr)
+       if(data->mf && data->mf[cur_index].mat_nr != data->mf[next_index].mat_nr)
                return 0;
 
-       if(tf && tf[cur_index].tpage != tf[next_index].tpage)
+       if(data->tf && data->tf[cur_index].tpage != data->tf[next_index].tpage)
                return 0;
 
        return 1;
@@ -646,14 +644,12 @@ static int compareDrawOptions(void *userData, int cur_index, int next_index)
 
 static int compareDrawOptionsEm(void *userData, int cur_index, int next_index)
 {
-       struct {DerivedMesh *dm; EditMesh *em; short has_mcol; short has_mtface;} *data= userData;
-       MFace *mf = DM_get_face_data_layer(data->dm, CD_MFACE);
-       MTFace *tf = DM_get_face_data_layer(data->dm, CD_MTFACE);
+       struct {EditMesh *em; short has_mcol; short has_mtface; MFace *mf; MTFace *tf;} *data= userData;
 
-       if(mf && mf[cur_index].mat_nr != mf[next_index].mat_nr)
+       if(data->mf && data->mf[cur_index].mat_nr != data->mf[next_index].mat_nr)
                return 0;
 
-       if(tf && tf[cur_index].tpage != tf[next_index].tpage)
+       if(data->tf && data->tf[cur_index].tpage != data->tf[next_index].tpage)
                return 0;
 
        return 1;
@@ -673,12 +669,13 @@ void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
        glColor4f(1.0f,1.0f,1.0f,1.0f);
 
        if(ob->mode & OB_MODE_EDIT) {
-               struct {DerivedMesh *dm; EditMesh *em; short has_mcol; short has_mtface;} data;
+               struct {EditMesh *em; short has_mcol; short has_mtface; MFace *mf; MTFace *tf;} data;
 
-               data.dm = dm;
                data.em= me->edit_mesh;
                data.has_mcol= CustomData_has_layer(&me->edit_mesh->fdata, CD_MCOL);
                data.has_mtface= CustomData_has_layer(&me->edit_mesh->fdata, CD_MTFACE);
+               data.mf= DM_get_face_data_layer(dm, CD_MFACE);
+               data.tf= DM_get_face_data_layer(dm, CD_MTFACE);
 
                dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, compareDrawOptionsEm, &data);
        }
@@ -696,10 +693,15 @@ void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
                                dm->drawFacesTex(dm, draw_tface__set_draw_legacy, NULL, NULL);
                }
                else {
+                       struct { MFace *mf; MTFace *tf; } userData;
+
                        if(!CustomData_has_layer(&dm->faceData,CD_TEXTURE_MCOL))
                                add_tface_color_layer(dm);
 
-                       dm->drawFacesTex(dm, draw_tface__set_draw, compareDrawOptions, dm);
+                       userData.mf = DM_get_face_data_layer(dm, CD_MFACE);
+                       userData.tf = DM_get_face_data_layer(dm, CD_MTFACE);
+
+                       dm->drawFacesTex(dm, draw_tface__set_draw, compareDrawOptions, &userData);
                }
        }
 
index f6f2c35163f760246249e2527af90cf9e48d050a..b3eba8652b021b22585d0a5590bc13c49831cd82 100644 (file)
@@ -2349,7 +2349,7 @@ static void draw_dm_edges_sharp(DerivedMesh *dm)
         * return 2 for the active face so it renders with stipple enabled */
 static int draw_dm_faces_sel__setDrawOptions(void *userData, int index, int *UNUSED(drawSmooth_r))
 {
-       struct { DerivedMesh *dm; unsigned char *cols[3]; EditFace *efa_act; } * data = userData;
+       struct { unsigned char *cols[3]; EditFace *efa_act; int *orig_index; } * data = userData;
        EditFace *efa = EM_get_face_for_index(index);
        unsigned char *col;
        
@@ -2369,17 +2369,16 @@ static int draw_dm_faces_sel__setDrawOptions(void *userData, int index, int *UNU
 
 static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int next_index)
 {
-       struct { DerivedMesh *dm; unsigned char *cols[3]; EditFace *efa_act; } *data = userData;
-       int *orig_index= DM_get_face_data_layer(data->dm, CD_ORIGINDEX);
+       struct { unsigned char *cols[3]; EditFace *efa_act; int *orig_index; } *data = userData;
        EditFace *efa;
        EditFace *next_efa;
        unsigned char *col, *next_col;
 
-       if(!orig_index)
+       if(!data->orig_index)
                return 0;
 
-       efa= EM_get_face_for_index(orig_index[index]);
-       next_efa= EM_get_face_for_index(orig_index[next_index]);
+       efa= EM_get_face_for_index(data->orig_index[index]);
+       next_efa= EM_get_face_for_index(data->orig_index[next_index]);
 
        if(efa == next_efa)
                return 1;
@@ -2399,12 +2398,12 @@ static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int
 /* also draws the active face */
 static void draw_dm_faces_sel(DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol, unsigned char *actCol, EditFace *efa_act) 
 {
-       struct { DerivedMesh *dm; unsigned char *cols[3]; EditFace *efa_act; } data;
-       data.dm= dm;
+       struct { unsigned char *cols[3]; EditFace *efa_act; int *orig_index; } data;
        data.cols[0] = baseCol;
        data.cols[1] = selCol;
        data.cols[2] = actCol;
        data.efa_act = efa_act;
+       data.orig_index = DM_get_face_data_layer(dm, CD_ORIGINDEX);
 
        dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, GPU_enable_material, draw_dm_faces_sel__compareDrawOptions, &data, 0);
 }