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"
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
22 
23  // whether the renderer waits for frame render
25 
26  // true if frame was completed; resizing is not synchronized until first frame
27  // was rendered
29 
30  GdkGLContext* main_context;
31  GdkGLContext* resource_context;
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 =
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 
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 
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 =
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 
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