Changeset 52504 in webkit
- Timestamp:
- Dec 22, 2009 3:00:20 PM (14 years ago)
- Location:
- trunk/WebKit/chromium
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebKit/chromium/ChangeLog
r52488 r52504 1 2009-12-22 Kenneth Russell <kbr@google.com> 2 3 Reviewed by Eric Seidel. 4 5 [Chromium] WebGL crashes intermittently on Linux 6 https://bugs.webkit.org/show_bug.cgi?id=32845 7 8 The dlclose'ing of libGL.so.1 and dlopen'ing of it each time a 9 GraphicsContext3D was created was occasionally causing it to be 10 re-mapped at a different base address. Since GLEW is not 11 re-initialized every time, primarily for performance reasons, its 12 cached function pointers were pointing to garbage. Stopped closing 13 and re-opening libGL.so.1 each time; now it is loaded lazily, when 14 the first 3D context is created. Also reused the X display 15 connection since the GLX routines' correctness might hinge upon it 16 not resulting in a change of GL implementation. 17 18 * src/GraphicsContext3D.cpp: 19 (WebCore::GraphicsContext3DInternal::GLConnection::chooseFBConfig): 20 (WebCore::GraphicsContext3DInternal::GLConnection::createNewContext): 21 (WebCore::GraphicsContext3DInternal::GLConnection::createPbuffer): 22 (WebCore::GraphicsContext3DInternal::GLConnection::destroyPbuffer): 23 (WebCore::GraphicsContext3DInternal::GLConnection::makeCurrent): 24 (WebCore::GraphicsContext3DInternal::GLConnection::destroyContext): 25 (WebCore::GraphicsContext3DInternal::GLConnection::getCurrentContext): 26 (WebCore::GraphicsContext3DInternal::GLConnection::GLConnection): 27 (WebCore::GraphicsContext3DInternal::GLConnection::tryLoad): 28 (WebCore::GraphicsContext3DInternal::GLConnection::create): 29 (WebCore::GraphicsContext3DInternal::GLConnection::~GLConnection): 30 (WebCore::GraphicsContext3DInternal::GraphicsContext3DInternal): 31 (WebCore::GraphicsContext3DInternal::~GraphicsContext3DInternal): 32 (WebCore::GraphicsContext3DInternal::makeContextCurrent): 33 1 34 2009-12-22 Yaar Schnitman <yaar@chromium.org> 2 35 -
trunk/WebKit/chromium/src/GraphicsContext3D.cpp
r52380 r52504 182 182 #endif 183 183 184 static bool s_initializedGLEW; 184 185 #if PLATFORM(WIN_OS) 185 186 HWND m_canvasWindow; … … 191 192 unsigned char* m_renderOutput; 192 193 #elif PLATFORM(LINUX) 193 Display* m_display;194 194 GLXContext m_contextObj; 195 195 GLXPbuffer m_pbuffer; 196 196 197 // In order to avoid problems caused by linking against libGL, we 197 198 // dynamically look up all the symbols we need. 198 199 // http://code.google.com/p/chromium/issues/detail?id=16800 199 void* m_libGL; 200 PFNGLXCHOOSEFBCONFIGPROC m_glXChooseFBConfig; 201 PFNGLXCREATENEWCONTEXTPROC m_glXCreateNewContext; 202 PFNGLXCREATEPBUFFERPROC m_glXCreatePbuffer; 203 PFNGLXDESTROYPBUFFERPROC m_glXDestroyPbuffer; 204 typedef Bool (* PFNGLXMAKECURRENTPROC)(Display* dpy, GLXDrawable drawable, GLXContext ctx); 205 PFNGLXMAKECURRENTPROC m_glXMakeCurrent; 206 typedef void (* PFNGLXDESTROYCONTEXTPROC)(Display* dpy, GLXContext ctx); 207 PFNGLXDESTROYCONTEXTPROC m_glXDestroyContext; 208 typedef GLXContext (* PFNGLXGETCURRENTCONTEXTPROC)(void); 209 PFNGLXGETCURRENTCONTEXTPROC m_glXGetCurrentContext; 200 class GLConnection { 201 public: 202 ~GLConnection(); 203 204 static GLConnection* create(); 205 206 GLXFBConfig* chooseFBConfig(int screen, const int *attrib_list, int *nelements) 207 { 208 return m_glXChooseFBConfig(m_display, screen, attrib_list, nelements); 209 } 210 211 GLXContext createNewContext(GLXFBConfig config, int renderType, GLXContext shareList, Bool direct) 212 { 213 return m_glXCreateNewContext(m_display, config, renderType, shareList, direct); 214 } 215 216 GLXPbuffer createPbuffer(GLXFBConfig config, const int *attribList) 217 { 218 return m_glXCreatePbuffer(m_display, config, attribList); 219 } 220 221 void destroyPbuffer(GLXPbuffer pbuf) 222 { 223 m_glXDestroyPbuffer(m_display, pbuf); 224 } 225 226 Bool makeCurrent(GLXDrawable drawable, GLXContext ctx) 227 { 228 return m_glXMakeCurrent(m_display, drawable, ctx); 229 } 230 231 void destroyContext(GLXContext ctx) 232 { 233 m_glXDestroyContext(m_display, ctx); 234 } 235 236 GLXContext getCurrentContext() 237 { 238 return m_glXGetCurrentContext(); 239 } 240 241 private: 242 Display* m_display; 243 void* m_libGL; 244 PFNGLXCHOOSEFBCONFIGPROC m_glXChooseFBConfig; 245 PFNGLXCREATENEWCONTEXTPROC m_glXCreateNewContext; 246 PFNGLXCREATEPBUFFERPROC m_glXCreatePbuffer; 247 PFNGLXDESTROYPBUFFERPROC m_glXDestroyPbuffer; 248 typedef Bool (* PFNGLXMAKECURRENTPROC)(Display* dpy, GLXDrawable drawable, GLXContext ctx); 249 PFNGLXMAKECURRENTPROC m_glXMakeCurrent; 250 typedef void (* PFNGLXDESTROYCONTEXTPROC)(Display* dpy, GLXContext ctx); 251 PFNGLXDESTROYCONTEXTPROC m_glXDestroyContext; 252 typedef GLXContext (* PFNGLXGETCURRENTCONTEXTPROC)(void); 253 PFNGLXGETCURRENTCONTEXTPROC m_glXGetCurrentContext; 254 255 GLConnection(Display* display, 256 void* libGL, 257 PFNGLXCHOOSEFBCONFIGPROC chooseFBConfig, 258 PFNGLXCREATENEWCONTEXTPROC createNewContext, 259 PFNGLXCREATEPBUFFERPROC createPbuffer, 260 PFNGLXDESTROYPBUFFERPROC destroyPbuffer, 261 PFNGLXMAKECURRENTPROC makeCurrent, 262 PFNGLXDESTROYCONTEXTPROC destroyContext, 263 PFNGLXGETCURRENTCONTEXTPROC getCurrentContext) 264 : m_libGL(libGL) 265 , m_display(display) 266 , m_glXChooseFBConfig(chooseFBConfig) 267 , m_glXCreateNewContext(createNewContext) 268 , m_glXCreatePbuffer(createPbuffer) 269 , m_glXDestroyPbuffer(destroyPbuffer) 270 , m_glXMakeCurrent(makeCurrent) 271 , m_glXDestroyContext(destroyContext) 272 , m_glXGetCurrentContext(getCurrentContext) 273 { 274 } 275 276 static void* tryLoad(const char* libName) 277 { 278 // We use RTLD_GLOBAL semantics so that GLEW initialization works; 279 // GLEW expects to be able to open the current process's handle 280 // and do dlsym's of GL entry points from there. 281 return dlopen(libName, RTLD_LAZY | RTLD_GLOBAL); 282 } 283 }; 284 285 static GLConnection* s_gl; 210 286 #else 211 287 #error Must port GraphicsContext3D to your platform 212 288 #endif 213 289 }; 290 291 bool GraphicsContext3DInternal::s_initializedGLEW = false; 292 #if PLATFORM(LINUX) 293 GraphicsContext3DInternal::GLConnection* GraphicsContext3DInternal::s_gl = 0; 294 #endif 295 296 GraphicsContext3DInternal::GLConnection* GraphicsContext3DInternal::GLConnection::create() 297 { 298 Display* dpy = XOpenDisplay(0); 299 if (!dpy) { 300 printf("GraphicsContext3D: error opening X display\n"); 301 return 0; 302 } 303 304 void* libGL = 0; 305 const char* libNames[] = { 306 "/usr/lib/libGL.so.1", 307 "/usr/lib32/libGL.so.1", 308 "/usr/lib64/libGL.so.1", 309 }; 310 for (int i = 0; i < sizeof(libNames) / sizeof(const char*); i++) { 311 libGL = tryLoad(libNames[i]); 312 if (libGL) 313 break; 314 } 315 if (!libGL) { 316 printf("GraphicsContext3D: error opening libGL.so.1\n"); 317 printf("GraphicsContext3D: tried:\n"); 318 for (int i = 0; i < sizeof(libNames) / sizeof(const char*); i++) 319 printf(" %s\n", libNames[i]); 320 return 0; 321 } 322 323 PFNGLXCHOOSEFBCONFIGPROC chooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC) dlsym(libGL, "glXChooseFBConfig"); 324 PFNGLXCREATENEWCONTEXTPROC createNewContext = (PFNGLXCREATENEWCONTEXTPROC) dlsym(libGL, "glXCreateNewContext"); 325 PFNGLXCREATEPBUFFERPROC createPbuffer = (PFNGLXCREATEPBUFFERPROC) dlsym(libGL, "glXCreatePbuffer"); 326 PFNGLXDESTROYPBUFFERPROC destroyPbuffer = (PFNGLXDESTROYPBUFFERPROC) dlsym(libGL, "glXDestroyPbuffer"); 327 PFNGLXMAKECURRENTPROC makeCurrent = (PFNGLXMAKECURRENTPROC) dlsym(libGL, "glXMakeCurrent"); 328 PFNGLXDESTROYCONTEXTPROC destroyContext = (PFNGLXDESTROYCONTEXTPROC) dlsym(libGL, "glXDestroyContext"); 329 PFNGLXGETCURRENTCONTEXTPROC getCurrentContext = (PFNGLXGETCURRENTCONTEXTPROC) dlsym(libGL, "glXGetCurrentContext"); 330 if (!chooseFBConfig || !createNewContext || !createPbuffer 331 || !destroyPbuffer || !makeCurrent || !destroyContext 332 || !getCurrentContext) { 333 XCloseDisplay(dpy); 334 dlclose(libGL); 335 printf("GraphicsContext3D: error looking up bootstrapping entry points\n"); 336 return 0; 337 } 338 return new GLConnection(dpy, 339 libGL, 340 chooseFBConfig, 341 createNewContext, 342 createPbuffer, 343 destroyPbuffer, 344 makeCurrent, 345 destroyContext, 346 getCurrentContext); 347 } 348 349 GraphicsContext3DInternal::GLConnection::~GLConnection() 350 { 351 XCloseDisplay(m_display); 352 dlclose(m_libGL); 353 } 214 354 215 355 GraphicsContext3DInternal::VertexAttribPointerState::VertexAttribPointerState() … … 225 365 } 226 366 227 #if PLATFORM(LINUX)228 static void* tryLoad(const char* libName)229 {230 // We use RTLD_GLOBAL semantics so that GLEW initialization works;231 // GLEW expects to be able to open the current process's handle232 // and do dlsym's of GL entry points from there.233 return dlopen(libName, RTLD_LAZY | RTLD_GLOBAL);234 }235 #endif236 237 367 GraphicsContext3DInternal::GraphicsContext3DInternal() 238 368 : m_texture(0) … … 256 386 , m_renderOutput(0) 257 387 #elif PLATFORM(LINUX) 258 , m_display(0)259 388 , m_contextObj(0) 260 389 , m_pbuffer(0) 261 , m_glXChooseFBConfig(0)262 , m_glXCreateNewContext(0)263 , m_glXCreatePbuffer(0)264 , m_glXDestroyPbuffer(0)265 , m_glXMakeCurrent(0)266 , m_glXDestroyContext(0)267 , m_glXGetCurrentContext(0)268 390 #else 269 391 #error Must port to your platform … … 383 505 m_contextObj = context; 384 506 #elif PLATFORM(LINUX) 385 m_display = XOpenDisplay(0); 386 if (!m_display) { 387 printf("GraphicsContext3D: error opening X display\n"); 388 return; 389 } 390 391 const char* libNames[] = { 392 "/usr/lib/libGL.so.1", 393 "/usr/lib32/libGL.so.1", 394 "/usr/lib64/libGL.so.1", 395 }; 396 for (int i = 0; i < sizeof(libNames) / sizeof(const char*); i++) { 397 m_libGL = tryLoad(libNames[i]); 398 if (m_libGL) 399 break; 400 } 401 if (!m_libGL) { 402 printf("GraphicsContext3D: error opening libGL.so.1\n"); 403 printf("GraphicsContext3D: tried:"); 404 for (int i = 0; i < sizeof(libNames) / sizeof(const char*); i++) 405 printf(" %s", libNames[i]); 406 return; 407 } 408 m_glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC) dlsym(m_libGL, "glXChooseFBConfig"); 409 m_glXCreateNewContext = (PFNGLXCREATENEWCONTEXTPROC) dlsym(m_libGL, "glXCreateNewContext"); 410 m_glXCreatePbuffer = (PFNGLXCREATEPBUFFERPROC) dlsym(m_libGL, "glXCreatePbuffer"); 411 m_glXDestroyPbuffer = (PFNGLXDESTROYPBUFFERPROC) dlsym(m_libGL, "glXDestroyPbuffer"); 412 m_glXMakeCurrent = (PFNGLXMAKECURRENTPROC) dlsym(m_libGL, "glXMakeCurrent"); 413 m_glXDestroyContext = (PFNGLXDESTROYCONTEXTPROC) dlsym(m_libGL, "glXDestroyContext"); 414 m_glXGetCurrentContext = (PFNGLXGETCURRENTCONTEXTPROC) dlsym(m_libGL, "glXGetCurrentContext"); 415 if (!m_glXChooseFBConfig || !m_glXCreateNewContext || !m_glXCreatePbuffer 416 || !m_glXDestroyPbuffer || !m_glXMakeCurrent || !m_glXDestroyContext 417 || !m_glXGetCurrentContext) { 418 printf("GraphicsContext3D: error looking up bootstrapping entry points\n"); 419 return; 420 } 507 if (!s_gl) { 508 s_gl = GLConnection::create(); 509 if (!s_gl) 510 return; 511 } 512 421 513 int configAttrs[] = { 422 514 GLX_DRAWABLE_TYPE, … … 429 521 }; 430 522 int nelements = 0; 431 GLXFBConfig* config = m_glXChooseFBConfig(m_display,0, configAttrs, &nelements);523 GLXFBConfig* config = s_gl->chooseFBConfig(0, configAttrs, &nelements); 432 524 if (!config) { 433 525 printf("GraphicsContext3D: glXChooseFBConfig failed\n"); … … 439 531 return; 440 532 } 441 GLXContext context = m_glXCreateNewContext(m_display,config[0], GLX_RGBA_TYPE, 0, True);533 GLXContext context = s_gl->createNewContext(config[0], GLX_RGBA_TYPE, 0, True); 442 534 if (!context) { 443 535 printf("GraphicsContext3D: glXCreateNewContext failed\n"); … … 452 544 0 453 545 }; 454 GLXPbuffer pbuffer = m_glXCreatePbuffer(m_display,config[0], pbufferAttrs);546 GLXPbuffer pbuffer = s_gl->createPbuffer(config[0], pbufferAttrs); 455 547 XFree(config); 456 548 if (!pbuffer) { … … 458 550 return; 459 551 } 460 if (! m_glXMakeCurrent(m_display,pbuffer, context)) {552 if (!s_gl->makeCurrent(pbuffer, context)) { 461 553 printf("GraphicsContext3D: glXMakeCurrent failed\n"); 462 554 return; … … 468 560 #endif 469 561 470 static bool initializedGLEW = false; 471 if (!initializedGLEW) { 562 if (!s_initializedGLEW) { 472 563 // Initialize GLEW and check for GL 2.0 support by the drivers. 473 564 GLenum glewInitResult = glewInit(); … … 480 571 return; 481 572 } 482 initializedGLEW = true;573 s_initializedGLEW = true; 483 574 } 484 575 } … … 512 603 delete[] m_renderOutput; 513 604 #elif PLATFORM(LINUX) 514 m_glXMakeCurrent(m_display, 0, 0); 515 m_glXDestroyContext(m_display, m_contextObj); 516 m_glXDestroyPbuffer(m_display, m_pbuffer); 517 XCloseDisplay(m_display); 518 dlclose(m_libGL); 605 s_gl->makeCurrent(0, 0); 606 s_gl->destroyContext(m_contextObj); 607 s_gl->destroyPbuffer(m_pbuffer); 519 608 #else 520 609 #error Must port to your platform … … 534 623 return true; 535 624 #elif PLATFORM(LINUX) 536 if ( m_glXGetCurrentContext() != m_contextObj)537 if ( m_glXMakeCurrent(m_display,m_pbuffer, m_contextObj))625 if (s_gl->getCurrentContext() != m_contextObj) 626 if (s_gl->makeCurrent(m_pbuffer, m_contextObj)) 538 627 return true; 539 628 #else
Note: See TracChangeset
for help on using the changeset viewer.