Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1791)

Unified Diff: webkit/api/src/GraphicsContext3D.cpp

Issue 258024: Ported Chrome's WebGL implementation to Linux. Required changes to... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/glew/src/glew.c ('k') | webkit/webkit.gyp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webkit/api/src/GraphicsContext3D.cpp
===================================================================
--- webkit/api/src/GraphicsContext3D.cpp (revision 28060)
+++ webkit/api/src/GraphicsContext3D.cpp (working copy)
@@ -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 @@
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 @@
{
}
+#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 @@
, 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 @@
}
m_pbuffer = pbuffer;
m_contextObj = context;
+#elif PLATFORM(LINUX)
+ m_display = XOpenDisplay(NULL);
+ if (m_display == NULL) {
+ printf("GraphicsContext3D: error opening X display\n");
+ return;
+ }
+
+ 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;
+ }
+ 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
- // 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;
+ 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;
}
- if (!glewIsSupported("GL_VERSION_2_0")) {
- printf("GraphicsContext3D: OpenGL 2.0 not supported\n");
- return;
- }
}
GraphicsContext3DInternal::~GraphicsContext3DInternal()
@@ -358,6 +488,12 @@
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 @@
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
« no previous file with comments | « third_party/glew/src/glew.c ('k') | webkit/webkit.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698