| Flutter Linux Embedder |

fl_compositor_software.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_compositor_software.h"
6
7 struct _FlCompositorSoftware {
8 FlCompositor parent_instance;
9
10 // Width of frame in pixels.
11 size_t width;
12
13 // Height of frame in pixels.
14 size_t height;
15
16 // Surface to draw on view.
17 cairo_surface_t* surface;
18
19 // Ensure Flutter and GTK can access the surface.
20 GMutex frame_mutex;
21
22 // Allow GTK to wait for Flutter to generate a suitable frame.
23 GCond frame_cond;
24 };
25
26 G_DEFINE_TYPE(FlCompositorSoftware,
27 fl_compositor_software,
28 fl_compositor_get_type())
29
30 static gboolean fl_compositor_software_present_layers(
31 FlCompositor* compositor,
32 const FlutterLayer** layers,
33 size_t layers_count) {
34 FlCompositorSoftware* self = FL_COMPOSITOR_SOFTWARE(compositor);
35
36 g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&self->frame_mutex);
37
38 if (layers_count == 0) {
39 return TRUE;
40 }
41
42 self->width = layers[0]->size.width;
43 self->height = layers[0]->size.height;
44
45 // TODO(robert-ancell): Support multiple layers
46 if (layers_count == 1) {
47 const FlutterLayer* layer = layers[0];
48 g_assert(layer->type == kFlutterLayerContentTypeBackingStore);
49 g_assert(layer->backing_store->type == kFlutterBackingStoreTypeSoftware);
50 const FlutterBackingStore* backing_store = layer->backing_store;
51
52 size_t allocation_length =
53 backing_store->software.row_bytes * backing_store->software.height;
54 unsigned char* old_data = self->surface != nullptr
55 ? cairo_image_surface_get_data(self->surface)
56 : nullptr;
57 unsigned char* data =
58 static_cast<unsigned char*>(realloc(old_data, allocation_length));
59 memcpy(data, backing_store->software.allocation, allocation_length);
60 cairo_surface_destroy(self->surface);
61 self->surface = cairo_image_surface_create_for_data(
62 data, CAIRO_FORMAT_ARGB32, backing_store->software.row_bytes / 4,
63 backing_store->software.height, backing_store->software.row_bytes);
64 }
65
66 // Signal a frame is ready.
67 g_cond_signal(&self->frame_cond);
68
69 return TRUE;
70 }
71
72 static gboolean fl_compositor_software_render(FlCompositor* compositor,
73 cairo_t* cr,
74 GdkWindow* window) {
75 FlCompositorSoftware* self = FL_COMPOSITOR_SOFTWARE(compositor);
76
77 g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&self->frame_mutex);
78
79 if (self->surface == nullptr) {
80 return FALSE;
81 }
82
83 // If frame not ready, then wait for it.
84 gint scale_factor = gdk_window_get_scale_factor(window);
85 size_t width = gdk_window_get_width(window) * scale_factor;
86 size_t height = gdk_window_get_height(window) * scale_factor;
87 while (self->width != width || self->height != height) {
88 g_cond_wait(&self->frame_cond, &self->frame_mutex);
89 }
90
91 cairo_surface_set_device_scale(self->surface, scale_factor, scale_factor);
92 cairo_set_source_surface(cr, self->surface, 0.0, 0.0);
93 cairo_paint(cr);
94
95 return TRUE;
96 }
97
98 static void fl_compositor_software_dispose(GObject* object) {
99 FlCompositorSoftware* self = FL_COMPOSITOR_SOFTWARE(object);
100
101 if (self->surface != nullptr) {
102 free(cairo_image_surface_get_data(self->surface));
103 }
104 g_clear_pointer(&self->surface, cairo_surface_destroy);
105 g_mutex_clear(&self->frame_mutex);
106 g_cond_clear(&self->frame_cond);
107
108 G_OBJECT_CLASS(fl_compositor_software_parent_class)->dispose(object);
109 }
110
111 static void fl_compositor_software_class_init(
112 FlCompositorSoftwareClass* klass) {
113 FL_COMPOSITOR_CLASS(klass)->present_layers =
114 fl_compositor_software_present_layers;
115 FL_COMPOSITOR_CLASS(klass)->render = fl_compositor_software_render;
116
117 G_OBJECT_CLASS(klass)->dispose = fl_compositor_software_dispose;
118 }
119
120 static void fl_compositor_software_init(FlCompositorSoftware* self) {
121 g_mutex_init(&self->frame_mutex);
122 g_cond_init(&self->frame_cond);
123 }
124
125 FlCompositorSoftware* fl_compositor_software_new() {
126 FlCompositorSoftware* self = FL_COMPOSITOR_SOFTWARE(
127 g_object_new(fl_compositor_software_get_type(), nullptr));
128 return self;
129 }
window
return window
Definition: fl_application.cc:41
layers_count
const FlutterLayer size_t layers_count
Definition: fl_compositor_software.cc:33
layers
const FlutterLayer ** layers
Definition: fl_compositor_software.cc:32
fl_compositor_software_new
FlCompositorSoftware * fl_compositor_software_new()
Definition: fl_compositor_software.cc:125
height
self height
Definition: fl_compositor_software.cc:43
fl_compositor_software_render
static gboolean fl_compositor_software_render(FlCompositor *compositor, cairo_t *cr, GdkWindow *window)
Definition: fl_compositor_software.cc:72
g_autoptr
g_autoptr(GMutexLocker) locker
width
self width
Definition: fl_compositor_software.cc:42
fl_compositor_software_class_init
static void fl_compositor_software_class_init(FlCompositorSoftwareClass *klass)
Definition: fl_compositor_software.cc:111
TRUE
return TRUE
Definition: fl_compositor_software.cc:69
self
g_cond_signal & self
Definition: fl_compositor_software.cc:67
G_DEFINE_TYPE
G_DEFINE_TYPE(FlCompositorSoftware, fl_compositor_software, fl_compositor_get_type()) static gboolean fl_compositor_software_present_layers(FlCompositor *compositor
fl_compositor_software_init
static void fl_compositor_software_init(FlCompositorSoftware *self)
Definition: fl_compositor_software.cc:120
fl_compositor_software_dispose
static void fl_compositor_software_dispose(GObject *object)
Definition: fl_compositor_software.cc:98
fl_compositor_software.h
_FlCompositorSoftware
Definition: fl_compositor_software.cc:7
_FlCompositorSoftware::frame_mutex
GMutex frame_mutex
Definition: fl_compositor_software.cc:20
_FlCompositorSoftware::frame_cond
GCond frame_cond
Definition: fl_compositor_software.cc:23
_FlCompositorSoftware::parent_instance
FlCompositor parent_instance
Definition: fl_compositor_software.cc:8
_FlCompositorSoftware::width
size_t width
Definition: fl_compositor_software.cc:11
_FlCompositorSoftware::height
size_t height
Definition: fl_compositor_software.cc:14
_FlCompositorSoftware::surface
cairo_surface_t * surface
Definition: fl_compositor_software.cc:17