[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