-
Notifications
You must be signed in to change notification settings - Fork 177
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WebRender-offload-mode subsurface compositing glitches #1272
Comments
What we don't support currently is the reordering of subsurfaces, does Firefox do that? |
The tracking bug I linked to links to swaywm/wlroots#1865 so… maybe? Is there a quick way to check? Anything in particular to look for in |
place_below/above are the relevant requests iirc |
Yeah, there's a lot of these.
|
Interestingly, Sway does not keep separate below/above lists internally: And subsurface order is just handled inside wlroots: Sway does not do anything special for this and doesn't have the glitches, so this might not be the relevant issue at all?? I've tried this awful test patchdiff --git i/src/view/surface.cpp w/src/view/surface.cpp
index ecc4f6d2..a03484d9 100644
--- i/src/view/surface.cpp
+++ w/src/view/surface.cpp
@@ -270,6 +270,7 @@ wf::wlr_surface_base_t::wlr_surface_base_t(surface_interface_t *self)
auto subsurface = std::make_unique<subsurface_implementation_t>(sub);
nonstd::observer_ptr<subsurface_implementation_t> ptr{subsurface};
+ sub->data = ptr.get();
_as_si->add_subsurface(std::move(subsurface), false);
if (sub->mapped)
{
@@ -340,7 +341,30 @@ void wf::wlr_surface_base_t::map(wlr_surface *surface)
/* Handle subsurfaces which were created before this surface was mapped */
wlr_subsurface *sub;
wl_list_for_each(sub, &surface->current.subsurfaces_below, current.link)
- handle_new_subsurface(sub);
+ // handle_new_subsurface(sub);
+ {
+ if (sub->data)
+ {
+ LOGE("Creating the same subsurface twice!");
+
+ return;
+ }
+
+ // parent isn't mapped yet
+ if (!sub->parent->data)
+ {
+ return;
+ }
+
+ auto subsurface = std::make_unique<subsurface_implementation_t>(sub);
+ nonstd::observer_ptr<subsurface_implementation_t> ptr{subsurface};
+ sub->data = ptr.get();
+ _as_si->add_subsurface(std::move(subsurface), true);
+ if (sub->mapped)
+ {
+ ptr->map(sub->surface);
+ }
+ };
wl_list_for_each(sub, &surface->current.subsurfaces_above, current.link)
handle_new_subsurface(sub);
@@ -406,6 +430,50 @@ void wf::wlr_surface_base_t::commit()
* a frame callback */
_as_si->get_output()->render->schedule_redraw();
}
+
+ wlr_subsurface *sub;
+ wl_list_for_each(sub, &surface->current.subsurfaces_below, current.link) {
+ // LOGI("below reordered ", sub->reordered, " ", sub, " data ", sub->data);
+ wf::surface_interface_t * si = static_cast<wf::surface_interface_t *>(sub->data);
+ auto it = std::find_if(_as_si->priv->surface_children_below.begin(), _as_si->priv->surface_children_below.end(),
+ [=] (const auto& ptr) { return ptr.get() == si; });
+ if (it != _as_si->priv->surface_children_below.end())
+ {
+ // LOGI("BELOW BELOW");
+ } else {
+ LOGE("BELOW NOT BELOW");
+ }
+ }
+ wl_list_for_each(sub, &surface->current.subsurfaces_above, current.link) {
+ // LOGI("above reordered ", sub->reordered, " ", sub, " data ", sub->data);
+ wf::surface_interface_t * si = static_cast<wf::surface_interface_t *>(sub->data);
+ auto it = std::find_if(_as_si->priv->surface_children_above.begin(), _as_si->priv->surface_children_above.end(),
+ [=] (const auto& ptr) { return ptr.get() == si; });
+ if (it != _as_si->priv->surface_children_above.end())
+ {
+ // LOGI("ABOVE ABOVE");
+ } else {
+ LOGE("ABOVE NOT ABOVE");
+ }
+ }
+ for (const auto &ptr : _as_si->priv->surface_children_above) {
+ bool found = false;
+ wl_list_for_each(sub, &surface->current.subsurfaces_above, current.link) {
+ if (sub->data == ptr.get())
+ found = true;
+ }
+ if (!found)
+ LOGE("above not above", ptr.get());
+ }
+ for (const auto &ptr : _as_si->priv->surface_children_below) {
+ bool found = false;
+ wl_list_for_each(sub, &surface->current.subsurfaces_below, current.link) {
+ if (sub->data == ptr.get())
+ found = true;
+ }
+ if (!found)
+ LOGE("below not below", ptr.get());
+ }
}
void wf::wlr_surface_base_t::update_output(wf::output_t *old_output, to check if there's ever any mismatch between Wayfire's |
Sway also does not support compositor-generated subsurfaces like we do, this is why they can use the wlroots list without problems. In fact, I have been considering that we can make wayfire do the same, and manually add the compositor subsurfaces (and keep only them in our lists). Shouldn't be too hard, we should already be storing the The alternative would be to reorder the internal lists, which is ugly, and we'd be duplicating the logic from wlroots.
Yes, it is not surprising they match when the surfaces are created .. however they are reordered later, after mapping. |
uhh in that patch above, I'm doing the check on every commit
Actually
Ohh right it's just a flat reordering, right, that's what I saw in wlroots, but when checking our lists I was expecting things to like, change nesting (e.g. become subsurface-of-subsurface) or change from below list to above list, for some reason :D |
Aha! So this quick patch fixes it (with a side effect of extra diff --git i/src/view/surface.cpp w/src/view/surface.cpp
index ecc4f6d2..6798ad1e 100644
--- i/src/view/surface.cpp
+++ w/src/view/surface.cpp
@@ -270,6 +270,7 @@ wf::wlr_surface_base_t::wlr_surface_base_t(surface_interface_t *self)
auto subsurface = std::make_unique<subsurface_implementation_t>(sub);
nonstd::observer_ptr<subsurface_implementation_t> ptr{subsurface};
+ sub->data = ptr.get();
_as_si->add_subsurface(std::move(subsurface), false);
if (sub->mapped)
{
@@ -406,6 +407,32 @@ void wf::wlr_surface_base_t::commit()
* a frame callback */
_as_si->get_output()->render->schedule_redraw();
}
+ auto remove_from = [=] (auto& container, auto subsurface)
+ {
+ auto it = std::find_if(container.begin(), container.end(),
+ [=] (const auto& ptr) { return ptr.get() == subsurface.get(); });
+
+ std::unique_ptr<surface_interface_t> ret = nullptr;
+ if (it != container.end())
+ {
+ ret = std::move(*it);
+ container.erase(it);
+ }
+
+ return ret;
+ };
+
+ wlr_subsurface *sub;
+ wl_list_for_each(sub, &surface->current.subsurfaces_above, current.link) {
+ nonstd::observer_ptr<surface_interface_t> ptr{static_cast<surface_interface_t*>(sub->data)};
+ auto rm = remove_from(_as_si->priv->surface_children_above, ptr);
+ _as_si->add_subsurface(std::move(rm), false);
+ }
+ wl_list_for_each(sub, &surface->current.subsurfaces_below, current.link) {
+ nonstd::observer_ptr<surface_interface_t> ptr{static_cast<surface_interface_t*>(sub->data)};
+ auto rm = remove_from(_as_si->priv->surface_children_below, ptr);
+ _as_si->add_subsurface(std::move(rm), true);
+ }
}
void wf::wlr_surface_base_t::update_output(wf::output_t *old_output, Not too ugly, but if you'd like to switch to the wlroots list please do :) |
In addition to the ordering thing, I have observed a little damage (?) related glitch (that also doesn't happen in Sway). e.g. with dropdowns like "View" on bugzilla.mozilla.org bug pages, or hover previews in the GitHub dashboard, when these page elements go away they can partially remain until scrolling away. |
I apologize for asking in a somewhat old thread, but is a solution for this currently possible? The graphic artifacts are distressing to me, but I need WebRender for hardware-accelerated video decoding. If a solution isn't feasible right now, can I use the above patch without breaking things? If not, that's okay, I'll figure something out. :) |
@KaryotypeB WebRender itself has never had any problems, this is all about a specific experimental mode that offloads compositing to the system compositor ( |
Ah, I see! I must have misunderstood what that option did. Thanks for clearing that up! :D |
Just had a crash in the above patch: |
Firefox webrender subsurface compositing will stay "experimental for the foreseeable future" according to this. |
Right. That doesn't mean we shouldn't properly implement all subsurface functionality though :) |
Describe the bug
Interesting visual glitches are happening with Firefox WebRender subsurface compositing… Possibly related to #1206
Compositor bugs tracking issue
To Reproduce
gfx.webrender.compositor.force-enabled
and restartScreenshots or stacktrace
https://dl.unrelenting.technology/wf-fx-compositor-1.webm
Wayfire version
git 28b3d39
The text was updated successfully, but these errors were encountered: