Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(218)

Side by Side Diff: ui/gl/gl_surface_egl.cc

Issue 1480333002: egl/x11: Created a child window to control resizes and prevent flashes (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« ui/gl/gl_surface_egl.h ('K') | « ui/gl/gl_surface_egl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« ui/gl/gl_surface_egl.h ('K') | « ui/gl/gl_surface_egl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698