| Flutter Linux Embedder |

fl_renderer.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 "fl_renderer.h"
6
7 #include <epoxy/egl.h>
8 #include <epoxy/gl.h>
9
10 #include "flutter/shell/platform/embedder/embedder.h"
11 #include "flutter/shell/platform/linux/fl_backing_store_provider.h"
12 #include "flutter/shell/platform/linux/fl_engine_private.h"
13
14 G_DEFINE_QUARK(fl_renderer_error_quark, fl_renderer_error)
15
16 typedef struct {
17 FlView* view;
18
19 // target dimension for resizing
20 int target_width;
21 int target_height;
22
23 // whether the renderer waits for frame render
24 bool blocking_main_thread;
25
26 // true if frame was completed; resizing is not synchronized until first frame
27 // was rendered
28 bool had_first_frame;
29
30 GdkGLContext* main_context;
31 GdkGLContext* resource_context;
32 } FlRendererPrivate;
33
34 G_DEFINE_TYPE_WITH_PRIVATE(FlRenderer, fl_renderer, G_TYPE_OBJECT)
35
36 static void fl_renderer_unblock_main_thread(FlRenderer* self) {
37 FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
38 fl_renderer_get_instance_private(self));
39 if (priv->blocking_main_thread) {
40 priv->blocking_main_thread = false;
41
42 FlTaskRunner* runner =
43 fl_engine_get_task_runner(fl_view_get_engine(priv->view));
44 fl_task_runner_release_main_thread(runner);
45 }
46 }
47
48 static void fl_renderer_dispose(GObject* self) {
49 fl_renderer_unblock_main_thread(FL_RENDERER(self));
50 G_OBJECT_CLASS(fl_renderer_parent_class)->dispose(self);
51 }
52
53 static void fl_renderer_class_init(FlRendererClass* klass) {
54 G_OBJECT_CLASS(klass)->dispose = fl_renderer_dispose;
55 }
56
57 static void fl_renderer_init(FlRenderer* self) {}
58
59 gboolean fl_renderer_start(FlRenderer* self, FlView* view, GError** error) {
60 g_return_val_if_fail(FL_IS_RENDERER(self), FALSE);
61 FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
62 fl_renderer_get_instance_private(self));
63 priv->view = view;
64 gboolean result = FL_RENDERER_GET_CLASS(self)->create_contexts(
65 self, GTK_WIDGET(view), &priv->main_context, &priv->resource_context,
66 error);
67
68 if (result) {
69 gdk_gl_context_realize(priv->main_context, error);
70 gdk_gl_context_realize(priv->resource_context, error);
71 }
72
73 if (*error != nullptr) {
74 return FALSE;
75 }
76 return TRUE;
77 }
78
79 FlView* fl_renderer_get_view(FlRenderer* self) {
80 FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
81 fl_renderer_get_instance_private(self));
82 return priv->view;
83 }
84
85 GdkGLContext* fl_renderer_get_context(FlRenderer* self) {
86 FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
87 fl_renderer_get_instance_private(self));
88 return priv->main_context;
89 }
90
91 void* fl_renderer_get_proc_address(FlRenderer* self, const char* name) {
92 return reinterpret_cast<void*>(eglGetProcAddress(name));
93 }
94
95 gboolean fl_renderer_make_current(FlRenderer* self, GError** error) {
96 FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
97 fl_renderer_get_instance_private(self));
98 if (priv->main_context) {
99 gdk_gl_context_make_current(priv->main_context);
100 }
101
102 return TRUE;
103 }
104
105 gboolean fl_renderer_make_resource_current(FlRenderer* self, GError** error) {
106 FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
107 fl_renderer_get_instance_private(self));
108 if (priv->resource_context) {
109 gdk_gl_context_make_current(priv->resource_context);
110 }
111
112 return TRUE;
113 }
114
115 gboolean fl_renderer_clear_current(FlRenderer* self, GError** error) {
116 gdk_gl_context_clear_current();
117 return TRUE;
118 }
119
120 guint32 fl_renderer_get_fbo(FlRenderer* self) {
121 // There is only one frame buffer object - always return that.
122 return 0;
123 }
124
125 gboolean fl_renderer_create_backing_store(
126 FlRenderer* self,
127 const FlutterBackingStoreConfig* config,
128 FlutterBackingStore* backing_store_out) {
129 return FL_RENDERER_GET_CLASS(self)->create_backing_store(self, config,
130 backing_store_out);
131 }
132
133 gboolean fl_renderer_collect_backing_store(
134 FlRenderer* self,
135 const FlutterBackingStore* backing_store) {
136 return FL_RENDERER_GET_CLASS(self)->collect_backing_store(self,
137 backing_store);
138 }
139
140 void fl_renderer_wait_for_frame(FlRenderer* self,
141 int target_width,
142 int target_height) {
143 FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
144 fl_renderer_get_instance_private(self));
145
146 priv->target_width = target_width;
147 priv->target_height = target_height;
148
149 if (priv->had_first_frame && !priv->blocking_main_thread) {
150 priv->blocking_main_thread = true;
151 FlTaskRunner* runner =
152 fl_engine_get_task_runner(fl_view_get_engine(priv->view));
153 fl_task_runner_block_main_thread(runner);
154 }
155 }
156
157 gboolean fl_renderer_present_layers(FlRenderer* self,
158 const FlutterLayer** layers,
159 size_t layers_count) {
160 FlRendererPrivate* priv = reinterpret_cast<FlRendererPrivate*>(
161 fl_renderer_get_instance_private(self));
162
163 // ignore incoming frame with wrong dimensions in trivial case with just one
164 // layer
165 if (priv->blocking_main_thread && layers_count == 1 &&
166 layers[0]->offset.x == 0 && layers[0]->offset.y == 0 &&
167 (layers[0]->size.width != priv->target_width ||
168 layers[0]->size.height != priv->target_height)) {
169 return true;
170 }
171
172 priv->had_first_frame = true;
173
174 fl_renderer_unblock_main_thread(self);
175
176 return FL_RENDERER_GET_CLASS(self)->present_layers(self, layers,
177 layers_count);
178 }
fl_renderer_wait_for_frame
void fl_renderer_wait_for_frame(FlRenderer *self, int target_width, int target_height)
Definition: fl_renderer.cc:140
fl_renderer_error_quark
GQuark fl_renderer_error_quark(void) G_GNUC_CONST
G_DEFINE_TYPE_WITH_PRIVATE
G_DEFINE_TYPE_WITH_PRIVATE(FlTextInputPlugin, fl_text_input_plugin, G_TYPE_OBJECT) static gboolean finish_method(GObject *object
fl_renderer_init
static void fl_renderer_init(FlRenderer *self)
Definition: fl_renderer.cc:57
fl_renderer_get_view
FlView * fl_renderer_get_view(FlRenderer *self)
Definition: fl_renderer.cc:79
FlRendererPrivate::resource_context
GdkGLContext * resource_context
Definition: fl_renderer.cc:31
priv
FlPixelBufferTexturePrivate * priv
Definition: fl_pixel_buffer_texture.cc:30
fl_renderer_clear_current
gboolean fl_renderer_clear_current(FlRenderer *self, GError **error)
Definition: fl_renderer.cc:115
FlRendererPrivate::target_width
int target_width
Definition: fl_renderer.cc:20
fl_renderer_get_proc_address
void * fl_renderer_get_proc_address(FlRenderer *self, const char *name)
Definition: fl_renderer.cc:91
fl_renderer_dispose
static void fl_renderer_dispose(GObject *self)
Definition: fl_renderer.cc:48
fl_renderer_make_resource_current
gboolean fl_renderer_make_resource_current(FlRenderer *self, GError **error)
Definition: fl_renderer.cc:105
FlRendererPrivate::blocking_main_thread
bool blocking_main_thread
Definition: fl_renderer.cc:24
G_DEFINE_QUARK
G_DEFINE_QUARK(fl_binary_messenger_codec_error_quark, fl_binary_messenger_codec_error) G_DECLARE_FINAL_TYPE(FlBinaryMessengerImpl
fl_renderer_class_init
static void fl_renderer_class_init(FlRendererClass *klass)
Definition: fl_renderer.cc:53
fl_renderer_collect_backing_store
gboolean fl_renderer_collect_backing_store(FlRenderer *self, const FlutterBackingStore *backing_store)
Definition: fl_renderer.cc:133
fl_renderer_present_layers
gboolean fl_renderer_present_layers(FlRenderer *self, const FlutterLayer **layers, size_t layers_count)
Definition: fl_renderer.cc:157
FlRendererPrivate::view
FlView * view
Definition: fl_renderer.cc:17
fl_engine_private.h
TRUE
return TRUE
Definition: fl_pixel_buffer_texture_test.cc:53
fl_view_get_engine
G_MODULE_EXPORT FlEngine * fl_view_get_engine(FlView *self)
Definition: fl_view.cc:744
fl_renderer.h
fl_renderer_unblock_main_thread
static void fl_renderer_unblock_main_thread(FlRenderer *self)
Definition: fl_renderer.cc:36
fl_task_runner_release_main_thread
void fl_task_runner_release_main_thread(FlTaskRunner *self)
Definition: fl_task_runner.cc:205
self
GdkEvent FlView * self
Definition: fl_view.cc:100
fl_renderer_start
gboolean fl_renderer_start(FlRenderer *self, FlView *view, GError **error)
Definition: fl_renderer.cc:59
result
GAsyncResult * result
Definition: fl_text_input_plugin.cc:106
error
const uint8_t uint32_t uint32_t GError ** error
Definition: fl_pixel_buffer_texture_test.cc:40
fl_engine_get_task_runner
FlTaskRunner * fl_engine_get_task_runner(FlEngine *self)
Definition: fl_engine.cc:899
FlRendererPrivate::main_context
GdkGLContext * main_context
Definition: fl_renderer.cc:30
fl_renderer_create_backing_store
gboolean fl_renderer_create_backing_store(FlRenderer *self, const FlutterBackingStoreConfig *config, FlutterBackingStore *backing_store_out)
Definition: fl_renderer.cc:125
FlRendererPrivate::target_height
int target_height
Definition: fl_renderer.cc:21
fl_backing_store_provider.h
fl_renderer_make_current
gboolean fl_renderer_make_current(FlRenderer *self, GError **error)
Definition: fl_renderer.cc:95
FlRendererPrivate
Definition: fl_renderer.cc:16
FlRendererPrivate::had_first_frame
bool had_first_frame
Definition: fl_renderer.cc:28
fl_renderer_get_fbo
guint32 fl_renderer_get_fbo(FlRenderer *self)
Definition: fl_renderer.cc:120
fl_task_runner_block_main_thread
void fl_task_runner_block_main_thread(FlTaskRunner *self)
Definition: fl_task_runner.cc:184
fl_renderer_get_context
GdkGLContext * fl_renderer_get_context(FlRenderer *self)
Definition: fl_renderer.cc:85