зеркало из https://github.com/mozilla/gecko-dev.git
b=565833; add GLX GLContextProvider, pbuffers only; r=vlad
This commit is contained in:
Родитель
ea259c048f
Коммит
fad26daa24
|
@ -226,6 +226,8 @@ LayerManagerOGL::Initialize()
|
|||
return false;
|
||||
}
|
||||
|
||||
mGLContext->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
|
||||
|
||||
if (mFBOTextureTarget == LOCAL_GL_TEXTURE_RECTANGLE_ARB) {
|
||||
/* If we're using TEXTURE_RECTANGLE, then we must have the ARB
|
||||
* extension -- the EXT variant does not provide support for
|
||||
|
|
|
@ -165,6 +165,8 @@ protected:
|
|||
|
||||
PRBool InitWithPrefix(const char *prefix, PRBool trygl);
|
||||
|
||||
PRBool IsExtensionSupported(const char *extension);
|
||||
|
||||
//
|
||||
// the wrapped functions
|
||||
//
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Bas Schouten <bschouten@mozilla.com>
|
||||
* Vladimir Vukicevic <vladimir@pobox.com>
|
||||
* Matt Woodrow <mwoodrow@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "GLContext.h"
|
||||
typedef realGLboolean GLboolean;
|
||||
#include <GL/glx.h>
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
|
||||
class GLXLibrary
|
||||
{
|
||||
public:
|
||||
GLXLibrary() : mInitialized(PR_FALSE), mOGLLibrary(nsnull) {}
|
||||
|
||||
typedef GLXContext (GLAPIENTRY * PFNGLXCREATECONTEXTPROC) (Display*,
|
||||
XVisualInfo*,
|
||||
GLXContext,
|
||||
Bool);
|
||||
PFNGLXCREATECONTEXTPROC xCreateContext;
|
||||
typedef void (GLAPIENTRY * PFNGLXDELETECONTEXTPROC) (Display*,
|
||||
GLXContext);
|
||||
PFNGLXDELETECONTEXTPROC xDeleteContext;
|
||||
typedef Bool (GLAPIENTRY * PFNGLXMAKECURRENTPROC) (Display*,
|
||||
GLXDrawable,
|
||||
GLXContext);
|
||||
PFNGLXMAKECURRENTPROC xMakeCurrent;
|
||||
typedef void* (GLAPIENTRY * PFNGLXGETPROCADDRESSPROC) (const char *);
|
||||
PFNGLXGETPROCADDRESSPROC xGetProcAddress;
|
||||
typedef XVisualInfo* (GLAPIENTRY * PFNGLXCHOOSEVISUALPROC) (Display*,
|
||||
int,
|
||||
int *);
|
||||
PFNGLXCHOOSEVISUALPROC xChooseVisual;
|
||||
typedef GLXFBConfig* (GLAPIENTRY * PFNGLXCHOOSEFBCONFIG) (Display *,
|
||||
int,
|
||||
const int *,
|
||||
int *);
|
||||
PFNGLXCHOOSEFBCONFIG xChooseFBConfig;
|
||||
typedef GLXPbuffer (GLAPIENTRY * PFNGLXCREATEPBUFFER) (Display *,
|
||||
GLXFBConfig,
|
||||
const int *);
|
||||
PFNGLXCREATEPBUFFER xCreatePbuffer;
|
||||
typedef GLXContext (GLAPIENTRY * PFNGLXCREATENEWCONTEXT) (Display *,
|
||||
GLXFBConfig,
|
||||
int,
|
||||
GLXContext,
|
||||
Bool);
|
||||
PFNGLXCREATENEWCONTEXT xCreateNewContext;
|
||||
typedef void (GLAPIENTRY * PFNGLXDESTROYPBUFFER) (Display *,
|
||||
GLXPbuffer);
|
||||
PFNGLXDESTROYPBUFFER xDestroyPbuffer;
|
||||
|
||||
typedef XVisualInfo* (GLAPIENTRY * PFNGLXGETVISUALFROMFBCONFIG) (Display *,
|
||||
GLXFBConfig);
|
||||
PFNGLXGETVISUALFROMFBCONFIG xGetVisualFromFBConfig;
|
||||
|
||||
PRBool EnsureInitialized();
|
||||
|
||||
private:
|
||||
PRBool mInitialized;
|
||||
PRLibrary *mOGLLibrary;
|
||||
};
|
||||
|
||||
// a global GLXLibrary instance
|
||||
extern GLXLibrary sGLXLibrary;
|
||||
|
||||
} /* namespace gl */
|
||||
} /* namespace mozilla */
|
||||
|
|
@ -74,7 +74,9 @@ endif
|
|||
ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
|
||||
|
||||
ifdef MOZ_X11
|
||||
EXPORTS += gfxXlibSurface.h
|
||||
EXPORTS += gfxXlibSurface.h \
|
||||
GLXLibrary.h \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ifdef MOZ_PANGO
|
||||
|
@ -94,6 +96,13 @@ EXPORTS += gfxFT2FontBase.h
|
|||
endif
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),qt)
|
||||
|
||||
ifdef MOZ_X11
|
||||
EXPORTS += gfxXlibSurface.h \
|
||||
GLXLibrary.h \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ifdef MOZ_PANGO
|
||||
EXPORTS += gfxPangoFonts.h
|
||||
else
|
||||
|
|
|
@ -42,7 +42,7 @@ namespace gl {
|
|||
class WGLLibrary
|
||||
{
|
||||
public:
|
||||
WGLLibrary() : mInitialized(PR_FALSE) {}
|
||||
WGLLibrary() : mInitialized(PR_FALSE), mOGLLibrary(nsnull) {}
|
||||
|
||||
typedef HGLRC (GLAPIENTRY * PFNWGLCREATECONTEXTPROC) (HDC);
|
||||
PFNWGLCREATECONTEXTPROC fCreateContext;
|
||||
|
|
|
@ -328,9 +328,43 @@ GLContext::InitWithPrefix(const char *prefix, PRBool trygl)
|
|||
};
|
||||
|
||||
mInitialized = LoadSymbols(&symbols[0], trygl, prefix);
|
||||
|
||||
return mInitialized;
|
||||
}
|
||||
|
||||
PRBool
|
||||
GLContext::IsExtensionSupported(const char *extension)
|
||||
{
|
||||
const GLubyte *extensions = NULL;
|
||||
const GLubyte *start;
|
||||
GLubyte *where, *terminator;
|
||||
|
||||
/* Extension names should not have spaces. */
|
||||
where = (GLubyte *) strchr(extension, ' ');
|
||||
if (where || *extension == '\0')
|
||||
return PR_FALSE;
|
||||
|
||||
extensions = fGetString(LOCAL_GL_EXTENSIONS);
|
||||
/*
|
||||
* It takes a bit of care to be fool-proof about parsing the
|
||||
* OpenGL extensions string. Don't be fooled by sub-strings,
|
||||
* etc.
|
||||
*/
|
||||
start = extensions;
|
||||
for (;;) {
|
||||
where = (GLubyte *) strstr((const char *) start, extension);
|
||||
if (!where) {
|
||||
break;
|
||||
}
|
||||
terminator = where + strlen(extension);
|
||||
if (where == start || *(where - 1) == ' ') {
|
||||
if (*terminator == ' ' || *terminator == '\0') {
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
start = terminator;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
} /* namespace gl */
|
||||
} /* namespace mozilla */
|
||||
|
|
|
@ -0,0 +1,283 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Matt Woodrow <mwoodrow@mozilla.com>
|
||||
* Bas Schouten <bschouten@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK2
|
||||
#include <gdk/gdk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
// we're using default display for now
|
||||
#define GET_NATIVE_WINDOW(aWidget) GDK_WINDOW_XID((GdkWindow *) aWidget->GetNativeData(NS_NATIVE_WINDOW))
|
||||
#define DISPLAY gdk_x11_get_default_xdisplay
|
||||
#elif defined(MOZ_WIDGET_QT)
|
||||
#include <QWidget>
|
||||
#include <QX11Info>
|
||||
// we're using default display for now
|
||||
#define GET_NATIVE_WINDOW(aWidget) static_cast<QWidget*>(aWidget->GetNativeData(NS_NATIVE_SHELLWIDGET))->handle()
|
||||
#define DISPLAY QX11Info().display
|
||||
#endif
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
#include "GLContextProvider.h"
|
||||
#include "nsDebug.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "GLXLibrary.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
|
||||
GLContextProvider sGLContextProvider;
|
||||
|
||||
PRBool
|
||||
GLXLibrary::EnsureInitialized()
|
||||
{
|
||||
if (mInitialized) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
if (!mOGLLibrary) {
|
||||
mOGLLibrary = PR_LoadLibrary("libGL.so.1");
|
||||
if (!mOGLLibrary) {
|
||||
NS_WARNING("Couldn't load OpenGL shared library.");
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
LibrarySymbolLoader::SymLoadStruct symbols[] = {
|
||||
{ (PRFuncPtr*) &xCreateContext, { "glXCreateContext", NULL } },
|
||||
{ (PRFuncPtr*) &xDeleteContext, { "glXDestroyContext", NULL } },
|
||||
{ (PRFuncPtr*) &xMakeCurrent, { "glXMakeCurrent", NULL } },
|
||||
{ (PRFuncPtr*) &xGetProcAddress, { "glXGetProcAddress", NULL } },
|
||||
{ (PRFuncPtr*) &xChooseVisual, { "glXChooseVisual", NULL } },
|
||||
{ (PRFuncPtr*) &xChooseFBConfig, { "glXChooseFBConfig", NULL } },
|
||||
{ (PRFuncPtr*) &xCreatePbuffer, { "glXCreatePbuffer", NULL } },
|
||||
{ (PRFuncPtr*) &xCreateNewContext, { "glXCreateNewContext", NULL } },
|
||||
{ (PRFuncPtr*) &xDestroyPbuffer, { "glXDestroyPbuffer", NULL } },
|
||||
{ (PRFuncPtr*) &xGetVisualFromFBConfig, { "glXGetVisualFromFBConfig", NULL } },
|
||||
{ NULL, { NULL } }
|
||||
};
|
||||
|
||||
if (!LibrarySymbolLoader::LoadSymbols(mOGLLibrary, &symbols[0])) {
|
||||
NS_WARNING("Couldn't find required entry point in OpenGL shared library");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
mInitialized = PR_TRUE;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
GLXLibrary sGLXLibrary;
|
||||
|
||||
static bool ctxErrorOccurred = false;
|
||||
static int
|
||||
ctxErrorHandler(Display *dpy, XErrorEvent *ev)
|
||||
{
|
||||
ctxErrorOccurred = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
class GLContextGLX : public GLContext
|
||||
{
|
||||
public:
|
||||
static GLContextGLX *CreateGLContext(Display *display, GLXDrawable drawable, GLXFBConfig cfg, PRBool pbuffer)
|
||||
{
|
||||
ctxErrorOccurred = false;
|
||||
int (*oldHandler)(Display *, XErrorEvent *) = XSetErrorHandler(&ctxErrorHandler);
|
||||
|
||||
GLXContext context = sGLXLibrary.xCreateNewContext(display,
|
||||
cfg,
|
||||
GLX_RGBA_TYPE,
|
||||
NULL,
|
||||
True);
|
||||
|
||||
XSync(display, False);
|
||||
XSetErrorHandler(oldHandler);
|
||||
|
||||
if (!context || ctxErrorOccurred) {
|
||||
NS_WARNING("Failed to create GLXContext!");
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
GLContextGLX *glContext = new GLContextGLX(display,
|
||||
drawable,
|
||||
context,
|
||||
pbuffer);
|
||||
if (!glContext->Init()) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
return glContext;
|
||||
}
|
||||
|
||||
~GLContextGLX()
|
||||
{
|
||||
if (mPBuffer) {
|
||||
sGLXLibrary.xDestroyPbuffer(mDisplay, mWindow);
|
||||
}
|
||||
|
||||
sGLXLibrary.xDeleteContext(mDisplay, mContext);
|
||||
}
|
||||
|
||||
PRBool Init()
|
||||
{
|
||||
MakeCurrent();
|
||||
SetupLookupFunction();
|
||||
if (!InitWithPrefix("gl", PR_TRUE)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
return IsExtensionSupported("GL_EXT_framebuffer_object");
|
||||
}
|
||||
|
||||
PRBool MakeCurrent()
|
||||
{
|
||||
Bool succeeded = sGLXLibrary.xMakeCurrent(mDisplay, mWindow, mContext);
|
||||
NS_ASSERTION(succeeded, "Failed to make GL context current!");
|
||||
return succeeded;
|
||||
}
|
||||
|
||||
PRBool SetupLookupFunction()
|
||||
{
|
||||
mLookupFunc = (PlatformLookupFunction)sGLXLibrary.xGetProcAddress;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
void *GetNativeData(NativeDataType aType)
|
||||
{
|
||||
switch(aType) {
|
||||
case NativeGLContext:
|
||||
return mContext;
|
||||
|
||||
case NativePBuffer:
|
||||
if (mPBuffer) {
|
||||
return (void *)mWindow;
|
||||
}
|
||||
|
||||
default:
|
||||
return nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
GLContextGLX(Display *aDisplay, GLXDrawable aWindow, GLXContext aContext, PRBool aPBuffer = PR_FALSE)
|
||||
: mContext(aContext),
|
||||
mDisplay(aDisplay),
|
||||
mWindow(aWindow),
|
||||
mPBuffer(aPBuffer) {}
|
||||
|
||||
GLXContext mContext;
|
||||
Display *mDisplay;
|
||||
GLXDrawable mWindow;
|
||||
PRBool mPBuffer;
|
||||
};
|
||||
|
||||
already_AddRefed<GLContext>
|
||||
GLContextProvider::CreateForWindow(nsIWidget *aWidget)
|
||||
{
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
int numFormats;
|
||||
Display *display = DISPLAY();
|
||||
int xscreen = DefaultScreen(display);
|
||||
|
||||
A2_(GLX_DOUBLEBUFFER, False);
|
||||
A2_(GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT);
|
||||
|
||||
A2_(GLX_RED_SIZE, aFormat.red);
|
||||
A2_(GLX_GREEN_SIZE, aFormat.green);
|
||||
A2_(GLX_BLUE_SIZE, aFormat.blue);
|
||||
A2_(GLX_ALPHA_SIZE, aFormat.alpha);
|
||||
A2_(GLX_DEPTH_SIZE, aFormat.depth);
|
||||
A1_(0);
|
||||
|
||||
GLXFBConfig *cfg = sGLXLibrary.xChooseFBConfig(display,
|
||||
xscreen,
|
||||
attribs.Elements(),
|
||||
&numFormats);
|
||||
|
||||
if (!cfg) {
|
||||
return nsnull;
|
||||
}
|
||||
NS_ASSERTION(numFormats > 0, "");
|
||||
|
||||
nsTArray<int> pbattribs;
|
||||
pbattribs.AppendElement(GLX_PBUFFER_WIDTH);
|
||||
pbattribs.AppendElement(aSize.width);
|
||||
pbattribs.AppendElement(GLX_PBUFFER_HEIGHT);
|
||||
pbattribs.AppendElement(aSize.height);
|
||||
pbattribs.AppendElement(GLX_PRESERVED_CONTENTS);
|
||||
pbattribs.AppendElement(True);
|
||||
|
||||
GLXPbuffer pbuffer = sGLXLibrary.xCreatePbuffer(display,
|
||||
cfg[0],
|
||||
pbattribs.Elements());
|
||||
|
||||
if (pbuffer == 0) {
|
||||
XFree(cfg);
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsRefPtr<GLContextGLX> glContext = GLContextGLX::CreateGLContext(display,
|
||||
pbuffer,
|
||||
cfg[0],
|
||||
PR_TRUE);
|
||||
XFree(cfg);
|
||||
|
||||
if (!glContext) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
return glContext.forget().get();
|
||||
}
|
||||
|
||||
} /* namespace gl */
|
||||
} /* namespace mozilla */
|
|
@ -232,6 +232,11 @@ GL_PROVIDER = WGL
|
|||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
|
||||
ifndef MOZ_PLATFORM_MAEMO
|
||||
GL_PROVIDER = GLX
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
|
||||
GL_PROVIDER = CGL
|
||||
|
|
Загрузка…
Ссылка в новой задаче