Flutter Linux Embedder
fl_opengl_manager.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <epoxy/egl.h>
6 #include <gdk/gdkwayland.h>
7 #ifdef GDK_WINDOWING_X11
8 #include <gdk/gdkx.h>
9 #endif
10 
12 
14  GObject parent_instance;
15 
16  // Display being rendered to.
17  EGLDisplay display;
18 
19  // Context used by the Flutter engine for rendering.
20  EGLContext render_context;
21 
22  // Context used by the Flutter engine to share resources.
23  EGLContext resource_context;
24 
25  // Context used by platform thread.
26  EGLContext platform_context;
27 };
28 
29 G_DEFINE_TYPE(FlOpenGLManager, fl_opengl_manager, G_TYPE_OBJECT)
30 
31 static void fl_opengl_manager_dispose(GObject* object) {
32  FlOpenGLManager* self = FL_OPENGL_MANAGER(object);
33 
34  eglDestroyContext(self->display, self->render_context);
35  eglDestroyContext(self->display, self->resource_context);
36  eglDestroyContext(self->display, self->platform_context);
37  eglTerminate(self->display);
38 
39  G_OBJECT_CLASS(fl_opengl_manager_parent_class)->dispose(object);
40 }
41 
42 static void fl_opengl_manager_class_init(FlOpenGLManagerClass* klass) {
43  G_OBJECT_CLASS(klass)->dispose = fl_opengl_manager_dispose;
44 }
45 
46 static void fl_opengl_manager_init(FlOpenGLManager* self) {
47  GdkDisplay* display = gdk_display_get_default();
48  if (GDK_IS_WAYLAND_DISPLAY(display)) {
49  self->display = eglGetPlatformDisplayEXT(
50  EGL_PLATFORM_WAYLAND_EXT, gdk_wayland_display_get_wl_display(display),
51  NULL);
52 #ifdef GDK_WINDOWING_X11
53  } else if (GDK_IS_X11_DISPLAY(display)) {
54  self->display = eglGetPlatformDisplayEXT(
55  EGL_PLATFORM_X11_EXT, gdk_x11_display_get_xdisplay(display), NULL);
56 #endif
57  } else {
58  g_critical("Unsupported GDK backend, unable to get EGL display");
59  }
60 
61  eglInitialize(self->display, nullptr, nullptr);
62 
63  const EGLint config_attributes[] = {EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8,
64  EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8,
65  EGL_DEPTH_SIZE, 8, EGL_STENCIL_SIZE, 8,
66  EGL_NONE};
67  EGLConfig config = nullptr;
68  EGLint num_config = 0;
69  eglChooseConfig(self->display, config_attributes, &config, 1, &num_config);
70 
71  const EGLint context_attributes[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
72 
73  self->render_context = eglCreateContext(self->display, config, EGL_NO_CONTEXT,
74  context_attributes);
75  if (self->render_context == EGL_NO_CONTEXT) {
76  g_warning("Failed to create EGL context for rendering");
77  }
78 
79  self->resource_context = eglCreateContext(
80  self->display, config, self->render_context, context_attributes);
81  if (self->resource_context == EGL_NO_CONTEXT) {
82  g_warning("Failed to create EGL context for resource sharing");
83  }
84 
85  self->platform_context = eglCreateContext(
86  self->display, config, self->render_context, context_attributes);
87  if (self->platform_context == EGL_NO_CONTEXT) {
88  g_warning("Failed to create EGL context for platform thread");
89  }
90 }
91 
92 FlOpenGLManager* fl_opengl_manager_new() {
93  FlOpenGLManager* self =
94  FL_OPENGL_MANAGER(g_object_new(fl_opengl_manager_get_type(), nullptr));
95  return self;
96 }
97 
98 gboolean fl_opengl_manager_make_current(FlOpenGLManager* self) {
99  return eglMakeCurrent(self->display, EGL_NO_SURFACE, EGL_NO_SURFACE,
100  self->render_context) == EGL_TRUE;
101 }
102 
103 gboolean fl_opengl_manager_make_resource_current(FlOpenGLManager* self) {
104  return eglMakeCurrent(self->display, EGL_NO_SURFACE, EGL_NO_SURFACE,
105  self->resource_context) == EGL_TRUE;
106 }
107 
108 gboolean fl_opengl_manager_make_platform_current(FlOpenGLManager* self) {
109  return eglMakeCurrent(self->display, EGL_NO_SURFACE, EGL_NO_SURFACE,
110  self->platform_context) == EGL_TRUE;
111 }
112 
113 gboolean fl_opengl_manager_clear_current(FlOpenGLManager* self) {
114  return eglMakeCurrent(self->display, EGL_NO_SURFACE, EGL_NO_SURFACE,
115  EGL_NO_CONTEXT) == EGL_TRUE;
116 }
G_DEFINE_TYPE(FlBasicMessageChannelResponseHandle, fl_basic_message_channel_response_handle, G_TYPE_OBJECT) static void fl_basic_message_channel_response_handle_dispose(GObject *object)
gboolean fl_opengl_manager_make_platform_current(FlOpenGLManager *self)
static void fl_opengl_manager_dispose(GObject *object)
static void fl_opengl_manager_class_init(FlOpenGLManagerClass *klass)
FlOpenGLManager * fl_opengl_manager_new()
gboolean fl_opengl_manager_make_resource_current(FlOpenGLManager *self)
gboolean fl_opengl_manager_clear_current(FlOpenGLManager *self)
gboolean fl_opengl_manager_make_current(FlOpenGLManager *self)
static void fl_opengl_manager_init(FlOpenGLManager *self)
EGLContext resource_context
EGLContext platform_context
EGLContext render_context