Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Eisel <julian@blender.org>2022-01-17 20:02:29 +0300
committerJulian Eisel <julian@blender.org>2022-01-17 20:26:10 +0300
commitaa0ecd17918d5f1c3ce684f8f14b6aa7080ea9e1 (patch)
treeda4beec20121acc32c54683a39277665f9f31633 /source/blender/editors/screen
parent4d10a46e6368f0b48a901325b94ebd43b672db32 (diff)
UI: Speed up icon scaling
Use GPU-side scaling to speed up the scaling itself, and to avoid having to copy the image buffer using the CPU. Mipmapping is used to get decent filtering when downscaling without ugly artifacts. In my comparisons, there was barely any difference between the methods for DPIs >= 1. Below that, the result looks a bit different due to the different filtering method. See D13144 for screen-recordings showing the difference. Part of T92922. Differential Revision: https://developer.blender.org/D13144 Reviewed by: Jeroen Bakker
Diffstat (limited to 'source/blender/editors/screen')
-rw-r--r--source/blender/editors/screen/glutil.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c
index 5f523df18d1..cb5c5df20ec 100644
--- a/source/blender/editors/screen/glutil.c
+++ b/source/blender/editors/screen/glutil.c
@@ -72,6 +72,75 @@ IMMDrawPixelsTexState immDrawPixelsTexSetup(int builtin)
return state;
}
+void immDrawPixelsTexScaledFullSize(const IMMDrawPixelsTexState *state,
+ const float x,
+ const float y,
+ const int img_w,
+ const int img_h,
+ const eGPUTextureFormat gpu_format,
+ const bool use_filter,
+ const void *rect,
+ const float scaleX,
+ const float scaleY,
+ const float xzoom,
+ const float yzoom,
+ const float color[4])
+{
+ const static float white[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+ const float draw_width = img_w * scaleX * xzoom;
+ const float draw_height = img_h * scaleY * yzoom;
+ /* Downscaling with regular bilinear interpolation (i.e. #GL_LINEAR) doesn't give good filtering
+ * results. Mipmaps can be used to get better results (i.e. #GL_LINEAR_MIPMAP_LINEAR), so always
+ * use mipmaps when filtering. */
+ const bool use_mipmap = use_filter && ((draw_width < img_w) || (draw_height < img_h));
+
+ GPUTexture *tex = GPU_texture_create_2d("immDrawPixels", img_w, img_h, 1, gpu_format, NULL);
+
+ const bool use_float_data = ELEM(gpu_format, GPU_RGBA16F, GPU_RGB16F, GPU_R16F);
+ eGPUDataFormat gpu_data_format = (use_float_data) ? GPU_DATA_FLOAT : GPU_DATA_UBYTE;
+ GPU_texture_update(tex, gpu_data_format, rect);
+
+ GPU_texture_filter_mode(tex, use_filter);
+ if (use_mipmap) {
+ GPU_texture_generate_mipmap(tex);
+ GPU_texture_mipmap_mode(tex, true, true);
+ }
+ GPU_texture_wrap_mode(tex, false, true);
+
+ GPU_texture_bind(tex, 0);
+
+ /* optional */
+ /* NOTE: Shader could be null for GLSL OCIO drawing, it is fine, since
+ * it does not need color.
+ */
+ if (state->shader != NULL && GPU_shader_get_uniform(state->shader, "color") != -1) {
+ immUniformColor4fv((color) ? color : white);
+ }
+
+ uint pos = state->pos, texco = state->texco;
+
+ immBegin(GPU_PRIM_TRI_FAN, 4);
+ immAttr2f(texco, 0.0f, 0.0f);
+ immVertex2f(pos, x, y);
+
+ immAttr2f(texco, 1.0f, 0.0f);
+ immVertex2f(pos, x + draw_width, y);
+
+ immAttr2f(texco, 1.0f, 1.0f);
+ immVertex2f(pos, x + draw_width, y + draw_height);
+
+ immAttr2f(texco, 0.0f, 1.0f);
+ immVertex2f(pos, x, y + draw_height);
+ immEnd();
+
+ if (state->do_shader_unbind) {
+ immUnbindProgram();
+ }
+
+ GPU_texture_unbind(tex);
+ GPU_texture_free(tex);
+}
+
void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state,
float x,
float y,