| 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_egl.h" | 5 #include "ui/gl/gl_surface_egl.h" |
| 6 | 6 |
| 7 #if defined(OS_ANDROID) | 7 #if defined(OS_ANDROID) |
| 8 #include <android/native_window_jni.h> | 8 #include <android/native_window_jni.h> |
| 9 #endif | 9 #endif |
| 10 | 10 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 #include "ui/gl/gl_implementation.h" | 23 #include "ui/gl/gl_implementation.h" |
| 24 #include "ui/gl/gl_surface_stub.h" | 24 #include "ui/gl/gl_surface_stub.h" |
| 25 #include "ui/gl/gl_switches.h" | 25 #include "ui/gl/gl_switches.h" |
| 26 #include "ui/gl/scoped_make_current.h" | 26 #include "ui/gl/scoped_make_current.h" |
| 27 #include "ui/gl/sync_control_vsync_provider.h" | 27 #include "ui/gl/sync_control_vsync_provider.h" |
| 28 | 28 |
| 29 #if defined(USE_X11) | 29 #if defined(USE_X11) |
| 30 extern "C" { | 30 extern "C" { |
| 31 #include <X11/Xlib.h> | 31 #include <X11/Xlib.h> |
| 32 } | 32 } |
| 33 #include "ui/events/platform/platform_event_source.h" |
| 33 #endif | 34 #endif |
| 34 | 35 |
| 35 #if defined (USE_OZONE) | 36 #if defined (USE_OZONE) |
| 36 #include "ui/ozone/public/ozone_platform.h" | 37 #include "ui/ozone/public/ozone_platform.h" |
| 37 #include "ui/ozone/public/surface_factory_ozone.h" | 38 #include "ui/ozone/public/surface_factory_ozone.h" |
| 38 #endif | 39 #endif |
| 39 | 40 |
| 40 #if defined(USE_X11) && !defined(OS_CHROMEOS) | 41 #if defined(USE_X11) && !defined(OS_CHROMEOS) |
| 41 #include "ui/gfx/x/x11_switches.h" | 42 #include "ui/gfx/x/x11_switches.h" |
| 42 #endif | 43 #endif |
| (...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 465 g_display = display; | 466 g_display = display; |
| 466 break; | 467 break; |
| 467 } | 468 } |
| 468 } | 469 } |
| 469 | 470 |
| 470 return g_display; | 471 return g_display; |
| 471 } | 472 } |
| 472 | 473 |
| 473 NativeViewGLSurfaceEGL::NativeViewGLSurfaceEGL(EGLNativeWindowType window) | 474 NativeViewGLSurfaceEGL::NativeViewGLSurfaceEGL(EGLNativeWindowType window) |
| 474 : window_(window), | 475 : window_(window), |
| 476 #if defined(USE_X11) |
| 477 parent_window_(0), |
| 478 #endif |
| 475 surface_(NULL), | 479 surface_(NULL), |
| 476 supports_post_sub_buffer_(false), | 480 supports_post_sub_buffer_(false), |
| 477 config_(NULL), | 481 config_(NULL), |
| 478 size_(1, 1), | 482 size_(1, 1), |
| 479 swap_interval_(1) { | 483 swap_interval_(1) { |
| 480 #if defined(OS_ANDROID) | 484 #if defined(OS_ANDROID) |
| 481 if (window) | 485 if (window) |
| 482 ANativeWindow_acquire(window); | 486 ANativeWindow_acquire(window); |
| 483 #endif | 487 #endif |
| 484 | 488 |
| 485 #if defined(OS_WIN) | 489 #if defined(OS_WIN) |
| 486 vsync_override_ = false; | 490 vsync_override_ = false; |
| 487 swap_generation_ = 0; | 491 swap_generation_ = 0; |
| 488 RECT windowRect; | 492 RECT windowRect; |
| 489 if (GetClientRect(window_, &windowRect)) | 493 if (GetClientRect(window_, &windowRect)) |
| 490 size_ = gfx::Rect(windowRect).size(); | 494 size_ = gfx::Rect(windowRect).size(); |
| 491 #endif | 495 #endif |
| 496 |
| 497 #if defined(USE_X11) |
| 498 // We use a child XWindow for X11, to help avoiding artifacts while resizing. |
| 499 parent_window_ = window_; |
| 500 window_ = 0; |
| 501 #endif |
| 492 } | 502 } |
| 493 | 503 |
| 494 bool NativeViewGLSurfaceEGL::Initialize() { | 504 bool NativeViewGLSurfaceEGL::Initialize() { |
| 495 return Initialize(nullptr); | 505 return Initialize(nullptr); |
| 496 } | 506 } |
| 497 | 507 |
| 498 bool NativeViewGLSurfaceEGL::Initialize( | 508 bool NativeViewGLSurfaceEGL::Initialize( |
| 499 scoped_ptr<VSyncProvider> sync_provider) { | 509 scoped_ptr<VSyncProvider> sync_provider) { |
| 500 DCHECK(!surface_); | 510 DCHECK(!surface_); |
| 501 | 511 |
| 502 if (!GetDisplay()) { | 512 if (!GetDisplay()) { |
| 503 LOG(ERROR) << "Trying to create surface with invalid display."; | 513 LOG(ERROR) << "Trying to create surface with invalid display."; |
| 504 return false; | 514 return false; |
| 505 } | 515 } |
| 506 | 516 |
| 517 #if defined(USE_X11) |
| 518 Display* x11_display = GetNativeDisplay(); |
| 519 XWindowAttributes attributes; |
| 520 if (!XGetWindowAttributes(x11_display, parent_window_, &attributes)) { |
| 521 LOG(ERROR) << "XGetWindowAttributes failed for window " << parent_window_ |
| 522 << "."; |
| 523 return false; |
| 524 } |
| 525 |
| 526 size_ = gfx::Size(attributes.width, attributes.height); |
| 527 |
| 528 // Create a child window, with a CopyFromParent visual (to avoid inducing |
| 529 // extra blits in the driver), that we can resize exactly in Resize(), |
| 530 // correctly ordered with GL, so that we don't have invalid transient states. |
| 531 // See https://crbug.com/326995. |
| 532 XSetWindowAttributes swa; |
| 533 memset(&swa, 0, sizeof(swa)); |
| 534 swa.background_pixmap = 0; |
| 535 swa.bit_gravity = NorthWestGravity; |
| 536 window_ = XCreateWindow(x11_display, parent_window_, 0, 0, size_.width(), |
| 537 size_.height(), 0, CopyFromParent, InputOutput, |
| 538 CopyFromParent, CWBackPixmap | CWBitGravity, &swa); |
| 539 XMapWindow(x11_display, window_); |
| 540 |
| 541 ui::PlatformEventSource* source = ui::PlatformEventSource::GetInstance(); |
| 542 // The event source can be nullptr in tests, when we don't care about Exposes. |
| 543 if (source) { |
| 544 XSelectInput(x11_display, window_, ExposureMask); |
| 545 source->AddPlatformEventDispatcher(this); |
| 546 } |
| 547 XFlush(x11_display); |
| 548 #endif // USE_X11 |
| 549 |
| 507 std::vector<EGLint> egl_window_attributes; | 550 std::vector<EGLint> egl_window_attributes; |
| 508 | 551 |
| 509 if (g_egl_window_fixed_size_supported) { | 552 if (g_egl_window_fixed_size_supported) { |
| 510 egl_window_attributes.push_back(EGL_FIXED_SIZE_ANGLE); | 553 egl_window_attributes.push_back(EGL_FIXED_SIZE_ANGLE); |
| 511 egl_window_attributes.push_back(EGL_TRUE); | 554 egl_window_attributes.push_back(EGL_TRUE); |
| 512 egl_window_attributes.push_back(EGL_WIDTH); | 555 egl_window_attributes.push_back(EGL_WIDTH); |
| 513 egl_window_attributes.push_back(size_.width()); | 556 egl_window_attributes.push_back(size_.width()); |
| 514 egl_window_attributes.push_back(EGL_HEIGHT); | 557 egl_window_attributes.push_back(EGL_HEIGHT); |
| 515 egl_window_attributes.push_back(size_.height()); | 558 egl_window_attributes.push_back(size_.height()); |
| 516 } | 559 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 547 } | 590 } |
| 548 | 591 |
| 549 void NativeViewGLSurfaceEGL::Destroy() { | 592 void NativeViewGLSurfaceEGL::Destroy() { |
| 550 if (surface_) { | 593 if (surface_) { |
| 551 if (!eglDestroySurface(GetDisplay(), surface_)) { | 594 if (!eglDestroySurface(GetDisplay(), surface_)) { |
| 552 LOG(ERROR) << "eglDestroySurface failed with error " | 595 LOG(ERROR) << "eglDestroySurface failed with error " |
| 553 << GetLastEGLErrorString(); | 596 << GetLastEGLErrorString(); |
| 554 } | 597 } |
| 555 surface_ = NULL; | 598 surface_ = NULL; |
| 556 } | 599 } |
| 600 |
| 601 #if defined(USE_X11) |
| 602 if (window_) { |
| 603 ui::PlatformEventSource* source = ui::PlatformEventSource::GetInstance(); |
| 604 if (source) |
| 605 source->RemovePlatformEventDispatcher(this); |
| 606 |
| 607 Display* x11_display = GetNativeDisplay(); |
| 608 XDestroyWindow(x11_display, window_); |
| 609 window_ = 0; |
| 610 XFlush(x11_display); |
| 611 } |
| 612 #endif |
| 557 } | 613 } |
| 558 | 614 |
| 559 EGLConfig NativeViewGLSurfaceEGL::GetConfig() { | 615 EGLConfig NativeViewGLSurfaceEGL::GetConfig() { |
| 560 #if !defined(USE_X11) | 616 #if !defined(USE_X11) |
| 561 return g_config; | 617 return g_config; |
| 562 #else | 618 #else |
| 563 if (!config_) { | 619 if (!config_) { |
| 564 // Get a config compatible with the window | 620 // Get a config compatible with the window |
| 565 DCHECK(window_); | 621 DCHECK(window_); |
| 566 XWindowAttributes win_attribs; | 622 XWindowAttributes win_attribs; |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 698 | 754 |
| 699 return gfx::Size(width, height); | 755 return gfx::Size(width, height); |
| 700 } | 756 } |
| 701 | 757 |
| 702 bool NativeViewGLSurfaceEGL::Resize(const gfx::Size& size, float scale_factor) { | 758 bool NativeViewGLSurfaceEGL::Resize(const gfx::Size& size, float scale_factor) { |
| 703 if (size == GetSize()) | 759 if (size == GetSize()) |
| 704 return true; | 760 return true; |
| 705 | 761 |
| 706 size_ = size; | 762 size_ = size; |
| 707 | 763 |
| 764 #if defined(USE_X11) |
| 765 eglWaitGL(); |
| 766 XResizeWindow(GetNativeDisplay(), window_, size.width(), size.height()); |
| 767 eglWaitNative(EGL_CORE_NATIVE_ENGINE); |
| 768 #else |
| 708 scoped_ptr<ui::ScopedMakeCurrent> scoped_make_current; | 769 scoped_ptr<ui::ScopedMakeCurrent> scoped_make_current; |
| 709 GLContext* current_context = GLContext::GetCurrent(); | 770 GLContext* current_context = GLContext::GetCurrent(); |
| 710 bool was_current = | 771 bool was_current = |
| 711 current_context && current_context->IsCurrent(this); | 772 current_context && current_context->IsCurrent(this); |
| 712 if (was_current) { | 773 if (was_current) { |
| 713 scoped_make_current.reset( | 774 scoped_make_current.reset( |
| 714 new ui::ScopedMakeCurrent(current_context, this)); | 775 new ui::ScopedMakeCurrent(current_context, this)); |
| 715 current_context->ReleaseCurrent(this); | 776 current_context->ReleaseCurrent(this); |
| 716 } | 777 } |
| 717 | 778 |
| 718 Destroy(); | 779 Destroy(); |
| 719 | 780 |
| 720 if (!Initialize()) { | 781 if (!Initialize()) { |
| 721 LOG(ERROR) << "Failed to resize window."; | 782 LOG(ERROR) << "Failed to resize window."; |
| 722 return false; | 783 return false; |
| 723 } | 784 } |
| 785 #endif |
| 724 | 786 |
| 725 return true; | 787 return true; |
| 726 } | 788 } |
| 727 | 789 |
| 728 bool NativeViewGLSurfaceEGL::Recreate() { | 790 bool NativeViewGLSurfaceEGL::Recreate() { |
| 729 Destroy(); | 791 Destroy(); |
| 730 if (!Initialize()) { | 792 if (!Initialize()) { |
| 731 LOG(ERROR) << "Failed to create surface."; | 793 LOG(ERROR) << "Failed to create surface."; |
| 732 return false; | 794 return false; |
| 733 } | 795 } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 781 } | 843 } |
| 782 | 844 |
| 783 NativeViewGLSurfaceEGL::~NativeViewGLSurfaceEGL() { | 845 NativeViewGLSurfaceEGL::~NativeViewGLSurfaceEGL() { |
| 784 Destroy(); | 846 Destroy(); |
| 785 #if defined(OS_ANDROID) | 847 #if defined(OS_ANDROID) |
| 786 if (window_) | 848 if (window_) |
| 787 ANativeWindow_release(window_); | 849 ANativeWindow_release(window_); |
| 788 #endif | 850 #endif |
| 789 } | 851 } |
| 790 | 852 |
| 853 #if defined(USE_X11) |
| 854 bool NativeViewGLSurfaceEGL::CanDispatchEvent(const ui::PlatformEvent& event) { |
| 855 return event->type == Expose && event->xexpose.window == window_; |
| 856 } |
| 857 |
| 858 uint32_t NativeViewGLSurfaceEGL::DispatchEvent(const ui::PlatformEvent& event) { |
| 859 XEvent x_event = *event; |
| 860 x_event.xexpose.window = parent_window_; |
| 861 |
| 862 Display* x11_display = GetNativeDisplay(); |
| 863 XSendEvent(x11_display, parent_window_, False, ExposureMask, &x_event); |
| 864 XFlush(x11_display); |
| 865 return ui::POST_DISPATCH_STOP_PROPAGATION; |
| 866 } |
| 867 #endif |
| 868 |
| 791 PbufferGLSurfaceEGL::PbufferGLSurfaceEGL(const gfx::Size& size) | 869 PbufferGLSurfaceEGL::PbufferGLSurfaceEGL(const gfx::Size& size) |
| 792 : size_(size), | 870 : size_(size), |
| 793 surface_(NULL) { | 871 surface_(NULL) { |
| 794 // Some implementations of Pbuffer do not support having a 0 size. For such | 872 // Some implementations of Pbuffer do not support having a 0 size. For such |
| 795 // cases use a (1, 1) surface. | 873 // cases use a (1, 1) surface. |
| 796 if (size_.GetArea() == 0) | 874 if (size_.GetArea() == 0) |
| 797 size_.SetSize(1, 1); | 875 size_.SetSize(1, 1); |
| 798 } | 876 } |
| 799 | 877 |
| 800 bool PbufferGLSurfaceEGL::Initialize() { | 878 bool PbufferGLSurfaceEGL::Initialize() { |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 955 } | 1033 } |
| 956 | 1034 |
| 957 void* SurfacelessEGL::GetShareHandle() { | 1035 void* SurfacelessEGL::GetShareHandle() { |
| 958 return NULL; | 1036 return NULL; |
| 959 } | 1037 } |
| 960 | 1038 |
| 961 SurfacelessEGL::~SurfacelessEGL() { | 1039 SurfacelessEGL::~SurfacelessEGL() { |
| 962 } | 1040 } |
| 963 | 1041 |
| 964 } // namespace gfx | 1042 } // namespace gfx |
| OLD | NEW |