Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
fl_view_renderer.cc File Reference

Go to the source code of this file.

Classes

struct  _FlViewRenderer
 

Enumerations

enum  {
  SIGNAL_FIRST_FRAME ,
  LAST_SIGNAL
}
 

Functions

static gboolean redraw_cb (gpointer user_data)
 
static void setup_opengl (FlViewRenderer *self)
 
static void setup_software (FlViewRenderer *self)
 
static void paint_background (FlViewRenderer *self, cairo_t *cr)
 
static void fl_view_renderer_realize (GtkWidget *widget)
 
static gboolean fl_view_renderer_draw (GtkWidget *widget, cairo_t *cr)
 
static void fl_view_renderer_dispose (GObject *object)
 
static void fl_view_renderer_finalize (GObject *object)
 
static void fl_view_renderer_class_init (FlViewRendererClass *klass)
 
static void fl_view_renderer_init (FlViewRenderer *self)
 
FlViewRenderer * fl_view_renderer_new (FlEngine *engine, gboolean sized_to_content)
 
void fl_view_renderer_set_background_color (FlViewRenderer *self, const GdkRGBA *color)
 
void fl_view_renderer_present_layers (FlViewRenderer *self, const FlutterLayer **layers, size_t layers_count)
 

Variables

static guint fl_view_renderer_signals [LAST_SIGNAL]
 

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
SIGNAL_FIRST_FRAME 
LAST_SIGNAL 

Definition at line 37 of file fl_view_renderer.cc.

@ LAST_SIGNAL
@ SIGNAL_FIRST_FRAME

Function Documentation

◆ fl_view_renderer_class_init()

static void fl_view_renderer_class_init ( FlViewRendererClass *  klass)
static

Definition at line 194 of file fl_view_renderer.cc.

194 {
195 G_OBJECT_CLASS(klass)->dispose = fl_view_renderer_dispose;
196 G_OBJECT_CLASS(klass)->finalize = fl_view_renderer_finalize;
197
198 GtkWidgetClass* widget_class = GTK_WIDGET_CLASS(klass);
199 widget_class->realize = fl_view_renderer_realize;
200 widget_class->draw = fl_view_renderer_draw;
201
203 g_signal_new("first-frame", fl_view_renderer_get_type(),
204 G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0);
205}
static gboolean fl_view_renderer_draw(GtkWidget *widget, cairo_t *cr)
static void fl_view_renderer_dispose(GObject *object)
static void fl_view_renderer_realize(GtkWidget *widget)
static void fl_view_renderer_finalize(GObject *object)
static guint fl_view_renderer_signals[LAST_SIGNAL]

References fl_view_renderer_dispose(), fl_view_renderer_draw(), fl_view_renderer_finalize(), fl_view_renderer_realize(), fl_view_renderer_signals, and SIGNAL_FIRST_FRAME.

◆ fl_view_renderer_dispose()

static void fl_view_renderer_dispose ( GObject *  object)
static

Definition at line 171 of file fl_view_renderer.cc.

171 {
172 FlViewRenderer* self = FL_VIEW_RENDERER(object);
173
174 g_clear_object(&self->render_context);
175 g_clear_object(&self->engine);
176 g_clear_pointer(&self->background_color, gdk_rgba_free);
177
178 G_OBJECT_CLASS(fl_view_renderer_parent_class)->dispose(object);
179}

References self.

Referenced by fl_view_renderer_class_init().

◆ fl_view_renderer_draw()

static gboolean fl_view_renderer_draw ( GtkWidget *  widget,
cairo_t *  cr 
)
static

Definition at line 145 of file fl_view_renderer.cc.

145 {
146 FlViewRenderer* self = FL_VIEW_RENDERER(widget);
147
149
150 // The compositor is created when the widget is realized; if it is not yet
151 // available there is nothing to render beyond the background.
152 if (self->compositor == nullptr) {
153 return TRUE;
154 }
155
156 if (self->render_context) {
157 gdk_gl_context_make_current(self->render_context);
158 }
159
160 gboolean wait_for_frame = !self->sized_to_content;
161 gboolean result = fl_compositor_render(
162 self->compositor, cr, gtk_widget_get_window(widget), wait_for_frame);
163
164 if (self->render_context) {
166 }
167
168 return result;
169}
gboolean fl_compositor_render(FlCompositor *self, cairo_t *cr, GdkWindow *window, gboolean wait_for_frame)
return TRUE
static void paint_background(FlViewRenderer *self, cairo_t *cr)
void gdk_gl_context_clear_current(GdkGLContext *context)
Definition mock_gtk.cc:162
void gdk_gl_context_make_current(GdkGLContext *context)
Definition mock_gtk.cc:166
GdkWindow * gtk_widget_get_window(GtkWidget *widget)
Definition mock_gtk.cc:309

References fl_compositor_render(), gdk_gl_context_clear_current(), gdk_gl_context_make_current(), gtk_widget_get_window(), paint_background(), self, and TRUE.

Referenced by fl_view_renderer_class_init().

◆ fl_view_renderer_finalize()

static void fl_view_renderer_finalize ( GObject *  object)
static

Definition at line 181 of file fl_view_renderer.cc.

181 {
182 FlViewRenderer* self = FL_VIEW_RENDERER(object);
183
184 // The compositor is released here rather than in dispose() so it outlives a
185 // forced dispose (e.g. gtk_widget_destroy()) and is only freed once the last
186 // reference is dropped. This keeps it alive for the raster thread, which
187 // holds a strong reference on the view (and thus this renderer) while
188 // presenting.
189 g_clear_object(&self->compositor);
190
191 G_OBJECT_CLASS(fl_view_renderer_parent_class)->finalize(object);
192}

References self.

Referenced by fl_view_renderer_class_init().

◆ fl_view_renderer_init()

static void fl_view_renderer_init ( FlViewRenderer *  self)
static

Definition at line 207 of file fl_view_renderer.cc.

207 {
208 GdkRGBA default_background = {
209 .red = 0.0, .green = 0.0, .blue = 0.0, .alpha = 1.0};
210 self->background_color = gdk_rgba_copy(&default_background);
211}

References self.

◆ fl_view_renderer_new()

FlViewRenderer * fl_view_renderer_new ( FlEngine *  engine,
gboolean  sized_to_content 
)

Definition at line 213 of file fl_view_renderer.cc.

214 {
215 g_return_val_if_fail(FL_IS_ENGINE(engine), nullptr);
216
217 FlViewRenderer* self =
218 FL_VIEW_RENDERER(g_object_new(fl_view_renderer_get_type(), nullptr));
219
220 self->engine = FL_ENGINE(g_object_ref(engine));
221 self->sized_to_content = sized_to_content;
222
223 return self;
224}
FlutterEngine engine
Definition main.cc:84
G_BEGIN_DECLS gboolean sized_to_content

References engine, self, and sized_to_content.

Referenced by setup_engine().

◆ fl_view_renderer_present_layers()

void fl_view_renderer_present_layers ( FlViewRenderer *  renderer,
const FlutterLayer **  layers,
size_t  layers_count 
)

fl_view_renderer_present_layers: @renderer: an #FlViewRenderer. @layers: layers to draw. @layers_count: number of layers.

Composites a frame into the renderer. This method can be called from any thread.

Definition at line 233 of file fl_view_renderer.cc.

235 {
236 g_return_if_fail(FL_IS_VIEW_RENDERER(self));
237
238 // Frames may be presented before the widget is realized and the compositor
239 // is set up; ignore them.
240 if (self->compositor == nullptr) {
241 return;
242 }
243
245
246 // Perform the redraw in the GTK thread.
247 g_idle_add(redraw_cb, g_object_ref(self));
248}
gboolean fl_compositor_present_layers(FlCompositor *self, const FlutterLayer **layers, size_t layers_count)
const FlutterLayer size_t layers_count
const FlutterLayer ** layers
static gboolean redraw_cb(gpointer user_data)

References fl_compositor_present_layers(), layers, layers_count, redraw_cb(), and self.

Referenced by fl_view_present_layers().

◆ fl_view_renderer_realize()

static void fl_view_renderer_realize ( GtkWidget *  widget)
static

Definition at line 127 of file fl_view_renderer.cc.

127 {
128 FlViewRenderer* self = FL_VIEW_RENDERER(widget);
129
130 GTK_WIDGET_CLASS(fl_view_renderer_parent_class)->realize(widget);
131
132 switch (fl_engine_get_renderer_type(self->engine)) {
133 case kOpenGL:
135 break;
136 case kSoftware:
138 break;
139 default:
140 break;
141 }
142}
@ kOpenGL
Definition embedder.h:80
@ kSoftware
Definition embedder.h:81
FlutterRendererType fl_engine_get_renderer_type(FlEngine *self)
Definition fl_engine.cc:744
static void setup_software(FlViewRenderer *self)
static void setup_opengl(FlViewRenderer *self)

References fl_engine_get_renderer_type(), kOpenGL, kSoftware, self, setup_opengl(), and setup_software().

Referenced by fl_view_renderer_class_init().

◆ fl_view_renderer_set_background_color()

void fl_view_renderer_set_background_color ( FlViewRenderer *  renderer,
const GdkRGBA *  color 
)

fl_view_renderer_set_background_color: @renderer: an #FlViewRenderer. @color: the background color.

Sets the background color drawn behind the Flutter frame.

Definition at line 226 of file fl_view_renderer.cc.

227 {
228 g_return_if_fail(FL_IS_VIEW_RENDERER(self));
229 gdk_rgba_free(self->background_color);
230 self->background_color = gdk_rgba_copy(color);
231}

References self.

Referenced by fl_view_set_background_color().

◆ paint_background()

static void paint_background ( FlViewRenderer *  self,
cairo_t *  cr 
)
static

Definition at line 114 of file fl_view_renderer.cc.

114 {
115 // Don't bother drawing if fully transparent - the widget above this will
116 // already be drawn by GTK.
117 if (self->background_color->red == 0 && self->background_color->green == 0 &&
118 self->background_color->blue == 0 && self->background_color->alpha == 0) {
119 return;
120 }
121
122 gdk_cairo_set_source_rgba(cr, self->background_color);
123 cairo_paint(cr);
124}
void gdk_cairo_set_source_rgba(cairo_t *cr, const GdkRGBA *rgba)
Definition mock_gtk.cc:154

References gdk_cairo_set_source_rgba(), and self.

Referenced by fl_view_renderer_draw().

◆ redraw_cb()

static gboolean redraw_cb ( gpointer  user_data)
static

Definition at line 44 of file fl_view_renderer.cc.

44 {
45 g_autoptr(FlViewRenderer) self = FL_VIEW_RENDERER(user_data);
46
47 if (self->compositor == nullptr) {
48 return G_SOURCE_REMOVE;
49 }
50
51 if (!self->have_first_frame) {
52 self->have_first_frame = TRUE;
54 }
55
56 // If Flutter is controlling the window size, then resize the view if
57 // necessary.
58 GtkWidget* render_widget = GTK_WIDGET(self);
59 GtkAllocation allocation;
60 gtk_widget_get_allocation(render_widget, &allocation);
61 gint scale_factor = gtk_widget_get_scale_factor(render_widget);
62 size_t width = allocation.width * scale_factor;
63 size_t height = allocation.height * scale_factor;
64 size_t frame_width, frame_height;
65 fl_compositor_get_frame_size(self->compositor, &frame_width, &frame_height);
66 gboolean frame_size_matches = width == frame_width && height == frame_height;
67 if (self->sized_to_content && !frame_size_matches) {
68 gtk_widget_set_size_request(render_widget, frame_width / scale_factor,
69 frame_height / scale_factor);
70 GtkWidget* toplevel = gtk_widget_get_toplevel(render_widget);
71 if (GTK_IS_WINDOW(toplevel)) {
72 // Resize to smallest size, so that the window will shrink to fit the new
73 // size of the render area.
74 gtk_window_resize(GTK_WINDOW(toplevel), 1, 1);
75 }
76 return G_SOURCE_REMOVE;
77 }
78
79 gtk_widget_queue_draw(render_widget);
80
81 return G_SOURCE_REMOVE;
82}
g_autoptr(FlEngine) engine
void fl_compositor_get_frame_size(FlCompositor *self, size_t *width, size_t *height)
void gtk_widget_queue_draw(GtkWidget *widget)
Definition mock_gtk.cc:271
void gtk_window_resize(GtkWindow *window, gint width, gint height)
Definition mock_gtk.cc:207
void gtk_widget_get_allocation(GtkWidget *widget, GtkAllocation *allocation)
Definition mock_gtk.cc:245
GtkWidget * gtk_widget_get_toplevel(GtkWidget *widget)
Definition mock_gtk.cc:304
gint gtk_widget_get_scale_factor(GtkWidget *widget)
Definition mock_gtk.cc:258
int32_t height
int32_t width

References fl_compositor_get_frame_size(), fl_view_renderer_signals, g_autoptr(), gtk_widget_get_allocation(), gtk_widget_get_scale_factor(), gtk_widget_get_toplevel(), gtk_widget_queue_draw(), gtk_window_resize(), height, self, SIGNAL_FIRST_FRAME, TRUE, user_data, and width.

Referenced by fl_view_renderer_present_layers().

◆ setup_opengl()

static void setup_opengl ( FlViewRenderer *  self)
static

Definition at line 84 of file fl_view_renderer.cc.

84 {
85 g_autoptr(GError) error = nullptr;
86
87 self->render_context = gdk_window_create_gl_context(
88 gtk_widget_get_window(GTK_WIDGET(self)), &error);
89 if (self->render_context == nullptr) {
90 g_warning("Failed to create OpenGL context: %s", error->message);
91 return;
92 }
93
94 if (!gdk_gl_context_realize(self->render_context, &error)) {
95 g_warning("Failed to realize OpenGL context: %s", error->message);
96 return;
97 }
98
99 // If using Wayland, then EGL is in use and we can access the frame
100 // from the Flutter context using EGLImage. If not (i.e. X11 using GLX)
101 // then we have to copy the texture via the CPU.
102 gboolean shareable =
103 GDK_IS_WAYLAND_DISPLAY(gtk_widget_get_display(GTK_WIDGET(self)));
104 self->compositor = FL_COMPOSITOR(fl_compositor_opengl_new(
107}
FlCompositorOpenGL * fl_compositor_opengl_new(FlTaskRunner *task_runner, FlOpenGLManager *opengl_manager, gboolean shareable)
G_BEGIN_DECLS FlOpenGLManager gboolean shareable
FlTaskRunner * fl_engine_get_task_runner(FlEngine *self)
FlOpenGLManager * fl_engine_get_opengl_manager(FlEngine *self)
Definition fl_engine.cc:749
const uint8_t uint32_t uint32_t GError ** error
GdkDisplay * gtk_widget_get_display(GtkWidget *widget)
Definition mock_gtk.cc:253
GdkGLContext * gdk_window_create_gl_context(GdkWindow *window, GError **error)
Definition mock_gtk.cc:149
void gdk_gl_context_realize(GdkGLContext *context)
Definition mock_gtk.cc:158

References error, fl_compositor_opengl_new(), fl_engine_get_opengl_manager(), fl_engine_get_task_runner(), g_autoptr(), gdk_gl_context_realize(), gdk_window_create_gl_context(), gtk_widget_get_display(), gtk_widget_get_window(), self, and shareable.

Referenced by fl_view_renderer_realize().

◆ setup_software()

static void setup_software ( FlViewRenderer *  self)
static

Definition at line 109 of file fl_view_renderer.cc.

109 {
110 self->compositor = FL_COMPOSITOR(
112}
FlCompositorSoftware * fl_compositor_software_new(FlTaskRunner *task_runner)

References fl_compositor_software_new(), fl_engine_get_task_runner(), and self.

Referenced by fl_view_renderer_realize().

Variable Documentation

◆ fl_view_renderer_signals

guint fl_view_renderer_signals[LAST_SIGNAL]
static

Definition at line 39 of file fl_view_renderer.cc.

Referenced by fl_view_renderer_class_init(), and redraw_cb().