Closed Bug 565833 Opened 14 years ago Closed 14 years ago

Add a GLX backend to GLContextProvider

Categories

(Core :: Graphics, defect)

x86
Linux
defect
Not set
normal

Tracking

()

RESOLVED FIXED
Tracking Status
blocking2.0 --- final+

People

(Reporter: mattwoodrow, Assigned: mattwoodrow)

References

Details

Attachments

(7 files, 8 obsolete files)

4.81 KB, text/plain
Details
23.35 KB, text/plain
Details
11.96 KB, text/plain
Details
11.96 KB, patch
karlt
: review-
Details | Diff | Splinter Review
36.71 KB, text/plain
Details
19.43 KB, patch
vlad
: review+
Details | Diff | Splinter Review
4.44 KB, patch
vlad
: review+
Details | Diff | Splinter Review
      No description provided.
Attached patch Partially working attempt 1 (obsolete) — Splinter Review
This appears to render video for my via opengl, but suffers from horrible performance (0.1fps approximately).
Basic profiling suggests most of the CPU time is being spent within libGLcore.so.

Attempting to run this on karl machine required adding doublebuffering support (only double buffered visuals were available) and now errors inside LayerManagerOGL::Initialize().

Line 157 - glTextImage2D throws GL_INVALID_VALUE on the first iteration (GL_TEXTURE_2D).
Stepping through this and clearing the error flags lets the second iteration complete, but the frame buffer status check (line 174) fails both times.

Could someone please try this on their hardware and see if any of the problems are resolved?
Don't know enough about gl coding to track the issues down currently, any suggestions would be appreciated.
glCheckFramebufferStatus appears to be returning 0 on both iterations, which isn't one of the documented return values for it.
What hardware and drivers are you testing this on?
Also, on karl's and your machines, what versions of GL are actually supported?  Pasting the output of glxinfo would help.
(II) Module radeon: vendor="X.Org Foundation"
        compiled for 1.5.3, module version = 6.12.2
        Module class: X.Org Video Driver
        ABI class: X.Org Video Driver, version 4.1

(--) RADEON(0): Chipset: "ATI Mobility Radeon X1400" (ChipID = 0x7145)

(II) RADEON(0): Framebuffer space used by Firmware (kb): 20
(II) RADEON(0): Start of VRAM area used by Firmware: 0x7ffb000
(II) RADEON(0): AtomBIOS requests 20kB of VRAM scratch space
(II) RADEON(0): AtomBIOS VRAM scratch base: 0x7ffb000
(II) RADEON(0): Cannot get VRAM scratch space. Allocating in main memory instead

(II) RADEON(0): [dri] Found DRI library version 1.3.0 and kernel module version 1.29.0

This might be relevant:

(**) RADEON(0): Option "FBTexPercent" "0"

             "Specifying 0 results in all offscreen video
              RAM being reserved for EXA and only GART memory being  available
              for  OpenGL  textures."
Attached file Glxinfo output
Attachment #445625 - Attachment mime type: application/octet-stream → text/plain
Karl's driver only supports OpenGL 1.4, and does not explicitly export GL_EXT_framebuffer_object -- mesa frequently provides dummy implementations of entries, so checking whether the function entries exist isn't sufficient to determine whether a feature is present and/or available.  We need to add explicit version and extension checks in the GL context providers.
Alright, I'll add a check for GL_EXT_framebuffer_object.

Regarding the terrible performance on my machine, I've narrowed it down to massive amounts of time being spent inside calls to glDrawArrays (3 seconds plus per call). oprofile shows 80%+ of the CPU time being spent inside libGLcore.so

This sounds like some sort of software fallback, but I can't find any information on how to detect if this is happening.
Attached patch Updated patch (obsolete) — Splinter Review
Added gl version string and gl extension checking.

This definitely needs testing on other hardware, appears to work for me though.
Attachment #445287 - Attachment is obsolete: true
Attachment #445848 - Flags: review?
Attachment #445848 - Flags: review? → review?(bas.schouten)
Attached patch Added CreatePBuffer support. (obsolete) — Splinter Review
Rebased against tip (vlad's Canvas layers changes) and added support for CreatePBuffer.

Tested with WebGL examples and works.
Attachment #445848 - Attachment is obsolete: true
Attachment #445848 - Flags: review?(bas.schouten)
(In reply to comment #10)
> Created an attachment (id=446135) [details]

Building this patch against 1e9af0857103, I get

GLContextProviderGLX.cpp
In file included from /usr/include/GL/glx.h:351,
                 from ../../../dist/include/GLXLibrary.h:41,
                 from /home/cjones/mozilla/mozilla-central/gfx/thebes/src/GLContextProviderGLX.cpp:41:
/usr/include/GL/glxext.h:803: error: ‘GLboolean’ has not been declared
make[6]: *** [GLContextProviderGLX.o] Error 1
make[5]: *** [libs] Error 2
make[4]: *** [libs] Error 2
make[3]: *** [libs_tier_platform] Error 2
make[2]: *** [tier_platform] Error 2
make[1]: *** [default] Error 2
make: *** [build] Error 2

on this machine

$ uname -a && glxinfo 
Linux beast 2.6.31-21-generic #59-Ubuntu SMP Wed Mar 24 07:28:27 UTC 2010 x86_64 GNU/Linux
name of display: :0.0
display: :0  screen: 0
direct rendering: Yes
server glx vendor string: NVIDIA Corporation
server glx version string: 1.4
[snip]
OpenGL vendor string: NVIDIA Corporation
OpenGL renderer string: GeForce GT 220/PCI/SSE2
OpenGL version string: 3.0.0 NVIDIA 185.18.36
OpenGL shading language version string: 1.30 NVIDIA via Cg compiler
[snip]
Chris, I suspect the solution is to not define __gl_h_ here:
http://hg.mozilla.org/mozilla-central/annotate/6d70525ff299/gfx/thebes/public/GLDefs.h#l43

because gl.h hasn't been included.
Attachment #446135 - Attachment is obsolete: true
Attachment #446380 - Flags: review?(bas.schouten)
Comment on attachment 446380 [details] [diff] [review]
Fixed compile issue on some systems

In general it would be a good idea to let someone else look at the widget part of this patch, and some of the linux stuff. Vlad suggested karlt. Here's my comments. It should probably be split up into a Widget patch and a GFx patch.

>@@ -190,6 +193,7 @@
>     return false;
>   }
> 
>+  mGLContext->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);

Why is this needed?

>+
>+#if defined LINUX
>+    /**
>+     * Creates an appropriate XVisualInfo setup for the current system.
>+     *
>+     * @return XVisualInfo pointer. Must not be freed.
>+     */
>+    static XVisualInfo *CreateVisualInfo();
>+#endif

Will this not also build in some Linux situations where we won't have XVisualInfo ? We probably need to check for some GDK specific thing? Should ask karlt about this or something. Also I'm really not happy about having this in here, but I don't see a better way for it right now sadly.

>     PFNWGLCREATECONTEXTPROC fCreateContext;
>diff -r f92702311196 gfx/thebes/src/GLContext.cpp
>--- a/gfx/thebes/src/GLContext.cpp	Wed May 19 09:56:42 2010 +1200
>+++ b/gfx/thebes/src/GLContext.cpp	Thu May 20 11:23:52 2010 +1200
>@@ -315,10 +315,52 @@
> 
>     };
> 
>-    mInitialized = LoadSymbols(&symbols[0], trygl, prefix);
>+    if (!LoadSymbols(&symbols[0], trygl, prefix)) {
>+        return PR_FALSE;
>+    }
>+    
>+    MakeCurrent();
>+    if (atof((const char *)fGetString(LOCAL_GL_VERSION)) < 2.0) {
>+        return PR_FALSE;
>+    }

I thought a bunch of the functions we look for don't exist on GL versions smaller than 2.0 anyway? So I don't think this is needed. In any case I'm not sure I'm happy about just atof here.. atof(NULL) is not allowed iirc.

>+PRBool GLContext::IsExtensionSupported(const char *extension)

Good idea to have this, if we end up using this more we may want to store it in some more clever way for quicker repeated use.

>+    if (!LibrarySymbolLoader::LoadSymbols(mOGLLibrary, &symbols[0])) {
>+        NS_WARNING("Couldn't find required entry point in OpenGL DLL");

Technically you're not looking in a DLL ;-)

>+already_AddRefed<GLContext>
>+GLContextProvider::CreatePBuffer(const gfxIntSize &aSize, const ContextFormat& aFormat)
>+{
>+    if (!sGLXLibrary.EnsureInitialized()) {
>+        return nsnull;
>+    }
>+
>+    nsTArray<int> attribs;
>+
>+#define A1_(_x)  do { attribs.AppendElement(_x); } while(0)
>+#define A2_(_x,_y)  do {                                                \
>+        attribs.AppendElement(_x);                                      \
>+        attribs.AppendElement(_y);                                      \
>+    } while(0)

Personally I'd prefer if these are defined outside of the function body.
Attachment #446380 - Flags: review?(bas.schouten) → review-
(In reply to comment #14)
> >+#if defined LINUX
> >+    /**
> >+     * Creates an appropriate XVisualInfo setup for the current system.
> >+     *
> >+     * @return XVisualInfo pointer. Must not be freed.
> >+     */
> >+    static XVisualInfo *CreateVisualInfo();
> >+#endif
> 
> Will this not also build in some Linux situations where we won't have
> XVisualInfo ? We probably need to check for some GDK specific thing?

Xlib.h will pull in XVisualInfo and I expect X11/Qt builds will want this too, so MOZ_X11 is probably the appropriate thing to test here.

(I don't know whether or not MOZ_DFB will use this file nor how GL works with DirectFB.)
(In reply to comment #14)
> >+    MakeCurrent();
> >+    if (atof((const char *)fGetString(LOCAL_GL_VERSION)) < 2.0) {
> >+        return PR_FALSE;
> >+    }
> 
> I thought a bunch of the functions we look for don't exist on GL versions
> smaller than 2.0 anyway? So I don't think this is needed. In any case I'm not
> sure I'm happy about just atof here.. atof(NULL) is not allowed iirc.

Mesa /always/ returns symbols (as do many other opengl implementations), even if the underlying hardware/driver/whatever combo does not support a particular extension.  So we need a check beyond just looking for the symbols; that's where the GL version check came from.

Checking for GL 2.0 is ok, but there might well be some systems out there that support the set of functionality we want via the extensions, but don't advertise OpenGL 2.0.  Not sure we care.  However, if we do go with just a GL version check, then we need to make sure that what we're using really is just GL 2.0 (and not stuff that was made core in 2.1 or whenever).  Otherwise we have to check GL_EXTENSIONS directly for the set of things that we need.
(In reply to comment #16)
> Checking for GL 2.0 is ok, but there might well be some systems out there that
> support the set of functionality we want via the extensions, but don't
> advertise OpenGL 2.0.  Not sure we care.

A useful data point might be the implication at http://xorg.freedesktop.org/wiki/RadeonFeature that because ATI cards older than R600 don't support ARB NPOT textures fully, they don't fully support OpenGL 2.0.  I don't know whether the missing features can or will be done in software one day such that the driver may advertise OpenGL 2.0 support.
Attached patch Widget changes (obsolete) — Splinter Review
Could someone please submit these two patches to the try server for me?

I've tried submitting using the web form and only got results back for the maemo platform.
Blocks: 569242
blocking2.0: --- → ?
Depends on: 569775
Hi, I just tried this patch on a new linux setup, and got a crash very early at firefox startup. I am attaching a backtrace obtained using MOZ_X_SYNC=1 as per the recommendation I got from the console output.

The linux system is Fedora 13 / x86-64 with the proprietary nvidia driver.
Comment on attachment 447475 [details] [diff] [review]
Widget changes

>+            cachedVisual = gdk_x11_screen_lookup_visual(gdkscreen, xvisual->visualid);
>+            if (visual) {
owAttr attributes;

Change this to if (cachedVisual).
I retried with the fix given in comment 23 (and another difference was that this time I had the patch from bug 569775 applied) and this fixes it. Moreover, I can now enjoy hw-accelerated WebGL for the first time. Thanks!
Can we get this checked in in its current state, and do followup fixes for various drivers/etc?  It's not something that's enabled by default (and we can even add a pref for fullscreen video if needed), but it would make WebGL work again on Linux (where it works, at least).
Attached patch Fixed unitialized variable (obsolete) — Splinter Review
Attachment #447475 - Attachment is obsolete: true
Attachment #449174 - Flags: review?(karlt)
Attachment #447474 - Flags: review?(bas.schouten)
Attachment #449174 - Attachment is obsolete: true
Attachment #449188 - Flags: review?(karlt)
Attachment #449174 - Flags: review?(karlt)
Comment on attachment 447474 [details] [diff] [review]
Rebased to tip, fixed maemo compile errors and separated widget patch

This looks fine to me.  We should probably do a gl version check as well as looking for the extension, for whatever version FBOs became core -- as is, if we were to create a forward-looking GL4 context, we'd fail that extension check even though everything needed is supported.  But we can fix that up later.
Attachment #447474 - Flags: review+
I've tried these patches, and it seems freeze forever or rendering very slow, and gdb always show that browser stay in libGL library.
This is funny, because I am using the nVidia proprietary driver like Oleg, and am not seeing any freeze/slowdown.
Comment on attachment 449188 [details] [diff] [review]
Moved visual/colormap creation into top level window (mozcontainer)

There are two big changes here:

1) Changing the visual on the windows.

   There is a risk here that some window managers may get confused.  I hope
   this we be fine, but I think it is worth making this change conditional on
   mozilla.widget.accelerated-layers.  That gives people the option to revert
   if necessary, and it makes sense to continue to use the system visual if
   there is no need for a GL-chosen visual.

   This visual should be set on the (toplevel) mShell.  (Sorry, I misadvised
   re mozcontainer here, but the existing colormap setting code in
   mozcontainer is in the wrong place.)  Setting the colormap on the mShell
   should also make it easier to release the colormap in
   nsWindow::ReleaseGlobals().

2) Use of LayerManager::LAYERS_OPENGL.

   There have been two reports of a big regression with NVIDIA drivers, as
   well as one positive report, but not much other testing.

   It doesn't seem right to cause a known big regression here, so I'd suggest
   defaulting mozilla.widget.accelerated-layers to off for now until we can
   come up with a workaround for this issue.
Attachment #449188 - Flags: review?(karlt) → review-
(In reply to comment #25)
> Can we get this checked in in its current state, and do followup fixes for
> various drivers/etc?  It's not something that's enabled by default (and we can
> even add a pref for fullscreen video if needed), but it would make WebGL work
> again on Linux (where it works, at least).

We can probably land attachment 447474 [details] [diff] [review] (thebes/layers parts) if/when it has
had enough review.

One thing I notice is that GLContextProvider::CreateForWindow should use the
visual from the window rather than re-choosing a visual and expecting it to be
the same.  (Maybe that won't matter in existing code - I haven't checked
thoroughly.)
Thanks Karl, I'll organize getting a linux box set up at home to address these comments.

Landing attachment 447474 [details] [diff] [review] probably requires the CreateForWindow section to be replace with 'return nsnull'. Seems worthwhile to get WebGL support added sooner rather than later.
Comment on attachment 447474 [details] [diff] [review]
Rebased to tip, fixed maemo compile errors and separated widget patch


>--- /dev/null
>+++ b/gfx/thebes/public/GLXLibrary.h
...
>+#include "GLContext.h"
>+#include <gdk/gdkx.h>
>+typedef realGLboolean GLboolean;
>+#include <GL/glx.h>

>+#include <gtk/gtk.h>
why do we need this header here?
Attachment #450295 - Flags: review?(matt.woodrow)
There are some other issues that changing the visual will cause.  They are
significant enough that they should preclude this visual change happening by
default in the GTK port.  I expect a fix would be a bit involved, so should happen in another bug.  (The changes here can still be made but with the pref defaulting to off.)

1. GTK Native theme rendering assumes that themes only understand the system
   visual and so things will get very slow with another visual.
   http://hg.mozilla.org/mozilla-central/annotate/f21132993dc2/widget/src/gtk2/nsNativeThemeGTK.cpp#l780
   http://hg.mozilla.org/mozilla-central/annotate/f21132993dc2/gfx/thebes/src/cairo-xlib-utils.c#l300

   I'm guessing (but not certain) that most themes will probably draw fine
   to non-system visuals that do not have an alpha channel
   (though this is not what the code currently tests for).

2. LookupGdkColormapForVisual won't know a colormap for the new visual:
   http://hg.mozilla.org/mozilla-central/annotate/f21132993dc2/gfx/thebes/src/gfxPlatformGtk.cpp#l803

   I expect this will be needed in some situations here:
   http://hg.mozilla.org/mozilla-central/annotate/f21132993dc2/gfx/thebes/src/gfxGdkNativeRenderer.cpp#l60
blocking2.0: ? → final+
Comment on attachment 447474 [details] [diff] [review]
Rebased to tip, fixed maemo compile errors and separated widget patch


>-    mInitialized = LoadSymbols(&symbols[0], trygl, prefix);
>+    if (!LoadSymbols(&symbols[0], trygl, prefix)) {
>+        return PR_FALSE;
>+    }
>+    
>+    mInitialized = IsExtensionSupported("GL_EXT_framebuffer_object");
>+    return mInitialized;

By some reason this GL_EXT_framebuffer_object extension not available on EGL... and it always fails here...
This is a GLX backend, not an EGL backend.  Why is this code being used on EGL at all?
The title of this bug has been bugging me for a while... fixing it :)
Summary: Add a Linux OpenGL backend to GLContextProvider → Add a GLX backend to GLContextProvider
(In reply to comment #38)
> This is a GLX backend, not an EGL backend.  Why is this code being used on EGL
> at all?

Because this is inside of GLContext.cpp... and that part is common for all backends
EGL is calling GLContext::InitWithPrefix
Oh wow, sorry -- didn't realize that was in the common code.  That should absolutely not be there, needs to get moved out to the platform-specific GL context code.
It looks like changing the visual of widgets/windows is going to be more trouble than it's worth, so maybe it would be a better solution to get GL to match the existing visual.

I think the best method would be to switch to using glxChooseFBConfig, and iterate the results, looking for one that matches the current widgets visual.

I've setup a quick test and it appears that the current visual is a double buffered one (not sure what this actually means in terms of a X visual). Hard coding the check to pick the FBConfig with the closest matching visual (identical except for double buffered flag) appears to work fine on my system, not sure if this is really an acceptable solution though.

Also, since this is unnecessarily blocking WebGL, maybe it should be separated into two bugs and we can get the requirements for WebGL landed asap.
(In reply to comment #43)
> Also, since this is unnecessarily blocking WebGL, maybe it should be separated
> into two bugs and we can get the requirements for WebGL landed asap.

Would be much appreciated.
I've removed the code to create a context for a window until we find a suitable solution to the visual problem.

I added romaxa's changes for Qt (untested) and moved the extension check into platform specific code.
My NVIDIA system runs this patch without crashing (OpenGL renderer string: GeForce GT 220/PCI/SSE2 | OpenGL version string: 3.0.0 NVIDIA 185.18.36).
Separated the GTK widget changes into a separate patch. This should be all that is required for EGL to work.
Attachment #447474 - Attachment is obsolete: true
Attachment #447474 - Flags: review?(bas.schouten)
Depends on: 572939
Attachment #452127 - Flags: review?(vladimir)
No longer depends on: 569775
We aren't dependant on the plugin change because we don't need to create any Colormap/Visuals any more.
Status: NEW → RESOLVED
Closed: 14 years ago
Resolution: --- → FIXED
Attachment #450295 - Attachment is obsolete: true
Attachment #450295 - Flags: review?(matt.woodrow+bugzilla)
Assignee: nobody → matt.woodrow+bugzilla
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: