[Bf-committers] Workaround for an NVidia driver bug with TNT2 in Linux

Timo Mihaljov bf-committers@blender.org
Wed, 6 Aug 2003 01:00:34 +0300


--Boundary-00=_CkCM/GDJKD1IwND
Content-Type: text/plain;
  charset="us-ascii"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

Hi,
I've been getting _a_lot_ of segmenation faults with 2.28 when editing IPO's. 
I looked into it and found a bug in NVidia's Linux drivers when used with 
TNT2. The following code causes a segmentation fault with them:

glBegin(GL_POINTS);
glColor3ub(0xF0, 0x0B, 0xA5);  // any color changing function triggers the bug
glEnd();

Because of that I had to do some minimal changes to draw_ipovertices (in 
blender/src/drawipo.c line 864) to draw every color with its own 
glBegin(GL_POINTS) / glEnd() block.

I also made the following changes:
- replaced the calls to cpack() with direct calls to glColor3ub() as the 
comment in BIF_gl.h instructs

- changed glVertex3fv's to glVertex2fv's (because the z-component is unset in 
the vector that's give to them)

- renamed some variables and replaced some pointer voodoo with an array to 
make the code easier to read

I have included a patch with these changes.


Timo Mihaljov
noid @ #blendersauce
















--Boundary-00=_CkCM/GDJKD1IwND
Content-Type: text/x-diff;
  charset="us-ascii";
  name="draw_ipovertices_tnt2.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
	filename="draw_ipovertices_tnt2.patch"

cvs server: Diffing .
Index: drawipo.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/src/drawipo.c,v
retrieving revision 1.9
diff -u -r1.9 drawipo.c
--- drawipo.c	20 Jul 2003 23:04:08 -0000	1.9
+++ drawipo.c	5 Aug 2003 21:40:58 -0000
@@ -863,40 +863,65 @@
 
 static void draw_ipovertices(int sel)
 {
-	EditIpo *ei;
+	EditIpo		*edit_ipos;
+	EditIpo		cur_ipo;
+	unsigned int	cur_ipo_idx;
+
+	unsigned int	vertices_left;
+
 	BezTriple *bezt;
 	float v1[2];
 	unsigned int col;
-	int val, ok, nr, a, b;
+	int val, ok, b;
 	
 	if(G.f & G_PICKSEL) return;
 	
 	glPointSize(3.0);
-	glBegin(GL_POINTS);
 	
-	ei= G.sipo->editipo;
-	for(nr=0; nr<G.sipo->totipo; nr++, ei++) {
-		if ISPOIN(ei, flag & IPO_VISIBLE, icu) {
+	edit_ipos = G.sipo->editipo;
+	
+	for(cur_ipo_idx = 0; cur_ipo_idx < G.sipo->totipo; cur_ipo_idx++) {
+		cur_ipo = edit_ipos[cur_ipo_idx];
+		
+		if ISPOIN((&cur_ipo), flag & IPO_VISIBLE, icu) {
 			
 			if(G.sipo->showkey) {
-				if(sel) col= 0xFFFFFF; else col= 0x0;
-			} else if(ei->flag & IPO_EDIT) {
-				if(sel) col= 0x77FFFF; else col= 0xFF70FF;
+				if(sel)
+					glColor3ub(0xFF, 0xFF, 0xFF);
+				else
+					glColor3ub(0x00, 0x00, 0x00);
+
+			} else if(cur_ipo.flag & IPO_EDIT) {
+				if(sel)
+					glColor3ub(0xFF, 0xFF, 0x77);
+				else
+					glColor3ub(0xFF, 0x70, 0xFF);
 			} else {
-				if(sel) col= 0xFFFFFF; else col= 0x0;
-				val= (ei->icu->flag & IPO_SELECT)!=0;
+				if(sel)
+					glColor3ub(0xFF, 0xFF, 0xFF);
+				else
+					glColor3ub(0x00, 0x00, 0x00);
+
+				val= (cur_ipo.icu->flag & IPO_SELECT)!=0;
 				if(sel != val) continue;
 			}
 			
-			cpack(col);
-			
-			bezt= ei->icu->bezt;
-			a= ei->icu->totvert;
-			while(a--) {				
+
+			/* We can't change the color in the middle of
+			 * GL_POINTS because then Blender will segfault
+			 * on TNT2 / Linux with NVidia's drivers
+			 * (at least up to ver. 4349) */
+
+			bezt= cur_ipo.icu->bezt;
+			vertices_left = cur_ipo.icu->totvert;
+
+			glBegin(GL_POINTS);
+
+			while(vertices_left--) {				
 				
-				if(ei->disptype==IPO_DISPBITS) {
+				if(cur_ipo.disptype==IPO_DISPBITS) {
 					ok= 0;
-					if(ei->flag & IPO_EDIT) {
+					if(cur_ipo.flag & IPO_EDIT) {
 						if( (bezt->f2 & 1) == sel ) ok= 1;
 					}
 					else ok= 1;
@@ -909,7 +934,7 @@
 						while(b<31) {
 							if(val & (1<<b)) {	
 								v1[1]= b+1;
-								glVertex3fv(v1);
+								glVertex2fv(v1);
 							}
 							b++;
 						}
@@ -917,28 +942,29 @@
 				}
 				else {
 					
-					if(ei->flag & IPO_EDIT) {
-						if(ei->icu->ipo==IPO_BEZ) {
+					if(cur_ipo.flag & IPO_EDIT) {
+						if(cur_ipo.icu->ipo==IPO_BEZ) {
 							if( (bezt->f1 & 1) == sel )	
-								glVertex3fv(bezt->vec[0]);
+								glVertex2fv(bezt->vec[0]);
 							if( (bezt->f3 & 1) == sel )	
-								glVertex3fv(bezt->vec[2]);
+								glVertex2fv(bezt->vec[2]);
 						}
 						if( (bezt->f2 & 1) == sel )	
-							glVertex3fv(bezt->vec[1]);
+							glVertex2fv(bezt->vec[1]);
 						
 					}
 					else {
-						glVertex3fv(bezt->vec[1]);
+						glVertex2fv(bezt->vec[1]);
 					}
 				}
 				
 				bezt++;
 			}
+
+			glEnd();
 		}
 	}
 	
-	glEnd();
 	glPointSize(1.0);
 }
 
cvs server: Diffing cre
cvs server: Diffing pub

--Boundary-00=_CkCM/GDJKD1IwND--