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 #include "ui/gl/gl_surface_glx.h" | 5 #include "ui/gl/gl_surface_glx.h" |
6 | 6 |
7 extern "C" { | 7 extern "C" { |
8 #include <X11/Xlib.h> | 8 #include <X11/Xlib.h> |
9 } | 9 } |
10 #include <memory> | 10 #include <memory> |
(...skipping 11 matching lines...) Expand all Loading... |
22 #include "base/threading/thread.h" | 22 #include "base/threading/thread.h" |
23 #include "base/threading/thread_task_runner_handle.h" | 23 #include "base/threading/thread_task_runner_handle.h" |
24 #include "base/time/time.h" | 24 #include "base/time/time.h" |
25 #include "base/trace_event/trace_event.h" | 25 #include "base/trace_event/trace_event.h" |
26 #include "build/build_config.h" | 26 #include "build/build_config.h" |
27 #include "ui/events/platform/platform_event_source.h" | 27 #include "ui/events/platform/platform_event_source.h" |
28 #include "ui/gfx/x/x11_connection.h" | 28 #include "ui/gfx/x/x11_connection.h" |
29 #include "ui/gfx/x/x11_types.h" | 29 #include "ui/gfx/x/x11_types.h" |
30 #include "ui/gl/gl_bindings.h" | 30 #include "ui/gl/gl_bindings.h" |
31 #include "ui/gl/gl_implementation.h" | 31 #include "ui/gl/gl_implementation.h" |
| 32 #include "ui/gl/gl_visual_picker_glx.h" |
32 #include "ui/gl/sync_control_vsync_provider.h" | 33 #include "ui/gl/sync_control_vsync_provider.h" |
33 | 34 |
34 namespace gl { | 35 namespace gl { |
35 | 36 |
36 namespace { | 37 namespace { |
37 | 38 |
38 Display* g_display = nullptr; | 39 Display* g_display = nullptr; |
39 bool g_glx_context_create = false; | 40 bool g_glx_context_create = false; |
40 bool g_glx_create_context_robustness_supported = false; | 41 bool g_glx_create_context_robustness_supported = false; |
41 bool g_glx_create_context_profile_supported = false; | 42 bool g_glx_create_context_profile_supported = false; |
42 bool g_glx_create_context_profile_es2_supported = false; | 43 bool g_glx_create_context_profile_es2_supported = false; |
43 bool g_glx_texture_from_pixmap_supported = false; | 44 bool g_glx_texture_from_pixmap_supported = false; |
44 bool g_glx_oml_sync_control_supported = false; | 45 bool g_glx_oml_sync_control_supported = false; |
45 | 46 |
46 // Track support of glXGetMscRateOML separately from GLX_OML_sync_control as a | 47 // Track support of glXGetMscRateOML separately from GLX_OML_sync_control as a |
47 // whole since on some platforms (e.g. crosbug.com/34585), glXGetMscRateOML | 48 // whole since on some platforms (e.g. crosbug.com/34585), glXGetMscRateOML |
48 // always fails even though GLX_OML_sync_control is reported as being supported. | 49 // always fails even though GLX_OML_sync_control is reported as being supported. |
49 bool g_glx_get_msc_rate_oml_supported = false; | 50 bool g_glx_get_msc_rate_oml_supported = false; |
50 | 51 |
51 bool g_glx_sgi_video_sync_supported = false; | 52 bool g_glx_sgi_video_sync_supported = false; |
52 | 53 |
| 54 // A 24-bit RGB visual and colormap to use when creating offscreen surfaces. |
| 55 Visual* g_visual = nullptr; |
| 56 int g_depth = CopyFromParent; |
| 57 Colormap g_colormap = CopyFromParent; |
| 58 |
53 GLXFBConfig GetConfigForWindow(Display* display, | 59 GLXFBConfig GetConfigForWindow(Display* display, |
54 gfx::AcceleratedWidget window) { | 60 gfx::AcceleratedWidget window) { |
55 DCHECK(window != 0); | 61 DCHECK(window != 0); |
56 | 62 |
57 // This code path is expensive, but we only take it when | 63 // This code path is expensive, but we only take it when |
58 // attempting to use GLX_ARB_create_context_robustness, in which | 64 // attempting to use GLX_ARB_create_context_robustness, in which |
59 // case we need a GLXFBConfig for the window in order to create a | 65 // case we need a GLXFBConfig for the window in order to create a |
60 // context for it. | 66 // context for it. |
61 // | 67 // |
62 // TODO(kbr): this is not a reliable code path. On platforms which | 68 // TODO(kbr): this is not a reliable code path. On platforms which |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 if (found) { | 108 if (found) { |
103 return configs.get()[i]; | 109 return configs.get()[i]; |
104 } | 110 } |
105 return nullptr; | 111 return nullptr; |
106 } | 112 } |
107 | 113 |
108 bool CreateDummyWindow(Display* display) { | 114 bool CreateDummyWindow(Display* display) { |
109 DCHECK(display); | 115 DCHECK(display); |
110 gfx::AcceleratedWidget parent_window = | 116 gfx::AcceleratedWidget parent_window = |
111 RootWindow(display, DefaultScreen(display)); | 117 RootWindow(display, DefaultScreen(display)); |
112 // We create a window with CopyFromParent visual so that we have the same | |
113 // visual as NativeViewGLSurfaceGLX (i.e. same GLXFBConfig), to ensure | |
114 // contexts are compatible and can be made current with either. | |
115 gfx::AcceleratedWidget window = | 118 gfx::AcceleratedWidget window = |
116 XCreateWindow(display, parent_window, 0, 0, 1, 1, 0, CopyFromParent, | 119 XCreateWindow(display, parent_window, 0, 0, 1, 1, 0, CopyFromParent, |
117 InputOutput, CopyFromParent, 0, nullptr); | 120 InputOutput, CopyFromParent, 0, nullptr); |
118 if (!window) { | 121 if (!window) { |
119 LOG(ERROR) << "XCreateWindow failed"; | 122 LOG(ERROR) << "XCreateWindow failed"; |
120 return false; | 123 return false; |
121 } | 124 } |
122 GLXFBConfig config = GetConfigForWindow(display, window); | 125 GLXFBConfig config = GetConfigForWindow(display, window); |
123 GLXWindow glx_window = glXCreateWindow(display, config, window, nullptr); | 126 GLXWindow glx_window = glXCreateWindow(display, config, window, nullptr); |
124 if (!glx_window) { | 127 if (!glx_window) { |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
415 g_glx_create_context_profile_supported = | 418 g_glx_create_context_profile_supported = |
416 HasGLXExtension("GLX_ARB_create_context_profile"); | 419 HasGLXExtension("GLX_ARB_create_context_profile"); |
417 g_glx_create_context_profile_es2_supported = | 420 g_glx_create_context_profile_es2_supported = |
418 HasGLXExtension("GLX_ARB_create_context_es2_profile"); | 421 HasGLXExtension("GLX_ARB_create_context_es2_profile"); |
419 g_glx_texture_from_pixmap_supported = | 422 g_glx_texture_from_pixmap_supported = |
420 HasGLXExtension("GLX_EXT_texture_from_pixmap"); | 423 HasGLXExtension("GLX_EXT_texture_from_pixmap"); |
421 g_glx_oml_sync_control_supported = HasGLXExtension("GLX_OML_sync_control"); | 424 g_glx_oml_sync_control_supported = HasGLXExtension("GLX_OML_sync_control"); |
422 g_glx_get_msc_rate_oml_supported = g_glx_oml_sync_control_supported; | 425 g_glx_get_msc_rate_oml_supported = g_glx_oml_sync_control_supported; |
423 g_glx_sgi_video_sync_supported = HasGLXExtension("GLX_SGI_video_sync"); | 426 g_glx_sgi_video_sync_supported = HasGLXExtension("GLX_SGI_video_sync"); |
424 | 427 |
| 428 const XVisualInfo& visual_info = |
| 429 gl::GLVisualPickerGLX::GetInstance()->system_visual(); |
| 430 g_visual = visual_info.visual; |
| 431 g_depth = visual_info.depth; |
| 432 g_colormap = XCreateColormap(g_display, DefaultRootWindow(g_display), |
| 433 visual_info.visual, AllocNone); |
| 434 |
425 // We create a dummy unmapped window for both the main Display and the video | 435 // We create a dummy unmapped window for both the main Display and the video |
426 // sync Display so that the Nvidia driver can initialize itself before the | 436 // sync Display so that the Nvidia driver can initialize itself before the |
427 // sandbox is set up. | 437 // sandbox is set up. |
428 // Unfortunately some fds e.g. /dev/nvidia0 are cached per thread and because | 438 // Unfortunately some fds e.g. /dev/nvidia0 are cached per thread and because |
429 // we can't start threads before the sandbox is set up, these are accessed | 439 // we can't start threads before the sandbox is set up, these are accessed |
430 // through the broker process. See GpuProcessPolicy::InitGpuBrokerProcess. | 440 // through the broker process. See GpuProcessPolicy::InitGpuBrokerProcess. |
431 if (!CreateDummyWindow(g_display)) { | 441 if (!CreateDummyWindow(g_display)) { |
432 LOG(ERROR) << "CreateDummyWindow(g_display) failed"; | 442 LOG(ERROR) << "CreateDummyWindow(g_display) failed"; |
433 return false; | 443 return false; |
434 } | 444 } |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
486 return g_glx_oml_sync_control_supported; | 496 return g_glx_oml_sync_control_supported; |
487 } | 497 } |
488 | 498 |
489 void* GLSurfaceGLX::GetDisplay() { | 499 void* GLSurfaceGLX::GetDisplay() { |
490 return g_display; | 500 return g_display; |
491 } | 501 } |
492 | 502 |
493 GLSurfaceGLX::~GLSurfaceGLX() {} | 503 GLSurfaceGLX::~GLSurfaceGLX() {} |
494 | 504 |
495 NativeViewGLSurfaceGLX::NativeViewGLSurfaceGLX(gfx::AcceleratedWidget window) | 505 NativeViewGLSurfaceGLX::NativeViewGLSurfaceGLX(gfx::AcceleratedWidget window) |
496 : parent_window_(window), window_(0), glx_window_(0), config_(nullptr) {} | 506 : parent_window_(window), |
| 507 window_(0), |
| 508 glx_window_(0), |
| 509 config_(nullptr), |
| 510 visual_id_(CopyFromParent) {} |
497 | 511 |
498 GLXDrawable NativeViewGLSurfaceGLX::GetDrawableHandle() const { | 512 GLXDrawable NativeViewGLSurfaceGLX::GetDrawableHandle() const { |
499 return glx_window_; | 513 return glx_window_; |
500 } | 514 } |
501 | 515 |
502 bool NativeViewGLSurfaceGLX::Initialize(GLSurface::Format format) { | 516 bool NativeViewGLSurfaceGLX::Initialize(GLSurface::Format format) { |
503 XWindowAttributes attributes; | 517 XWindowAttributes attributes; |
504 if (!XGetWindowAttributes(g_display, parent_window_, &attributes)) { | 518 if (!XGetWindowAttributes(g_display, parent_window_, &attributes)) { |
505 LOG(ERROR) << "XGetWindowAttributes failed for window " << parent_window_ | 519 LOG(ERROR) << "XGetWindowAttributes failed for window " << parent_window_ |
506 << "."; | 520 << "."; |
507 return false; | 521 return false; |
508 } | 522 } |
509 size_ = gfx::Size(attributes.width, attributes.height); | 523 size_ = gfx::Size(attributes.width, attributes.height); |
| 524 visual_id_ = XVisualIDFromVisual(attributes.visual); |
510 // Create a child window, with a CopyFromParent visual (to avoid inducing | 525 // Create a child window, with a CopyFromParent visual (to avoid inducing |
511 // extra blits in the driver), that we can resize exactly in Resize(), | 526 // extra blits in the driver), that we can resize exactly in Resize(), |
512 // correctly ordered with GL, so that we don't have invalid transient states. | 527 // correctly ordered with GL, so that we don't have invalid transient states. |
513 // See https://crbug.com/326995. | 528 // See https://crbug.com/326995. |
514 XSetWindowAttributes swa; | 529 XSetWindowAttributes swa; |
515 memset(&swa, 0, sizeof(swa)); | 530 memset(&swa, 0, sizeof(swa)); |
516 swa.background_pixmap = 0; | 531 swa.background_pixmap = 0; |
517 swa.bit_gravity = NorthWestGravity; | 532 swa.bit_gravity = NorthWestGravity; |
518 window_ = XCreateWindow(g_display, parent_window_, 0, 0, size_.width(), | 533 window_ = XCreateWindow(g_display, parent_window_, 0, 0, size_.width(), |
519 size_.height(), 0, CopyFromParent, InputOutput, | 534 size_.height(), 0, CopyFromParent, InputOutput, |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
594 bool NativeViewGLSurfaceGLX::SupportsPostSubBuffer() { | 609 bool NativeViewGLSurfaceGLX::SupportsPostSubBuffer() { |
595 return g_driver_glx.ext.b_GLX_MESA_copy_sub_buffer; | 610 return g_driver_glx.ext.b_GLX_MESA_copy_sub_buffer; |
596 } | 611 } |
597 | 612 |
598 void* NativeViewGLSurfaceGLX::GetConfig() { | 613 void* NativeViewGLSurfaceGLX::GetConfig() { |
599 if (!config_) | 614 if (!config_) |
600 config_ = GetConfigForWindow(g_display, window_); | 615 config_ = GetConfigForWindow(g_display, window_); |
601 return config_; | 616 return config_; |
602 } | 617 } |
603 | 618 |
| 619 unsigned long NativeViewGLSurfaceGLX::GetCompatibilityKey() { |
| 620 return visual_id_; |
| 621 } |
| 622 |
604 gfx::SwapResult NativeViewGLSurfaceGLX::PostSubBuffer(int x, | 623 gfx::SwapResult NativeViewGLSurfaceGLX::PostSubBuffer(int x, |
605 int y, | 624 int y, |
606 int width, | 625 int width, |
607 int height) { | 626 int height) { |
608 DCHECK(g_driver_glx.ext.b_GLX_MESA_copy_sub_buffer); | 627 DCHECK(g_driver_glx.ext.b_GLX_MESA_copy_sub_buffer); |
609 glXCopySubBufferMESA(g_display, GetDrawableHandle(), x, y, width, height); | 628 glXCopySubBufferMESA(g_display, GetDrawableHandle(), x, y, width, height); |
610 return gfx::SwapResult::SWAP_ACK; | 629 return gfx::SwapResult::SWAP_ACK; |
611 } | 630 } |
612 | 631 |
613 gfx::VSyncProvider* NativeViewGLSurfaceGLX::GetVSyncProvider() { | 632 gfx::VSyncProvider* NativeViewGLSurfaceGLX::GetVSyncProvider() { |
(...skipping 20 matching lines...) Expand all Loading... |
634 const gfx::Size& size) | 653 const gfx::Size& size) |
635 : size_(size), config_(nullptr), window_(0), glx_window_(0) { | 654 : size_(size), config_(nullptr), window_(0), glx_window_(0) { |
636 // Ensure that we don't create a window with zero size. | 655 // Ensure that we don't create a window with zero size. |
637 if (size_.GetArea() == 0) | 656 if (size_.GetArea() == 0) |
638 size_.SetSize(1, 1); | 657 size_.SetSize(1, 1); |
639 } | 658 } |
640 | 659 |
641 bool UnmappedNativeViewGLSurfaceGLX::Initialize(GLSurface::Format format) { | 660 bool UnmappedNativeViewGLSurfaceGLX::Initialize(GLSurface::Format format) { |
642 DCHECK(!window_); | 661 DCHECK(!window_); |
643 | 662 |
644 gfx::AcceleratedWidget parent_window = | 663 gfx::AcceleratedWidget parent_window = DefaultRootWindow(g_display); |
645 RootWindow(g_display, DefaultScreen(g_display)); | |
646 | 664 |
647 // We create a window with CopyFromParent visual so that we have the same | 665 XSetWindowAttributes attrs; |
648 // visual as NativeViewGLSurfaceGLX (i.e. same GLXFBConfig), to ensure | 666 attrs.border_pixel = 0; |
649 // contexts are compatible and can be made current with either. | 667 attrs.colormap = g_colormap; |
650 window_ = XCreateWindow(g_display, parent_window, 0, 0, size_.width(), | 668 window_ = XCreateWindow(g_display, parent_window, 0, 0, size_.width(), |
651 size_.height(), 0, CopyFromParent, InputOutput, | 669 size_.height(), 0, g_depth, InputOutput, g_visual, |
652 CopyFromParent, 0, nullptr); | 670 CWBorderPixel | CWColormap, &attrs); |
653 GetConfig(); | 671 GetConfig(); |
654 DCHECK(config_); | 672 DCHECK(config_); |
655 glx_window_ = glXCreateWindow(g_display, config_, window_, NULL); | 673 glx_window_ = glXCreateWindow(g_display, config_, window_, NULL); |
656 return window_ != 0; | 674 return window_ != 0; |
657 } | 675 } |
658 | 676 |
659 void UnmappedNativeViewGLSurfaceGLX::Destroy() { | 677 void UnmappedNativeViewGLSurfaceGLX::Destroy() { |
660 config_ = nullptr; | 678 config_ = nullptr; |
661 if (glx_window_) { | 679 if (glx_window_) { |
662 glXDestroyWindow(g_display, glx_window_); | 680 glXDestroyWindow(g_display, glx_window_); |
(...skipping 21 matching lines...) Expand all Loading... |
684 void* UnmappedNativeViewGLSurfaceGLX::GetHandle() { | 702 void* UnmappedNativeViewGLSurfaceGLX::GetHandle() { |
685 return reinterpret_cast<void*>(glx_window_); | 703 return reinterpret_cast<void*>(glx_window_); |
686 } | 704 } |
687 | 705 |
688 void* UnmappedNativeViewGLSurfaceGLX::GetConfig() { | 706 void* UnmappedNativeViewGLSurfaceGLX::GetConfig() { |
689 if (!config_) | 707 if (!config_) |
690 config_ = GetConfigForWindow(g_display, window_); | 708 config_ = GetConfigForWindow(g_display, window_); |
691 return config_; | 709 return config_; |
692 } | 710 } |
693 | 711 |
| 712 unsigned long UnmappedNativeViewGLSurfaceGLX::GetCompatibilityKey() { |
| 713 return XVisualIDFromVisual(g_visual); |
| 714 } |
| 715 |
694 UnmappedNativeViewGLSurfaceGLX::~UnmappedNativeViewGLSurfaceGLX() { | 716 UnmappedNativeViewGLSurfaceGLX::~UnmappedNativeViewGLSurfaceGLX() { |
695 Destroy(); | 717 Destroy(); |
696 } | 718 } |
697 | 719 |
698 } // namespace gl | 720 } // namespace gl |
OLD | NEW |