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

Go to the source code of this file.

Classes

struct  _FlViewRendererSoftware
 

Functions

 G_DEFINE_TYPE (FlViewRendererSoftware, fl_view_renderer_software, fl_view_renderer_get_type()) static gboolean redraw_cb(gpointer user_data)
 
static void wait_for_frame (FlViewRendererSoftware *self, GdkWindow *window, gint scale_factor)
 
static void fl_view_renderer_software_realize (GtkWidget *widget)
 
static gboolean fl_view_renderer_software_draw (GtkWidget *widget, cairo_t *cr)
 
static void fl_view_renderer_software_present_layers (FlViewRenderer *renderer, const FlutterLayer **layers, size_t layers_count)
 
static void fl_view_renderer_software_dispose (GObject *object)
 
static void fl_view_renderer_software_finalize (GObject *object)
 
static void fl_view_renderer_software_class_init (FlViewRendererSoftwareClass *klass)
 
static void fl_view_renderer_software_init (FlViewRendererSoftware *self)
 
FlViewRendererSoftware * fl_view_renderer_software_new (FlEngine *engine, gboolean sized_to_content)
 

Variables

static constexpr gint64 kRenderTimeoutMicroseconds = 100000
 

Function Documentation

◆ fl_view_renderer_software_class_init()

static void fl_view_renderer_software_class_init ( FlViewRendererSoftwareClass *  klass)
static

Definition at line 199 of file fl_view_renderer_software.cc.

200 {
201 GObjectClass* object_class = G_OBJECT_CLASS(klass);
202 object_class->dispose = fl_view_renderer_software_dispose;
203 object_class->finalize = fl_view_renderer_software_finalize;
204
205 GtkWidgetClass* widget_class = GTK_WIDGET_CLASS(klass);
206 widget_class->realize = fl_view_renderer_software_realize;
207 widget_class->draw = fl_view_renderer_software_draw;
208
209 FlViewRendererClass* renderer_class = FL_VIEW_RENDERER_CLASS(klass);
210 renderer_class->present_layers = fl_view_renderer_software_present_layers;
211}
static gboolean fl_view_renderer_software_draw(GtkWidget *widget, cairo_t *cr)
static void fl_view_renderer_software_realize(GtkWidget *widget)
static void fl_view_renderer_software_finalize(GObject *object)
static void fl_view_renderer_software_present_layers(FlViewRenderer *renderer, const FlutterLayer **layers, size_t layers_count)
static void fl_view_renderer_software_dispose(GObject *object)

References fl_view_renderer_software_dispose(), fl_view_renderer_software_draw(), fl_view_renderer_software_finalize(), fl_view_renderer_software_present_layers(), and fl_view_renderer_software_realize().

◆ fl_view_renderer_software_dispose()

static void fl_view_renderer_software_dispose ( GObject *  object)
static

Definition at line 176 of file fl_view_renderer_software.cc.

176 {
177 FlViewRendererSoftware* self = FL_VIEW_RENDERER_SOFTWARE(object);
178
179 g_clear_object(&self->engine);
180 g_clear_object(&self->task_runner);
181 g_mutex_clear(&self->frame_mutex);
182
183 G_OBJECT_CLASS(fl_view_renderer_software_parent_class)->dispose(object);
184}

References self.

Referenced by fl_view_renderer_software_class_init().

◆ fl_view_renderer_software_draw()

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

Definition at line 122 of file fl_view_renderer_software.cc.

122 {
123 FlViewRendererSoftware* self = FL_VIEW_RENDERER_SOFTWARE(widget);
124
125 fl_view_renderer_paint_background(FL_VIEW_RENDERER(self), cr);
126
127 // The compositor is created when the widget is realized; if it is not yet
128 // available there is nothing to render beyond the background.
129 if (self->compositor == nullptr) {
130 return TRUE;
131 }
132
133 GdkWindow* window = gtk_widget_get_window(widget);
134 gint scale_factor = gdk_window_get_scale_factor(window);
135
136 g_mutex_lock(&self->frame_mutex);
137
138 // If frame not ready, then wait for it.
139 if (!self->sized_to_content) {
140 wait_for_frame(self, window, scale_factor);
141 }
142
143 gboolean result =
144 fl_compositor_software_render(self->compositor, cr, scale_factor);
145
146 g_mutex_unlock(&self->frame_mutex);
147
148 return result;
149}
GLFWwindow * window
Definition main.cc:60
gboolean fl_compositor_software_render(FlCompositorSoftware *self, cairo_t *cr, gint scale_factor)
void fl_view_renderer_paint_background(FlViewRenderer *self, cairo_t *cr)
static void wait_for_frame(FlViewRendererSoftware *self, GdkWindow *window, gint scale_factor)
gint gdk_window_get_scale_factor(GdkWindow *window)
Definition mock_gtk.cc:95
GdkWindow * gtk_widget_get_window(GtkWidget *widget)
Definition mock_gtk.cc:309

References fl_compositor_software_render(), fl_view_renderer_paint_background(), gdk_window_get_scale_factor(), gtk_widget_get_window(), self, TRUE, wait_for_frame(), and window.

Referenced by fl_view_renderer_software_class_init().

◆ fl_view_renderer_software_finalize()

static void fl_view_renderer_software_finalize ( GObject *  object)
static

Definition at line 186 of file fl_view_renderer_software.cc.

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

References self.

Referenced by fl_view_renderer_software_class_init().

◆ fl_view_renderer_software_init()

static void fl_view_renderer_software_init ( FlViewRendererSoftware *  self)
static

Definition at line 213 of file fl_view_renderer_software.cc.

213 {
214 g_mutex_init(&self->frame_mutex);
215}

References self.

◆ fl_view_renderer_software_new()

FlViewRendererSoftware * fl_view_renderer_software_new ( FlEngine *  engine,
gboolean  sized_to_content 
)

Definition at line 217 of file fl_view_renderer_software.cc.

219 {
220 g_return_val_if_fail(FL_IS_ENGINE(engine), nullptr);
221
222 FlViewRendererSoftware* self = FL_VIEW_RENDERER_SOFTWARE(
223 g_object_new(fl_view_renderer_software_get_type(), nullptr));
224 self->engine = FL_ENGINE(g_object_ref(engine));
225 self->sized_to_content = sized_to_content;
226 return self;
227}
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_software_present_layers()

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

Definition at line 152 of file fl_view_renderer_software.cc.

155 {
156 FlViewRendererSoftware* self = FL_VIEW_RENDERER_SOFTWARE(renderer);
157
158 // Frames may be presented before the widget is realized and the compositor
159 // is set up; ignore them.
160 if (self->compositor == nullptr) {
161 return;
162 }
163
164 g_mutex_lock(&self->frame_mutex);
167 g_mutex_unlock(&self->frame_mutex);
168
169 // Wake up the GTK thread if it is waiting for this frame.
170 fl_task_runner_stop_wait(self->task_runner);
171
172 // Perform the redraw in the GTK thread.
173 g_idle_add(redraw_cb, g_object_ref(self));
174}
gboolean fl_compositor_software_composite_layers(FlCompositorSoftware *self, const FlutterLayer **layers, size_t layers_count)
void fl_task_runner_stop_wait(FlTaskRunner *self)
const FlutterLayer size_t layers_count
const FlutterLayer ** layers

References fl_compositor_software_composite_layers(), fl_task_runner_stop_wait(), layers, layers_count, and self.

Referenced by fl_view_renderer_software_class_init().

◆ fl_view_renderer_software_realize()

static void fl_view_renderer_software_realize ( GtkWidget *  widget)
static

Definition at line 111 of file fl_view_renderer_software.cc.

111 {
112 FlViewRendererSoftware* self = FL_VIEW_RENDERER_SOFTWARE(widget);
113
114 GTK_WIDGET_CLASS(fl_view_renderer_software_parent_class)->realize(widget);
115
116 self->task_runner =
117 FL_TASK_RUNNER(g_object_ref(fl_engine_get_task_runner(self->engine)));
118 self->compositor = fl_compositor_software_new();
119}
FlCompositorSoftware * fl_compositor_software_new()
FlTaskRunner * fl_engine_get_task_runner(FlEngine *self)

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

Referenced by fl_view_renderer_software_class_init().

◆ G_DEFINE_TYPE()

G_DEFINE_TYPE ( FlViewRendererSoftware  ,
fl_view_renderer_software  ,
fl_view_renderer_get_type()   
)

Definition at line 33 of file fl_view_renderer_software.cc.

38 {
39 g_autoptr(FlViewRendererSoftware) self = FL_VIEW_RENDERER_SOFTWARE(user_data);
40
41 if (self->compositor == nullptr) {
42 return G_SOURCE_REMOVE;
43 }
44
45 fl_view_renderer_notify_frame(FL_VIEW_RENDERER(self));
46
47 // If Flutter is controlling the window size, then resize the view if
48 // necessary.
49 GtkWidget* render_widget = GTK_WIDGET(self);
50 GtkAllocation allocation;
51 gtk_widget_get_allocation(render_widget, &allocation);
52 gint scale_factor = gtk_widget_get_scale_factor(render_widget);
53 size_t width = allocation.width * scale_factor;
54 size_t height = allocation.height * scale_factor;
55 size_t frame_width, frame_height;
56 {
57 g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&self->frame_mutex);
58 fl_compositor_software_get_frame_size(self->compositor, &frame_width,
59 &frame_height);
60 }
61 gboolean frame_size_matches = width == frame_width && height == frame_height;
62 if (self->sized_to_content && !frame_size_matches) {
63 gtk_widget_set_size_request(render_widget, frame_width / scale_factor,
64 frame_height / scale_factor);
65 GtkWidget* toplevel = gtk_widget_get_toplevel(render_widget);
66 if (GTK_IS_WINDOW(toplevel)) {
67 // Resize to smallest size, so that the window will shrink to fit the new
68 // size of the render area.
69 gtk_window_resize(GTK_WINDOW(toplevel), 1, 1);
70 }
71 return G_SOURCE_REMOVE;
72 }
73
74 gtk_widget_queue_draw(render_widget);
75
76 return G_SOURCE_REMOVE;
77}
g_autoptr(FlEngine) engine
void fl_compositor_software_get_frame_size(FlCompositorSoftware *self, size_t *width, size_t *height)
void fl_view_renderer_notify_frame(FlViewRenderer *self)
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_software_get_frame_size(), fl_view_renderer_notify_frame(), g_autoptr(), gtk_widget_get_allocation(), gtk_widget_get_scale_factor(), gtk_widget_get_toplevel(), gtk_widget_queue_draw(), gtk_window_resize(), height, self, user_data, and width.

◆ wait_for_frame()

static void wait_for_frame ( FlViewRendererSoftware *  self,
GdkWindow *  window,
gint  scale_factor 
)
static

Definition at line 82 of file fl_view_renderer_software.cc.

84 {
85 gint64 expiry_time = g_get_monotonic_time() + kRenderTimeoutMicroseconds;
86 while (true) {
87 size_t width = gdk_window_get_width(window) * scale_factor;
88 size_t height = gdk_window_get_height(window) * scale_factor;
89 size_t frame_width, frame_height;
90 fl_compositor_software_get_frame_size(self->compositor, &frame_width,
91 &frame_height);
92 if (frame_width == width && frame_height == height) {
93 break;
94 }
95
96 if (g_get_monotonic_time() > expiry_time) {
97 g_warning(
98 "Timed out waiting for software frame of size %zdx%zd (have "
99 "%zdx%zd)",
100 width, height, frame_width, frame_height);
101 break;
102 }
103
104 g_mutex_unlock(&self->frame_mutex);
105 fl_task_runner_wait(self->task_runner, expiry_time);
106 g_mutex_lock(&self->frame_mutex);
107 }
108}
void fl_task_runner_wait(FlTaskRunner *self, gint64 expiry_time)
static constexpr gint64 kRenderTimeoutMicroseconds
int gdk_window_get_width(GdkWindow *window)
Definition mock_gtk.cc:79
int gdk_window_get_height(GdkWindow *window)
Definition mock_gtk.cc:87

References fl_compositor_software_get_frame_size(), fl_task_runner_wait(), gdk_window_get_height(), gdk_window_get_width(), height, kRenderTimeoutMicroseconds, self, width, and window.

Referenced by fl_view_renderer_software_draw().

Variable Documentation

◆ kRenderTimeoutMicroseconds

constexpr gint64 kRenderTimeoutMicroseconds = 100000
staticconstexpr

Definition at line 12 of file fl_view_renderer_software.cc.

Referenced by wait_for_frame().