27 fl_compositor_software,
28 fl_compositor_get_type())
30 static gboolean fl_compositor_software_present_layers(
31 FlCompositor* compositor,
34 FlCompositorSoftware*
self = FL_COMPOSITOR_SOFTWARE(compositor);
36 g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&self->frame_mutex);
43 self->height =
layers[0]->size.height;
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;
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)
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);
74 FlCompositorSoftware*
self = FL_COMPOSITOR_SOFTWARE(compositor);
76 g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&self->frame_mutex);
78 if (
width !=
nullptr) {
89 gboolean wait_for_frame) {
90 FlCompositorSoftware*
self = FL_COMPOSITOR_SOFTWARE(compositor);
92 g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&self->frame_mutex);
94 if (self->surface ==
nullptr) {
99 gint scale_factor = gdk_window_get_scale_factor(window);
100 if (wait_for_frame) {
104 size_t width = gdk_window_get_width(window) * scale_factor;
105 size_t height = gdk_window_get_height(window) * scale_factor;
106 if (self->width ==
width && self->height ==
height) {
110 if (g_get_monotonic_time() > expiry_time) {
112 "Timed out waiting for software frame of size %zdx%zd (have "
118 g_mutex_unlock(&self->frame_mutex);
120 g_mutex_lock(&self->frame_mutex);
124 cairo_surface_set_device_scale(self->surface, scale_factor, scale_factor);
125 cairo_set_source_surface(cr, self->surface, 0.0, 0.0);
132 FlCompositorSoftware*
self = FL_COMPOSITOR_SOFTWARE(
object);
134 g_clear_object(&self->task_runner);
135 if (self->surface !=
nullptr) {
136 free(cairo_image_surface_get_data(self->surface));
138 g_clear_pointer(&self->surface, cairo_surface_destroy);
139 g_mutex_clear(&self->frame_mutex);
141 G_OBJECT_CLASS(fl_compositor_software_parent_class)->dispose(
object);
145 FlCompositorSoftwareClass* klass) {
146 FL_COMPOSITOR_CLASS(klass)->present_layers =
147 fl_compositor_software_present_layers;
148 FL_COMPOSITOR_CLASS(klass)->get_frame_size =
156 g_mutex_init(&self->frame_mutex);
160 FlCompositorSoftware*
self = FL_COMPOSITOR_SOFTWARE(
161 g_object_new(fl_compositor_software_get_type(),
nullptr));
162 self->task_runner = FL_TASK_RUNNER(g_object_ref(task_runner));
constexpr G_BEGIN_DECLS gint64 kCompositorRenderTimeoutMicroseconds
const FlutterLayer size_t layers_count
const FlutterLayer ** layers
g_autoptr(GMutexLocker) locker
static void fl_compositor_software_class_init(FlCompositorSoftwareClass *klass)
G_DEFINE_TYPE(FlCompositorSoftware, fl_compositor_software, fl_compositor_get_type()) static gboolean fl_compositor_software_present_layers(FlCompositor *compositor
static void fl_compositor_software_init(FlCompositorSoftware *self)
fl_task_runner_stop_wait(self->task_runner)
static void fl_compositor_software_get_frame_size(FlCompositor *compositor, size_t *width, size_t *height)
FlCompositorSoftware * fl_compositor_software_new(FlTaskRunner *task_runner)
static void fl_compositor_software_dispose(GObject *object)
static gboolean fl_compositor_software_render(FlCompositor *compositor, cairo_t *cr, GdkWindow *window, gboolean wait_for_frame)
void fl_task_runner_wait(FlTaskRunner *self, gint64 expiry_time)
FlTaskRunner * task_runner
FlCompositor parent_instance
cairo_surface_t * surface