summaryrefslogtreecommitdiffstats
path: root/webkit/api/src/GraphicsContext3D.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'webkit/api/src/GraphicsContext3D.cpp')
-rw-r--r--webkit/api/src/GraphicsContext3D.cpp158
1 files changed, 149 insertions, 9 deletions
diff --git a/webkit/api/src/GraphicsContext3D.cpp b/webkit/api/src/GraphicsContext3D.cpp
index 6f1f777..49819f5 100644
--- a/webkit/api/src/GraphicsContext3D.cpp
+++ b/webkit/api/src/GraphicsContext3D.cpp
@@ -81,6 +81,11 @@
#define USE_TEXTURE_RECTANGLE_FOR_FRAMEBUFFER
#endif
+#if PLATFORM(LINUX)
+#include <dlfcn.h>
+#include "GL/glxew.h"
+#endif
+
using namespace std;
namespace WebCore {
@@ -167,6 +172,24 @@ private:
CGLContextObj m_contextObj;
unsigned char* m_renderOutput;
CGContextRef m_cgContext;
+#elif PLATFORM(LINUX)
+ Display* m_display;
+ GLXContext m_contextObj;
+ GLXPbuffer m_pbuffer;
+ // In order to avoid problems caused by linking against libGL, we
+ // dynamically look up all the symbols we need.
+ // http://code.google.com/p/chromium/issues/detail?id=16800
+ void* m_libGL;
+ PFNGLXCHOOSEFBCONFIGPROC m_glXChooseFBConfig;
+ PFNGLXCREATENEWCONTEXTPROC m_glXCreateNewContext;
+ PFNGLXCREATEPBUFFERPROC m_glXCreatePbuffer;
+ PFNGLXDESTROYPBUFFERPROC m_glXDestroyPbuffer;
+ typedef Bool (* PFNGLXMAKECURRENTPROC)(Display* dpy, GLXDrawable drawable, GLXContext ctx);
+ PFNGLXMAKECURRENTPROC m_glXMakeCurrent;
+ typedef void (* PFNGLXDESTROYCONTEXTPROC)(Display* dpy, GLXContext ctx);
+ PFNGLXDESTROYCONTEXTPROC m_glXDestroyContext;
+ typedef GLXContext (* PFNGLXGETCURRENTCONTEXTPROC)(void);
+ PFNGLXGETCURRENTCONTEXTPROC m_glXGetCurrentContext;
#else
#error Must port GraphicsContext3D to your platform
#endif
@@ -184,6 +207,15 @@ GraphicsContext3DInternal::VertexAttribPointerState::VertexAttribPointerState()
{
}
+#if PLATFORM(LINUX)
+static void* tryLoad(const char* libName) {
+ // We use RTLD_GLOBAL semantics so that GLEW initialization works;
+ // GLEW expects to be able to open the current process's handle
+ // and do dlsym's of GL entry points from there.
+ return dlopen(libName, RTLD_LAZY | RTLD_GLOBAL);
+}
+#endif
+
GraphicsContext3DInternal::GraphicsContext3DInternal()
: m_texture(0)
, m_fbo(0)
@@ -201,6 +233,17 @@ GraphicsContext3DInternal::GraphicsContext3DInternal()
, m_contextObj(NULL)
, m_renderOutput(NULL)
, m_cgContext(NULL)
+#elif PLATFORM(LINUX)
+ , m_display(NULL)
+ , m_contextObj(NULL)
+ , m_pbuffer(NULL)
+ , m_glXChooseFBConfig(NULL)
+ , m_glXCreateNewContext(NULL)
+ , m_glXCreatePbuffer(NULL)
+ , m_glXDestroyPbuffer(NULL)
+ , m_glXMakeCurrent(NULL)
+ , m_glXDestroyContext(NULL)
+ , m_glXGetCurrentContext(NULL)
#else
#error Must port to your platform
#endif
@@ -317,20 +360,107 @@ GraphicsContext3DInternal::GraphicsContext3DInternal()
}
m_pbuffer = pbuffer;
m_contextObj = context;
-#else
-#error Must port to your platform
-#endif
+#elif PLATFORM(LINUX)
+ m_display = XOpenDisplay(NULL);
+ if (m_display == NULL) {
+ printf("GraphicsContext3D: error opening X display\n");
+ return;
+ }
- // Initialize GLEW and check for GL 2.0 support by the drivers.
- GLenum glewInitResult = glewInit();
- if (glewInitResult != GLEW_OK) {
- printf("GraphicsContext3D: GLEW initialization failed\n");
+ const char* libNames[] = {
+ "/usr/lib/libGL.so.1",
+ "/usr/lib32/libGL.so.1",
+ "/usr/lib64/libGL.so.1",
+ };
+ for (int i = 0; i < sizeof(libNames) / sizeof(const char*); i++) {
+ m_libGL = tryLoad(libNames[i]);
+ if (m_libGL != NULL)
+ break;
+ }
+ if (m_libGL == NULL) {
+ printf("GraphicsContext3D: error opening libGL.so.1\n");
+ printf("GraphicsContext3D: tried:");
+ for (int i = 0; i < sizeof(libNames) / sizeof(const char*); i++) {
+ printf(" %s", libNames[i]);
+ }
+ return;
+ }
+ m_glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC) dlsym(m_libGL, "glXChooseFBConfig");
+ m_glXCreateNewContext = (PFNGLXCREATENEWCONTEXTPROC) dlsym(m_libGL, "glXCreateNewContext");
+ m_glXCreatePbuffer = (PFNGLXCREATEPBUFFERPROC) dlsym(m_libGL, "glXCreatePbuffer");
+ m_glXDestroyPbuffer = (PFNGLXDESTROYPBUFFERPROC) dlsym(m_libGL, "glXDestroyPbuffer");
+ m_glXMakeCurrent = (PFNGLXMAKECURRENTPROC) dlsym(m_libGL, "glXMakeCurrent");
+ m_glXDestroyContext = (PFNGLXDESTROYCONTEXTPROC) dlsym(m_libGL, "glXDestroyContext");
+ m_glXGetCurrentContext = (PFNGLXGETCURRENTCONTEXTPROC) dlsym(m_libGL, "glXGetCurrentContext");
+ if (!m_glXChooseFBConfig || !m_glXCreateNewContext || !m_glXCreatePbuffer ||
+ !m_glXDestroyPbuffer || !m_glXMakeCurrent || !m_glXDestroyContext ||
+ !m_glXGetCurrentContext) {
+ printf("GraphicsContext3D: error looking up bootstrapping entry points\n");
+ return;
+ }
+ int configAttrs[] = {
+ GLX_DRAWABLE_TYPE,
+ GLX_PBUFFER_BIT,
+ GLX_RENDER_TYPE,
+ GLX_RGBA_BIT,
+ GLX_DOUBLEBUFFER,
+ 0,
+ 0
+ };
+ int nelements = 0;
+ GLXFBConfig* config = m_glXChooseFBConfig(m_display, 0, configAttrs, &nelements);
+ if (config == NULL) {
+ printf("GraphicsContext3D: glXChooseFBConfig failed\n");
+ return;
+ }
+ if (nelements == 0) {
+ printf("GraphicsContext3D: glXChooseFBConfig returned 0 elements\n");
+ XFree(config);
+ return;
+ }
+ GLXContext context = m_glXCreateNewContext(m_display, config[0], GLX_RGBA_TYPE, NULL, True);
+ if (context == NULL) {
+ printf("GraphicsContext3D: glXCreateNewContext failed\n");
+ XFree(config);
return;
}
- if (!glewIsSupported("GL_VERSION_2_0")) {
- printf("GraphicsContext3D: OpenGL 2.0 not supported\n");
+ int pbufferAttrs[] = {
+ GLX_PBUFFER_WIDTH,
+ 1,
+ GLX_PBUFFER_HEIGHT,
+ 1,
+ 0
+ };
+ GLXPbuffer pbuffer = m_glXCreatePbuffer(m_display, config[0], pbufferAttrs);
+ XFree(config);
+ if (!pbuffer) {
+ printf("GraphicsContext3D: glxCreatePbuffer failed\n");
+ return;
+ }
+ if (!m_glXMakeCurrent(m_display, pbuffer, context)) {
+ printf("GraphicsContext3D: glXMakeCurrent failed\n");
return;
}
+ m_contextObj = context;
+ m_pbuffer = pbuffer;
+#else
+#error Must port to your platform
+#endif
+
+ static bool initializedGLEW = false;
+ if (!initializedGLEW) {
+ // Initialize GLEW and check for GL 2.0 support by the drivers.
+ GLenum glewInitResult = glewInit();
+ if (glewInitResult != GLEW_OK) {
+ printf("GraphicsContext3D: GLEW initialization failed\n");
+ return;
+ }
+ if (!glewIsSupported("GL_VERSION_2_0")) {
+ printf("GraphicsContext3D: OpenGL 2.0 not supported\n");
+ return;
+ }
+ initializedGLEW = true;
+ }
}
GraphicsContext3DInternal::~GraphicsContext3DInternal()
@@ -358,6 +488,12 @@ GraphicsContext3DInternal::~GraphicsContext3DInternal()
CGContextRelease(m_cgContext);
if (m_renderOutput != NULL)
delete[] m_renderOutput;
+#elif PLATFORM(LINUX)
+ m_glXMakeCurrent(m_display, NULL, NULL);
+ m_glXDestroyContext(m_display, m_contextObj);
+ m_glXDestroyPbuffer(m_display, m_pbuffer);
+ XCloseDisplay(m_display);
+ dlclose(m_libGL);
#else
#error Must port to your platform
#endif
@@ -385,6 +521,10 @@ bool GraphicsContext3DInternal::makeContextCurrent()
if (CGLGetCurrentContext() != m_contextObj)
if (CGLSetCurrentContext(m_contextObj) == kCGLNoError)
return true;
+#elif PLATFORM(LINUX)
+ if (m_glXGetCurrentContext() != m_contextObj)
+ if (m_glXMakeCurrent(m_display, m_pbuffer, m_contextObj))
+ return true;
#else
#error Must port to your platform
#endif