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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « third_party/glew/src/glew.c ('k') | webkit/webkit.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2009 Google Inc. All rights reserved. 2 * Copyright (C) 2009 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 #endif 74 #endif
75 75
76 #if PLATFORM(SKIA) 76 #if PLATFORM(SKIA)
77 #include "NativeImageSkia.h" 77 #include "NativeImageSkia.h"
78 #endif 78 #endif
79 79
80 #if PLATFORM(DARWIN) 80 #if PLATFORM(DARWIN)
81 #define USE_TEXTURE_RECTANGLE_FOR_FRAMEBUFFER 81 #define USE_TEXTURE_RECTANGLE_FOR_FRAMEBUFFER
82 #endif 82 #endif
83 83
84 #if PLATFORM(LINUX)
85 #include <dlfcn.h>
86 #include "GL/glxew.h"
87 #endif
88
84 using namespace std; 89 using namespace std;
85 90
86 namespace WebCore { 91 namespace WebCore {
87 92
88 // GraphicsContext3DInternal ----------------------------------------------------- 93 // GraphicsContext3DInternal -----------------------------------------------------
89 94
90 // Uncomment this to render to a separate window for debugging 95 // Uncomment this to render to a separate window for debugging
91 // #define RENDER_TO_DEBUGGING_WINDOW 96 // #define RENDER_TO_DEBUGGING_WINDOW
92 97
93 #define EXTRACT(val) (val == NULL ? 0 : val->object()) 98 #define EXTRACT(val) (val == NULL ? 0 : val->object())
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 165
161 #if PLATFORM(WIN_OS) 166 #if PLATFORM(WIN_OS)
162 HWND m_canvasWindow; 167 HWND m_canvasWindow;
163 HDC m_canvasDC; 168 HDC m_canvasDC;
164 HGLRC m_contextObj; 169 HGLRC m_contextObj;
165 #elif PLATFORM(CG) 170 #elif PLATFORM(CG)
166 CGLPBufferObj m_pbuffer; 171 CGLPBufferObj m_pbuffer;
167 CGLContextObj m_contextObj; 172 CGLContextObj m_contextObj;
168 unsigned char* m_renderOutput; 173 unsigned char* m_renderOutput;
169 CGContextRef m_cgContext; 174 CGContextRef m_cgContext;
175 #elif PLATFORM(LINUX)
176 Display* m_display;
177 GLXContext m_contextObj;
178 GLXPbuffer m_pbuffer;
179 // In order to avoid problems caused by linking against libGL, we
180 // dynamically look up all the symbols we need.
181 // http://code.google.com/p/chromium/issues/detail?id=16800
182 void* m_libGL;
183 PFNGLXCHOOSEFBCONFIGPROC m_glXChooseFBConfig;
184 PFNGLXCREATENEWCONTEXTPROC m_glXCreateNewContext;
185 PFNGLXCREATEPBUFFERPROC m_glXCreatePbuffer;
186 PFNGLXDESTROYPBUFFERPROC m_glXDestroyPbuffer;
187 typedef Bool (* PFNGLXMAKECURRENTPROC)(Display* dpy, GLXDrawable drawable, GLXContext ctx);
188 PFNGLXMAKECURRENTPROC m_glXMakeCurrent;
189 typedef void (* PFNGLXDESTROYCONTEXTPROC)(Display* dpy, GLXContext ctx);
190 PFNGLXDESTROYCONTEXTPROC m_glXDestroyContext;
191 typedef GLXContext (* PFNGLXGETCURRENTCONTEXTPROC)(void);
192 PFNGLXGETCURRENTCONTEXTPROC m_glXGetCurrentContext;
170 #else 193 #else
171 #error Must port GraphicsContext3D to your platform 194 #error Must port GraphicsContext3D to your platform
172 #endif 195 #endif
173 }; 196 };
174 197
175 GraphicsContext3DInternal::VertexAttribPointerState::VertexAttribPointerState() 198 GraphicsContext3DInternal::VertexAttribPointerState::VertexAttribPointerState()
176 : enabled(false) 199 : enabled(false)
177 , buffer(0) 200 , buffer(0)
178 , indx(0) 201 , indx(0)
179 , size(0) 202 , size(0)
180 , type(0) 203 , type(0)
181 , normalized(false) 204 , normalized(false)
182 , stride(0) 205 , stride(0)
183 , offset(0) 206 , offset(0)
184 { 207 {
185 } 208 }
186 209
210 #if PLATFORM(LINUX)
211 static void* tryLoad(const char* libName) {
212 // We use RTLD_GLOBAL semantics so that GLEW initialization works;
213 // GLEW expects to be able to open the current process's handle
214 // and do dlsym's of GL entry points from there.
215 return dlopen(libName, RTLD_LAZY | RTLD_GLOBAL);
216 }
217 #endif
218
187 GraphicsContext3DInternal::GraphicsContext3DInternal() 219 GraphicsContext3DInternal::GraphicsContext3DInternal()
188 : m_texture(0) 220 : m_texture(0)
189 , m_fbo(0) 221 , m_fbo(0)
190 , m_depthBuffer(0) 222 , m_depthBuffer(0)
191 #ifdef FLIP_FRAMEBUFFER_VERTICALLY 223 #ifdef FLIP_FRAMEBUFFER_VERTICALLY
192 , m_scanline(NULL) 224 , m_scanline(NULL)
193 #endif 225 #endif
194 , m_boundArrayBuffer(0) 226 , m_boundArrayBuffer(0)
195 #if PLATFORM(WIN_OS) 227 #if PLATFORM(WIN_OS)
196 , m_canvasWindow(NULL) 228 , m_canvasWindow(NULL)
197 , m_canvasDC(NULL) 229 , m_canvasDC(NULL)
198 , m_contextObj(NULL) 230 , m_contextObj(NULL)
199 #elif PLATFORM(CG) 231 #elif PLATFORM(CG)
200 , m_pbuffer(NULL) 232 , m_pbuffer(NULL)
201 , m_contextObj(NULL) 233 , m_contextObj(NULL)
202 , m_renderOutput(NULL) 234 , m_renderOutput(NULL)
203 , m_cgContext(NULL) 235 , m_cgContext(NULL)
236 #elif PLATFORM(LINUX)
237 , m_display(NULL)
238 , m_contextObj(NULL)
239 , m_pbuffer(NULL)
240 , m_glXChooseFBConfig(NULL)
241 , m_glXCreateNewContext(NULL)
242 , m_glXCreatePbuffer(NULL)
243 , m_glXDestroyPbuffer(NULL)
244 , m_glXMakeCurrent(NULL)
245 , m_glXDestroyContext(NULL)
246 , m_glXGetCurrentContext(NULL)
204 #else 247 #else
205 #error Must port to your platform 248 #error Must port to your platform
206 #endif 249 #endif
207 { 250 {
208 #if PLATFORM(WIN_OS) 251 #if PLATFORM(WIN_OS)
209 WNDCLASS wc; 252 WNDCLASS wc;
210 if (!GetClassInfo(GetModuleHandle(NULL), L"CANVASGL", &wc)) { 253 if (!GetClassInfo(GetModuleHandle(NULL), L"CANVASGL", &wc)) {
211 ZeroMemory(&wc, sizeof(WNDCLASS)); 254 ZeroMemory(&wc, sizeof(WNDCLASS));
212 wc.style = CS_OWNDC; 255 wc.style = CS_OWNDC;
213 wc.hInstance = GetModuleHandle(NULL); 256 wc.hInstance = GetModuleHandle(NULL);
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 return; 353 return;
311 } 354 }
312 if (CGLSetCurrentContext(context) != kCGLNoError) { 355 if (CGLSetCurrentContext(context) != kCGLNoError) {
313 CGLDestroyContext(context); 356 CGLDestroyContext(context);
314 CGLDestroyPBuffer(pbuffer); 357 CGLDestroyPBuffer(pbuffer);
315 printf("GraphicsContext3D: error making context current\n"); 358 printf("GraphicsContext3D: error making context current\n");
316 return; 359 return;
317 } 360 }
318 m_pbuffer = pbuffer; 361 m_pbuffer = pbuffer;
319 m_contextObj = context; 362 m_contextObj = context;
363 #elif PLATFORM(LINUX)
364 m_display = XOpenDisplay(NULL);
365 if (m_display == NULL) {
366 printf("GraphicsContext3D: error opening X display\n");
367 return;
368 }
369
370 const char* libNames[] = {
371 "/usr/lib/libGL.so.1",
372 "/usr/lib32/libGL.so.1",
373 "/usr/lib64/libGL.so.1",
374 };
375 for (int i = 0; i < sizeof(libNames) / sizeof(const char*); i++) {
376 m_libGL = tryLoad(libNames[i]);
377 if (m_libGL != NULL)
378 break;
379 }
380 if (m_libGL == NULL) {
381 printf("GraphicsContext3D: error opening libGL.so.1\n");
382 printf("GraphicsContext3D: tried:");
383 for (int i = 0; i < sizeof(libNames) / sizeof(const char*); i++) {
384 printf(" %s", libNames[i]);
385 }
386 return;
387 }
388 m_glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC) dlsym(m_libGL, "glXChooseFBConfig");
389 m_glXCreateNewContext = (PFNGLXCREATENEWCONTEXTPROC) dlsym(m_libGL, "glXCreateNewContext");
390 m_glXCreatePbuffer = (PFNGLXCREATEPBUFFERPROC) dlsym(m_libGL, "glXCreatePbuffer");
391 m_glXDestroyPbuffer = (PFNGLXDESTROYPBUFFERPROC) dlsym(m_libGL, "glXDestroyPbuffer");
392 m_glXMakeCurrent = (PFNGLXMAKECURRENTPROC) dlsym(m_libGL, "glXMakeCurrent");
393 m_glXDestroyContext = (PFNGLXDESTROYCONTEXTPROC) dlsym(m_libGL, "glXDestroyContext");
394 m_glXGetCurrentContext = (PFNGLXGETCURRENTCONTEXTPROC) dlsym(m_libGL, "glXGetCurrentContext");
395 if (!m_glXChooseFBConfig || !m_glXCreateNewContext || !m_glXCreatePbuffer ||
396 !m_glXDestroyPbuffer || !m_glXMakeCurrent || !m_glXDestroyContext ||
397 !m_glXGetCurrentContext) {
398 printf("GraphicsContext3D: error looking up bootstrapping entry points\n");
399 return;
400 }
401 int configAttrs[] = {
402 GLX_DRAWABLE_TYPE,
403 GLX_PBUFFER_BIT,
404 GLX_RENDER_TYPE,
405 GLX_RGBA_BIT,
406 GLX_DOUBLEBUFFER,
407 0,
408 0
409 };
410 int nelements = 0;
411 GLXFBConfig* config = m_glXChooseFBConfig(m_display, 0, configAttrs, &nelements);
412 if (config == NULL) {
413 printf("GraphicsContext3D: glXChooseFBConfig failed\n");
414 return;
415 }
416 if (nelements == 0) {
417 printf("GraphicsContext3D: glXChooseFBConfig returned 0 elements\n");
418 XFree(config);
419 return;
420 }
421 GLXContext context = m_glXCreateNewContext(m_display, config[0], GLX_RGBA_TYPE, NULL, True);
422 if (context == NULL) {
423 printf("GraphicsContext3D: glXCreateNewContext failed\n");
424 XFree(config);
425 return;
426 }
427 int pbufferAttrs[] = {
428 GLX_PBUFFER_WIDTH,
429 1,
430 GLX_PBUFFER_HEIGHT,
431 1,
432 0
433 };
434 GLXPbuffer pbuffer = m_glXCreatePbuffer(m_display, config[0], pbufferAttrs);
435 XFree(config);
436 if (!pbuffer) {
437 printf("GraphicsContext3D: glxCreatePbuffer failed\n");
438 return;
439 }
440 if (!m_glXMakeCurrent(m_display, pbuffer, context)) {
441 printf("GraphicsContext3D: glXMakeCurrent failed\n");
442 return;
443 }
444 m_contextObj = context;
445 m_pbuffer = pbuffer;
320 #else 446 #else
321 #error Must port to your platform 447 #error Must port to your platform
322 #endif 448 #endif
323 449
324 // Initialize GLEW and check for GL 2.0 support by the drivers. 450 static bool initializedGLEW = false;
325 GLenum glewInitResult = glewInit(); 451 if (!initializedGLEW) {
326 if (glewInitResult != GLEW_OK) { 452 // Initialize GLEW and check for GL 2.0 support by the drivers.
327 printf("GraphicsContext3D: GLEW initialization failed\n"); 453 GLenum glewInitResult = glewInit();
328 return; 454 if (glewInitResult != GLEW_OK) {
329 } 455 printf("GraphicsContext3D: GLEW initialization failed\n");
330 if (!glewIsSupported("GL_VERSION_2_0")) { 456 return;
331 printf("GraphicsContext3D: OpenGL 2.0 not supported\n"); 457 }
332 return; 458 if (!glewIsSupported("GL_VERSION_2_0")) {
459 printf("GraphicsContext3D: OpenGL 2.0 not supported\n");
460 return;
461 }
462 initializedGLEW = true;
333 } 463 }
334 } 464 }
335 465
336 GraphicsContext3DInternal::~GraphicsContext3DInternal() 466 GraphicsContext3DInternal::~GraphicsContext3DInternal()
337 { 467 {
338 makeContextCurrent(); 468 makeContextCurrent();
339 #ifndef RENDER_TO_DEBUGGING_WINDOW 469 #ifndef RENDER_TO_DEBUGGING_WINDOW
340 glDeleteRenderbuffersEXT(1, &m_depthBuffer); 470 glDeleteRenderbuffersEXT(1, &m_depthBuffer);
341 glDeleteTextures(1, &m_texture); 471 glDeleteTextures(1, &m_texture);
342 #ifdef FLIP_FRAMEBUFFER_VERTICALLY 472 #ifdef FLIP_FRAMEBUFFER_VERTICALLY
343 if (m_scanline != NULL) 473 if (m_scanline != NULL)
344 delete[] m_scanline; 474 delete[] m_scanline;
345 #endif 475 #endif
346 glDeleteFramebuffersEXT(1, &m_fbo); 476 glDeleteFramebuffersEXT(1, &m_fbo);
347 #endif // !RENDER_TO_DEBUGGING_WINDOW 477 #endif // !RENDER_TO_DEBUGGING_WINDOW
348 #if PLATFORM(WIN_OS) 478 #if PLATFORM(WIN_OS)
349 wglMakeCurrent(NULL, NULL); 479 wglMakeCurrent(NULL, NULL);
350 wglDeleteContext(m_contextObj); 480 wglDeleteContext(m_contextObj);
351 ReleaseDC(m_canvasWindow, m_canvasDC); 481 ReleaseDC(m_canvasWindow, m_canvasDC);
352 DestroyWindow(m_canvasWindow); 482 DestroyWindow(m_canvasWindow);
353 #elif PLATFORM(CG) 483 #elif PLATFORM(CG)
354 CGLSetCurrentContext(NULL); 484 CGLSetCurrentContext(NULL);
355 CGLDestroyContext(m_contextObj); 485 CGLDestroyContext(m_contextObj);
356 CGLDestroyPBuffer(m_pbuffer); 486 CGLDestroyPBuffer(m_pbuffer);
357 if (m_cgContext != NULL) 487 if (m_cgContext != NULL)
358 CGContextRelease(m_cgContext); 488 CGContextRelease(m_cgContext);
359 if (m_renderOutput != NULL) 489 if (m_renderOutput != NULL)
360 delete[] m_renderOutput; 490 delete[] m_renderOutput;
491 #elif PLATFORM(LINUX)
492 m_glXMakeCurrent(m_display, NULL, NULL);
493 m_glXDestroyContext(m_display, m_contextObj);
494 m_glXDestroyPbuffer(m_display, m_pbuffer);
495 XCloseDisplay(m_display);
496 dlclose(m_libGL);
361 #else 497 #else
362 #error Must port to your platform 498 #error Must port to your platform
363 #endif 499 #endif
364 m_contextObj = NULL; 500 m_contextObj = NULL;
365 } 501 }
366 502
367 void GraphicsContext3DInternal::checkError() const 503 void GraphicsContext3DInternal::checkError() const
368 { 504 {
369 // FIXME: This needs to only be done in the debug context. It 505 // FIXME: This needs to only be done in the debug context. It
370 // will need to throw an exception on error. 506 // will need to throw an exception on error.
371 GLenum error = glGetError(); 507 GLenum error = glGetError();
372 if (error != GL_NO_ERROR) { 508 if (error != GL_NO_ERROR) {
373 printf("GraphicsContext3DInternal: GL Error : %x\n", error); 509 printf("GraphicsContext3DInternal: GL Error : %x\n", error);
374 notImplemented(); 510 notImplemented();
375 } 511 }
376 } 512 }
377 513
378 bool GraphicsContext3DInternal::makeContextCurrent() 514 bool GraphicsContext3DInternal::makeContextCurrent()
379 { 515 {
380 #if PLATFORM(WIN_OS) 516 #if PLATFORM(WIN_OS)
381 if (wglGetCurrentContext() != m_contextObj) 517 if (wglGetCurrentContext() != m_contextObj)
382 if (wglMakeCurrent(m_canvasDC, m_contextObj)) 518 if (wglMakeCurrent(m_canvasDC, m_contextObj))
383 return true; 519 return true;
384 #elif PLATFORM(CG) 520 #elif PLATFORM(CG)
385 if (CGLGetCurrentContext() != m_contextObj) 521 if (CGLGetCurrentContext() != m_contextObj)
386 if (CGLSetCurrentContext(m_contextObj) == kCGLNoError) 522 if (CGLSetCurrentContext(m_contextObj) == kCGLNoError)
387 return true; 523 return true;
524 #elif PLATFORM(LINUX)
525 if (m_glXGetCurrentContext() != m_contextObj)
526 if (m_glXMakeCurrent(m_display, m_pbuffer, m_contextObj))
527 return true;
388 #else 528 #else
389 #error Must port to your platform 529 #error Must port to your platform
390 #endif 530 #endif
391 return false; 531 return false;
392 } 532 }
393 533
394 PlatformGraphicsContext3D GraphicsContext3DInternal::platformGraphicsContext3D() const 534 PlatformGraphicsContext3D GraphicsContext3DInternal::platformGraphicsContext3D() const
395 { 535 {
396 return m_contextObj; 536 return m_contextObj;
397 } 537 }
(...skipping 1629 matching lines...) Expand 10 before | Expand all | Expand 10 after
2027 2167
2028 void GraphicsContext3D::viewport(long x, long y, unsigned long width, unsigned long height) 2168 void GraphicsContext3D::viewport(long x, long y, unsigned long width, unsigned long height)
2029 { 2169 {
2030 makeContextCurrent(); 2170 makeContextCurrent();
2031 m_internal->viewportImpl(x, y, width, height); 2171 m_internal->viewportImpl(x, y, width, height);
2032 } 2172 }
2033 2173
2034 } 2174 }
2035 2175
2036 #endif // ENABLE(3D_CANVAS) 2176 #endif // ENABLE(3D_CANVAS)
OLDNEW
« 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