Commit 658978a2 authored by Jonah Ryan-Davis's avatar Jonah Ryan-Davis Committed by Commit Bot

Forward XExposeEvents from ANGLE's child window

ANGLE creates a child window when using X11. The Expose events from this
child window need to be forwarded to Chrome's parent window for the
window to be properly redrawn.

Bug: 991577
Change-Id: Ibba1ad07110953dc46b7bd1939b03471a316f798
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1822721
Commit-Queue: Jonah Ryan-Davis <jonahr@google.com>
Reviewed-by: default avatarZhenyao Mo <zmo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#700394}
parent 1bd5d6f0
......@@ -22,6 +22,7 @@
#include "base/system/sys_info.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "ui/events/platform/platform_event_source.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/gpu_fence.h"
#include "ui/gl/angle_platform_impl.h"
......@@ -37,9 +38,8 @@
#include "ui/gl/sync_control_vsync_provider.h"
#if defined(USE_X11)
#include "ui/gfx/x/x11.h"
#include "ui/base/x/x11_util_internal.h" // nogncheck
#include "ui/gfx/x/x11.h"
#endif
#if defined(OS_ANDROID)
......@@ -148,6 +148,8 @@
#endif /* EGL_ANGLE_feature_control */
using ui::GetLastEGLErrorString;
using ui::PlatformEvent;
using ui::PlatformEventSource;
namespace gl {
......@@ -1179,6 +1181,30 @@ bool NativeViewGLSurfaceEGL::Initialize(GLSurfaceFormat format) {
return false;
}
#if defined(USE_X11)
// Query all child windows and store them. ANGLE creates a child window when
// eglCreateWidnowSurface is called on X11 and expose events from this window
// need to be received by this class.
Display* x11_display = GetNativeDisplay();
Window root = 0;
Window parent = 0;
Window* children = nullptr;
unsigned num_children = 0;
if (XQueryTree(x11_display, window_, &root, &parent, &children,
&num_children)) {
for (unsigned int i = 0; i < num_children; ++i) {
children_.push_back(children[i]);
}
if (num_children > 0) {
XFree(children);
}
}
if (PlatformEventSource* source = PlatformEventSource::GetInstance()) {
source->AddPlatformEventDispatcher(this);
}
#endif
if (g_driver_egl.ext.b_EGL_NV_post_sub_buffer) {
EGLint surfaceVal;
EGLBoolean retVal = eglQuerySurface(
......@@ -1288,6 +1314,11 @@ void NativeViewGLSurfaceEGL::Destroy() {
vsync_provider_internal_ = nullptr;
if (surface_) {
#if defined(USE_X11)
if (PlatformEventSource* source = PlatformEventSource::GetInstance()) {
source->RemovePlatformEventDispatcher(this);
}
#endif
if (!eglDestroySurface(GetDisplay(), surface_)) {
LOG(ERROR) << "eglDestroySurface failed with error "
<< GetLastEGLErrorString();
......@@ -1768,6 +1799,30 @@ bool NativeViewGLSurfaceEGL::CommitAndClearPendingOverlays() {
return success;
}
bool NativeViewGLSurfaceEGL::CanDispatchEvent(const PlatformEvent& event) {
#if defined(USE_X11)
// When ANGLE is used for EGL, it creates an X11 child window. Expose events
// from this window need to be forwarded to this class.
return event->type == Expose &&
std::find(children_.begin(), children_.end(), event->xexpose.window) !=
children_.end();
#else
return false;
#endif
}
uint32_t NativeViewGLSurfaceEGL::DispatchEvent(const PlatformEvent& event) {
#if defined(USE_X11)
XEvent x_event = *event;
x_event.xexpose.window = window_;
Display* x11_display = GetNativeDisplay();
XSendEvent(x11_display, window_, x11::False, ExposureMask, &x_event);
XFlush(x11_display);
#endif
return ui::POST_DISPATCH_STOP_PROPAGATION;
}
PbufferGLSurfaceEGL::PbufferGLSurfaceEGL(const gfx::Size& size)
: size_(size),
surface_(NULL) {
......
......@@ -19,6 +19,7 @@
#include "base/macros.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "ui/events/platform/platform_event_dispatcher.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/vsync_provider.h"
#include "ui/gl/egl_timestamps.h"
......@@ -107,7 +108,8 @@ class GL_EXPORT GLSurfaceEGL : public GLSurface {
// Encapsulates an EGL surface bound to a view.
class GL_EXPORT NativeViewGLSurfaceEGL : public GLSurfaceEGL,
public EGLTimestampClient {
public EGLTimestampClient,
public ui::PlatformEventDispatcher {
public:
NativeViewGLSurfaceEGL(EGLNativeWindowType window,
std::unique_ptr<gfx::VSyncProvider> vsync_provider);
......@@ -162,6 +164,7 @@ class GL_EXPORT NativeViewGLSurfaceEGL : public GLSurfaceEGL,
~NativeViewGLSurfaceEGL() override;
EGLNativeWindowType window_ = 0;
std::vector<EGLNativeWindowType> children_;
gfx::Size size_ = gfx::Size(1, 1);
bool enable_fixed_size_angle_ = true;
......@@ -180,6 +183,10 @@ class GL_EXPORT NativeViewGLSurfaceEGL : public GLSurfaceEGL,
void UpdateSwapEvents(EGLuint64KHR newFrameId, bool newFrameIdIsValid);
void TraceSwapEvents(EGLuint64KHR oldFrameId);
// PlatformEventDispatcher implementation.
bool CanDispatchEvent(const ui::PlatformEvent& event) override;
uint32_t DispatchEvent(const ui::PlatformEvent& event) override;
EGLSurface surface_ = nullptr;
bool supports_post_sub_buffer_ = false;
bool supports_swap_buffer_with_damage_ = false;
......
......@@ -40,12 +40,7 @@ bool NativeViewGLSurfaceEGLX11::InitializeNativeWindow() {
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);
}
XSelectInput(x11_display, window_, ExposureMask);
XFlush(x11_display);
return true;
......@@ -55,9 +50,6 @@ void NativeViewGLSurfaceEGLX11::Destroy() {
NativeViewGLSurfaceEGL::Destroy();
if (window_) {
if (PlatformEventSource* source = PlatformEventSource::GetInstance())
source->RemovePlatformEventDispatcher(this);
Display* x11_display = GetNativeDisplay();
XDestroyWindow(x11_display, window_);
window_ = 0;
......
......@@ -10,15 +10,13 @@
#include <string>
#include "base/macros.h"
#include "ui/events/platform/platform_event_dispatcher.h"
#include "ui/gl/gl_export.h"
#include "ui/gl/gl_surface_egl.h"
namespace gl {
// Encapsulates an EGL surface bound to a view using the X Window System.
class GL_EXPORT NativeViewGLSurfaceEGLX11 : public NativeViewGLSurfaceEGL,
public ui::PlatformEventDispatcher {
class GL_EXPORT NativeViewGLSurfaceEGLX11 : public NativeViewGLSurfaceEGL {
public:
explicit NativeViewGLSurfaceEGLX11(EGLNativeWindowType window);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment