[Bf-blender-cvs] [564532510fc] temp-select-pick: Modified method of cycling selection

Campbell Barton noreply at git.blender.org
Wed Mar 8 18:38:56 CET 2017


Commit: 564532510fc14c4fe3e73d1342162e69d8df5fcc
Author: Campbell Barton
Date:   Thu Mar 9 04:41:40 2017 +1100
Branches: temp-select-pick
https://developer.blender.org/rB564532510fc14c4fe3e73d1342162e69d8df5fcc

Modified method of cycling selection

===================================================================

M	source/blender/gpu/intern/gpu_select_pick.c

===================================================================

diff --git a/source/blender/gpu/intern/gpu_select_pick.c b/source/blender/gpu/intern/gpu_select_pick.c
index 80d3e6122a8..23531c1d4fd 100644
--- a/source/blender/gpu/intern/gpu_select_pick.c
+++ b/source/blender/gpu/intern/gpu_select_pick.c
@@ -48,7 +48,7 @@
 
 #include "gpu_select_private.h"
 
-#define DEBUG_PRINT
+/* #define DEBUG_PRINT */
 
 /* Alloc number for depths */
 #define ALLOC_DEPTHS 200
@@ -116,12 +116,49 @@ static DepthBufCache *depth_buf_malloc(unsigned int rect_len)
 	return rect;
 }
 
+static bool depth_buf_rect_depth_any(
+        const DepthBufCache *rect_depth,
+        unsigned int rect_len)
+{
+	const depth_t *curr = rect_depth->buf;
+	for (unsigned int i = 0; i < rect_len; i++, curr++) {
+		if (*curr != DEPTH_MAX) {
+			return true;
+		}
+	}
+	return false;
+}
+
+static bool depth_buf_subrect_depth_any(
+        const DepthBufCache *rect_depth,
+        const SubRectStride *sub_rect)
+{
+	const depth_t *curr = rect_depth->buf + sub_rect->start;
+	for (unsigned int i = 0; i < sub_rect->span_len; i++) {
+		const depth_t *curr_end = curr + sub_rect->span;
+		for (; curr < curr_end; curr++, curr++) {
+			if (*curr != DEPTH_MAX) {
+				return true;
+			}
+		}
+		curr += sub_rect->skip;
+	}
+	return false;
+}
+
+static bool depth_buf_rect_not_equal(
+        const DepthBufCache *rect_depth_a, const DepthBufCache *rect_depth_b,
+        unsigned int rect_len)
+{
+	return memcmp(rect_depth_a->buf, rect_depth_b->buf, rect_len * sizeof(depth_t)) != 0;
+}
+
 /**
  * Both buffers are the same size, just check if the sub-rect contains any differences.
  */
-static bool depth_buf_subrect_equal(
-        const SubRectStride *sub_rect,
-        const DepthBufCache *rect_src, const DepthBufCache *rect_dst)
+static bool depth_buf_subrect_not_equal(
+        const DepthBufCache *rect_src, const DepthBufCache *rect_dst,
+        const SubRectStride *sub_rect)
 {
 	/* same as above but different rect sizes */
 	const depth_t *prev = rect_src->buf + sub_rect->start;
@@ -130,13 +167,13 @@ static bool depth_buf_subrect_equal(
 		const depth_t *curr_end = curr + sub_rect->span;
 		for (; curr < curr_end; prev++, curr++) {
 			if (*prev != *curr) {
-				return false;
+				return true;
 			}
 		}
 		prev += sub_rect->skip;
 		curr += sub_rect->skip;
 	}
-	return true;
+	return false;
 }
 
 /* ----------------------------------------------------------------------------
@@ -306,13 +343,14 @@ void gpu_select_pick_begin(
 		ps->gl.rect_depth = depth_buf_malloc(rect_len);
 
 		/* set initial 'far' value */
-#if 1
+#if 0
 		GPU_ASSERT_NO_GL_ERRORS(__func__);
 		glReadPixels(UNPACK4(ps->gl.clip_readpixels), GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, ps->gl.rect_depth->buf);
 		GPU_ASSERT_NO_GL_ERRORS(__func__);
-		printf("%u\n", ps->gl.rect_depth->buf[0]);
 #else
-		copy_vn_fl(ps->gl.rect_depth->buf, rect_len, DEPTH_MAX);
+		for (unsigned int i = 0; i < rect_len; i++) {
+			ps->gl.rect_depth->buf[i] = DEPTH_MAX;
+		}
 #endif
 
 		ps->gl.is_init = false;
@@ -342,19 +380,61 @@ void gpu_select_pick_begin(
  * Given 2x depths, we know are different - update the depth information
  * use for both cached/uncached depth buffers.
  */
-static void gpu_select_load_id_pass(const DepthBufCache *rect_prev, const DepthBufCache *rect_curr)
+static void gpu_select_load_id_pass_all(const DepthBufCache *rect_curr)
 {
 	GPUPickState *ps = &g_pick_state;
 	const unsigned int id = rect_curr->id;
-	if (g_pick_state.mode == GPU_SELECT_PICK_SORT_ALL) {
-		/* find the best depth for this pass and store in 'all.hits' */
-		depth_t depth_best = DEPTH_MAX;
+	/* find the best depth for this pass and store in 'all.hits' */
+	depth_t depth_best = DEPTH_MAX;
+
+#define EVAL_TEST() \
+	if (depth_best > *curr) { \
+		depth_best = *curr; \
+	} ((void)0)
+
+	if (ps->is_cached == false) {
+		const depth_t *curr = rect_curr->buf;
+		BLI_assert(ps->src.rect_len == ps->dst.rect_len);
+		const unsigned int rect_len = ps->src.rect_len;
+		for (unsigned int i = 0; i < rect_len; i++, curr++) {
+			EVAL_TEST();
+		}
+	}
+	else {
+		/* same as above but different rect sizes */
+		const depth_t *curr = rect_curr->buf + ps->cache.sub_rect.start;
+		for (unsigned int i = 0; i < ps->cache.sub_rect.span_len; i++) {
+			const depth_t *curr_end = curr + ps->cache.sub_rect.span;
+			for (; curr < curr_end; curr++) {
+				EVAL_TEST();
+			}
+			curr += ps->cache.sub_rect.skip;
+		}
+	}
+
+#undef EVAL_TEST
+
+	/* ensure enough space */
+	if (UNLIKELY(ps->all.hits_len == ps->all.hits_len_alloc)) {
+		ps->all.hits_len_alloc += ALLOC_DEPTHS;
+		ps->all.hits = MEM_reallocN(ps->all.hits, ps->all.hits_len_alloc * sizeof(*ps->all.hits));
+	}
+	DepthID *d = &ps->all.hits[ps->all.hits_len++];
+	d->id = id;
+	d->depth = depth_best;
+}
+
+static void gpu_select_load_id_pass_nearest(const DepthBufCache *rect_prev, const DepthBufCache *rect_curr)
+{
+	GPUPickState *ps = &g_pick_state;
+	const unsigned int id = rect_curr->id;
+	/* keep track each pixels ID in 'nearest.rect_id' */
+	if (id != SELECT_ID_NONE) {
+		unsigned int *id_ptr = ps->nearest.rect_id;
 
 #define EVAL_TEST() \
 		if (*curr != *prev) { \
-			if (depth_best > *curr) { \
-				depth_best = *curr; \
-			} \
+			*id_ptr = id; \
 		} ((void)0)
 
 		if (ps->is_cached == false) {
@@ -362,7 +442,7 @@ static void gpu_select_load_id_pass(const DepthBufCache *rect_prev, const DepthB
 			const depth_t *curr = rect_curr->buf;
 			BLI_assert(ps->src.rect_len == ps->dst.rect_len);
 			const unsigned int rect_len = ps->src.rect_len;
-			for (unsigned int i = 0; i < rect_len; i++, curr++, prev++) {
+			for (unsigned int i = 0; i < rect_len; i++, curr++, prev++, id_ptr++) {
 				EVAL_TEST();
 			}
 		}
@@ -372,7 +452,7 @@ static void gpu_select_load_id_pass(const DepthBufCache *rect_prev, const DepthB
 			const depth_t *curr = rect_curr->buf + ps->cache.sub_rect.start;
 			for (unsigned int i = 0; i < ps->cache.sub_rect.span_len; i++) {
 				const depth_t *curr_end = curr + ps->cache.sub_rect.span;
-				for (; curr < curr_end; prev++, curr++) {
+				for (; curr < curr_end; prev++, curr++, id_ptr++) {
 					EVAL_TEST();
 				}
 				prev += ps->cache.sub_rect.skip;
@@ -381,55 +461,10 @@ static void gpu_select_load_id_pass(const DepthBufCache *rect_prev, const DepthB
 		}
 
 #undef EVAL_TEST
-
-		/* ensure enough space */
-		if (UNLIKELY(ps->all.hits_len == ps->all.hits_len_alloc)) {
-			ps->all.hits_len_alloc += ALLOC_DEPTHS;
-			ps->all.hits = MEM_reallocN(ps->all.hits, ps->all.hits_len_alloc * sizeof(*ps->all.hits));
-		}
-		DepthID *d = &ps->all.hits[ps->all.hits_len++];
-		d->id = id;
-		d->depth = depth_best;
-	}
-	else {
-		/* keep track each pixels ID in 'nearest.rect_id' */
-		if (id != SELECT_ID_NONE) {
-			unsigned int *id_ptr = ps->nearest.rect_id;
-
-#define EVAL_TEST() \
-			if (*curr != *prev) { \
-				*id_ptr = id; \
-			} ((void)0)
-
-			if (ps->is_cached == false) {
-				const depth_t *prev = rect_prev->buf;
-				const depth_t *curr = rect_curr->buf;
-				BLI_assert(ps->src.rect_len == ps->dst.rect_len);
-				const unsigned int rect_len = ps->src.rect_len;
-				for (unsigned int i = 0; i < rect_len; i++, curr++, prev++, id_ptr++) {
-					EVAL_TEST();
-				}
-			}
-			else {
-				/* same as above but different rect sizes */
-				const depth_t *prev = rect_prev->buf + ps->cache.sub_rect.start;
-				const depth_t *curr = rect_curr->buf + ps->cache.sub_rect.start;
-				for (unsigned int i = 0; i < ps->cache.sub_rect.span_len; i++) {
-					const depth_t *curr_end = curr + ps->cache.sub_rect.span;
-					for (; curr < curr_end; prev++, curr++, id_ptr++) {
-						EVAL_TEST();
-					}
-					prev += ps->cache.sub_rect.skip;
-					curr += ps->cache.sub_rect.skip;
-				}
-			}
-
-#undef EVAL_TEST
-
-		}
 	}
 }
 
+
 bool gpu_select_pick_load_id(unsigned int id)
 {
 	GPUPickState *ps = &g_pick_state;
@@ -438,12 +473,25 @@ bool gpu_select_pick_load_id(unsigned int id)
 		GPU_ASSERT_NO_GL_ERRORS(__func__);
 		glReadPixels(UNPACK4(ps->gl.clip_readpixels), GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, ps->gl.rect_depth_test->buf);
 		GPU_ASSERT_NO_GL_ERRORS(__func__);
-		/* perform initial memcmp since most cases the array remains unchanged  */
-		if (memcmp(ps->gl.rect_depth->buf, ps->gl.rect_depth_test->buf, rect_len * sizeof(depth_t)) != 0) {
-			ps->gl.rect_depth_test->id = ps->gl.prev_id;
-
-			gpu_select_load_id_pass(ps->gl.rect_depth, ps->gl.rect_depth_test);
+		/* perform initial check since most cases the array remains unchanged  */
+
+		bool do_pass = false;
+		if (g_pick_state.mode == GPU_SELECT_PICK_SORT_ALL) {
+			if (depth_buf_rect_depth_any(ps->gl.rect_depth_test, rect_len)) {
+				ps->gl.rect_depth_test->id = ps->gl.prev_id;
+				gpu_select_load_id_pass_all(ps->gl.rect_depth_test);
+				do_pass = true;
+			}
+		}
+		else {
+			if (depth_buf_rect_not_equal(ps->gl.rect_depth, ps->gl.rect_depth_test, rect_len)) {
+				ps->gl.rect_depth_test->id = ps->gl.prev_id;
+				gpu_select_load_id_pass_nearest(ps->gl.rect_depth, ps->gl.rect_depth_test);
+				do_pass = true;
+			}
+		}
 
+		if (do_pass) {
 			/* Store depth in cache */
 			if (ps->use_cache) {
 				BLI_addtail(&ps->cache.bufs, ps->gl.rect_depth);
@@ -451,6 +499,11 @@ bool gpu_select_pick_load_id(unsigned int id)
 			}
 
 			SWAP(DepthBufCache *, ps->gl.rect_depth, ps->gl.rect_depth_test);
+
+			if (g_pick_state.mode == GPU_SELECT_PICK_SORT_ALL) {
+				/* we want new depths every time */
+				glClear(GL_DEPTH_BUFFER_BIT);
+			}
 		}
 	}
 
@@ -662,8 +715,15 @@ void gpu_select_pick_cache_load_id(void)
 		if (rect_depth->next != NULL) {
 			/* we know the buffers differ, but this sub-region may not.
 			 * double check before adding an id-pass */
-			if (!depth_buf_subrect_equal(&ps->cache.sub_rect, rect_depth, rect_depth->next)) {
-				gpu_select_load_id_pass(rect_depth, rect_depth->next);
+			if (g_pick_state.mode == GPU_SELECT_PICK_SORT_ALL) {
+				if (depth_buf_subrect_depth_any(rect_depth->next, &ps->cache.sub_rect)) {
+					gpu_select_load_id_pass_all(rect_depth->next);
+				}
+			}
+			else {
+				if (depth_buf_subrect_not_equal(rect_depth, rect_depth->next, &ps->cache.sub_rect)) {
+					gpu_select_load_id_pass_nearest(rect_depth, rect_depth->next);
+				}
 			}
 		}
 	}




More information about the Bf-blender-cvs mailing list