Bug 640082 - Part 1 - Add texture_from pixmap support to GLContextProviderGLX. r=joe

This commit is contained in:
Matt Woodrow 2011-04-07 16:58:07 -07:00
parent 96573580ac
commit ce2fc8c5d5
2 changed files with 118 additions and 1 deletions

View File

@ -118,6 +118,7 @@ GLXLibrary::EnsureInitialized()
{ (PRFuncPtr*) &xSwapBuffers, { "glXSwapBuffers", NULL } },
{ (PRFuncPtr*) &xQueryVersion, { "glXQueryVersion", NULL } },
{ (PRFuncPtr*) &xGetCurrentContext, { "glXGetCurrentContext", NULL } },
{ (PRFuncPtr*) &xWaitGL, { "glXWaitGL", NULL } },
/* functions introduced in GLX 1.1 */
{ (PRFuncPtr*) &xQueryExtensionsString, { "glXQueryExtensionsString", NULL } },
{ (PRFuncPtr*) &xGetClientString, { "glXGetClientString", NULL } },
@ -166,6 +167,12 @@ GLXLibrary::EnsureInitialized()
{ NULL, { NULL } }
};
LibrarySymbolLoader::SymLoadStruct symbols_texturefrompixmap[] = {
{ (PRFuncPtr*) &xBindTexImage, { "glXBindTexImageEXT", NULL } },
{ (PRFuncPtr*) &xReleaseTexImage, { "glXReleaseTexImageEXT", NULL } },
{ NULL, { NULL } }
};
if (!LibrarySymbolLoader::LoadSymbols(mOGLLibrary, &symbols[0])) {
NS_WARNING("Couldn't find required entry point in OpenGL shared library");
return PR_FALSE;
@ -261,6 +268,12 @@ GLXLibrary::EnsureInitialized()
return PR_FALSE;
}
if (HasExtension(extensionsStr, "GLX_EXT_texture_from_pixmap") &&
LibrarySymbolLoader::LoadSymbols(mOGLLibrary, symbols_texturefrompixmap))
{
mHasTextureFromPixmap = PR_TRUE;
}
gIsATI = serverVendor && DoesVendorStringMatch(serverVendor, "ATI");
gIsChromium = (serverVendor &&
DoesVendorStringMatch(serverVendor, "Chromium")) ||
@ -271,6 +284,85 @@ GLXLibrary::EnsureInitialized()
return PR_TRUE;
}
GLXPixmap
GLXLibrary::CreatePixmap(gfxASurface* aSurface)
{
if (aSurface->GetType() != gfxASurface::SurfaceTypeXlib || !mHasTextureFromPixmap) {
return 0;
}
if (!EnsureInitialized()) {
return 0;
}
int attribs[] = { GLX_DOUBLEBUFFER, False,
GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
GLX_BIND_TO_TEXTURE_RGBA_EXT, True,
None };
int numFormats;
Display *display = DefaultXDisplay();
int xscreen = DefaultScreen(display);
ScopedXFree<GLXFBConfig> cfg(xChooseFBConfig(display,
xscreen,
attribs,
&numFormats));
if (!cfg) {
return 0;
}
NS_ABORT_IF_FALSE(numFormats > 0,
"glXChooseFBConfig() failed to match our requested format and violated its spec (!)");
gfxXlibSurface *xs = static_cast<gfxXlibSurface*>(aSurface);
int pixmapAttribs[] = { GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGBA_EXT,
None};
GLXPixmap glxpixmap = xCreatePixmap(display,
cfg[0],
xs->XDrawable(),
pixmapAttribs);
return glxpixmap;
}
void
GLXLibrary::DestroyPixmap(GLXPixmap aPixmap)
{
if (!mHasTextureFromPixmap) {
return;
}
Display *display = DefaultXDisplay();
xDestroyPixmap(display, aPixmap);
}
void
GLXLibrary::BindTexImage(GLXPixmap aPixmap)
{
if (!mHasTextureFromPixmap) {
return;
}
Display *display = DefaultXDisplay();
// Make sure all X drawing to the surface has finished before binding to a texture.
XSync(DefaultXDisplay(), False);
xBindTexImage(display, aPixmap, GLX_FRONT_LEFT_EXT, NULL);
}
void
GLXLibrary::ReleaseTexImage(GLXPixmap aPixmap)
{
if (!mHasTextureFromPixmap) {
return;
}
Display *display = DefaultXDisplay();
xReleaseTexImage(display, aPixmap, GLX_FRONT_LEFT_EXT);
}
GLXLibrary sGLXLibrary;
class GLContextGLX : public GLContext
@ -416,6 +508,7 @@ TRY_AGAIN_NO_SHARING:
if (!mDoubleBuffered)
return PR_FALSE;
sGLXLibrary.xSwapBuffers(mDisplay, mDrawable);
sGLXLibrary.xWaitGL();
return PR_TRUE;
}

View File

@ -35,6 +35,9 @@
*
* ***** END LICENSE BLOCK ***** */
#ifndef GFX_GLXLIBRARY_H
#define GFX_GLXLIBRARY_H
#include "GLContext.h"
typedef realGLboolean GLboolean;
#include <GL/glx.h>
@ -46,7 +49,7 @@ class GLXLibrary
{
public:
GLXLibrary() : mInitialized(PR_FALSE), mTriedInitializing(PR_FALSE),
mOGLLibrary(nsnull) {}
mHasTextureFromPixmap(PR_FALSE), mOGLLibrary(nsnull) {}
typedef void (GLAPIENTRY * PFNGLXDESTROYCONTEXTPROC) (Display*,
GLXContext);
@ -120,11 +123,31 @@ public:
int *);
PFNGLXQUERYVERSION xQueryVersion;
typedef void (GLAPIENTRY * PFNGLXBINDTEXIMAGE) (Display *,
GLXDrawable,
int,
const int *);
PFNGLXBINDTEXIMAGE xBindTexImage;
typedef void (GLAPIENTRY * PFNGLXRELEASETEXIMAGE) (Display *,
GLXDrawable,
int);
PFNGLXRELEASETEXIMAGE xReleaseTexImage;
typedef void (GLAPIENTRY * PFNGLXWAITGL) ();
PFNGLXWAITGL xWaitGL;
PRBool EnsureInitialized();
GLXPixmap CreatePixmap(gfxASurface* aSurface);
void DestroyPixmap(GLXPixmap aPixmap);
void BindTexImage(GLXPixmap aPixmap);
void ReleaseTexImage(GLXPixmap aPixmap);
private:
PRBool mInitialized;
PRBool mTriedInitializing;
PRBool mHasTextureFromPixmap;
PRLibrary *mOGLLibrary;
};
@ -133,4 +156,5 @@ extern GLXLibrary sGLXLibrary;
} /* namespace gl */
} /* namespace mozilla */
#endif /* GFX_GLXLIBRARY_H */