OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 extern "C" { | 5 extern "C" { |
6 #include <X11/Xlib.h> | 6 #include <X11/Xlib.h> |
7 } | 7 } |
8 | 8 |
9 #include "ui/gl/gl_surface_glx.h" | 9 #include "ui/gl/gl_surface_glx.h" |
10 | 10 |
(...skipping 23 matching lines...) Expand all Loading... |
34 // where "XVisualInfo" is any X type that is freed with XFree. | 34 // where "XVisualInfo" is any X type that is freed with XFree. |
35 class ScopedPtrXFree { | 35 class ScopedPtrXFree { |
36 public: | 36 public: |
37 void operator()(void* x) const { | 37 void operator()(void* x) const { |
38 ::XFree(x); | 38 ::XFree(x); |
39 } | 39 } |
40 }; | 40 }; |
41 | 41 |
42 Display* g_display; | 42 Display* g_display; |
43 const char* g_glx_extensions = NULL; | 43 const char* g_glx_extensions = NULL; |
| 44 bool g_glx_context_create = false; |
44 bool g_glx_create_context_robustness_supported = false; | 45 bool g_glx_create_context_robustness_supported = false; |
45 bool g_glx_texture_from_pixmap_supported = false; | 46 bool g_glx_texture_from_pixmap_supported = false; |
46 bool g_glx_oml_sync_control_supported = false; | 47 bool g_glx_oml_sync_control_supported = false; |
47 | 48 |
48 // Track support of glXGetMscRateOML separately from GLX_OML_sync_control as a | 49 // Track support of glXGetMscRateOML separately from GLX_OML_sync_control as a |
49 // whole since on some platforms (e.g. crosbug.com/34585), glXGetMscRateOML | 50 // whole since on some platforms (e.g. crosbug.com/34585), glXGetMscRateOML |
50 // always fails even though GLX_OML_sync_control is reported as being supported. | 51 // always fails even though GLX_OML_sync_control is reported as being supported. |
51 bool g_glx_get_msc_rate_oml_supported = false; | 52 bool g_glx_get_msc_rate_oml_supported = false; |
52 | 53 |
53 bool g_glx_sgi_video_sync_supported = false; | 54 bool g_glx_sgi_video_sync_supported = false; |
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
378 LOG(ERROR) << "glxQueryVersion failed"; | 379 LOG(ERROR) << "glxQueryVersion failed"; |
379 return false; | 380 return false; |
380 } | 381 } |
381 | 382 |
382 if (major == 1 && minor < 3) { | 383 if (major == 1 && minor < 3) { |
383 LOG(ERROR) << "GLX 1.3 or later is required."; | 384 LOG(ERROR) << "GLX 1.3 or later is required."; |
384 return false; | 385 return false; |
385 } | 386 } |
386 | 387 |
387 g_glx_extensions = glXQueryExtensionsString(g_display, 0); | 388 g_glx_extensions = glXQueryExtensionsString(g_display, 0); |
| 389 g_glx_context_create = |
| 390 HasGLXExtension("GLX_ARB_create_context"); |
388 g_glx_create_context_robustness_supported = | 391 g_glx_create_context_robustness_supported = |
389 HasGLXExtension("GLX_ARB_create_context_robustness"); | 392 HasGLXExtension("GLX_ARB_create_context_robustness"); |
390 g_glx_texture_from_pixmap_supported = | 393 g_glx_texture_from_pixmap_supported = |
391 HasGLXExtension("GLX_EXT_texture_from_pixmap"); | 394 HasGLXExtension("GLX_EXT_texture_from_pixmap"); |
392 g_glx_oml_sync_control_supported = | 395 g_glx_oml_sync_control_supported = |
393 HasGLXExtension("GLX_OML_sync_control"); | 396 HasGLXExtension("GLX_OML_sync_control"); |
394 g_glx_get_msc_rate_oml_supported = g_glx_oml_sync_control_supported; | 397 g_glx_get_msc_rate_oml_supported = g_glx_oml_sync_control_supported; |
395 g_glx_sgi_video_sync_supported = | 398 g_glx_sgi_video_sync_supported = |
396 HasGLXExtension("GLX_SGI_video_sync"); | 399 HasGLXExtension("GLX_SGI_video_sync"); |
397 | 400 |
398 if (!g_glx_get_msc_rate_oml_supported && g_glx_sgi_video_sync_supported) | 401 if (!g_glx_get_msc_rate_oml_supported && g_glx_sgi_video_sync_supported) |
399 SGIVideoSyncProviderThreadShim::g_display = XOpenDisplay(NULL); | 402 SGIVideoSyncProviderThreadShim::g_display = XOpenDisplay(NULL); |
400 | 403 |
401 initialized = true; | 404 initialized = true; |
402 return true; | 405 return true; |
403 } | 406 } |
404 | 407 |
405 // static | 408 // static |
406 const char* GLSurfaceGLX::GetGLXExtensions() { | 409 const char* GLSurfaceGLX::GetGLXExtensions() { |
407 return g_glx_extensions; | 410 return g_glx_extensions; |
408 } | 411 } |
409 | 412 |
410 // static | 413 // static |
411 bool GLSurfaceGLX::HasGLXExtension(const char* name) { | 414 bool GLSurfaceGLX::HasGLXExtension(const char* name) { |
412 return ExtensionsContain(GetGLXExtensions(), name); | 415 return ExtensionsContain(GetGLXExtensions(), name); |
413 } | 416 } |
414 | 417 |
415 // static | 418 // static |
| 419 bool GLSurfaceGLX::IsCreateContextSupported() { |
| 420 return g_glx_context_create; |
| 421 } |
| 422 |
| 423 // static |
416 bool GLSurfaceGLX::IsCreateContextRobustnessSupported() { | 424 bool GLSurfaceGLX::IsCreateContextRobustnessSupported() { |
417 return g_glx_create_context_robustness_supported; | 425 return g_glx_create_context_robustness_supported; |
418 } | 426 } |
419 | 427 |
420 // static | 428 // static |
421 bool GLSurfaceGLX::IsTextureFromPixmapSupported() { | 429 bool GLSurfaceGLX::IsTextureFromPixmapSupported() { |
422 return g_glx_texture_from_pixmap_supported; | 430 return g_glx_texture_from_pixmap_supported; |
423 } | 431 } |
424 | 432 |
425 // static | 433 // static |
(...skipping 18 matching lines...) Expand all Loading... |
444 LOG(ERROR) << "XGetWindowAttributes failed for window " << window_ << "."; | 452 LOG(ERROR) << "XGetWindowAttributes failed for window " << window_ << "."; |
445 return false; | 453 return false; |
446 } | 454 } |
447 size_ = gfx::Size(attributes.width, attributes.height); | 455 size_ = gfx::Size(attributes.width, attributes.height); |
448 | 456 |
449 if (g_glx_oml_sync_control_supported) | 457 if (g_glx_oml_sync_control_supported) |
450 vsync_provider_.reset(new OMLSyncControlVSyncProvider(window_)); | 458 vsync_provider_.reset(new OMLSyncControlVSyncProvider(window_)); |
451 else if (g_glx_sgi_video_sync_supported) | 459 else if (g_glx_sgi_video_sync_supported) |
452 vsync_provider_.reset(new SGIVideoSyncVSyncProvider(window_)); | 460 vsync_provider_.reset(new SGIVideoSyncVSyncProvider(window_)); |
453 | 461 |
| 462 glx_window_ = glXCreateWindow( |
| 463 g_display, |
| 464 static_cast<GLXFBConfig>(GetConfig()), |
| 465 window_, |
| 466 NULL); |
| 467 if (!glx_window_) { |
| 468 LOG(ERROR) << "glXCreateWindow failed for window " << window_ << "."; |
| 469 return false; |
| 470 } |
| 471 |
454 return true; | 472 return true; |
455 } | 473 } |
456 | 474 |
457 void NativeViewGLSurfaceGLX::Destroy() { | 475 void NativeViewGLSurfaceGLX::Destroy() { |
| 476 if (glx_window_) { |
| 477 glXDestroyWindow(g_display, glx_window_); |
| 478 glx_window_ = 0; |
| 479 } |
458 } | 480 } |
459 | 481 |
460 bool NativeViewGLSurfaceGLX::Resize(const gfx::Size& size) { | 482 bool NativeViewGLSurfaceGLX::Resize(const gfx::Size& size) { |
461 // On Intel drivers, the frame buffer won't be resize until the next swap. If | 483 // On Intel drivers, the frame buffer won't be resize until the next swap. If |
462 // we only do PostSubBuffer, then we're stuck in the old size. Force a swap | 484 // we only do PostSubBuffer, then we're stuck in the old size. Force a swap |
463 // now. | 485 // now. |
464 if (gfx::g_driver_glx.ext.b_GLX_MESA_copy_sub_buffer && size_ != size) | 486 if (gfx::g_driver_glx.ext.b_GLX_MESA_copy_sub_buffer && size_ != size) |
465 SwapBuffers(); | 487 SwapBuffers(); |
466 size_ = size; | 488 size_ = size; |
467 return true; | 489 return true; |
468 } | 490 } |
469 | 491 |
470 bool NativeViewGLSurfaceGLX::IsOffscreen() { | 492 bool NativeViewGLSurfaceGLX::IsOffscreen() { |
471 return false; | 493 return false; |
472 } | 494 } |
473 | 495 |
474 bool NativeViewGLSurfaceGLX::SwapBuffers() { | 496 bool NativeViewGLSurfaceGLX::SwapBuffers() { |
475 glXSwapBuffers(g_display, window_); | 497 glXSwapBuffers(g_display, glx_window_); |
476 // For latency_tests.cc: | 498 // For latency_tests.cc: |
477 UNSHIPPED_TRACE_EVENT_INSTANT0("test_gpu", "CompositorSwapBuffersComplete"); | 499 UNSHIPPED_TRACE_EVENT_INSTANT0("test_gpu", "CompositorSwapBuffersComplete"); |
478 return true; | 500 return true; |
479 } | 501 } |
480 | 502 |
481 gfx::Size NativeViewGLSurfaceGLX::GetSize() { | 503 gfx::Size NativeViewGLSurfaceGLX::GetSize() { |
482 return size_; | 504 return size_; |
483 } | 505 } |
484 | 506 |
485 void* NativeViewGLSurfaceGLX::GetHandle() { | 507 void* NativeViewGLSurfaceGLX::GetHandle() { |
486 return reinterpret_cast<void*>(window_); | 508 return reinterpret_cast<void*>(glx_window_); |
487 } | 509 } |
488 | 510 |
489 std::string NativeViewGLSurfaceGLX::GetExtensions() { | 511 std::string NativeViewGLSurfaceGLX::GetExtensions() { |
490 std::string extensions = GLSurface::GetExtensions(); | 512 std::string extensions = GLSurface::GetExtensions(); |
491 if (gfx::g_driver_glx.ext.b_GLX_MESA_copy_sub_buffer) { | 513 if (gfx::g_driver_glx.ext.b_GLX_MESA_copy_sub_buffer) { |
492 extensions += extensions.empty() ? "" : " "; | 514 extensions += extensions.empty() ? "" : " "; |
493 extensions += "GL_CHROMIUM_post_sub_buffer"; | 515 extensions += "GL_CHROMIUM_post_sub_buffer"; |
494 } | 516 } |
495 return extensions; | 517 return extensions; |
496 } | 518 } |
497 | 519 |
498 void* NativeViewGLSurfaceGLX::GetConfig() { | 520 void* NativeViewGLSurfaceGLX::GetConfig() { |
499 if (!config_) { | 521 if (!config_) { |
500 // This code path is expensive, but we only take it when | 522 // This code path is expensive, but we only take it when |
501 // attempting to use GLX_ARB_create_context_robustness, in which | 523 // attempting to use GLX_ARB_create_context_robustness, in which |
502 // case we need a GLXFBConfig for the window in order to create a | 524 // case we need a GLXFBConfig for the window in order to create a |
503 // context for it. | 525 // context for it. |
504 // | 526 // |
505 // TODO(kbr): this is not a reliable code path. On platforms which | 527 // TODO(kbr): this is not a reliable code path. On platforms which |
506 // support it, we should use glXChooseFBConfig in the browser | 528 // support it, we should use glXChooseFBConfig in the browser |
507 // process to choose the FBConfig and from there the X Visual to | 529 // process to choose the FBConfig and from there the X Visual to |
508 // use when creating the window in the first place. Then we can | 530 // use when creating the window in the first place. Then we can |
509 // pass that FBConfig down rather than attempting to reconstitute | 531 // pass that FBConfig down rather than attempting to reconstitute |
510 // it. | 532 // it. |
511 | 533 |
512 XWindowAttributes attributes; | 534 XWindowAttributes attributes; |
513 if (!XGetWindowAttributes( | 535 if (!XGetWindowAttributes( |
514 g_display, | 536 g_display, |
515 reinterpret_cast<GLXDrawable>(GetHandle()), | 537 window_, |
516 &attributes)) { | 538 &attributes)) { |
517 LOG(ERROR) << "XGetWindowAttributes failed for window " << | 539 LOG(ERROR) << "XGetWindowAttributes failed for window " << |
518 reinterpret_cast<GLXDrawable>(GetHandle()) << "."; | 540 window_ << "."; |
519 return NULL; | 541 return NULL; |
520 } | 542 } |
521 | 543 |
522 int visual_id = XVisualIDFromVisual(attributes.visual); | 544 int visual_id = XVisualIDFromVisual(attributes.visual); |
523 | 545 |
524 int num_elements = 0; | 546 int num_elements = 0; |
525 scoped_ptr_malloc<GLXFBConfig, ScopedPtrXFree> configs( | 547 scoped_ptr_malloc<GLXFBConfig, ScopedPtrXFree> configs( |
526 glXGetFBConfigs(g_display, | 548 glXGetFBConfigs(g_display, |
527 DefaultScreen(g_display), | 549 DefaultScreen(g_display), |
528 &num_elements)); | 550 &num_elements)); |
(...skipping 23 matching lines...) Expand all Loading... |
552 config_ = configs.get()[i]; | 574 config_ = configs.get()[i]; |
553 } | 575 } |
554 } | 576 } |
555 | 577 |
556 return config_; | 578 return config_; |
557 } | 579 } |
558 | 580 |
559 bool NativeViewGLSurfaceGLX::PostSubBuffer( | 581 bool NativeViewGLSurfaceGLX::PostSubBuffer( |
560 int x, int y, int width, int height) { | 582 int x, int y, int width, int height) { |
561 DCHECK(gfx::g_driver_glx.ext.b_GLX_MESA_copy_sub_buffer); | 583 DCHECK(gfx::g_driver_glx.ext.b_GLX_MESA_copy_sub_buffer); |
562 glXCopySubBufferMESA(g_display, window_, x, y, width, height); | 584 glXCopySubBufferMESA(g_display, glx_window_, x, y, width, height); |
563 return true; | 585 return true; |
564 } | 586 } |
565 | 587 |
566 void NativeViewGLSurfaceGLX::GetVSyncParameters( | 588 void NativeViewGLSurfaceGLX::GetVSyncParameters( |
567 const UpdateVSyncCallback& callback) { | 589 const UpdateVSyncCallback& callback) { |
568 if (vsync_provider_) | 590 if (vsync_provider_) |
569 vsync_provider_->GetVSyncParameters(callback); | 591 vsync_provider_->GetVSyncParameters(callback); |
570 } | 592 } |
571 | 593 |
572 NativeViewGLSurfaceGLX::NativeViewGLSurfaceGLX() | 594 NativeViewGLSurfaceGLX::NativeViewGLSurfaceGLX() |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
661 | 683 |
662 void* PbufferGLSurfaceGLX::GetConfig() { | 684 void* PbufferGLSurfaceGLX::GetConfig() { |
663 return config_; | 685 return config_; |
664 } | 686 } |
665 | 687 |
666 PbufferGLSurfaceGLX::~PbufferGLSurfaceGLX() { | 688 PbufferGLSurfaceGLX::~PbufferGLSurfaceGLX() { |
667 Destroy(); | 689 Destroy(); |
668 } | 690 } |
669 | 691 |
670 } // namespace gfx | 692 } // namespace gfx |
OLD | NEW |