[Bf-blender-cvs] [ade8448ca4] temp-select-pick: Various fixes

Campbell Barton noreply at git.blender.org
Tue Mar 7 17:42:13 CET 2017


Commit: ade8448ca4106bab2446a0f0a6f6cfa7fa48fd8f
Author: Campbell Barton
Date:   Wed Mar 8 03:44:16 2017 +1100
Branches: temp-select-pick
https://developer.blender.org/rBade8448ca4106bab2446a0f0a6f6cfa7fa48fd8f

Various fixes

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

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

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

diff --git a/source/blender/gpu/intern/gpu_select.c b/source/blender/gpu/intern/gpu_select.c
index f47ba4dcde..b21b850685 100644
--- a/source/blender/gpu/intern/gpu_select.c
+++ b/source/blender/gpu/intern/gpu_select.c
@@ -46,6 +46,12 @@
 
 #include "gpu_select_private.h"
 
+enum {
+	SELECT_METHOD_GL_LEGACY = 1,
+	SELECT_METHOD_GL_QUERY = 2,
+	SELECT_METHOD_GL_PICK = 3,
+};
+
 typedef struct GPUSelectState {
 	/* To ignore selection id calls when not initialized */
 	bool select_is_active;
@@ -53,6 +59,8 @@ typedef struct GPUSelectState {
 	bool use_gpu_select;
 	/* mode of operation */
 	char mode;
+	/* internal algorithm for selection */
+	char select_method;
 	/* allow GPU_select_begin/end without drawing */
 	bool use_cache;
 } GPUSelectState;
@@ -69,18 +77,36 @@ void GPU_select_begin(unsigned int *buffer, unsigned int bufsize, const rcti *in
 	g_select_state.mode = mode;
 
 	if (!g_select_state.use_gpu_select) {
-		g_select_state.use_cache = false;
-		glSelectBuffer(bufsize, (GLuint *)buffer);
-		glRenderMode(GL_SELECT);
-		glInitNames();
-		glPushName(-1);
+		g_select_state.select_method = SELECT_METHOD_GL_LEGACY;
 	}
 	else if (ELEM(g_select_state.mode, GPU_SELECT_PICK_SORT_ALL, GPU_SELECT_PICK_SORT_NEAREST)) {
-		gpu_select_pick_begin((unsigned int (*)[4])buffer, bufsize / 4, input, mode);
+		g_select_state.select_method = SELECT_METHOD_GL_PICK;
 	}
 	else {
-		g_select_state.use_cache = false;
-		gpu_select_query_begin((unsigned int (*)[4])buffer, bufsize / 4, input, mode, oldhits);
+		g_select_state.select_method = SELECT_METHOD_GL_QUERY;
+	}
+
+	switch (g_select_state.select_method) {
+		case SELECT_METHOD_GL_LEGACY:
+		{
+			g_select_state.use_cache = false;
+			glSelectBuffer(bufsize, (GLuint *)buffer);
+			glRenderMode(GL_SELECT);
+			glInitNames();
+			glPushName(-1);
+			break;
+		}
+		case SELECT_METHOD_GL_QUERY:
+		{
+			g_select_state.use_cache = false;
+			gpu_select_query_begin((unsigned int (*)[4])buffer, bufsize / 4, input, mode, oldhits);
+			break;
+		}
+		default:  /* SELECT_METHOD_GL_PICK */
+		{
+			gpu_select_pick_begin((unsigned int (*)[4])buffer, bufsize / 4, input, mode);
+			break;
+		}
 	}
 }
 
@@ -97,15 +123,20 @@ bool GPU_select_load_id(unsigned int id)
 	if (!g_select_state.select_is_active)
 		return true;
 
-	if (!g_select_state.use_gpu_select) {
-		glLoadName(id);
-		return true;
-	}
-	else if (ELEM(g_select_state.mode, GPU_SELECT_PICK_SORT_ALL, GPU_SELECT_PICK_SORT_NEAREST)) {
-		return gpu_select_pick_load_id(id);
-	}
-	else {
-		return gpu_select_query_load_id(id);
+	switch (g_select_state.select_method) {
+		case SELECT_METHOD_GL_LEGACY:
+		{
+			glLoadName(id);
+			return true;
+		}
+		case SELECT_METHOD_GL_QUERY:
+		{
+			return gpu_select_query_load_id(id);
+		}
+		default:  /* SELECT_METHOD_GL_PICK */
+		{
+			return gpu_select_pick_load_id(id);
+		}
 	}
 }
 
@@ -117,15 +148,24 @@ bool GPU_select_load_id(unsigned int id)
 unsigned int GPU_select_end(void)
 {
 	unsigned int hits = 0;
-	if (!g_select_state.use_gpu_select) {
-		glPopName();
-		hits = glRenderMode(GL_RENDER);
-	}
-	else if (ELEM(g_select_state.mode, GPU_SELECT_PICK_SORT_ALL, GPU_SELECT_PICK_SORT_NEAREST)) {
-		hits = gpu_select_pick_end();
-	}
-	else {
-		hits = gpu_select_query_end();
+
+	switch (g_select_state.select_method) {
+		case SELECT_METHOD_GL_LEGACY:
+		{
+			glPopName();
+			hits = glRenderMode(GL_RENDER);
+			break;
+		}
+		case SELECT_METHOD_GL_QUERY:
+		{
+			hits = gpu_select_query_end();
+			break;
+		}
+		default:  /* SELECT_METHOD_GL_PICK */
+		{
+			hits = gpu_select_pick_end();
+			break;
+		}
 	}
 
 	g_select_state.select_is_active = false;
@@ -158,34 +198,24 @@ void GPU_select_cache_begin(void)
 	/* validate on GPU_select_begin, clear if not supported */
 	BLI_assert(g_select_state.use_cache == false);
 	g_select_state.use_cache = true;
+	if (g_select_state.select_method == SELECT_METHOD_GL_PICK) {
+		gpu_select_pick_cache_begin();
+	}
 }
 
 void GPU_select_cache_load_id(void)
 {
-	if (!g_select_state.use_gpu_select) {
-		/* pass */
-	}
-	else if (ELEM(g_select_state.mode, GPU_SELECT_PICK_SORT_ALL, GPU_SELECT_PICK_SORT_NEAREST)) {
+	BLI_assert(g_select_state.use_cache == true);
+	if (g_select_state.select_method == SELECT_METHOD_GL_PICK) {
 		gpu_select_pick_cache_load_id();
 	}
-	else {
-		/* pass */
-	}
 }
 
 void GPU_select_cache_end(void)
 {
-	BLI_assert(g_select_state.use_cache == true);
-
-	if (!g_select_state.use_gpu_select) {
-		/* pass */
-	}
-	else if (ELEM(g_select_state.mode, GPU_SELECT_PICK_SORT_ALL, GPU_SELECT_PICK_SORT_NEAREST)) {
+	if (g_select_state.select_method == SELECT_METHOD_GL_PICK) {
 		gpu_select_pick_cache_end();
 	}
-	else {
-		/* pass */
-	}
 	g_select_state.use_cache = false;
 }
 
diff --git a/source/blender/gpu/intern/gpu_select_pick.c b/source/blender/gpu/intern/gpu_select_pick.c
index c41c85c912..c5da48dc0c 100644
--- a/source/blender/gpu/intern/gpu_select_pick.c
+++ b/source/blender/gpu/intern/gpu_select_pick.c
@@ -45,6 +45,8 @@
 
 #include "gpu_select_private.h"
 
+// #define DEBUG_PRINT
+
 /* Alloc number for depths */
 #define ALLOC_DEPTHS 200
 
@@ -136,7 +138,7 @@ typedef struct GPUPickState {
 	/* mode of operation */
 	char mode;
 
-	/* OpenGL drawing, (use_cached == false). */
+	/* OpenGL drawing, never use when (is_cached == false). */
 	struct {
 		DepthBufCache *rect_depth;
 		/* scratch buffer, avoid allocs every time */
@@ -164,12 +166,14 @@ typedef struct GPUPickState {
 	bool use_cache;
 	bool is_cached;
 	struct {
-		/* src.clip_rect -> dst.clip_rect */
+		/* Cleanup used for iterating over both source and destination buffers:
+		 * src.clip_rect -> dst.clip_rect */
 		SubRectStride sub_rect;
 
 		ListBase bufs;
 	} cache;
 
+	/* Pickign methods */
 	union {
 		/* GPU_SELECT_PICK_SORT_ALL */
 		struct {
@@ -194,12 +198,16 @@ void gpu_select_pick_begin(
 {
 	GPUPickState *ps = &g_pick_state;
 
+#ifdef DEBUG_PRINT
+	printf("%s: mode=%d, use_cache=%d, is_cache=%d\n", __func__, mode, ps->use_cache, ps->is_cached);
+#endif
+
 	ps->bufsize = bufsize;
 	ps->buffer = buffer;
 	ps->mode = mode;
 
+	const unsigned int rect_len = BLI_rcti_size_x(input) * BLI_rcti_size_y(input);
 	ps->dst.clip_rect = *input;
-	const unsigned int rect_len = BLI_rcti_size_x(&ps->dst.clip_rect) * BLI_rcti_size_y(&ps->dst.clip_rect);
 	ps->dst.rect_len = rect_len;
 
 	/* Restrict OpenGL operations for when we don't have cache */
@@ -263,18 +271,16 @@ void gpu_select_pick_begin(
 	}
 }
 
-/* Given 2x depths, we know are different - update the depth information
- * use for both cached/uncached  */
-static void gpu_select_load_id_pass(
-        const DepthBufCache *rect_depth,
-        const DepthBufCache *rect_depth_test)
+/**
+ * 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_depth, const DepthBufCache *rect_depth_test)
 {
 	GPUPickState *ps = &g_pick_state;
 	const unsigned int prev_id = rect_depth_test->id;
 	if (g_pick_state.mode == GPU_SELECT_PICK_SORT_ALL) {
 		/* find the best depth for this pass and store in 'all.hits' */
-		const float *prev = rect_depth->buf;
-		const float *curr = rect_depth_test->buf;
 		float depth_best = FLT_MAX;
 
 #define UPDATE_DEPTH_TEST() \
@@ -285,6 +291,8 @@ static void gpu_select_load_id_pass(
 		} ((void)0)
 
 		if (ps->is_cached == false) {
+			const float *prev = rect_depth->buf;
+			const float *curr = rect_depth_test->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++) {
@@ -293,8 +301,8 @@ static void gpu_select_load_id_pass(
 		}
 		else {
 			/* same as above but different rect sizes */
-			prev += ps->cache.sub_rect.start;
-			curr += ps->cache.sub_rect.start;
+			const float *prev = rect_depth->buf + ps->cache.sub_rect.start;
+			const float *curr = rect_depth_test->buf + ps->cache.sub_rect.start;
 			for (unsigned int i = 0; i < ps->cache.sub_rect.len; i++) {
 				const float *prev_final = prev + ps->cache.sub_rect.span;
 				for (; prev < prev_final; prev++, curr++) {
@@ -319,8 +327,6 @@ static void gpu_select_load_id_pass(
 	else {
 		/* keep track each pixels ID in 'nearest.rect_id' */
 		if (prev_id != SELECT_ID_NONE) {
-			const float *prev = rect_depth->buf;
-			const float *curr = rect_depth_test->buf;
 			unsigned int *id_ptr = ps->nearest.rect_id;
 
 #define UPDATE_ID_TEST() \
@@ -329,6 +335,8 @@ static void gpu_select_load_id_pass(
 			} ((void)0)
 
 			if (ps->is_cached == false) {
+				const float *prev = rect_depth->buf;
+				const float *curr = rect_depth_test->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++) {
@@ -337,8 +345,8 @@ static void gpu_select_load_id_pass(
 			}
 			else {
 				/* same as above but different rect sizes */
-				prev += ps->cache.sub_rect.start;
-				curr += ps->cache.sub_rect.start;
+				const float *prev = rect_depth->buf + ps->cache.sub_rect.start;
+				const float *curr = rect_depth_test->buf + ps->cache.sub_rect.start;
 				for (unsigned int i = 0; i < ps->cache.sub_rect.len; i++) {
 					const float *prev_final = prev + ps->cache.sub_rect.span;
 					for (; prev < prev_final; prev++, curr++, id_ptr++) {
@@ -461,8 +469,7 @@ unsigned int gpu_select_pick_end(void)
 			}
 			else {
 				/* same as above but different rect sizes */
-				unsigned int i_src = 0, i_dst = 0;
-				i_src += ps->cache.sub_rect.start;
+				unsigned int i_src = ps->cache.sub_rect.start, i_dst = 0;
 				for (unsigned int j = 0; j < ps->cache.sub_rect.len; j++) {
 					const unsigned int i_src_final = i_src + ps->cache.sub_rect.span;
 					for (; i_src < i_src_final; i_src++, i_dst++) {
@@ -515,13 +522,8 @@ unsigned int gpu_select_pick_end(void)
 
 	MEM_freeN(depth_data);
 
-	if (ps->gl.rect_depth != NULL) {
-		MEM_freeN(ps->gl.rect_depth);
-	}
-	MEM_freeN(ps->gl.rect_depth_test);
-
-	ps->gl.rect_depth = NULL;
-	ps->gl.rect_depth_test = NULL;
+	MEM_SAFE_FREE(ps->gl.rect_depth);
+	MEM_SAFE_FREE(ps->gl.rect_depth_test);
 
 	if (g_pick_state.mode 

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list