mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Adds a support for compiling flutter engine when gdk does not have X11 backend. In such a configuration the generated gdkconfig.h header file looks like the following: /* gdkconfig.h * * This is a generated file. Please modify `configure.ac' */ #ifndef __GDKCONFIG_H__ #define __GDKCONFIG_H__ #if !defined (__GDK_H_INSIDE__) && !defined (GDK_COMPILATION) #error "Only <gdk/gdk.h> can be included directly." #endif #include <glib.h> G_BEGIN_DECLS #define GDK_WINDOWING_WAYLAND G_END_DECLS #endif /* __GDKCONFIG_H__ */ Additionally headers like <gdk/gdkx.h> are not available at all. Above configuration can be found on the most of the embedded systems. This patch enables compilation of X11 specific code only when gdk defines GDK_WINDOWING_X11. Signed-off-by: Damian Wrobel <dwrobel@ertelnet.rybnik.pl>
115 lines
4.3 KiB
C++
115 lines
4.3 KiB
C++
// Copyright 2013 The Flutter 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 "fl_renderer_x11.h"
|
|
#ifdef GDK_WINDOWING_X11
|
|
|
|
#include "flutter/shell/platform/linux/egl_utils.h"
|
|
|
|
struct _FlRendererX11 {
|
|
FlRenderer parent_instance;
|
|
};
|
|
|
|
G_DEFINE_TYPE(FlRendererX11, fl_renderer_x11, fl_renderer_get_type())
|
|
|
|
// Implements FlRenderer::setup_window_attr.
|
|
static gboolean fl_renderer_x11_setup_window_attr(
|
|
FlRenderer* renderer,
|
|
GtkWidget* widget,
|
|
EGLDisplay display,
|
|
EGLConfig config,
|
|
GdkWindowAttr* window_attributes,
|
|
gint* mask,
|
|
GError** error) {
|
|
EGLint visual_id;
|
|
if (!eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &visual_id)) {
|
|
g_set_error(error, fl_renderer_error_quark(), FL_RENDERER_ERROR_FAILED,
|
|
"Failed to determine EGL configuration visual");
|
|
return FALSE;
|
|
}
|
|
|
|
GdkX11Screen* screen = GDK_X11_SCREEN(gtk_widget_get_screen(widget));
|
|
if (!screen) {
|
|
g_set_error(error, fl_renderer_error_quark(), FL_RENDERER_ERROR_FAILED,
|
|
"View widget is not on an X11 screen");
|
|
return FALSE;
|
|
}
|
|
|
|
window_attributes->visual = gdk_x11_screen_lookup_visual(screen, visual_id);
|
|
if (window_attributes->visual == nullptr) {
|
|
g_set_error(error, fl_renderer_error_quark(), FL_RENDERER_ERROR_FAILED,
|
|
"Failed to find visual 0x%x", visual_id);
|
|
return FALSE;
|
|
}
|
|
|
|
*mask |= GDK_WA_VISUAL;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// Implements FlRenderer::create_display.
|
|
static EGLDisplay fl_renderer_x11_create_display(FlRenderer* renderer) {
|
|
// Note the use of EGL_DEFAULT_DISPLAY rather than sharing the existing
|
|
// display connection from GTK. This is because this EGL display is going to
|
|
// be accessed by a thread from Flutter. The GTK/X11 display connection is not
|
|
// thread safe and would cause a crash.
|
|
return eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
|
}
|
|
|
|
// Implements FlRenderer::create_surfaces.
|
|
static gboolean fl_renderer_x11_create_surfaces(FlRenderer* renderer,
|
|
GtkWidget* widget,
|
|
EGLDisplay display,
|
|
EGLConfig config,
|
|
EGLSurface* visible,
|
|
EGLSurface* resource,
|
|
GError** error) {
|
|
GdkWindow* window = gtk_widget_get_window(widget);
|
|
if (!GDK_IS_X11_WINDOW(window)) {
|
|
g_set_error(
|
|
error, fl_renderer_error_quark(), FL_RENDERER_ERROR_FAILED,
|
|
"Can not create EGL surface: view doesn't have an X11 GDK window");
|
|
return FALSE;
|
|
}
|
|
|
|
*visible = eglCreateWindowSurface(display, config,
|
|
gdk_x11_window_get_xid(window), nullptr);
|
|
if (*visible == EGL_NO_SURFACE) {
|
|
EGLint egl_error = eglGetError(); // Must be before egl_config_to_string().
|
|
g_autofree gchar* config_string = egl_config_to_string(display, config);
|
|
g_set_error(error, fl_renderer_error_quark(), FL_RENDERER_ERROR_FAILED,
|
|
"Failed to create EGL surface using configuration (%s): %s",
|
|
config_string, egl_error_to_string(egl_error));
|
|
return FALSE;
|
|
}
|
|
|
|
const EGLint attribs[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE};
|
|
*resource = eglCreatePbufferSurface(display, config, attribs);
|
|
if (*resource == EGL_NO_SURFACE) {
|
|
EGLint egl_error = eglGetError(); // Must be before egl_config_to_string().
|
|
g_autofree gchar* config_string = egl_config_to_string(display, config);
|
|
g_set_error(error, fl_renderer_error_quark(), FL_RENDERER_ERROR_FAILED,
|
|
"Failed to create EGL resource using configuration (%s): %s",
|
|
config_string, egl_error_to_string(egl_error));
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static void fl_renderer_x11_class_init(FlRendererX11Class* klass) {
|
|
FL_RENDERER_CLASS(klass)->setup_window_attr =
|
|
fl_renderer_x11_setup_window_attr;
|
|
FL_RENDERER_CLASS(klass)->create_display = fl_renderer_x11_create_display;
|
|
FL_RENDERER_CLASS(klass)->create_surfaces = fl_renderer_x11_create_surfaces;
|
|
}
|
|
|
|
static void fl_renderer_x11_init(FlRendererX11* self) {}
|
|
|
|
FlRendererX11* fl_renderer_x11_new() {
|
|
return FL_RENDERER_X11(g_object_new(fl_renderer_x11_get_type(), nullptr));
|
|
}
|
|
|
|
#endif // GDK_WINDOWING_X11
|