diff options
author | Daniel van Vugt <daniel.van.vugt@canonical.com> | 2018-08-02 19:03:30 +0800 |
---|---|---|
committer | Jonas Ã…dahl <jadahl@gmail.com> | 2019-09-02 16:41:13 +0000 |
commit | 14c706e51b4d70ac4046ea3c8bacd7292681651c (patch) | |
tree | 19cfff38f726d8e6bbb6f67d71a1845b1a2d228a /clutter/clutter/clutter-main.c | |
parent | a70823dd1ca3a0892f7b5fa9c7fe88d885d306eb (diff) | |
download | mutter-14c706e51b4d70ac4046ea3c8bacd7292681651c.tar.gz |
clutter: Introduce geometric picking
Currently, Clutter does picking by drawing with Cogl and reading
the pixel that's beneath the given point. Since Cogl has a journal
that records drawing operations, and has optimizations to read a
single pixel from a list of rectangle, it would be expected that
we would hit this fast path and not flush the journal while picking.
However, that's not the case: dithering, clipping with scissors, etc,
can all flush the journal, issuing commands to the GPU and making
picking slow. On NVidia-based systems, this glReadPixels() call is
extremely costly.
Introduce geometric picking, and avoid using the Cogl journal entirely.
Do this by introducing a stack of actors in ClutterStage. This stack
is cached, but for now, don't use the cache as much as possible.
The picking routines are still tied to painting.
When projecting the actor vertexes, do it manually and take the modelview
matrix of the framebuffer into account as well.
CPU usage on an Intel i7-7700, tested with two different GPUs/drivers:
| | Intel | Nvidia |
| ------: | --------: | -----: |
| Moving the mouse: |
| Before | 10% | 10% |
| After | 6% | 6% |
| Moving a window: |
| Before | 23% | 81% |
| After | 19% | 40% |
Closes: https://gitlab.gnome.org/GNOME/mutter/issues/154,
https://gitlab.gnome.org/GNOME/mutter/issues/691
Helps significantly with: https://gitlab.gnome.org/GNOME/mutter/issues/283,
https://gitlab.gnome.org/GNOME/mutter/issues/590,
https://gitlab.gnome.org/GNOME/mutter/issues/700
v2: Fix code style issues
Simplify quadrilateral checks
Remove the 0.5f hack
Differentiate axis-aligned rectangles
https://gitlab.gnome.org/GNOME/mutter/merge_requests/189
Diffstat (limited to 'clutter/clutter/clutter-main.c')
-rw-r--r-- | clutter/clutter/clutter-main.c | 120 |
1 files changed, 0 insertions, 120 deletions
diff --git a/clutter/clutter/clutter-main.c b/clutter/clutter/clutter-main.c index 171441577..2bb5bd2c8 100644 --- a/clutter/clutter/clutter-main.c +++ b/clutter/clutter/clutter-main.c @@ -129,7 +129,6 @@ static const GDebugKey clutter_debug_keys[] = { static const GDebugKey clutter_pick_debug_keys[] = { { "nop-picking", CLUTTER_DEBUG_NOP_PICKING }, - { "dump-pick-buffers", CLUTTER_DEBUG_DUMP_PICK_BUFFERS }, }; static const GDebugKey clutter_paint_debug_keys[] = { @@ -401,125 +400,6 @@ clutter_disable_accessibility (void) clutter_enable_accessibility = FALSE; } -void -_clutter_id_to_color (guint id_, - ClutterColor *col) -{ - ClutterMainContext *ctx; - gint red, green, blue; - - ctx = _clutter_context_get_default (); - - if (ctx->fb_g_mask == 0) - { - /* Figure out framebuffer masks used for pick */ - cogl_get_bitmasks (&ctx->fb_r_mask, - &ctx->fb_g_mask, - &ctx->fb_b_mask, NULL); - - ctx->fb_r_mask_used = ctx->fb_r_mask; - ctx->fb_g_mask_used = ctx->fb_g_mask; - ctx->fb_b_mask_used = ctx->fb_b_mask; - - /* XXX - describe what "fuzzy picking" is */ - if (clutter_use_fuzzy_picking) - { - ctx->fb_r_mask_used--; - ctx->fb_g_mask_used--; - ctx->fb_b_mask_used--; - } - } - - /* compute the numbers we'll store in the components */ - red = (id_ >> (ctx->fb_g_mask_used+ctx->fb_b_mask_used)) - & (0xff >> (8-ctx->fb_r_mask_used)); - green = (id_ >> ctx->fb_b_mask_used) - & (0xff >> (8-ctx->fb_g_mask_used)); - blue = (id_) - & (0xff >> (8-ctx->fb_b_mask_used)); - - /* shift left bits a bit and add one, this circumvents - * at least some potential rounding errors in GL/GLES - * driver / hw implementation. - */ - if (ctx->fb_r_mask_used != ctx->fb_r_mask) - red = red * 2; - if (ctx->fb_g_mask_used != ctx->fb_g_mask) - green = green * 2; - if (ctx->fb_b_mask_used != ctx->fb_b_mask) - blue = blue * 2; - - /* shift up to be full 8bit values */ - red = (red << (8 - ctx->fb_r_mask)) | (0x7f >> (ctx->fb_r_mask_used)); - green = (green << (8 - ctx->fb_g_mask)) | (0x7f >> (ctx->fb_g_mask_used)); - blue = (blue << (8 - ctx->fb_b_mask)) | (0x7f >> (ctx->fb_b_mask_used)); - - col->red = red; - col->green = green; - col->blue = blue; - col->alpha = 0xff; - - /* XXX: We rotate the nibbles of the colors here so that there is a - * visible variation between colors of sequential actor identifiers; - * otherwise pick buffers dumped to an image will pretty much just look - * black. - */ - if (G_UNLIKELY (clutter_pick_debug_flags & CLUTTER_DEBUG_DUMP_PICK_BUFFERS)) - { - col->red = (col->red << 4) | (col->red >> 4); - col->green = (col->green << 4) | (col->green >> 4); - col->blue = (col->blue << 4) | (col->blue >> 4); - } -} - -guint -_clutter_pixel_to_id (guchar pixel[4]) -{ - ClutterMainContext *ctx; - gint red, green, blue; - guint retval; - - ctx = _clutter_context_get_default (); - - /* reduce the pixel components to the number of bits actually used of the - * 8bits. - */ - if (G_UNLIKELY (clutter_pick_debug_flags & CLUTTER_DEBUG_DUMP_PICK_BUFFERS)) - { - guchar tmp; - - /* XXX: In _clutter_id_to_color we rotated the nibbles of the colors so - * that there is a visible variation between colors of sequential actor - * identifiers (otherwise pick buffers dumped to an image will pretty - * much just look black.) Here we reverse that rotation. - */ - tmp = ((pixel[0] << 4) | (pixel[0] >> 4)); - red = tmp >> (8 - ctx->fb_r_mask); - tmp = ((pixel[1] << 4) | (pixel[1] >> 4)); - green = tmp >> (8 - ctx->fb_g_mask); - tmp = ((pixel[2] << 4) | (pixel[2] >> 4)); - blue = tmp >> (8 - ctx->fb_b_mask); - } - else - { - red = pixel[0] >> (8 - ctx->fb_r_mask); - green = pixel[1] >> (8 - ctx->fb_g_mask); - blue = pixel[2] >> (8 - ctx->fb_b_mask); - } - - /* divide potentially by two if 'fuzzy' */ - red = red >> (ctx->fb_r_mask - ctx->fb_r_mask_used); - green = green >> (ctx->fb_g_mask - ctx->fb_g_mask_used); - blue = blue >> (ctx->fb_b_mask - ctx->fb_b_mask_used); - - /* combine the correct per component values into the final id */ - retval = blue - + (green << ctx->fb_b_mask_used) - + (red << (ctx->fb_b_mask_used + ctx->fb_g_mask_used)); - - return retval; -} - static CoglPangoFontMap * clutter_context_get_pango_fontmap (void) { |