Closed
Bug 942302
Opened 12 years ago
Closed 5 years ago
Use GLX pixmaps to provide faster compositing of WebGL with xrender
Categories
(Core :: Graphics: CanvasWebGL, enhancement, P3)
Core
Graphics: CanvasWebGL
Tracking
()
RESOLVED
DUPLICATE
of bug 1572697
People
(Reporter: jgilbert, Unassigned)
References
Details
(Whiteboard: webgl-perf)
Attachments
(1 file, 1 obsolete file)
45.50 KB,
patch
|
karlt
:
review+
nrc
:
review+
|
Details | Diff | Splinter Review |
From talking with :karlt, it sounds like if we render into pixmaps for WebGL, we should get fast rendering when we hand them off to xrender. This should improve default performance of WebGL on linux where we don't have proper OGL accel. (the lack of which is the current default)
Reporter | ||
Updated•12 years ago
|
Whiteboard: webgl-perf
Reporter | ||
Comment 1•12 years ago
|
||
WIP, almost building.
I'm hitting a symbol resolution conflict, though:
0:08.36 In file included from /home/jgilbert/ram/objs/obj-dbg/gfx/layers/Unified_cpp_gfx_layers1.cpp:9:
0:08.36 In file included from /home/jgilbert/dev/mozilla/central/gfx/layers/client/ClientCanvasLayer.cpp:33:
0:08.36 In file included from ../../dist/include/SharedSurfaceXRenderPixmap.h:9:
0:08.36 In file included from ../../dist/include/gfxXlibSurface.h:11:
0:08.36 In file included from ../../dist/system_wrappers/X11/extensions/Xrender.h:3:
0:08.36 /usr/include/X11/extensions/Xrender.h:302:13: error: reference to 'Glyph' is ambiguous
0:08.36 _Xconst Glyph *gids,
0:08.36 ^
0:08.36 /usr/include/X11/extensions/render.h:31:14: note: candidate found by name lookup is 'Glyph'
0:08.36 typedef XID Glyph;
0:08.36 ^
0:08.36 ../../dist/include/mozilla/gfx/2D.h:478:8: note: candidate found by name lookup is 'mozilla::gfx::Glyph'
0:08.36 struct Glyph
Assignee: nobody → jgilbert
Reporter | ||
Comment 3•12 years ago
|
||
WFM. I'll post it to try and see how sad things are.
Attachment #8337164 -
Attachment is obsolete: true
Attachment #8343486 -
Flags: review?(ncameron)
Attachment #8343486 -
Flags: review?(karlt)
Reporter | ||
Comment 4•12 years ago
|
||
Comment 5•12 years ago
|
||
Comment on attachment 8343486 [details] [diff] [review]
webgl-pixmap
I started looking through this. Some comments to date:
>+ virtual void SetGLXDrawableOverride(uint64_t drawable) {
XID is a typedef for long. Making this parameter long will mean that no casts
are required.
>+ // Call with LOCAL_GLX_NONE to reset the override.
"None". GLX_NONE is different.
>+ LOCAL_GLX_RENDER_TYPE, caps.alpha ? LOCAL_GLX_RGBA_BIT : 0,
GLX_RENDER_TYPE shouldn't depend on caps.alpha.
We probably want GLX_RGBA_BIT always.
GLX_COLOR_INDEX_BIT corresponds to GLX_PSEUDO_COLOR. Usually 8-bit color.
Does LOCAL_GLX_DOUBLEBUFFER matter for offscreen contexts?
>+#include "nsAutoPtr.h"
template <class T> class nsRefPtr;
>+SharedSurface_XRenderPixmap::Fence()
>+{
>+ mGLX.xWaitGL();
>+ virtual bool WaitSync() MOZ_OVERRIDE { return true; }
I don't know exactly what Fence and WaitSync mean, but somewhere I assume we
need a glxWaitX() to ensure that reading from a surface has finished.
Also, note that glxWaitX is a no-op (but shouldn't be) with Mesa, and so
FinishX was used with tfp.
http://hg.mozilla.org/mozilla-central/annotate/551efcc4de6f/gfx/gl/GLContextProviderGLX.cpp#l446
Similarly, if there isn't already a glFlush with the Fence(), I suspect one will be needed with Mesa because glxWaitGL doesn't do the
right thing.
https://bugs.freedesktop.org/show_bug.cgi?id=52930
Reporter | ||
Comment 6•12 years ago
|
||
(In reply to Karl Tomlinson (:karlt) from comment #5)
> Comment on attachment 8343486 [details] [diff] [review]
> webgl-pixmap
>
> I started looking through this. Some comments to date:
>
> >+ virtual void SetGLXDrawableOverride(uint64_t drawable) {
>
> XID is a typedef for long. Making this parameter long will mean that no
> casts
> are required.
Fair.
>
> >+ // Call with LOCAL_GLX_NONE to reset the override.
>
> "None". GLX_NONE is different.
Yep, I discovered this, but it looks like I forgot to update the comments.
>
> >+ LOCAL_GLX_RENDER_TYPE, caps.alpha ? LOCAL_GLX_RGBA_BIT : 0,
>
> GLX_RENDER_TYPE shouldn't depend on caps.alpha.
> We probably want GLX_RGBA_BIT always.
> GLX_COLOR_INDEX_BIT corresponds to GLX_PSEUDO_COLOR. Usually 8-bit color.
This seems weird, but ok. I assume then that RGBA here is a misnomer, and it's actually RGB(X/A)?
>
> Does LOCAL_GLX_DOUBLEBUFFER matter for offscreen contexts?
IIRC, pixmaps are single-buffered.
>
> >+#include "nsAutoPtr.h"
>
> template <class T> class nsRefPtr;
>
> >+SharedSurface_XRenderPixmap::Fence()
> >+{
> >+ mGLX.xWaitGL();
>
> >+ virtual bool WaitSync() MOZ_OVERRIDE { return true; }
>
> I don't know exactly what Fence and WaitSync mean, but somewhere I assume we
> need a glxWaitX() to ensure that reading from a surface has finished.
We don't actually fence on both sides of the operation, currently. I think that glxWaitGL should actually be in WaitSync instead of Fence, anyways.
Fence is called when Content is done rendering a frame. WaitSync is called by the consumer (compositor) when it wants to make sure the frame data is actually realized.
>
> Also, note that glxWaitX is a no-op (but shouldn't be) with Mesa, and so
> FinishX was used with tfp.
> http://hg.mozilla.org/mozilla-central/annotate/551efcc4de6f/gfx/gl/
> GLContextProviderGLX.cpp#l446
>
> Similarly, if there isn't already a glFlush with the Fence(), I suspect one
> will be needed with Mesa because glxWaitGL doesn't do the
> right thing.
> https://bugs.freedesktop.org/show_bug.cgi?id=52930
Gross, but ok.
Comment 7•12 years ago
|
||
Comment on attachment 8343486 [details] [diff] [review]
webgl-pixmap
Review of attachment 8343486 [details] [diff] [review]:
-----------------------------------------------------------------
Just checked the layers stuff. The GLContext and X things I don't know well enough to review. Not sure if karl will cover GLContext, might be good to ask bjacob to review that.
::: gfx/layers/CopyableCanvasLayer.cpp
@@ +63,5 @@
> + // Possibly morph to a faster SurfaceFactory type.
> + GLScreenBuffer* screen = mGLContext->Screen();
> + const SurfaceCaps& caps = screen->Caps();
> + SurfaceFactory_GL* factory = nullptr;
> + if (!mForceReadback) {
nit: merge with below if
@@ +72,5 @@
> +#endif
> + }
> +
> + if (factory) {
> + SurfaceStreamType streamType =
whitespace
@@ +130,5 @@
> if (!sharedSurf) {
> NS_WARNING("Null frame received.");
> return;
> }
> + if (!sharedSurf->HasAlpha()) {
merge the if clause into the assert
@@ +133,5 @@
> }
> + if (!sharedSurf->HasAlpha()) {
> + MOZ_ASSERT(GetContentFlags() & CONTENT_OPAQUE);
> + }
> +
whitespace
@@ +159,4 @@
> } else {
> + // Non-ShSurfBasic readback. Not a standard GLContext path.
> + // Don't bother to optimize away copies for this.
> + MOZ_ASSERT(!tempSurf);
seems unnecessary
@@ +161,5 @@
> + // Don't bother to optimize away copies for this.
> + MOZ_ASSERT(!tempSurf);
> + tempSurf = GetTempSurface(readSize, format);
> + // Readback handles Flush/MarkDirty.
> + mGLContext->Screen()->Readback(surfGL, tempSurf);
does this always succeed?
@@ +167,5 @@
> +
> + if (!destSurf) {
> + destSurf = srcSurf; // Avoid creating multiple temp surfs
> + // Also, since this is a temp surf, we can modify it, unlike the data
> + // in srcSurf, which we can't safely change.
this comment is unclear to me, aren't we just aliasing srcSurf/tempSurf, so the data is the same?
@@ +193,5 @@
> + tempSurf = GetTempSurface(readSize, format);
> + destSurf = tempSurf;
> + }
> + MOZ_ASSERT(destSurf);
> +
whitespace
@@ +194,5 @@
> + destSurf = tempSurf;
> + }
> + MOZ_ASSERT(destSurf);
> +
> + nsRefPtr<gfxImageSurface> mutableSurf = destSurf->GetAsImageSurface(); // Nullable
nit don't need the comment - it is obvious from the next if statement
@@ +223,3 @@
> }
> +
> + if (!destSurf)
{}, but I don't think we ever hit this - you assert destSurf above and don't null it.
@@ +224,5 @@
> +
> + if (!destSurf)
> + destSurf = srcSurf;
> +
> + if (srcSurf != destSurf)
{}
::: gfx/layers/client/ClientCanvasLayer.cpp
@@ +46,5 @@
>
> mCanvasClient = nullptr;
>
> if (mGLContext) {
> + mNeedsYFlip = true;
indent
@@ +47,5 @@
> mCanvasClient = nullptr;
>
> if (mGLContext) {
> + mNeedsYFlip = true;
> +
whitespace
@@ +53,4 @@
> SurfaceFactory_GL* factory = nullptr;
> if (!mForceReadback) {
> + const SurfaceCaps& caps = screen->Caps();
> +
whitespace
Attachment #8343486 -
Flags: review?(ncameron) → review+
Comment 8•11 years ago
|
||
Comment on attachment 8343486 [details] [diff] [review]
webgl-pixmap
(In reply to Jeff Gilbert [:jgilbert] from comment #6)
> (In reply to Karl Tomlinson (:karlt) from comment #5)
> >
> > >+ LOCAL_GLX_RENDER_TYPE, caps.alpha ? LOCAL_GLX_RGBA_BIT : 0,
> >
> > GLX_RENDER_TYPE shouldn't depend on caps.alpha.
> > We probably want GLX_RGBA_BIT always.
> > GLX_COLOR_INDEX_BIT corresponds to GLX_PSEUDO_COLOR. Usually 8-bit color.
> This seems weird, but ok. I assume then that RGBA here is a misnomer, and
> it's actually RGB(X/A)?
Yes, I assume RGBA just means there are separate channels rather than indices, even if some of the channels may have zero bits.
> >
> > Does LOCAL_GLX_DOUBLEBUFFER matter for offscreen contexts?
> IIRC, pixmaps are single-buffered.
http://www.opengl.org/sdk/docs/man2/xhtml/glXCreateGLXPixmap.xml says "GLX
pixmaps with double-buffering are supported. However, glXSwapBuffers is
ignored by these pixmaps."
I guess that means that pixmaps with double buffering behave like those
without, so GLX_DOUBLEBUFFER doesn't matter here.
> > >+SharedSurface_XRenderPixmap::Fence()
> > >+{
> > >+ mGLX.xWaitGL();
> >
> > >+ virtual bool WaitSync() MOZ_OVERRIDE { return true; }
> >
> > I don't know exactly what Fence and WaitSync mean, but somewhere I assume we
> > need a glxWaitX() to ensure that reading from a surface has finished.
> We don't actually fence on both sides of the operation, currently.
That may not be too bad with the way layers are always only reused for the
same content. If reading has not finished when the new bits are being drawn,
then the reading will read new bits instead of the old. That may produce some
flickering or tearing but eventually all new bits should be displayed.
> I think
> that glxWaitGL should actually be in WaitSync instead of Fence, anyways.
> Fence is called when Content is done rendering a frame. WaitSync is called
> by the consumer (compositor) when it wants to make sure the frame data is
> actually realized.
I guess the best implementation here would set a flag in Fence, and
glxWaitGL/Flush in WaitSync if the flag has been set.
>- GLXPixmap glxpixmap = 0;
>+ GLXPixmap pixmap;
I found this less confusing when the variable was named |glxpixmap|.
>+ MOZ_ASSERT(!caps.any);
>+ SurfaceCaps offscreenCaps = caps;
>+ if (caps.antialias) {
>+ offscreenCaps.depth = false;
>+ offscreenCaps.stencil = false;
>+ offscreenCaps.antialias = false;
>+ }
I don't know why antialias implies depth and stencil are false.
>+/*
>+#ifdef MOZ_WIDGET_GTK
>+#include <gdk/gdk.h>
>+#include <gdk/gdkx.h>
>+#define GET_NATIVE_WINDOW(aWidget) GDK_WINDOW_XID((GdkWindow *) aWidget->GetNativeData(NS_NATIVE_WINDOW))
>+#elif defined(MOZ_WIDGET_QT)
>+#include <QWidget>
>+#define GET_NATIVE_WINDOW(aWidget) static_cast<QWidget*>(aWidget->GetNativeData(NS_NATIVE_SHELLWIDGET))->winId()
>+#endif
>+*/
This can be removed, I assume.
>+ GLXLibrary& glx,
>+ GLXLibrary& mGLX;
Convention is usually to use a pointer, isn't it?
What was the motivation for using a reference?
>- ? gfxImageFormatRGB24
>- : gfxImageFormatARGB32;
>+ ? gfxImageFormatRGB24
>+ : gfxImageFormatARGB32;
Unnecessary whitespace change.
r+ on the gl/ changes, assuming the build can be fixed as well as the
X_PutImage BadDrawable and ASAN crash. Any ideas there?
I quickly looked over the layers changes, but didn't review them.
I'll leave those to nrc.
Attachment #8343486 -
Flags: review?(karlt) → review+
Reporter | ||
Updated•11 years ago
|
See Also: → slow-linux-webgl
Reporter | ||
Updated•11 years ago
|
Blocks: slow-linux-webgl
Comment 10•10 years ago
|
||
Any progress to report?
Reporter | ||
Comment 11•10 years ago
|
||
(In reply to madbiologist from comment #10)
> Any progress to report?
This is pretty heavily bitrotted. IIRC, the issue I was having that prevented landing was a number of miscellaneous GLX errors when run on Try.
It's worth picking this up again at some point, as the core concept is still valid. Not right now though.
Assignee: jgilbert → nobody
Reporter | ||
Updated•6 years ago
|
Priority: -- → P3
Reporter | ||
Updated•6 years ago
|
Type: defect → enhancement
Comment 12•5 years ago
|
||
I guess this can now be closed, right? We now use DMABuf sharing instead.
Updated•5 years ago
|
Status: NEW → RESOLVED
Closed: 5 years ago
Resolution: --- → DUPLICATE
You need to log in
before you can comment on or make changes to this bug.
Description
•