diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2018-04-07 00:54:24 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2018-04-07 00:54:39 +0300 |
commit | 2d618974d14672e6ec38612e76aca70e619f7242 (patch) | |
tree | 4d670fd5d6e6b55c6fe75ac27c5bd030f9906667 /source | |
parent | 3e998b886080d3cd11137327356d1c861ae7ddb4 (diff) |
UI: Perf: Port color widgets to batch.
This is more for completeness than perf.
Shader is tiny bit more complex but we get less overdraw and drawcalls.
Diffstat (limited to 'source')
6 files changed, 71 insertions, 57 deletions
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 86814c54fbb..043dfc9fd99 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -712,7 +712,7 @@ typedef struct uiWidgetBaseParameters { float color_tria[4]; float tria1_center[2], tria2_center[2]; float tria1_size, tria2_size; - float shade_dir, clamp; + float shade_dir, do_alpha_check; } uiWidgetBaseParameters; enum { diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index fbad76f441a..4b04c08a952 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -964,8 +964,10 @@ static void widgetbase_set_uniform_colors_ubv( const unsigned char *col1, const unsigned char *col2, const unsigned char *outline, const unsigned char *emboss, - const unsigned char *tria) + const unsigned char *tria, + const bool alpha_check) { + wtb->uniform_params.do_alpha_check = (float)alpha_check; rgba_float_args_set_ch(wtb->uniform_params.color_inner1, col1[0], col1[1], col1[2], col1[3]); rgba_float_args_set_ch(wtb->uniform_params.color_inner2, col2[0], col2[1], col2[2], col2[3]); rgba_float_args_set_ch(wtb->uniform_params.color_outline, outline[0], outline[1], outline[2], outline[3]); @@ -985,6 +987,8 @@ struct { void UI_widgetbase_draw_cache_flush(void) { + float checker_params[3] = {UI_ALPHA_CHECKER_DARK / 255.0f, UI_ALPHA_CHECKER_LIGHT / 255.0f, 8.0f}; + if (g_widget_base_batch.count == 0) return; @@ -993,11 +997,13 @@ void UI_widgetbase_draw_cache_flush(void) /* draw single */ GWN_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE); GWN_batch_uniform_4fv_array(batch, "parameters", 11, (float *)g_widget_base_batch.params); + GWN_batch_uniform_3fv(batch, "checkerColorAndSize", checker_params); GWN_batch_draw(batch); } else { GWN_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE_INST); GWN_batch_uniform_4fv_array(batch, "parameters", 11 * MAX_WIDGET_BASE_BATCH, (float *)g_widget_base_batch.params); + GWN_batch_uniform_3fv(batch, "checkerColorAndSize", checker_params); gpuBindMatrices(batch->interface); GWN_batch_draw_range_ex(batch, 0, g_widget_base_batch.count, true); GWN_batch_program_use_end(batch); @@ -1057,75 +1063,35 @@ static void draw_widgetbase_batch(Gwn_Batch *batch, uiWidgetBase *wtb) } } else { + float checker_params[3] = {UI_ALPHA_CHECKER_DARK / 255.0f, UI_ALPHA_CHECKER_LIGHT / 255.0f, 8.0f}; /* draw single */ GWN_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE); GWN_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&wtb->uniform_params); + GWN_batch_uniform_3fv(batch, "checkerColorAndSize", checker_params); GWN_batch_draw(batch); } } static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol) { - int a; unsigned char inner_col1[4] = {0}; unsigned char inner_col2[4] = {0}; unsigned char emboss_col[4] = {0}; unsigned char outline_col[4] = {0}; unsigned char tria_col[4] = {0}; + /* For color widget. */ + bool alpha_check = (wcol->alpha_check && (wcol->shaded == 0)); + glEnable(GL_BLEND); /* backdrop non AA */ if (wtb->draw_inner) { - BLI_assert(wtb->totvert != 0); if (wcol->shaded == 0) { - if (wcol->alpha_check) { - float inner_v_half[WIDGET_SIZE_MAX][2]; - float x_mid = 0.0f; /* used for dumb clamping of values */ - - unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_2D_CHECKER); - - /* checkers */ - immUniform4f("color1", UI_ALPHA_CHECKER_DARK / 255.0f, UI_ALPHA_CHECKER_DARK / 255.0f, UI_ALPHA_CHECKER_DARK / 255.0f, 1.0f); - immUniform4f("color2", UI_ALPHA_CHECKER_LIGHT / 255.0f, UI_ALPHA_CHECKER_LIGHT / 255.0f, UI_ALPHA_CHECKER_LIGHT / 255.0f, 1.0f); - immUniform1i("size", 8); - - widget_draw_vertex_buffer(pos, 0, GL_TRIANGLE_FAN, wtb->inner_v, NULL, wtb->totvert); - - immUnbindProgram(); - - /* alpha fill */ - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - immUniformColor4ubv((unsigned char *)wcol->inner); - - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - - for (a = 0; a < wtb->totvert; a++) { - x_mid += wtb->inner_v[a][0]; - } - x_mid /= wtb->totvert; - - widget_draw_vertex_buffer(pos, 0, GL_TRIANGLE_FAN, wtb->inner_v, NULL, wtb->totvert); - - /* 1/2 solid color */ - immUniformColor3ubv((unsigned char *)wcol->inner); - - for (a = 0; a < wtb->totvert; a++) { - inner_v_half[a][0] = MIN2(wtb->inner_v[a][0], x_mid); - inner_v_half[a][1] = wtb->inner_v[a][1]; - } - - widget_draw_vertex_buffer(pos, 0, GL_TRIANGLE_FAN, inner_v_half, NULL, wtb->totvert); - - immUnbindProgram(); - } - else { - /* simple fill */ - inner_col1[0] = inner_col2[0] = (unsigned char)wcol->inner[0]; - inner_col1[1] = inner_col2[1] = (unsigned char)wcol->inner[1]; - inner_col1[2] = inner_col2[2] = (unsigned char)wcol->inner[2]; - inner_col1[3] = inner_col2[3] = (unsigned char)wcol->inner[3]; - } + /* simple fill */ + inner_col1[0] = inner_col2[0] = (unsigned char)wcol->inner[0]; + inner_col1[1] = inner_col2[1] = (unsigned char)wcol->inner[1]; + inner_col1[2] = inner_col2[2] = (unsigned char)wcol->inner[2]; + inner_col1[3] = inner_col2[3] = (unsigned char)wcol->inner[3]; } else { /* gradient fill */ @@ -1154,8 +1120,8 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol) } /* Draw everything in one drawcall */ - if (inner_col1[3] || inner_col2[3] || outline_col[3] || emboss_col[3] || tria_col[3]) { - widgetbase_set_uniform_colors_ubv(wtb, inner_col1, inner_col2, outline_col, emboss_col, tria_col); + if (inner_col1[3] || inner_col2[3] || outline_col[3] || emboss_col[3] || tria_col[3] || alpha_check) { + widgetbase_set_uniform_colors_ubv(wtb, inner_col1, inner_col2, outline_col, emboss_col, tria_col, alpha_check); Gwn_Batch *roundbox_batch = ui_batch_roundbox_widget_get(wtb->tria1.type); draw_widgetbase_batch(roundbox_batch, wtb); diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index e6c6e6c0eb4..bf0e6ea3368 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -133,6 +133,7 @@ data_to_c_simple(shaders/gpu_shader_flat_color_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_flat_color_alpha_test_0_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_2D_vert.glsl SRC) data_to_c_simple(shaders/gpu_shader_2D_widget_base_vert.glsl SRC) +data_to_c_simple(shaders/gpu_shader_2D_widget_base_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_2D_widget_shadow_vert.glsl SRC) data_to_c_simple(shaders/gpu_shader_2D_widget_shadow_frag.glsl SRC) data_to_c_simple(shaders/gpu_shader_2D_nodelink_frag.glsl SRC) diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c index 7c7297e90fb..db5c2d1bcb5 100644 --- a/source/blender/gpu/intern/gpu_shader.c +++ b/source/blender/gpu/intern/gpu_shader.c @@ -68,6 +68,7 @@ extern char datatoc_gpu_shader_2D_image_vert_glsl[]; extern char datatoc_gpu_shader_2D_image_rect_vert_glsl[]; extern char datatoc_gpu_shader_2D_image_multi_rect_vert_glsl[]; extern char datatoc_gpu_shader_2D_widget_base_vert_glsl[]; +extern char datatoc_gpu_shader_2D_widget_base_frag_glsl[]; extern char datatoc_gpu_shader_2D_widget_shadow_vert_glsl[]; extern char datatoc_gpu_shader_2D_widget_shadow_frag_glsl[]; extern char datatoc_gpu_shader_2D_nodelink_frag_glsl[]; @@ -802,9 +803,9 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader) datatoc_gpu_shader_instance_edges_variying_color_geom_glsl}, [GPU_SHADER_2D_WIDGET_BASE] = { datatoc_gpu_shader_2D_widget_base_vert_glsl, - datatoc_gpu_shader_2D_smooth_color_frag_glsl}, + datatoc_gpu_shader_2D_widget_base_frag_glsl}, [GPU_SHADER_2D_WIDGET_BASE_INST] = { datatoc_gpu_shader_2D_widget_base_vert_glsl, - datatoc_gpu_shader_2D_smooth_color_frag_glsl}, + datatoc_gpu_shader_2D_widget_base_frag_glsl}, [GPU_SHADER_2D_WIDGET_SHADOW] = { datatoc_gpu_shader_2D_widget_shadow_vert_glsl, datatoc_gpu_shader_2D_widget_shadow_frag_glsl }, [GPU_SHADER_2D_NODELINK] = { datatoc_gpu_shader_2D_nodelink_vert_glsl, diff --git a/source/blender/gpu/shaders/gpu_shader_2D_widget_base_frag.glsl b/source/blender/gpu/shaders/gpu_shader_2D_widget_base_frag.glsl new file mode 100644 index 00000000000..929674ab446 --- /dev/null +++ b/source/blender/gpu/shaders/gpu_shader_2D_widget_base_frag.glsl @@ -0,0 +1,34 @@ +uniform vec3 checkerColorAndSize; + +noperspective in vec4 finalColor; +noperspective in float butCo; + +out vec4 fragColor; + +vec4 do_checkerboard() +{ + float size = checkerColorAndSize.z; + vec2 phase = mod(gl_FragCoord.xy, size * 2.0); + + if ((phase.x > size && phase.y < size) || + (phase.x < size && phase.y > size)) + { + return vec4(checkerColorAndSize.xxx, 1.0); + } + else { + return vec4(checkerColorAndSize.yyy, 1.0); + } +} + +void main() +{ + fragColor = finalColor; + + if (butCo > 0.5) { + fragColor = mix(do_checkerboard(), fragColor, fragColor.a); + } + + if (butCo > 0.0) { + fragColor.a = 1.0; + } +}
\ No newline at end of file diff --git a/source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl index f4dafd7de16..9f28d9bb3a3 100644 --- a/source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl @@ -95,10 +95,12 @@ uniform vec4 parameters[11]; #define tria1Size parameters[gl_InstanceID * 11 + 10].x #define tria2Size parameters[gl_InstanceID * 11 + 10].y #define shadeDir parameters[gl_InstanceID * 11 + 10].z +#define doAlphaCheck parameters[gl_InstanceID * 11 + 10].w in uint vflag; noperspective out vec4 finalColor; +noperspective out float butCo; vec2 do_widget(void) { @@ -128,13 +130,22 @@ vec2 do_widget(void) if (color_id == COLOR_INNER) { vec2 uv = faci * (v - recti.xz); float fac = clamp((shadeDir > 0.0) ? uv.y : uv.x, 0.0, 1.0); - finalColor = mix(colorInner2, colorInner1, fac); + if (doAlphaCheck != 0.0) { + finalColor = colorInner1; + butCo = uv.x; + } + else { + finalColor = mix(colorInner2, colorInner1, fac); + butCo = -1.0; + } } else if (color_id == COLOR_EDGE) { finalColor = colorEdge; + butCo = -1.0; } else /* (color_id == COLOR_EMBOSS) */ { finalColor = colorEmboss; + butCo = -1.0; } bool is_emboss = (vflag & EMBOSS_FLAG) != 0u; @@ -150,6 +161,7 @@ vec2 do_tria() vec2 v = triavec[vofs]; finalColor = colorTria; + butCo = -1.0; bool is_tria_first = (vflag & TRIA_FIRST) != 0u; |