diff options
Diffstat (limited to 'source/blender/editors/interface/interface_icons.c')
-rw-r--r-- | source/blender/editors/interface/interface_icons.c | 112 |
1 files changed, 77 insertions, 35 deletions
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index c20129b4184..d0a7716b4dd 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -253,37 +253,6 @@ static void def_internal_vicon(int icon_id, VectorDrawFunc drawFunc) /* Utilities */ -static void viconutil_set_point(int pt[2], int x, int y) -{ - pt[0] = x; - pt[1] = y; -} - -static void vicon_small_tri_right_draw(int x, int y, int w, int UNUSED(h), float alpha) -{ - int pts[3][2]; - const int cx = x + w / 2 - 4; - const int cy = y + w / 2; - const int d = w / 5, d2 = w / 7; - - viconutil_set_point(pts[0], cx - d2, cy + d); - viconutil_set_point(pts[1], cx - d2, cy - d); - viconutil_set_point(pts[2], cx + d2, cy); - - uint pos = GPU_vertformat_attr_add( - immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - immUniformColor4f(0.2f, 0.2f, 0.2f, alpha); - - immBegin(GPU_PRIM_TRIS, 3); - immVertex2iv(pos, pts[0]); - immVertex2iv(pos, pts[1]); - immVertex2iv(pos, pts[2]); - immEnd(); - - immUnbindProgram(); -} - static void vicon_keytype_draw_wrapper( int x, int y, int w, int h, float alpha, short key_type, short handle_type) { @@ -982,8 +951,6 @@ static void init_internal_icons(void) } } - def_internal_vicon(ICON_SMALL_TRI_RIGHT_VEC, vicon_small_tri_right_draw); - def_internal_vicon(ICON_KEYTYPE_KEYFRAME_VEC, vicon_keytype_keyframe_draw); def_internal_vicon(ICON_KEYTYPE_BREAKDOWN_VEC, vicon_keytype_breakdown_draw); def_internal_vicon(ICON_KEYTYPE_EXTREME_VEC, vicon_keytype_extreme_draw); @@ -1515,6 +1482,78 @@ PreviewImage *UI_icon_to_preview(int icon_id) return NULL; } +/** + * Version of #icon_draw_rect() that uses the GPU for scaling. This is only used for + * #ICON_TYPE_IMBUF because it's a back-ported fix for performance issues, see T92922. Only + * File/Asset Browser use #ICON_TYPE_IMBUF right now, which makes implications more predictable. + * + * TODO(Julian): This code is mostly duplicated. #icon_draw_rect() should be ported to use the GPU + * instead (D13144). + */ +static void icon_draw_rect_fast(float x, + float y, + int w, + int h, + float UNUSED(aspect), + int rw, + int rh, + uint *rect, + float alpha, + const float desaturate) +{ + int draw_w = w; + int draw_h = h; + int draw_x = x; + /* We need to round y, to avoid the icon jittering in some cases. */ + int draw_y = round_fl_to_int(y); + + /* sanity check */ + if (w <= 0 || h <= 0 || w > 2000 || h > 2000) { + printf("%s: icons are %i x %i pixels?\n", __func__, w, h); + BLI_assert_msg(0, "invalid icon size"); + return; + } + /* modulate color */ + const float col[4] = {alpha, alpha, alpha, alpha}; + + float scale_x = 1.0f; + float scale_y = 1.0f; + /* rect contains image in 'rendersize', we only scale if needed */ + if (rw != w || rh != h) { + /* preserve aspect ratio and center */ + if (rw > rh) { + draw_w = w; + draw_h = (int)(((float)rh / (float)rw) * (float)w); + draw_y += (h - draw_h) / 2; + } + else if (rw < rh) { + draw_w = (int)(((float)rw / (float)rh) * (float)h); + draw_h = h; + draw_x += (w - draw_w) / 2; + } + scale_x = draw_w / (float)rw; + scale_y = draw_h / (float)rh; + /* If the image is squared, the `draw_*` initialization values are good. */ + } + + /* draw */ + eGPUBuiltinShader shader; + if (desaturate != 0.0f) { + shader = GPU_SHADER_2D_IMAGE_DESATURATE_COLOR; + } + else { + shader = GPU_SHADER_2D_IMAGE_COLOR; + } + IMMDrawPixelsTexState state = immDrawPixelsTexSetup(shader); + + if (shader == GPU_SHADER_2D_IMAGE_DESATURATE_COLOR) { + immUniform1f("factor", desaturate); + } + + immDrawPixelsTexScaled( + &state, draw_x, draw_y, rw, rh, GPU_RGBA8, true, rect, scale_x, scale_y, 1.0f, 1.0f, col); +} + static void icon_draw_rect(float x, float y, int w, @@ -1530,7 +1569,8 @@ static void icon_draw_rect(float x, int draw_w = w; int draw_h = h; int draw_x = x; - int draw_y = y; + /* We need to round y, to avoid the icon jittering in some cases. */ + int draw_y = round_fl_to_int(y); /* sanity check */ if (w <= 0 || h <= 0 || w > 2000 || h > 2000) { @@ -1838,7 +1878,9 @@ static void icon_draw_size(float x, ImBuf *ibuf = icon->obj; GPU_blend(GPU_BLEND_ALPHA_PREMULT); - icon_draw_rect(x, y, w, h, aspect, ibuf->x, ibuf->y, ibuf->rect, alpha, desaturate); + /* These icons are only used by the File/Asset Browser currently. Without this `_fast()` + * version, there may be performance issues, see T92922. */ + icon_draw_rect_fast(x, y, w, h, aspect, ibuf->x, ibuf->y, ibuf->rect, alpha, desaturate); GPU_blend(GPU_BLEND_ALPHA); } else if (di->type == ICON_TYPE_VECTOR) { |