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

Unified Diff: ui/gl/gl_surface_egl_x11.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: Moved up the call to InitializeNativeWindow() 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/gl/gl_surface_egl_x11.h ('k') | ui/gl/gl_surface_x11.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/gl/gl_surface_egl_x11.cc
diff --git a/ui/gl/gl_surface_egl_x11.cc b/ui/gl/gl_surface_egl_x11.cc
new file mode 100644
index 0000000000000000000000000000000000000000..91b2f54d084cdae4d3c41c4f53c0af6060431d6c
--- /dev/null
+++ b/ui/gl/gl_surface_egl_x11.cc
@@ -0,0 +1,179 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/gl/gl_surface_egl_x11.h"
+
+#include "ui/events/platform/platform_event_source.h"
+#include "ui/gl/egl_util.h"
+
+extern "C" {
+#include <X11/Xlib.h>
+}
+
+using ui::GetLastEGLErrorString;
+using ui::PlatformEvent;
+using ui::PlatformEventSource;
+
+namespace gfx {
+
+NativeViewGLSurfaceEGLX11::NativeViewGLSurfaceEGLX11(EGLNativeWindowType window)
+ : NativeViewGLSurfaceEGL(0),
+ parent_window_(window) {
+}
+
+bool NativeViewGLSurfaceEGLX11::InitializeNativeWindow() {
+ Display* x11_display = GetNativeDisplay();
+ XWindowAttributes attributes;
+ if (!XGetWindowAttributes(x11_display, parent_window_, &attributes)) {
+ LOG(ERROR) << "XGetWindowAttributes failed for window " << parent_window_
+ << ".";
+ return false;
+ }
+
+ size_ = gfx::Size(attributes.width, attributes.height);
+
+ // Create a child window, with a CopyFromParent visual (to avoid inducing
+ // extra blits in the driver), that we can resize exactly in Resize(),
+ // correctly ordered with GL, so that we don't have invalid transient states.
+ // See https://crbug.com/326995.
+ XSetWindowAttributes swa;
+ memset(&swa, 0, sizeof(swa));
+ swa.background_pixmap = 0;
+ swa.bit_gravity = NorthWestGravity;
+ window_ = XCreateWindow(x11_display, parent_window_, 0, 0, size_.width(),
+ size_.height(), 0, CopyFromParent, InputOutput,
+ CopyFromParent, CWBackPixmap | CWBitGravity, &swa);
+ XMapWindow(x11_display, window_);
+
+ // The event source can be nullptr in tests, when we don't care about Exposes.
+ if (PlatformEventSource* source = PlatformEventSource::GetInstance()) {
+ XSelectInput(x11_display, window_, ExposureMask);
+ source->AddPlatformEventDispatcher(this);
+ }
+ XFlush(x11_display);
+
+ return true;
+}
+
+void NativeViewGLSurfaceEGLX11::Destroy() {
+ if (window_) {
+ if (PlatformEventSource* source = PlatformEventSource::GetInstance())
+ source->RemovePlatformEventDispatcher(this);
+
+ Display* x11_display = GetNativeDisplay();
+ XDestroyWindow(x11_display, window_);
+ window_ = 0;
+ XFlush(x11_display);
+ }
+
+ NativeViewGLSurfaceEGL::Destroy();
+}
+
+EGLConfig NativeViewGLSurfaceEGLX11::GetConfig() {
+ if (!config_) {
+ // Get a config compatible with the window
+ DCHECK(window_);
+ XWindowAttributes win_attribs;
+ if (!XGetWindowAttributes(GetNativeDisplay(), window_, &win_attribs)) {
+ return NULL;
+ }
+
+ // Try matching the window depth with an alpha channel,
+ // because we're worried the destination alpha width could
+ // constrain blending precision.
+ const int kBufferSizeOffset = 1;
+ const int kAlphaSizeOffset = 3;
+ EGLint config_attribs[] = {
+ EGL_BUFFER_SIZE, ~0,
+ EGL_ALPHA_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_RED_SIZE, 8,
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
+ EGL_NONE
+ };
+ config_attribs[kBufferSizeOffset] = win_attribs.depth;
+
+ EGLDisplay display = GetHardwareDisplay();
+ EGLint num_configs;
+ if (!eglChooseConfig(display,
+ config_attribs,
+ &config_,
+ 1,
+ &num_configs)) {
+ LOG(ERROR) << "eglChooseConfig failed with error "
+ << GetLastEGLErrorString();
+ return NULL;
+ }
+
+ if (num_configs) {
+ EGLint config_depth;
+ if (!eglGetConfigAttrib(display,
+ config_,
+ EGL_BUFFER_SIZE,
+ &config_depth)) {
+ LOG(ERROR) << "eglGetConfigAttrib failed with error "
+ << GetLastEGLErrorString();
+ return NULL;
+ }
+
+ if (config_depth == win_attribs.depth) {
+ return config_;
+ }
+ }
+
+ // Try without an alpha channel.
+ config_attribs[kAlphaSizeOffset] = 0;
+ if (!eglChooseConfig(display,
+ config_attribs,
+ &config_,
+ 1,
+ &num_configs)) {
+ LOG(ERROR) << "eglChooseConfig failed with error "
+ << GetLastEGLErrorString();
+ return NULL;
+ }
+
+ if (num_configs == 0) {
+ LOG(ERROR) << "No suitable EGL configs found.";
+ return NULL;
+ }
+ }
+ return config_;
+}
+
+bool NativeViewGLSurfaceEGLX11::Resize(const gfx::Size& size,
+ float scale_factor) {
+ if (size == GetSize())
+ return true;
+
+ size_ = size;
+
+ eglWaitGL();
+ XResizeWindow(GetNativeDisplay(), window_, size.width(), size.height());
+ eglWaitNative(EGL_CORE_NATIVE_ENGINE);
+
+ return true;
+}
+
+bool NativeViewGLSurfaceEGLX11::CanDispatchEvent(const PlatformEvent& event) {
+ return event->type == Expose && event->xexpose.window == window_;
+}
+
+uint32_t NativeViewGLSurfaceEGLX11::DispatchEvent(const PlatformEvent& event) {
+ XEvent x_event = *event;
+ x_event.xexpose.window = parent_window_;
+
+ Display* x11_display = GetNativeDisplay();
+ XSendEvent(x11_display, parent_window_, False, ExposureMask, &x_event);
+ XFlush(x11_display);
+ return ui::POST_DISPATCH_STOP_PROPAGATION;
+}
+
+NativeViewGLSurfaceEGLX11::~NativeViewGLSurfaceEGLX11() {
+ Destroy();
+}
+
+} // namespace gfx
« no previous file with comments | « ui/gl/gl_surface_egl_x11.h ('k') | ui/gl/gl_surface_x11.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698