| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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) |
| OLD | NEW |