Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 516cbae

Browse files
Explicitly make the X connection for EGL. (#21831)
Explicitly make the X connection for EGL. EGL can mistakenly choose the GBM backend when using EGL_DEFAULT_DISPLAY. Fixes flutter/flutter#60429
1 parent c7e5d54 commit 516cbae

File tree

3 files changed

+32
-9
lines changed

3 files changed

+32
-9
lines changed

shell/platform/linux/BUILD.gn

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ source_set("flutter_linux") {
129129
"//flutter/shell/platform/linux/config:gtk",
130130
"//flutter/shell/platform/linux/config:egl",
131131
"//flutter/shell/platform/linux/config:wayland-egl",
132+
"//flutter/shell/platform/linux/config:x11",
132133
"//third_party/khronos:khronos_headers",
133134
]
134135

@@ -172,6 +173,7 @@ executable("flutter_linux_unittests") {
172173
configs += [
173174
"//flutter/shell/platform/linux/config:gtk",
174175
"//flutter/shell/platform/linux/config:wayland-egl",
176+
"//flutter/shell/platform/linux/config:x11",
175177
]
176178

177179
# Set flag to allow public headers to be directly included (library users should not do this)

shell/platform/linux/config/BUILD.gn

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,8 @@
55
import("//build/config/linux/pkg_config.gni")
66
import("//flutter/shell/platform/glfw/config.gni")
77

8-
if (build_glfw_shell) {
9-
pkg_config("x11") {
10-
packages = [ "x11" ]
11-
}
8+
pkg_config("x11") {
9+
packages = [ "x11" ]
1210
}
1311

1412
pkg_config("gtk") {

shell/platform/linux/fl_renderer_x11.cc

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,30 @@
55
#include "fl_renderer_x11.h"
66
#ifdef GDK_WINDOWING_X11
77

8+
#include <X11/X.h>
9+
810
#include "flutter/shell/platform/linux/egl_utils.h"
911

1012
struct _FlRendererX11 {
1113
FlRenderer parent_instance;
14+
15+
// Connection to the X server.
16+
Display* display;
1217
};
1318

1419
G_DEFINE_TYPE(FlRendererX11, fl_renderer_x11, fl_renderer_get_type())
1520

21+
static void fl_renderer_x11_dispose(GObject* object) {
22+
FlRendererX11* self = FL_RENDERER_X11(object);
23+
24+
if (self->display != nullptr) {
25+
XCloseDisplay(self->display);
26+
self->display = nullptr;
27+
}
28+
29+
G_OBJECT_CLASS(fl_renderer_x11_parent_class)->dispose(object);
30+
}
31+
1632
// Implements FlRenderer::setup_window_attr.
1733
static gboolean fl_renderer_x11_setup_window_attr(
1834
FlRenderer* renderer,
@@ -50,11 +66,17 @@ static gboolean fl_renderer_x11_setup_window_attr(
5066

5167
// Implements FlRenderer::create_display.
5268
static EGLDisplay fl_renderer_x11_create_display(FlRenderer* renderer) {
53-
// Note the use of EGL_DEFAULT_DISPLAY rather than sharing the existing
54-
// display connection from GTK. This is because this EGL display is going to
55-
// be accessed by a thread from Flutter. The GTK/X11 display connection is not
56-
// thread safe and would cause a crash.
57-
return eglGetDisplay(EGL_DEFAULT_DISPLAY);
69+
FlRendererX11* self = FL_RENDERER_X11(renderer);
70+
71+
// Create a dedicated connection to the X server because the EGL calls are
72+
// made from Flutter on a different thread to GTK. Re-using the existing
73+
// GTK X11 connection would crash as Xlib is not thread safe.
74+
if (self->display == nullptr) {
75+
Display* display = gdk_x11_get_default_xdisplay();
76+
self->display = XOpenDisplay(DisplayString(display));
77+
}
78+
79+
return eglGetDisplay(self->display);
5880
}
5981

6082
// Implements FlRenderer::create_surfaces.
@@ -99,6 +121,7 @@ static gboolean fl_renderer_x11_create_surfaces(FlRenderer* renderer,
99121
}
100122

101123
static void fl_renderer_x11_class_init(FlRendererX11Class* klass) {
124+
G_OBJECT_CLASS(klass)->dispose = fl_renderer_x11_dispose;
102125
FL_RENDERER_CLASS(klass)->setup_window_attr =
103126
fl_renderer_x11_setup_window_attr;
104127
FL_RENDERER_CLASS(klass)->create_display = fl_renderer_x11_create_display;

0 commit comments

Comments
 (0)