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.
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user