Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2010-10-21 11:38:09 +0400
committerCampbell Barton <ideasman42@gmail.com>2010-10-21 11:38:09 +0400
commit0ec320783ec5867cc9c29fff9a09a4d8f1b7fbdf (patch)
tree4021d8405bf6d875f7a50ed9eccbd52df08b29a4 /source
parentec6b9948ace08c3925486a009147af2fe0a6e4f0 (diff)
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.
Diffstat (limited to 'source')
-rw-r--r--source/blender/editors/include/ED_view3d.h1
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c68
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c117
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h2
4 files changed, 96 insertions, 92 deletions
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index f5a84aa4c19..fe024be29e0 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -63,6 +63,7 @@ typedef struct ViewContext {
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];
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 1d18f484ae0..7722ca5605b 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -1569,7 +1569,51 @@ static void draw_dupli_objects(Scene *scene, ARegion *ar, View3D *v3d, Base *bas
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 @@ void view3d_update_depths(ARegion *ar)
}
}
+/* 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;
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index dc75efcc5ca..a5cca6341f6 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -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 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
/* 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,38 +1683,19 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
/* 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;
- }
-
- 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;
+ /* 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);
}
- 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 @@ void VIEW3D_OT_enable_manipulator(wmOperatorType *ot)
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;
-
- /* 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;
- }
- }
- }
- }
+ view3d_update_depths_rect(ar, &depth_temp, &rect);
+ depth_close= view3d_depth_near(&depth_temp);
- depth= depth_close;
- }
+ MEM_freeN(depth_temp.depths);
- 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(Scene *scene, ARegion *ar, View3D *v3d, short *mval, float mou
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 @@ int view_autodist_init(Scene *scene, ARegion *ar, View3D *v3d, int mode) //, flo
break;
}
- /* force updating */
- if (rv3d->depths) {
- rv3d->depths->damaged = 1;
- }
-
- view3d_update_depths(ar);
return 1;
}
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index d6d8fddd442..e81d0b87589 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -131,6 +131,8 @@ void add_view3d_after(ListBase *lb, Base *base, int flag);
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);