Enable map/unmap optimizations for subsurfaces

* subcompositor.c (ViewMap, ViewUnmap): Union view inferior
bounds whenever possible, instead of garbaging the
subcompositor.
* tests/subsurface_test.c (enum test_kind): New test
`SUBSURFACE_STACKING_1_KIND'.
(test_names): Add new name.
(LAST_TEST): Set to SUBSURFACE_STACKING_1_KIND.
(test_single_step): Implement SUBSURFACE_STACKING_1_KIND.
This commit is contained in:
hujianwei 2022-11-05 10:45:39 +00:00
parent e712b6b57a
commit c26d1c4939
2 changed files with 73 additions and 7 deletions

View file

@ -1793,19 +1793,29 @@ ViewMap (View *view)
if (view->subcompositor if (view->subcompositor
&& (view->link != view->inferior || view->buffer)) && (view->link != view->inferior || view->buffer))
{ {
/* Garbage the subcompositor and recompute bounds, if something /* Recompute bounds, if something is attached to the view or it
is attached to the view or it is not empty. */ is not empty. */
SetGarbaged (view->subcompositor);
SubcompositorUpdateBounds (view->subcompositor, DoAll); SubcompositorUpdateBounds (view->subcompositor, DoAll);
/* Now, if the subcompositor is still not garbaged, damage each
inferior of the view. */
if (!IsGarbaged (view->subcompositor))
DamageIncludingInferiors (view);
} }
} }
void void
ViewUnmap (View *view) ViewUnmap (View *view)
{ {
pixman_region32_t damage;
if (IsViewUnmapped (view)) if (IsViewUnmapped (view))
return; return;
/* Init the damage region. */
pixman_region32_init (&damage);
ViewUnionInferiorBounds (view, &damage);
/* Mark the view as unmapped. */ /* Mark the view as unmapped. */
SetUnmapped (view); SetUnmapped (view);
@ -1824,10 +1834,18 @@ ViewUnmap (View *view)
SubcompositorUpdateBounds (view->subcompositor, SubcompositorUpdateBounds (view->subcompositor,
DoAll); DoAll);
/* Garbage the view's subcompositor. */ /* If the subcompositor is still not garbaged, then apply
SetGarbaged (view->subcompositor); the bounds of view and all its inferiors as extra
damage. */
if (!IsGarbaged (view->subcompositor))
pixman_region32_union (&view->subcompositor->additional_damage,
&view->subcompositor->additional_damage,
&damage);
} }
} }
/* Finalize the damage region. */
pixman_region32_fini (&damage);
} }
void void

View file

@ -31,6 +31,7 @@ enum test_kind
SUBSURFACE_STACKING_KIND, SUBSURFACE_STACKING_KIND,
SUBSURFACE_TREE_KIND, SUBSURFACE_TREE_KIND,
SUBSURFACE_GROW_SHRINK_KIND, SUBSURFACE_GROW_SHRINK_KIND,
SUBSURFACE_STACKING_1_KIND,
}; };
static const char *test_names[] = static const char *test_names[] =
@ -42,6 +43,7 @@ static const char *test_names[] =
"subsurface_stacking", "subsurface_stacking",
"subsurface_tree", "subsurface_tree",
"subsurface_grow_shrink", "subsurface_grow_shrink",
"subsurface_stacking_1",
}; };
struct test_subsurface struct test_subsurface
@ -53,7 +55,7 @@ struct test_subsurface
struct wl_surface *surface; struct wl_surface *surface;
}; };
#define LAST_TEST SUBSURFACE_GROW_SHRINK_KIND #define LAST_TEST SUBSURFACE_STACKING_1_KIND
/* The display. */ /* The display. */
static struct test_display *display; static struct test_display *display;
@ -427,7 +429,6 @@ test_single_step (enum test_kind kind)
disappear! */ disappear! */
wl_surface_attach (subsurfaces[1]->surface, NULL, 0, 0); wl_surface_attach (subsurfaces[1]->surface, NULL, 0, 0);
wl_surface_commit (subsurfaces[1]->surface); wl_surface_commit (subsurfaces[1]->surface);
wl_surface_commit (subsurfaces[1]->surface);
wait_frame_callback (wayland_surface); wait_frame_callback (wayland_surface);
sleep_or_verify (); sleep_or_verify ();
@ -504,6 +505,53 @@ test_single_step (enum test_kind kind)
wl_surface_commit (subsurfaces[1]->surface); wl_surface_commit (subsurfaces[1]->surface);
wait_frame_callback (wayland_surface); wait_frame_callback (wayland_surface);
sleep_or_verify (); sleep_or_verify ();
test_single_step (SUBSURFACE_STACKING_1_KIND);
break;
case SUBSURFACE_STACKING_1_KIND:
/* Move the second subsurface above the first. Then, move the
third subsurface above the fourth, and the fourth below the
second. */
wl_subsurface_place_above (subsurfaces[1]->subsurface,
subsurfaces[0]->surface);
wl_subsurface_place_above (subsurfaces[2]->subsurface,
subsurfaces[3]->surface);
wl_subsurface_place_below (subsurfaces[3]->subsurface,
subsurfaces[1]->surface);
/* Next, attach some buffers to the third and fourth
surface. */
wl_surface_attach (subsurfaces[2]->surface, gradient_png, 0, 0);
wl_surface_attach (subsurfaces[3]->surface, cow_transparent_png,
0, 0);
submit_surface_opaque_region (subsurfaces[2]->surface, 0, 0,
100, 300);
wl_surface_commit (subsurfaces[2]->surface);
wl_surface_commit (subsurfaces[3]->surface);
/* Commit the first subsurface. */
wl_surface_commit (subsurfaces[1]->surface);
wait_frame_callback (wayland_surface);
/* The result of the test should be as follows. Above the first
subsurface lies the fourth subsurface (cow_transparent.png),
above which is the second subsurface (small.png), above which
is the third subsurface (gradient.png). */
sleep_or_verify ();
/* Next, test moving the third subsurface immediately below the
fourth. */
wl_subsurface_place_below (subsurfaces[2]->subsurface,
subsurfaces[3]->surface);
wl_surface_commit (subsurfaces[1]->surface);
wait_frame_callback (wayland_surface);
/* The result of the test should be as follows. Above the first
subsurface lies the third subsurface (gradient.png), above
which lies the fourth subsurface (cow_transparent.png), and
finally the third (small.png). */
sleep_or_verify ();
break; break;
} }