7 #include <gdk/gdkwayland.h>
41 G_DEFINE_TYPE(FlViewRenderer, fl_view_renderer, GTK_TYPE_DRAWING_AREA)
47 if (self->compositor ==
nullptr) {
48 return G_SOURCE_REMOVE;
51 if (!self->have_first_frame) {
52 self->have_first_frame =
TRUE;
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;
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)) {
74 gtk_window_resize(GTK_WINDOW(toplevel), 1, 1);
76 return G_SOURCE_REMOVE;
79 gtk_widget_queue_draw(render_widget);
81 return G_SOURCE_REMOVE;
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);
94 if (!gdk_gl_context_realize(self->render_context, &
error)) {
95 g_warning(
"Failed to realize OpenGL context: %s",
error->message);
103 GDK_IS_WAYLAND_DISPLAY(gtk_widget_get_display(GTK_WIDGET(
self)));
110 self->compositor = FL_COMPOSITOR(
117 if (self->background_color->red == 0 && self->background_color->green == 0 &&
118 self->background_color->blue == 0 && self->background_color->alpha == 0) {
122 gdk_cairo_set_source_rgba(cr, self->background_color);
128 FlViewRenderer*
self = FL_VIEW_RENDERER(widget);
130 GTK_WIDGET_CLASS(fl_view_renderer_parent_class)->realize(widget);
146 FlViewRenderer*
self = FL_VIEW_RENDERER(widget);
152 if (self->compositor ==
nullptr) {
156 if (self->render_context) {
157 gdk_gl_context_make_current(self->render_context);
160 gboolean wait_for_frame = !
self->sized_to_content;
162 self->compositor, cr, gtk_widget_get_window(widget), wait_for_frame);
164 if (self->render_context) {
165 gdk_gl_context_clear_current();
172 FlViewRenderer*
self = FL_VIEW_RENDERER(
object);
174 g_clear_object(&self->render_context);
175 g_clear_object(&self->engine);
176 g_clear_pointer(&self->background_color, gdk_rgba_free);
178 G_OBJECT_CLASS(fl_view_renderer_parent_class)->dispose(
object);
182 FlViewRenderer*
self = FL_VIEW_RENDERER(
object);
189 g_clear_object(&self->compositor);
191 G_OBJECT_CLASS(fl_view_renderer_parent_class)->finalize(
object);
198 GtkWidgetClass* widget_class = GTK_WIDGET_CLASS(klass);
203 g_signal_new(
"first-frame", fl_view_renderer_get_type(),
204 G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0);
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);
215 g_return_val_if_fail(FL_IS_ENGINE(engine),
nullptr);
217 FlViewRenderer*
self =
218 FL_VIEW_RENDERER(g_object_new(fl_view_renderer_get_type(),
nullptr));
220 self->engine = FL_ENGINE(g_object_ref(engine));
227 const GdkRGBA* color) {
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);
234 const FlutterLayer**
layers,
236 g_return_if_fail(FL_IS_VIEW_RENDERER(
self));
240 if (self->compositor ==
nullptr) {
247 g_idle_add(
redraw_cb, g_object_ref(
self));
g_autoptr(FlEngine) engine
const char FlTextDirection FlAssertiveness gpointer user_data
G_DEFINE_TYPE(FlBasicMessageChannelResponseHandle, fl_basic_message_channel_response_handle, G_TYPE_OBJECT) static void fl_basic_message_channel_response_handle_dispose(GObject *object)
gboolean fl_compositor_render(FlCompositor *self, cairo_t *cr, GdkWindow *window, gboolean wait_for_frame)
void fl_compositor_get_frame_size(FlCompositor *self, size_t *width, size_t *height)
gboolean fl_compositor_present_layers(FlCompositor *self, const FlutterLayer **layers, size_t layers_count)
FlCompositorOpenGL * fl_compositor_opengl_new(FlTaskRunner *task_runner, FlOpenGLManager *opengl_manager, gboolean shareable)
FlFramebuffer double double int int height
FlFramebuffer double double int width
G_BEGIN_DECLS FlOpenGLManager gboolean shareable
const FlutterLayer size_t layers_count
const FlutterLayer ** layers
FlCompositorSoftware * fl_compositor_software_new(FlTaskRunner *task_runner)
FlOpenGLManager * fl_engine_get_opengl_manager(FlEngine *self)
FlutterRendererType fl_engine_get_renderer_type(FlEngine *self)
FlTaskRunner * fl_engine_get_task_runner(FlEngine *self)
const uint8_t uint32_t uint32_t GError ** error
static gboolean fl_view_renderer_draw(GtkWidget *widget, cairo_t *cr)
static void fl_view_renderer_dispose(GObject *object)
void fl_view_renderer_set_background_color(FlViewRenderer *self, const GdkRGBA *color)
static void fl_view_renderer_realize(GtkWidget *widget)
static gboolean redraw_cb(gpointer user_data)
static void setup_software(FlViewRenderer *self)
static void fl_view_renderer_init(FlViewRenderer *self)
static void fl_view_renderer_finalize(GObject *object)
static void setup_opengl(FlViewRenderer *self)
static void fl_view_renderer_class_init(FlViewRendererClass *klass)
static void paint_background(FlViewRenderer *self, cairo_t *cr)
FlViewRenderer * fl_view_renderer_new(FlEngine *engine, gboolean sized_to_content)
void fl_view_renderer_present_layers(FlViewRenderer *self, const FlutterLayer **layers, size_t layers_count)
static guint fl_view_renderer_signals[LAST_SIGNAL]
G_BEGIN_DECLS gboolean sized_to_content
GdkGLContext * render_context
gboolean have_first_frame
GdkRGBA * background_color
FlCompositor * compositor
gboolean sized_to_content
GtkDrawingArea parent_instance