[X11][WebRender] Linux partial present
Categories
(Core :: Graphics: WebRender, enhancement, P5)
Tracking
()
People
(Reporter: sotaro, Assigned: nical)
References
(Blocks 2 open bugs)
Details
Attachments
(3 files)
X11 version of Bug 1620076.
Reporter | ||
Comment 1•5 years ago
|
||
It seems that we could use glxCopySubBufferMESA() for it.
- https://www.khronos.org/registry/OpenGL/extensions/MESA/GLX_MESA_copy_sub_buffer.txt
chromium seems to use it. - https://source.chromium.org/chromium/chromium/src/+/master:ui/gl/gl_surface_glx.cc;l=779
Implementation seems not difficult. But I am not sure yet, if glxCopySubBufferMESA() works as expected.
Comment 2•5 years ago
|
||
FTR again, if someone with an better understanding of the code than me would give bug 1474281 a go, we could (hopefully quite easily) implement bug 788319 and therefore use EGL_KHR_swap_buffers_with_damage
on X11, Wayland and Android.
Comment 3•5 years ago
•
|
||
Please wontfix GLX. EGL/X11 is required for bug 1580166 (see bug 1010527 comment 32 and bug 1619523). surfman also switched to EGL on X11.
Updated•5 years ago
|
Updated•5 years ago
|
Comment 5•5 years ago
|
||
Jan, can we reopen this and mark it as dependent on bug 1620076, bug 788319 and https://gitlab.freedesktop.org/mesa/mesa/-/issues/3030? bug 1620076 alone won't be enough for X11 while it is for Wayland.
Comment 6•5 years ago
|
||
Yes, thank you! :)
Updated•5 years ago
|
Updated•4 years ago
|
Updated•4 years ago
|
Assignee | ||
Comment 7•4 years ago
|
||
Comment 8•4 years ago
•
|
||
Nico, are you aware that stransky is actively working on bug 788319 (or bug 1640048, which already implements almost everything needed) as it's needed for bug 1619523? I don't think it makes sense to invest much time into the GLX backend - the EGL backend gives us partial damage in a proper manner for free (as it's shared with Wayland/Android).
Edit: most importantly bug 1580166 has already landed - it's necessary to get good WebGL performance without readbacks)
Edit2: that means with bug 1640048 applied you should already get partial damage support when using the nvidia proprietary driver. Mesa drivers are blocked by https://gitlab.freedesktop.org/mesa/mesa/-/issues/3030
edit3: also, glxCopySubBufferMESA
is obviously not supported on the nvidia driver - and mesa drivers benefit the most from the switch to EGL because of the dmabuf work.
Updated•4 years ago
|
Assignee | ||
Comment 9•4 years ago
•
|
||
Nico, are you aware that stransky is actively working on bug 788319
I wasn't sure whether there was active work towards using EGL instead of GLX. My goal in this hacky portotype was to see if a simple change could yield some short term wins (but I am leaning towads "probably not") and help ship wr on linux+x11 quickly.
I'm definitely in favor of using EGL, but we'll probably want to get webrender enabled for some linux user before it happens.
--
I did a very quick and dirty integration of glxCopySubBuffer in https://phabricator.services.mozilla.com/D81868 to see how it works. The documentation is scarse:
void glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable,
int x, int y, int width, int height );
may be used to copy a rectangular region of the back color buffer to
the front color buffer. This can be used to quickly repaint 3D windows
in response to expose events when the back color buffer cannot be
damaged by other windows.
<x> and <y> indicates the lower-left corner of the region to copy and
<width> and <height> indicate the size in pixels. Coordinate (0,0)
corresponds to the lower-left pixel of the window, like glReadPixels.
If dpy and drawable are the display and drawable for the calling
thread's current context, glXCopySubBufferMESA performs an
implicit glFlush before it returns. Subsequent OpenGL commands
may be issued immediately after calling glXCopySubBufferMESA, but
are not executed until the copy is completed.
This seems to imply a model where we don't swap between buffers, we'd only copy from the back buffer to a persistent front buffer for the window (implying some sort of double buffering, wouldn't work with triple buffering or other types of swapchain)?
If we invalidate the whole window this would mean an extra copy entirely compared to swapbuffer. It's unclear whether we can we mix swap buffer and copysubbuffer depending on the amount of damage.
I am not 100% sure I understand the part about "when the back color buffer cannot be damaged by other windows". I'm assuming that we don't need to worry when the window has its own surface as opposed to rendering directly into the screen as was customary in the earlier days of x11.
Testing this out I get some glitches, for example after scrolling, in a way that looks like glxCopySubBuffer does pretty much what the documentation says without enforcing double buffering. To make it work I suppose we would need to present with double buffering.
An alternative is to use the buffer age extension but having frame building and the renderer on separate threads makes this a bit error prone and ugly.
It looks like EGL has a cleaner API for this, split in two independent pieces: buffer_age to avoid re-rendering content and EGL_KHR_swap_buffers_with_damage to tell the window manager which parts were invalidated and reduce compositor overhead.
Comment 10•4 years ago
•
|
||
bug 1640048 waits for a review over a month now.
- It is the last blocker to reuse the existing Wayland zero copy WebGL and VAAPI code path (bug 1586696, bug 1616185, bug 1629788) on X11.
- DMABUF WebGL is enabled by default on Wayland (bug 1646007 comment 4)
- Enabling VAAPI hardware video decoding by default depends on bug 1595994.
- Almost complete DMABUF/EGL/X11 work is happening here: bug 1645704, bug 1645734, bug 1649120, bug 1619523 comment 23
Comment 11•4 years ago
|
||
Oh, you have edited your comment while I was typing. Sorry for writing the same.
Comment 12•4 years ago
|
||
(In reply to Nicolas Silva [:nical] from comment #9)
I'm definitely in favor of using EGL, but we'll probably want to get webrender enabled for some linux user before it happens.
VAAPI is a killer feature and the VAAPI/DMABUF/EGL/X11 WIP already works fine. 🙈 (bug 1580166 comment 7)
Users have been quite sad that it was Wayland-only so far.
Assignee | ||
Comment 13•4 years ago
|
||
Exciting! It's likely we'll ship the first wave of webrender on linux via x11 nonetheless because it has had more testing and we'd like to start doing that soon. We can forget about partial present through GLX and get it via egl when it's landed, one less thing to do.
Comment 14•4 years ago
|
||
(In reply to Nicolas Silva [:nical] from comment #9)
It looks like EGL has a cleaner API for this, split in two independent pieces: buffer_age to avoid re-rendering content and EGL_KHR_swap_buffers_with_damage to tell the window manager which parts were invalidated and reduce compositor overhead.
Indeed and that's how it was implemented for the EGL backend in bug 1620076 - so what we need here is really only:
- switch to the EGL backend on X11 - stransky took that over and is working on it now
- fix remaining issues with partial present and turn it on by default, tracked in bug 1648799 and bug 1640710 - that's were we could need some help by the gfx team / you :) It would also benefit Android and Win8 AFAIK.
Comment 15•4 years ago
|
||
(In reply to Nicolas Silva [:nical] from comment #9)
Testing this out I get some glitches, for example after scrolling, in a way that looks like glxCopySubBuffer does pretty much what the documentation says without enforcing double buffering. To make it work I suppose we would need to present with double buffering.
I believe there are two issues with your patch:
mGL->SwapBuffers();
is always called, sometimes twice in a row;- missing coordinate translation (see
RenderCompositorEGL::EndFrame()
for the example).
I've attached a fixed version. Could you take a look please?
Assignee | ||
Comment 16•4 years ago
|
||
Thanks Rinat, your version indeed works quite a bit better. I'll look into making sure it only runs where the extension is available, and landing it preffed off. After a bit of testing we'll see if we put it in the MVP since it's a low hanging fruit.
Comment 17•4 years ago
|
||
(In reply to Nicolas Silva [:nical] from comment #16)
<...> and landing it preffed off. After a bit of testing we'll see if we put it in the MVP since it's a low hanging fruit.
That's exactly what I wanted you to consider. Thanks!
As for the pref, there is probably no need for it: gfx::gfxVars::WebRenderMaxPartialPresentRects()
can be used for that, just like it's done in RenderCompositorEGL
.
I've also got some approximate power consumption estimation (PkgWatt
metric from turbostat
). With that patch it goes from ~2.3 W to ~1.8 W on a page with nothing but a 128x128 GIF animation, so it really gains something.
Updated•4 years ago
|
Comment 18•4 years ago
|
||
(In reply to Robert Mader [:rmader] from comment #8)
edit3: also,
glxCopySubBufferMESA
is obviously not supported on the nvidia driver - and mesa drivers benefit the most from the switch to EGL because of the dmabuf work.
While NVIDIA drivers have no string "GLX_MESA_copy_sub_buffer" inside them, their libGL.so.1.7.0
exports glXCopySubBufferMESA
symbol.
Currently I have no access to a machine which has NVIDIA as a primary video adapter, so I'm not sure if it works. But it may work. After all, it's a 20-year old tech. Perhaps it was added at some point, but without mentioning it in the supported extensions list.
Comment 19•4 years ago
|
||
Thanks for fixing the patch!
Proprietary Nvidia should better not be part of the initial MVP.
- On Gnome desktops it is still affected by broken rendering when resuming from standby.
- On non-Gnome desktops, it additionally causes noticeable performance problems until users manually enable "Force Composition Pipeline" in Nvidia X Server settings. Even glxgears is affected by that.
- Of course it would be nice if it supported this GLX extension.
- Proprietary Nvidia supports EGL_EXT_buffer_age and EGL_KHR_swap_buffers_with_damage. bug 1650583 blocks us from using EGL there. Surfman had the same problem and there are two approaches: Either "Avoid calling eglMakeCurrent prior to creating a window surface" or "create a 1x1 pbuffer dummy surface and make current against that when you want to unlock your main surface".
Comment 20•4 years ago
|
||
(In reply to Rinat from comment #18)
While NVIDIA drivers have no string "GLX_MESA_copy_sub_buffer" inside them, their
libGL.so.1.7.0
exportsglXCopySubBufferMESA
symbol.Currently I have no access to a machine which has NVIDIA as a primary video adapter, so I'm not sure if it works. But it may work. After all, it's a 20-year old tech. Perhaps it was added at some point, but without mentioning it in the supported extensions list.
Oh, that's good to know, thanks. I still hope to get the EGL backend into shape soon, but given that EGL_KHR_swap_buffers_with_damage
on X11 has not even landed in mesa it's probably a good idea to start the MVP with this.
Comment 21•4 years ago
|
||
Assignee | ||
Comment 22•4 years ago
|
||
Currently I have no access to a machine which has NVIDIA as a primary video adapter, so I'm not sure if it works. But it may work.
The extension doesn't work on my nvidia desktop (proprietary drivers). Calling glXCopySubBufferMESA symbol does nothing as far as I can tell (if I skip checking that the extension is supported).
Oh, that's good to know, thanks. I still hope to get the EGL backend into shape soon,
EGL is still very much the way forward.
Comment 23•4 years ago
|
||
Backed out for wr failure on position-sticky-scroll-reposition.html
Backout link: https://hg.mozilla.org/integration/autoland/rev/3bec24fa02a398b09ed6d9179694c54e38751859
Log link: https://treeherder.mozilla.org/logviewer.html#/jobs?job_id=309970916&repo=autoland&lineNumber=13885
Comment 24•4 years ago
|
||
(In reply to Nicolas Silva [:nical] from comment #22)
The extension doesn't work on my nvidia desktop (proprietary drivers). Calling glXCopySubBufferMESA symbol does nothing as far as I can tell (if I skip checking that the extension is supported).
That explains why it wasn't mentioned in the list of supported extensions.
EGL is still very much the way forward.
By the way, are EGL-partial-present-related extensions working on NVIDIA's proprietary driver?
Comment 25•4 years ago
|
||
(In reply to Rinat from comment #24)
By the way, are EGL-partial-present-related extensions working on NVIDIA's proprietary driver?
Unfortunately we couldn't test that with FF so far because of bug 1650583 and bug 1648872 :(
Comment 26•4 years ago
|
||
Gnome XWayland, Debian Testing, Radeon RX480
With steps from bug 1648872 comment 0 I can confirm that GLX partial present works with build from comment 21:
mozregression --repo autoland --launch 74a508f9bac4 --pref gfx.webrender.all:true gfx.webrender.max-partial-present-rects:1
Comment 27•4 years ago
|
||
(In reply to Robert Mader [:rmader] from comment #25)
Unfortunately we couldn't test that with FF so far because of bug 1650583 and bug 1648872 :(
The only thing that really blocks from testing it, is the physical absence of a machine with NVIDIA adapter. :)
Simple test would consist of creating GL context, glClear() with all-red color, buffer swap, then glClear() with all-green color, partial present of some rectangle. If in result one can see a green box on a red background, then partial present works.
Comment 28•4 years ago
|
||
(In reply to Jan Andre Ikenmeyer [:darkspirit] from comment #26)
Gnome XWayland, Debian Testing, Radeon RX480
With steps from bug 1648872 comment 0 I can confirm that GLX partial present works with build from comment 21:
mozregression --repo autoland --launch 74a508f9bac4 --pref gfx.webrender.all:true gfx.webrender.max-partial-present-rects:1
This is good to hear as it suggest X11 is not affected by bug 1648872 and maybe points into a direction I speculated about in bug 1617002 comment 1 - will check.
(In reply to Rinat from comment #27)
(In reply to Robert Mader [:rmader] from comment #25)
Unfortunately we couldn't test that with FF so far because of bug 1650583 and bug 1648872 :(
The only thing that really blocks from testing it, is the physical absence of a machine with NVIDIA adapter. :)
Same here :)
Simple test would consist of creating GL context, glClear() with all-red color, buffer swap, then glClear() with all-green color, partial present of some rectangle. If in result one can see a green box on a red background, then partial present works.
Indeed, although I'd recommed to also validate with some external tool like e.g. Mutter as described in bug 1648872 comment 0 - so we can be sure that WMs / compostitors really get the right info.
Assignee | ||
Updated•4 years ago
|
Comment 29•4 years ago
|
||
(In reply to Rinat from comment #27)
The only thing that really blocks from testing it, is the physical absence of a machine with NVIDIA adapter. :)
Err only understood you now - right :)
Don't have one here, will you give it a try?
Comment 30•4 years ago
|
||
Yes, SwapBuffersWithDamageKHR is supported by proprietary Nvidia (GTX1060) on X11 and it works:
https://github.com/rust-windowing/glutin/blob/master/glutin_examples/examples/damage.rs
As expected, only the bottom-left corner gets invalidated if nothing else has to be invalidated.
git clone https://github.com/rust-windowing/glutin
cd glutin
nano glutin_examples/examples/damage.rs
change
ContextBuilder::new().build_windowed(wb, &el).unwrap();
to
ContextBuilder::new().with_gl(glutin::GlRequest::Specific(glutin::Api::OpenGlEs, (3, 1))).build_windowed(wb, &el).unwrap();
to use GLES/EGL
cargo run --example damage
Comment 31•4 years ago
|
||
Comment 32•4 years ago
|
||
(In reply to Robert Mader [:rmader] from comment #29)
(In reply to Rinat from comment #27)
The only thing that really blocks from testing it, is the physical absence of a machine with NVIDIA adapter. :)
Err only understood you now - right :)
Don't have one here, will you give it a try?
I don't have any available unfortunately, so couldn't check myself.
There is an eGPU enclosure, but I failed to pass-through GPU from it to a VM. Looks like NVIDIA driver actively refuses to support VMs.
Comment 33•4 years ago
|
||
bugherder |
Comment 34•4 years ago
|
||
(In reply to Rinat from comment #27)
Simple test would consist of creating GL context, glClear() with all-red color, buffer swap, then glClear() with all-green color, partial present of some rectangle. If in result one can see a green box on a red background, then partial present works.
Temporary got a cloud VM with NVIDIA GPU attached, and tried exactly that. Can confirm that glXCopySubBufferMESA()
has no visible effects when running on NVIDIA proprietary driver.
Comment 35•4 years ago
•
|
||
I just got a ping from Michel Dänzer (xorg/mesa dev) that glXCopySubBufferMESA()
is somewhat buggy in his experience. So it might turn out we need to wait for EGL_KHR_swap_buffers_with_damage
on X11 support and the EGL switch to really turn this on :/ - but lets wait a bit for some testing.
Edit: he just commented, see bug 1648799 comment 5
Assignee | ||
Comment 36•4 years ago
|
||
This landed preffed off so the bug isn't fixed quite yet.
I just got a ping from Michel Dänzer (xorg/mesa dev) that glXCopySubBufferMESA() is somewhat buggy in his experience.
Ok thanks, that's good to know. well let's keep it preffed off an reevaluate if we find that performance/power usage is unacceptable.
Updated•4 years ago
|
Assignee | ||
Updated•4 years ago
|
Comment 37•4 years ago
|
||
EGL_KHR_swap_buffers_with_damage support for X11 has now been merged to upstream Mesa (so it'll be in mesa 20.3). Backport to mesa 20.2 branch is still pending.
Comment 38•4 years ago
|
||
EGL_KHR_swap_buffers_with_damage support for X11 https://gitlab.freedesktop.org/mesa/mesa/-/issues/3030 and https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6132
Comment 39•4 years ago
|
||
egl/x11 support for EGL_KHR_swap_buffers_with_damage has now been merged to mesa 20.2 branch, and is available in mesa 20.2.0-rc4 (and later).
https://lists.freedesktop.org/archives/mesa-dev/2020-September/224608.html
Updated•4 years ago
|
Updated•4 years ago
|
Comment 40•4 years ago
|
||
mesa 20.2.0 has been released recently, and it includes egl/x11 support for "EGL_KHR_swap_buffers_with_damage".
Comment 41•4 years ago
|
||
With bug 1656533 fixed, I think this can also be declared fixed.
On to bug 1648799!
Updated•4 years ago
|
Description
•