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 |
11 #include "base/lazy_instance.h" | 11 #include "base/lazy_instance.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/macros.h" | 13 #include "base/macros.h" |
14 #include "base/memory/scoped_ptr.h" | 14 #include "base/memory/scoped_ptr.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 |