Skip to content

Commit

Permalink
wlr-surface-node: do not schedule damage behind opaque surfaces
Browse files Browse the repository at this point in the history
Fixes #864

The optimization is hidden behind a flag for now, needs more testing.
  • Loading branch information
ammen99 committed Mar 27, 2024
1 parent 3bbd612 commit f03f15f
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 3 deletions.
4 changes: 4 additions & 0 deletions metadata/workarounds.xml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@
<option name="enable_input_method_v2" type="bool">
<_short>Enable support for the newer input-method-v2 protocol. Note that the input-method-v1 protocol works better in many cases.</_short>
<default>false</default>
</option>
<option name="enable_opaque_region_damage_optimizations" type="bool">
<_short>Enable certain damage optimizations which are based on a surfaces' opaque regions. In some cases, this optimization might give unexpected results (i.e background app stops updating) even though this is fine according to Wayland's protocol.</_short>
<default>false</default>
</option>
</plugin>
</wayfire>
27 changes: 24 additions & 3 deletions src/view/wlr-surface-node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ class wf::scene::wlr_surface_node_t::wlr_surface_render_instance_t : public rend

wf::output_t *visible_on;
damage_callback push_damage;
wf::region_t last_visibility;

wf::signal::connection_t<node_damage_signal> on_surface_damage =
[=] (node_damage_signal *data)
Expand All @@ -249,7 +250,17 @@ class wf::scene::wlr_surface_node_t::wlr_surface_render_instance_t : public rend
}
}

push_damage(data->region);
static wf::option_wrapper_t<bool> use_opaque_optimizations{
"workarounds/enable_opaque_region_damage_optimizations"
};

if (use_opaque_optimizations)
{
push_damage(data->region & last_visibility);
} else
{
push_damage(data->region);
}
};

public:
Expand Down Expand Up @@ -400,13 +411,23 @@ class wf::scene::wlr_surface_node_t::wlr_surface_render_instance_t : public rend
{
auto our_box = self->get_bounding_box();
on_frame_done.disconnect();
last_visibility = visible & our_box;

if (!(visible & our_box).empty())
static wf::option_wrapper_t<bool> use_opaque_optimizations{
"workarounds/enable_opaque_region_damage_optimizations"
};

if (!last_visibility.empty())
{
// We are visible on the given output => send wl_surface.frame on output frame, so that clients
// can draw the next frame.
output->connect(&on_frame_done);
// TODO: compute actually visible region and disable damage reporting for that region.

if (use_opaque_optimizations && self->surface)
{
pixman_region32_subtract(visible.to_pixman(), visible.to_pixman(),
&self->surface->opaque_region);
}
}
}
};
Expand Down

0 comments on commit f03f15f

Please sign in to comment.