[Bf-blender-cvs] [8b2640f0885] blender2.8: Draw Manager: fix draw-state switching logic

Campbell Barton noreply at git.blender.org
Wed May 3 00:20:15 CEST 2017


Commit: 8b2640f08858f200eda84e19f74ed234a2833eb2
Author: Campbell Barton
Date:   Wed May 3 08:20:11 2017 +1000
Branches: blender2.8
https://developer.blender.org/rB8b2640f08858f200eda84e19f74ed234a2833eb2

Draw Manager: fix draw-state switching logic

Changing states didn't properly reset between shading groups
causing the GL state to be wrong based on draw order.

States are now only set when changed.

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

M	source/blender/draw/intern/DRW_render.h
M	source/blender/draw/intern/draw_common.c
M	source/blender/draw/intern/draw_manager.c
M	source/blender/draw/intern/draw_view.c
M	source/blender/draw/modes/edit_armature_mode.c
M	source/blender/draw/modes/object_mode.c

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

diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index 15ed8aeb979..53fbd22e7ab 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -249,6 +249,7 @@ typedef enum {
 	DRW_STATE_TEST_STENCIL_ACTIVE  = (1 << 17),
 } DRWState;
 
+
 DRWShadingGroup *DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass);
 DRWShadingGroup *DRW_shgroup_material_create(struct GPUMaterial *material, DRWPass *pass);
 DRWShadingGroup *DRW_shgroup_material_instance_create(struct GPUMaterial *material, DRWPass *pass, struct Batch *geom);
@@ -267,7 +268,7 @@ void DRW_shgroup_call_dynamic_add_array(DRWShadingGroup *shgroup, const void *at
 	DRW_shgroup_call_dynamic_add_array(shgroup, NULL, 0); \
 } while (0)
 
-void DRW_shgroup_state_set(DRWShadingGroup *shgroup, DRWState state);
+void DRW_shgroup_state_enable(DRWShadingGroup *shgroup, DRWState state);
 void DRW_shgroup_attrib_int(DRWShadingGroup *shgroup, const char *name, int size);
 void DRW_shgroup_attrib_float(DRWShadingGroup *shgroup, const char *name, int size);
 
diff --git a/source/blender/draw/intern/draw_common.c b/source/blender/draw/intern/draw_common.c
index e50d21e0eb0..c266c45e71c 100644
--- a/source/blender/draw/intern/draw_common.c
+++ b/source/blender/draw/intern/draw_common.c
@@ -131,7 +131,7 @@ DRWShadingGroup *shgroup_dynpoints_uniform_color(DRWPass *pass, float color[4],
 	DRWShadingGroup *grp = DRW_shgroup_point_batch_create(sh, pass);
 	DRW_shgroup_uniform_vec4(grp, "color", color, 1);
 	DRW_shgroup_uniform_float(grp, "size", size, 1);
-	DRW_shgroup_state_set(grp, DRW_STATE_POINT);
+	DRW_shgroup_state_enable(grp, DRW_STATE_POINT);
 
 	return grp;
 }
@@ -152,7 +152,7 @@ DRWShadingGroup *shgroup_groundpoints_uniform_color(DRWPass *pass, float color[4
 
 	DRWShadingGroup *grp = DRW_shgroup_point_batch_create(sh, pass);
 	DRW_shgroup_uniform_vec4(grp, "color", color, 1);
-	DRW_shgroup_state_set(grp, DRW_STATE_POINT);
+	DRW_shgroup_state_enable(grp, DRW_STATE_POINT);
 
 	return grp;
 }
@@ -167,7 +167,7 @@ DRWShadingGroup *shgroup_instance_screenspace(DRWPass *pass, struct Batch *geom,
 	DRW_shgroup_uniform_float(grp, "size", size, 1);
 	DRW_shgroup_uniform_float(grp, "pixel_size", DRW_viewport_pixelsize_get(), 1);
 	DRW_shgroup_uniform_vec3(grp, "screen_vecs[0]", DRW_viewport_screenvecs_get(), 2);
-	DRW_shgroup_state_set(grp, DRW_STATE_STIPPLE_3);
+	DRW_shgroup_state_enable(grp, DRW_STATE_STIPPLE_3);
 
 	return grp;
 }
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 06cebab1c72..196f239119e 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -196,7 +196,7 @@ struct DRWShadingGroup {
 	GPUShader *shader;               /* Shader to bind */
 	DRWInterface *interface;         /* Uniforms pointers */
 	ListBase calls;                  /* DRWCall or DRWCallDynamic depending of type */
-	DRWState state;                  /* State changes for this batch only */
+	DRWState state_extra;            /* State changes for this batch only (or'd with the pass's state) */
 	int type;
 
 	Batch *instance_geom;  /* Geometry to instance */
@@ -229,6 +229,9 @@ static struct DRWGlobalState {
 	ListBase bound_texs;
 	int tex_bind_id;
 
+	/* Managed by `DRW_state_set`, `DRW_state_reset` */
+	DRWState state;
+
 	/* Per viewport */
 	GPUViewport *viewport;
 	struct GPUFrameBuffer *default_framebuffer;
@@ -608,7 +611,7 @@ DRWShadingGroup *DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass)
 	shgroup->type = DRW_SHG_NORMAL;
 	shgroup->shader = shader;
 	shgroup->interface = DRW_interface_create(shader);
-	shgroup->state = 0;
+	shgroup->state_extra = 0;
 	shgroup->batch_geom = NULL;
 	shgroup->instance_geom = NULL;
 
@@ -797,9 +800,10 @@ void DRW_shgroup_call_dynamic_add_array(DRWShadingGroup *shgroup, const void *at
 
 /* Make sure you know what you do when using this,
  * State is not revert back at the end of the shgroup */
-void DRW_shgroup_state_set(DRWShadingGroup *shgroup, DRWState state)
+
+void DRW_shgroup_state_enable(DRWShadingGroup *shgroup, DRWState state)
 {
-	shgroup->state = state;
+	shgroup->state_extra |= state;
 }
 
 void DRW_shgroup_attrib_float(DRWShadingGroup *shgroup, const char *name, int size)
@@ -1027,127 +1031,226 @@ void DRW_pass_free(DRWPass *pass)
 /** \name Draw (DRW_draw)
  * \{ */
 
-static void set_state(DRWState flag, const bool reset)
+static void DRW_state_set(DRWState state)
 {
-	/* TODO Keep track of the state and only revert what is needed */
+	if (DST.state == state) {
+		return;
+	}
 
-	if (reset) {
-		/* Depth Write */
-		if (flag & DRW_STATE_WRITE_DEPTH)
-			glDepthMask(GL_TRUE);
-		else
-			glDepthMask(GL_FALSE);
 
-		/* Color Write */
-		if (flag & DRW_STATE_WRITE_COLOR)
-			glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-		else
-			glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+#define CHANGED_TO(f) \
+	((DST.state & (f)) ? \
+		((state & (f)) ?  0 : -1) : \
+		((state & (f)) ?  1 :  0))
 
-		/* Backface Culling */
-		if (flag & DRW_STATE_CULL_BACK ||
-		    flag & DRW_STATE_CULL_FRONT)
-		{
-			glEnable(GL_CULL_FACE);
+#define CHANGED_ANY(f) \
+	((DST.state & (f)) != (state & (f)))
 
-			if (flag & DRW_STATE_CULL_BACK)
-				glCullFace(GL_BACK);
-			else if (flag & DRW_STATE_CULL_FRONT)
-				glCullFace(GL_FRONT);
+#define CHANGED_ANY_STORE_VAR(f, enabled) \
+	((DST.state & (f)) != (enabled = (state & (f))))
+
+	/* Depth Write */
+	{
+		int test;
+		if ((test = CHANGED_TO(DRW_STATE_WRITE_DEPTH))) {
+			if (test == 1) {
+				glDepthMask(GL_TRUE);
+			}
+			else {
+				glDepthMask(GL_FALSE);
+			}
 		}
-		else {
-			glDisable(GL_CULL_FACE);
+	}
+
+	/* Color Write */
+	{
+		int test;
+		if ((test = CHANGED_TO(DRW_STATE_WRITE_COLOR))) {
+			if (test == 1) {
+				glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+			}
+			else {
+				glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+			}
 		}
+	}
 
-		/* Depth Test */
-		if ((flag & (DRW_STATE_DEPTH_LESS | DRW_STATE_DEPTH_EQUAL | DRW_STATE_DEPTH_GREATER)) != 0) {
-			glEnable(GL_DEPTH_TEST);
+	/* Cull */
+	{
+		DRWState test;
+		if (CHANGED_ANY_STORE_VAR(
+		        DRW_STATE_CULL_BACK | DRW_STATE_CULL_FRONT,
+		        test))
+		{
+			if (test) {
+				glEnable(GL_CULL_FACE);
 
-			if (flag & DRW_STATE_DEPTH_LESS)
-				glDepthFunc(GL_LEQUAL);
-			else if (flag & DRW_STATE_DEPTH_EQUAL)
-				glDepthFunc(GL_EQUAL);
-			else if (flag & DRW_STATE_DEPTH_GREATER)
-				glDepthFunc(GL_GREATER);
+				if ((state & DRW_STATE_CULL_BACK) != 0) {
+					glCullFace(GL_BACK);
+				}
+				else if ((state & DRW_STATE_CULL_FRONT) != 0) {
+					glCullFace(GL_FRONT);
+				}
+				else {
+					BLI_assert(0);
+				}
+			}
+			else {
+				glDisable(GL_CULL_FACE);
+			}
 		}
-		else {
-			glDisable(GL_DEPTH_TEST);
+	}
+
+	/* Depth Test */
+	{
+		DRWState test;
+		if (CHANGED_ANY_STORE_VAR(
+		        DRW_STATE_DEPTH_LESS | DRW_STATE_DEPTH_EQUAL | DRW_STATE_DEPTH_GREATER,
+		        test))
+		{
+			if (test) {
+				glEnable(GL_DEPTH_TEST);
+
+				if (state & DRW_STATE_DEPTH_LESS) {
+					glDepthFunc(GL_LEQUAL);
+				}
+				else if (state & DRW_STATE_DEPTH_EQUAL) {
+					glDepthFunc(GL_EQUAL);
+				}
+				else if (state & DRW_STATE_DEPTH_GREATER) {
+					glDepthFunc(GL_GREATER);
+				}
+				else {
+					BLI_assert(0);
+				}
+			}
+			else {
+				glDisable(GL_DEPTH_TEST);
+			}
 		}
 	}
 
 	/* Wire Width */
-	if ((flag & DRW_STATE_WIRE) != 0) {
-		glLineWidth(1.0f);
-	}
-	else if ((flag & DRW_STATE_WIRE_LARGE) != 0) {
-		glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f);
+	{
+		if (CHANGED_ANY(DRW_STATE_WIRE | DRW_STATE_WIRE_LARGE)) {
+			if ((state & DRW_STATE_WIRE) != 0) {
+				glLineWidth(1.0f);
+			}
+			else if ((state & DRW_STATE_WIRE_LARGE) != 0) {
+				glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f);
+			}
+			else {
+				/* do nothing */
+			}
+		}
 	}
 
 	/* Points Size */
-	if ((flag & DRW_STATE_POINT) != 0) {
-		GPU_enable_program_point_size();
-		glPointSize(5.0f);
-	}
-	else if (reset) {
-		GPU_disable_program_point_size();
+	{
+		int test;
+		if ((test = CHANGED_TO(DRW_STATE_POINT))) {
+			if (test == 1) {
+				GPU_enable_program_point_size();
+				glPointSize(5.0f);
+			}
+			else {
+				GPU_disable_program_point_size();
+			}
+		}
 	}
 
 	/* Blending (all buffer) */
-	if ((flag & DRW_STATE_BLEND) != 0) {
-		glEnable(GL_BLEND);
-		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-	}
-	else if (reset) {
-		glDisable(GL_BLEND);
+	{
+		int test;
+		if ((test = CHANGED_TO(DRW_STATE_BLEND))) {
+			if (test == 1) {
+				glEnable(GL_BLEND);
+				glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+			}
+			else {
+				glDisable(GL_BLEND);
+			}
+		}
 	}
 
 	/* Line Stipple */
-	if ((flag & DRW_STATE_STIPPLE_2) != 0) {
-		setlinestyle(2);
-	}
-	else if ((flag & DRW_STATE_STIPPLE_3) != 0) {
-		setlinestyle(3);
-	}
-	else if ((flag & DRW_STATE_STIPPLE_4) != 0) {
-		setlinestyle(4);
-	}
-	else if (reset) {
-		setlinestyle(0);
+	{
+		int test;
+		if (CHANGED_ANY_STORE_VAR(
+		        DRW_STATE_STIPPLE_2 | DRW_STATE_STIPPLE_3 | DRW_STATE_STIPPLE_4,
+		        test))
+		{
+			if (test) {
+				if ((state & DRW_STATE_STIPPLE_2) != 0) {
+					setlinestyle(2);
+				}
+				else if ((state & DRW_STATE_STIPPLE_3) != 0) {
+					setlinestyle(3);
+				}
+				else if ((state & DRW_STATE_STIPPLE_4) != 0) {
+					setlinestyle(4);
+				}
+				else {
+					BLI_assert(0);
+				}
+			}
+			else {
+				setlinestyle(0);
+			}
+		}
 	}
 
 	/* Stencil */
-	if ((flag & (DRW_STATE_WRITE_STENCIL_SELECT | DRW_STATE_WRITE_STENCIL_ACTIVE |
-	            DRW_STATE_TEST_STENCIL_SELECT | DRW_STATE_TEST_STENCIL_ACTIVE)) != 0)
 	{
-		glEnable(GL_STENCIL_TEST);
-
-		/* Stencil Write */
-		if ((flag & DRW_STATE_WRITE_STENCIL_SELECT) != 0) {
-			glStencilMask(STENCIL_SELECT);
-			glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
-			glStencilFunc(GL_ALWAYS, 0xFF, STENCIL_SELECT);
-		}
-		else if ((flag & DRW_STATE_WRITE_STENCIL_ACTIVE) != 0) {
-			glStencilMask(STENCIL_ACTIVE);
-			glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
-			glStencilFunc(GL_ALWAYS, 0xFF, STENCIL_ACTIVE);
-		}
-		/* Stencil Test */
-		else if ((flag & DRW_STATE_TEST_STENCIL_SELECT) != 0) {


@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list