| 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> |
| 11 | 11 |
| 12 #include "base/lazy_instance.h" | 12 #include "base/lazy_instance.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/macros.h" | 14 #include "base/macros.h" |
| 15 #include "base/memory/weak_ptr.h" | 15 #include "base/memory/weak_ptr.h" |
| 16 #include "base/message_loop/message_loop.h" | 16 #include "base/message_loop/message_loop.h" |
| 17 #include "base/single_thread_task_runner.h" | 17 #include "base/single_thread_task_runner.h" |
| 18 #include "base/synchronization/cancellation_flag.h" | 18 #include "base/synchronization/cancellation_flag.h" |
| 19 #include "base/synchronization/lock.h" | 19 #include "base/synchronization/lock.h" |
| 20 #include "base/thread_task_runner_handle.h" | 20 #include "base/thread_task_runner_handle.h" |
| 21 #include "base/threading/non_thread_safe.h" | 21 #include "base/threading/non_thread_safe.h" |
| 22 #include "base/threading/thread.h" | 22 #include "base/threading/thread.h" |
| 23 #include "base/time/time.h" | 23 #include "base/time/time.h" |
| 24 #include "base/trace_event/trace_event.h" | 24 #include "base/trace_event/trace_event.h" |
| 25 #include "build/build_config.h" | 25 #include "build/build_config.h" |
| 26 #include "ui/events/platform/platform_event_source.h" | |
| 27 #include "ui/gfx/x/x11_connection.h" | 26 #include "ui/gfx/x/x11_connection.h" |
| 28 #include "ui/gfx/x/x11_types.h" | 27 #include "ui/gfx/x/x11_types.h" |
| 29 #include "ui/gl/gl_bindings.h" | 28 #include "ui/gl/gl_bindings.h" |
| 30 #include "ui/gl/gl_implementation.h" | 29 #include "ui/gl/gl_implementation.h" |
| 31 #include "ui/gl/sync_control_vsync_provider.h" | 30 #include "ui/gl/sync_control_vsync_provider.h" |
| 32 | 31 |
| 33 namespace gfx { | 32 namespace gfx { |
| 34 | 33 |
| 35 namespace { | 34 namespace { |
| 36 | 35 |
| (...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 436 return g_glx_oml_sync_control_supported; | 435 return g_glx_oml_sync_control_supported; |
| 437 } | 436 } |
| 438 | 437 |
| 439 void* GLSurfaceGLX::GetDisplay() { | 438 void* GLSurfaceGLX::GetDisplay() { |
| 440 return g_display; | 439 return g_display; |
| 441 } | 440 } |
| 442 | 441 |
| 443 GLSurfaceGLX::~GLSurfaceGLX() {} | 442 GLSurfaceGLX::~GLSurfaceGLX() {} |
| 444 | 443 |
| 445 NativeViewGLSurfaceGLX::NativeViewGLSurfaceGLX(gfx::AcceleratedWidget window) | 444 NativeViewGLSurfaceGLX::NativeViewGLSurfaceGLX(gfx::AcceleratedWidget window) |
| 446 : parent_window_(window), window_(0), glx_window_(0), config_(nullptr) { | 445 : parent_window_(window), window_(0), glx_window_(0), config_(nullptr) {} |
| 447 } | |
| 448 | 446 |
| 449 GLXDrawable NativeViewGLSurfaceGLX::GetDrawableHandle() const { | 447 GLXDrawable NativeViewGLSurfaceGLX::GetDrawableHandle() const { |
| 450 return glx_window_; | 448 return glx_window_; |
| 451 } | 449 } |
| 452 | 450 |
| 453 bool NativeViewGLSurfaceGLX::Initialize(GLSurface::Format format) { | 451 bool NativeViewGLSurfaceGLX::Initialize(GLSurface::Format format) { |
| 454 XWindowAttributes attributes; | 452 XWindowAttributes attributes; |
| 455 if (!XGetWindowAttributes(g_display, parent_window_, &attributes)) { | 453 if (!XGetWindowAttributes(g_display, parent_window_, &attributes)) { |
| 456 LOG(ERROR) << "XGetWindowAttributes failed for window " << parent_window_ | 454 LOG(ERROR) << "XGetWindowAttributes failed for window " << parent_window_ |
| 457 << "."; | 455 << "."; |
| 458 return false; | 456 return false; |
| 459 } | 457 } |
| 460 size_ = gfx::Size(attributes.width, attributes.height); | 458 size_ = gfx::Size(attributes.width, attributes.height); |
| 461 // Create a child window, with a CopyFromParent visual (to avoid inducing | 459 // Create a child window, with a CopyFromParent visual (to avoid inducing |
| 462 // extra blits in the driver), that we can resize exactly in Resize(), | 460 // extra blits in the driver), that we can resize exactly in Resize(), |
| 463 // correctly ordered with GL, so that we don't have invalid transient states. | 461 // correctly ordered with GL, so that we don't have invalid transient states. |
| 464 // See https://crbug.com/326995. | 462 // See https://crbug.com/326995. |
| 465 XSetWindowAttributes swa; | 463 XSetWindowAttributes swa; |
| 466 memset(&swa, 0, sizeof(swa)); | 464 memset(&swa, 0, sizeof(swa)); |
| 467 swa.background_pixmap = 0; | 465 swa.background_pixmap = 0; |
| 468 swa.bit_gravity = NorthWestGravity; | 466 swa.bit_gravity = NorthWestGravity; |
| 469 window_ = XCreateWindow(g_display, parent_window_, 0, 0, size_.width(), | 467 window_ = XCreateWindow(g_display, parent_window_, 0, 0, size_.width(), |
| 470 size_.height(), 0, CopyFromParent, InputOutput, | 468 size_.height(), 0, CopyFromParent, InputOutput, |
| 471 CopyFromParent, CWBackPixmap | CWBitGravity, &swa); | 469 CopyFromParent, CWBackPixmap | CWBitGravity, &swa); |
| 472 XMapWindow(g_display, window_); | 470 XMapWindow(g_display, window_); |
| 473 | 471 |
| 474 ui::PlatformEventSource* event_source = | 472 RegisterEvents(); |
| 475 ui::PlatformEventSource::GetInstance(); | |
| 476 // Can be nullptr in tests, when we don't care about Exposes. | |
| 477 if (event_source) { | |
| 478 XSelectInput(g_display, window_, ExposureMask); | |
| 479 ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this); | |
| 480 } | |
| 481 XFlush(g_display); | 473 XFlush(g_display); |
| 482 | 474 |
| 483 GetConfig(); | 475 GetConfig(); |
| 484 DCHECK(config_); | 476 DCHECK(config_); |
| 485 glx_window_ = glXCreateWindow(g_display, config_, window_, NULL); | 477 glx_window_ = glXCreateWindow(g_display, config_, window_, NULL); |
| 486 | 478 |
| 487 if (g_glx_oml_sync_control_supported) | 479 if (g_glx_oml_sync_control_supported) |
| 488 vsync_provider_.reset(new OMLSyncControlVSyncProvider(glx_window_)); | 480 vsync_provider_.reset(new OMLSyncControlVSyncProvider(glx_window_)); |
| 489 else if (g_glx_sgi_video_sync_supported) | 481 else if (g_glx_sgi_video_sync_supported) |
| 490 vsync_provider_.reset(new SGIVideoSyncVSyncProvider(config_, glx_window_)); | 482 vsync_provider_.reset(new SGIVideoSyncVSyncProvider(config_, glx_window_)); |
| 491 | 483 |
| 492 return true; | 484 return true; |
| 493 } | 485 } |
| 494 | 486 |
| 495 void NativeViewGLSurfaceGLX::Destroy() { | 487 void NativeViewGLSurfaceGLX::Destroy() { |
| 496 vsync_provider_.reset(); | 488 vsync_provider_.reset(); |
| 497 if (glx_window_) { | 489 if (glx_window_) { |
| 498 glXDestroyWindow(g_display, glx_window_); | 490 glXDestroyWindow(g_display, glx_window_); |
| 499 glx_window_ = 0; | 491 glx_window_ = 0; |
| 500 } | 492 } |
| 501 if (window_) { | 493 if (window_) { |
| 502 ui::PlatformEventSource* event_source = | 494 UnregisterEvents(); |
| 503 ui::PlatformEventSource::GetInstance(); | |
| 504 if (event_source) | |
| 505 event_source->RemovePlatformEventDispatcher(this); | |
| 506 XDestroyWindow(g_display, window_); | 495 XDestroyWindow(g_display, window_); |
| 507 window_ = 0; | 496 window_ = 0; |
| 508 XFlush(g_display); | 497 XFlush(g_display); |
| 509 } | 498 } |
| 510 } | 499 } |
| 511 | 500 |
| 512 bool NativeViewGLSurfaceGLX::CanDispatchEvent(const ui::PlatformEvent& event) { | |
| 513 return event->type == Expose && event->xexpose.window == window_; | |
| 514 } | |
| 515 | |
| 516 uint32_t NativeViewGLSurfaceGLX::DispatchEvent(const ui::PlatformEvent& event) { | |
| 517 XEvent forwarded_event = *event; | |
| 518 forwarded_event.xexpose.window = parent_window_; | |
| 519 XSendEvent(g_display, parent_window_, False, ExposureMask, | |
| 520 &forwarded_event); | |
| 521 XFlush(g_display); | |
| 522 return ui::POST_DISPATCH_STOP_PROPAGATION; | |
| 523 } | |
| 524 | |
| 525 bool NativeViewGLSurfaceGLX::Resize(const gfx::Size& size, | 501 bool NativeViewGLSurfaceGLX::Resize(const gfx::Size& size, |
| 526 float scale_factor, | 502 float scale_factor, |
| 527 bool has_alpha) { | 503 bool has_alpha) { |
| 528 size_ = size; | 504 size_ = size; |
| 529 glXWaitGL(); | 505 glXWaitGL(); |
| 530 XResizeWindow(g_display, window_, size.width(), size.height()); | 506 XResizeWindow(g_display, window_, size.width(), size.height()); |
| 531 glXWaitX(); | 507 glXWaitX(); |
| 532 return true; | 508 return true; |
| 533 } | 509 } |
| 534 | 510 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 573 } | 549 } |
| 574 | 550 |
| 575 VSyncProvider* NativeViewGLSurfaceGLX::GetVSyncProvider() { | 551 VSyncProvider* NativeViewGLSurfaceGLX::GetVSyncProvider() { |
| 576 return vsync_provider_.get(); | 552 return vsync_provider_.get(); |
| 577 } | 553 } |
| 578 | 554 |
| 579 NativeViewGLSurfaceGLX::~NativeViewGLSurfaceGLX() { | 555 NativeViewGLSurfaceGLX::~NativeViewGLSurfaceGLX() { |
| 580 Destroy(); | 556 Destroy(); |
| 581 } | 557 } |
| 582 | 558 |
| 559 void NativeViewGLSurfaceGLX::ForwardExposeEvent(XEvent* event) { |
| 560 XEvent forwarded_event = *event; |
| 561 forwarded_event.xexpose.window = parent_window_; |
| 562 XSendEvent(g_display, parent_window_, False, ExposureMask, &forwarded_event); |
| 563 XFlush(g_display); |
| 564 } |
| 565 |
| 566 bool NativeViewGLSurfaceGLX::CanHandleEvent(XEvent* event) { |
| 567 return event->type == Expose && |
| 568 event->xexpose.window == static_cast<Window>(window_); |
| 569 } |
| 570 |
| 583 UnmappedNativeViewGLSurfaceGLX::UnmappedNativeViewGLSurfaceGLX( | 571 UnmappedNativeViewGLSurfaceGLX::UnmappedNativeViewGLSurfaceGLX( |
| 584 const gfx::Size& size) | 572 const gfx::Size& size) |
| 585 : size_(size), config_(nullptr), window_(0), glx_window_(0) { | 573 : size_(size), config_(nullptr), window_(0), glx_window_(0) { |
| 586 // Ensure that we don't create a window with zero size. | 574 // Ensure that we don't create a window with zero size. |
| 587 if (size_.GetArea() == 0) | 575 if (size_.GetArea() == 0) |
| 588 size_.SetSize(1, 1); | 576 size_.SetSize(1, 1); |
| 589 } | 577 } |
| 590 | 578 |
| 591 bool UnmappedNativeViewGLSurfaceGLX::Initialize(GLSurface::Format format) { | 579 bool UnmappedNativeViewGLSurfaceGLX::Initialize(GLSurface::Format format) { |
| 592 DCHECK(!window_); | 580 DCHECK(!window_); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 639 if (!config_) | 627 if (!config_) |
| 640 config_ = GetConfigForWindow(g_display, window_); | 628 config_ = GetConfigForWindow(g_display, window_); |
| 641 return config_; | 629 return config_; |
| 642 } | 630 } |
| 643 | 631 |
| 644 UnmappedNativeViewGLSurfaceGLX::~UnmappedNativeViewGLSurfaceGLX() { | 632 UnmappedNativeViewGLSurfaceGLX::~UnmappedNativeViewGLSurfaceGLX() { |
| 645 Destroy(); | 633 Destroy(); |
| 646 } | 634 } |
| 647 | 635 |
| 648 } // namespace gfx | 636 } // namespace gfx |
| OLD | NEW |