[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [32626] trunk/blender/source/blender/ editors: fix [#24339] Auto Depth, makes viewport lag.

Campbell Barton ideasman42 at gmail.com
Thu Oct 21 09:38:09 CEST 2010


Revision: 32626
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=32626
Author:   campbellbarton
Date:     2010-10-21 09:38:09 +0200 (Thu, 21 Oct 2010)

Log Message:
-----------
fix [#24339] Auto Depth, makes viewport lag.

The problem is the opensource nvidia nouveau drivers are slow running glReadPixels(), was hanging on memcpy().
However for autodepth its not needed to update the entire 3D view depths, so added view3d_update_depths_rect() to get the depths for a smaller area.

Modified Paths:
--------------
    trunk/blender/source/blender/editors/include/ED_view3d.h
    trunk/blender/source/blender/editors/space_view3d/view3d_draw.c
    trunk/blender/source/blender/editors/space_view3d/view3d_edit.c
    trunk/blender/source/blender/editors/space_view3d/view3d_intern.h

Modified: trunk/blender/source/blender/editors/include/ED_view3d.h
===================================================================
--- trunk/blender/source/blender/editors/include/ED_view3d.h	2010-10-21 07:29:15 UTC (rev 32625)
+++ trunk/blender/source/blender/editors/include/ED_view3d.h	2010-10-21 07:38:09 UTC (rev 32626)
@@ -63,6 +63,7 @@
 
 typedef struct ViewDepths {
 	unsigned short w, h;
+	short x, y; /* only for temp use for sub-rects, added to ar->winx/y */
 	float *depths;
 	double depth_range[2];
 	

Modified: trunk/blender/source/blender/editors/space_view3d/view3d_draw.c
===================================================================
--- trunk/blender/source/blender/editors/space_view3d/view3d_draw.c	2010-10-21 07:29:15 UTC (rev 32625)
+++ trunk/blender/source/blender/editors/space_view3d/view3d_draw.c	2010-10-21 07:38:09 UTC (rev 32626)
@@ -1569,7 +1569,51 @@
 	draw_dupli_objects_color(scene, ar, v3d, base, color);
 }
 
+void view3d_update_depths_rect(ARegion *ar, ViewDepths *d, rcti *rect)
+{
+	int x, y, w, h;	
+	/* clamp rect by area */
+	
+	/* Constrain rect to depth bounds */
+	if (rect->xmin < 0) rect->xmin = 0;
+	if (rect->ymin < 0) rect->ymin = 0;
+	if (rect->xmax >= ar->winx) rect->xmax = ar->winx-1;
+	if (rect->ymax >= ar->winy) rect->ymax = ar->winy-1;
 
+	/* assign values to compare with the ViewDepths */
+	x= ar->winrct.xmin + rect->xmin;
+	y= ar->winrct.ymin + rect->ymin;
+
+	w= rect->xmax - rect->xmin;
+	h= rect->ymax - rect->ymin;
+
+	if(	d->w != w ||
+		d->h != h ||
+		d->x != x ||
+		d->y != y ||
+		d->depths==NULL
+	) {
+		d->x= x;
+		d->y= y;
+		d->w= w;
+		d->h= h;
+
+		if(d->depths)
+			MEM_freeN(d->depths);
+
+		d->depths= MEM_mallocN(sizeof(float)*d->w*d->h,"View depths Subset");
+		
+		d->damaged= 1;		
+	}
+
+	if(d->damaged) {
+		glReadPixels(ar->winrct.xmin+d->x,ar->winrct.ymin+d->y, d->w,d->h, GL_DEPTH_COMPONENT,GL_FLOAT, d->depths);
+		glGetDoublev(GL_DEPTH_RANGE,d->depth_range);
+		d->damaged= 0;
+	}
+}
+
+/* note, with nouveau drivers the glReadPixels() is very slow. [#24339] */
 void view3d_update_depths(ARegion *ar)
 {
 	RegionView3D *rv3d= ar->regiondata;
@@ -1600,6 +1644,30 @@
 	}
 }
 
+/* utility function to find the closest Z value, use for autodepth */
+float view3d_depth_near(ViewDepths *d)
+{
+	/* convert to float for comparisons */
+	const float near= (float)d->depth_range[0];
+	const float far_real= (float)d->depth_range[1];
+	float far= far_real;
+
+	const float *depths= d->depths;
+	float depth= FLT_MAX;
+	int i= d->w * d->h;
+
+	/* far is both the starting 'far' value
+	 * and the closest value found. */	
+	while(i--) {
+		depth= *depths++;
+		if((depth < far) && (depth > near)) {
+			far= depth;
+		}
+	}
+
+	return far == far_real ? FLT_MAX : far;
+}
+
 void draw_depth_gpencil(Scene *scene, ARegion *ar, View3D *v3d)
 {
 	short zbuf= v3d->zbuf;

Modified: trunk/blender/source/blender/editors/space_view3d/view3d_edit.c
===================================================================
--- trunk/blender/source/blender/editors/space_view3d/view3d_edit.c	2010-10-21 07:29:15 UTC (rev 32625)
+++ trunk/blender/source/blender/editors/space_view3d/view3d_edit.c	2010-10-21 07:38:09 UTC (rev 32626)
@@ -63,6 +63,7 @@
 #include "ED_screen.h"
 #include "ED_transform.h"
 #include "ED_mesh.h"
+#include "ED_view3d.h"
 
 
 #include "PIL_time.h" /* smoothview */
@@ -1667,10 +1668,8 @@
 
 	/* ZBuffer depth vars */
 	bglMats mats;
-	float depth, depth_close= FLT_MAX;
-	int had_depth = 0;
+	float depth_close= FLT_MAX;
 	double cent[2],  p[3];
-	int xs, ys;
 
 	/* note; otherwise opengl won't work */
 	view3d_operator_needs_opengl(C);
@@ -1684,39 +1683,20 @@
 	/* Get Z Depths, needed for perspective, nice for ortho */
 	bgl_get_mats(&mats);
 	draw_depth(scene, ar, v3d, NULL);
+	
+	{
+		/* avoid allocating the whole depth buffer */
+		ViewDepths depth_temp= {0};
 
-	/* force updating */
-	if (rv3d->depths) {
-		had_depth = 1;
-		rv3d->depths->damaged = 1;
+		/* avoid view3d_update_depths() for speed. */
+		view3d_update_depths_rect(ar, &depth_temp, &rect);
+	
+		/* find the closest Z pixel */
+		depth_close= view3d_depth_near(&depth_temp);
+	
+		MEM_freeN(depth_temp.depths);
 	}
 
-	view3d_update_depths(ar);
-
-	/* Constrain rect to depth bounds */
-	if (rect.xmin < 0) rect.xmin = 0;
-	if (rect.ymin < 0) rect.ymin = 0;
-	if (rect.xmax >= rv3d->depths->w) rect.xmax = rv3d->depths->w-1;
-	if (rect.ymax >= rv3d->depths->h) rect.ymax = rv3d->depths->h-1;
-
-	/* Find the closest Z pixel */
-	for (xs=rect.xmin; xs < rect.xmax; xs++) {
-		for (ys=rect.ymin; ys < rect.ymax; ys++) {
-			depth= rv3d->depths->depths[ys*rv3d->depths->w+xs];
-			if(depth < rv3d->depths->depth_range[1] && depth > rv3d->depths->depth_range[0]) {
-				if (depth_close > depth) {
-					depth_close = depth;
-				}
-			}
-		}
-	}
-
-	if (had_depth==0) {
-		MEM_freeN(rv3d->depths->depths);
-		rv3d->depths->depths = NULL;
-	}
-	rv3d->depths->damaged = 1;
-
 	cent[0] = (((double)rect.xmin)+((double)rect.xmax)) / 2;
 	cent[1] = (((double)rect.ymin)+((double)rect.ymax)) / 2;
 
@@ -2574,88 +2554,49 @@
 
 static float view_autodist_depth_margin(ARegion *ar, short *mval, int margin)
 {
-	RegionView3D *rv3d= ar->regiondata;
-	float depth= FLT_MAX;
+	ViewDepths depth_temp= {0};
+	rcti rect;
+	float depth_close;
 
 	if(margin==0) {
-		if (mval[0] < 0) return 0;
-		if (mval[1] < 0) return 0;
-		if (mval[0] >= rv3d->depths->w) return 0;
-		if (mval[1] >= rv3d->depths->h) return 0;
-
 		/* Get Z Depths, needed for perspective, nice for ortho */
-		depth= rv3d->depths->depths[mval[1]*rv3d->depths->w+mval[0]];
-		if(depth >= rv3d->depths->depth_range[1] || depth <= rv3d->depths->depth_range[0]) {
-			depth= FLT_MAX;
-		}
+		rect.xmin= mval[0];
+		rect.ymin= mval[1];
+		rect.xmax= mval[0] + 1;
+		rect.ymax= mval[1] + 1;
 	}
 	else {
-		rcti rect;
-		float depth_close= FLT_MAX;
-		int xs, ys;
-
 		rect.xmax = mval[0] + margin;
 		rect.ymax = mval[1] + margin;
 
 		rect.xmin = mval[0] - margin;
 		rect.ymin = mval[1] - margin;
+	}
 
-		/* Constrain rect to depth bounds */
-		if (rect.xmin < 0) rect.xmin = 0;
-		if (rect.ymin < 0) rect.ymin = 0;
-		if (rect.xmax >= rv3d->depths->w) rect.xmax = rv3d->depths->w-1;
-		if (rect.ymax >= rv3d->depths->h) rect.ymax = rv3d->depths->h-1;
+	view3d_update_depths_rect(ar, &depth_temp, &rect);
+	depth_close= view3d_depth_near(&depth_temp);
 
-		/* Find the closest Z pixel */
-		for (xs=rect.xmin; xs < rect.xmax; xs++) {
-			for (ys=rect.ymin; ys < rect.ymax; ys++) {
-				depth= rv3d->depths->depths[ys*rv3d->depths->w+xs];
-				if(depth < rv3d->depths->depth_range[1] && depth > rv3d->depths->depth_range[0]) {
-					if (depth_close > depth) {
-						depth_close = depth;
-					}
-				}
-			}
-		}
+	MEM_freeN(depth_temp.depths);
 
-		depth= depth_close;
-	}
-
-	return depth;
+	return depth_close;	
 }
 
 /* XXX todo Zooms in on a border drawn by the user */
 int view_autodist(Scene *scene, ARegion *ar, View3D *v3d, short *mval, float mouse_worldloc[3] ) //, float *autodist )
 {
-	RegionView3D *rv3d= ar->regiondata;
 	bglMats mats; /* ZBuffer depth vars */
 	float depth_close= FLT_MAX;
-	int had_depth = 0;
 	double cent[2],  p[3];
 
 	/* Get Z Depths, needed for perspective, nice for ortho */
 	bgl_get_mats(&mats);
 	draw_depth(scene, ar, v3d, NULL);
 
-	/* force updating */
-	if (rv3d->depths) {
-		had_depth = 1;
-		rv3d->depths->damaged = 1;
-	}
-
-	view3d_update_depths(ar);
-
 	depth_close= view_autodist_depth_margin(ar, mval, 4);
 
 	if (depth_close==FLT_MAX)
 		return 0;
 
-	if (had_depth==0) {
-		MEM_freeN(rv3d->depths->depths);
-		rv3d->depths->depths = NULL;
-	}
-	rv3d->depths->damaged = 1;
-
 	cent[0] = (double)mval[0];
 	cent[1] = (double)mval[1];
 
@@ -2670,8 +2611,6 @@
 
 int view_autodist_init(Scene *scene, ARegion *ar, View3D *v3d, int mode) //, float *autodist )
 {
-	RegionView3D *rv3d= ar->regiondata;
-
 	/* Get Z Depths, needed for perspective, nice for ortho */
 	switch(mode) {
 	case 0:
@@ -2682,12 +2621,6 @@
 		break;
 	}
 
-	/* force updating */
-	if (rv3d->depths) {
-		rv3d->depths->damaged = 1;
-	}
-
-	view3d_update_depths(ar);
 	return 1;
 }
 

Modified: trunk/blender/source/blender/editors/space_view3d/view3d_intern.h
===================================================================
--- trunk/blender/source/blender/editors/space_view3d/view3d_intern.h	2010-10-21 07:29:15 UTC (rev 32625)
+++ trunk/blender/source/blender/editors/space_view3d/view3d_intern.h	2010-10-21 07:38:09 UTC (rev 32626)
@@ -131,6 +131,8 @@
 void circf(float x, float y, float rad);
 void circ(float x, float y, float rad);
 void view3d_update_depths(struct ARegion *ar);
+void view3d_update_depths_rect(struct ARegion *ar, struct ViewDepths *d, struct rcti *rect);
+float view3d_depth_near(struct ViewDepths *d);
 
 /* view3d_select.c */
 void VIEW3D_OT_select(struct wmOperatorType *ot);





More information about the Bf-blender-cvs mailing list