7#include <gdk/gdkwayland.h>
40 fl_view_renderer_opengl,
41 fl_view_renderer_get_type())
44static gboolean redraw_cb(gpointer
user_data) {
47 if (
self->compositor ==
nullptr) {
48 return G_SOURCE_REMOVE;
55 GtkWidget* render_widget = GTK_WIDGET(
self);
56 GtkAllocation allocation;
59 size_t width = allocation.width * scale_factor;
60 size_t height = allocation.height * scale_factor;
61 size_t frame_width, frame_height;
63 g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&
self->frame_mutex);
67 gboolean frame_size_matches =
width == frame_width &&
height == frame_height;
68 if (
self->sized_to_content && !frame_size_matches) {
69 gtk_widget_set_size_request(render_widget, frame_width / scale_factor,
70 frame_height / scale_factor);
72 if (GTK_IS_WINDOW(toplevel)) {
77 return G_SOURCE_REMOVE;
82 return G_SOURCE_REMOVE;
95 size_t frame_width, frame_height;
98 if (frame_width ==
width && frame_height ==
height) {
102 if (g_get_monotonic_time() > expiry_time) {
104 "Timed out waiting for OpenGL frame of size %zdx%zd (have "
110 g_mutex_unlock(&
self->frame_mutex);
112 g_mutex_lock(&
self->frame_mutex);
118 FlViewRendererOpenGL*
self = FL_VIEW_RENDERER_OPENGL(widget);
120 GTK_WIDGET_CLASS(fl_view_renderer_opengl_parent_class)->realize(widget);
125 if (
self->render_context ==
nullptr) {
126 g_warning(
"Failed to create OpenGL context: %s",
error->message);
131 g_warning(
"Failed to realize OpenGL context: %s",
error->message);
132 g_clear_object(&
self->render_context);
149 FlViewRendererOpenGL*
self = FL_VIEW_RENDERER_OPENGL(widget);
155 if (
self->compositor ==
nullptr) {
162 g_mutex_lock(&
self->frame_mutex);
165 if (!
self->sized_to_content) {
169 if (
self->render_context !=
nullptr) {
175 if (
self->render_context !=
nullptr) {
179 g_mutex_unlock(&
self->frame_mutex);
188 FlViewRendererOpenGL*
self = FL_VIEW_RENDERER_OPENGL(renderer);
192 if (
self->compositor ==
nullptr) {
196 g_mutex_lock(&
self->frame_mutex);
198 g_mutex_unlock(&
self->frame_mutex);
204 g_idle_add(redraw_cb, g_object_ref(
self));
208 FlViewRendererOpenGL*
self = FL_VIEW_RENDERER_OPENGL(
object);
210 g_clear_object(&
self->engine);
211 g_clear_object(&
self->render_context);
212 g_clear_object(&
self->task_runner);
213 g_mutex_clear(&
self->frame_mutex);
215 G_OBJECT_CLASS(fl_view_renderer_opengl_parent_class)->dispose(
object);
219 FlViewRendererOpenGL*
self = FL_VIEW_RENDERER_OPENGL(
object);
226 g_clear_object(&
self->compositor);
228 G_OBJECT_CLASS(fl_view_renderer_opengl_parent_class)->finalize(
object);
232 FlViewRendererOpenGLClass* klass) {
233 GObjectClass* object_class = G_OBJECT_CLASS(klass);
237 GtkWidgetClass* widget_class = GTK_WIDGET_CLASS(klass);
241 FlViewRendererClass* renderer_class = FL_VIEW_RENDERER_CLASS(klass);
246 g_mutex_init(&
self->frame_mutex);
251 g_return_val_if_fail(FL_IS_ENGINE(
engine),
nullptr);
253 FlViewRendererOpenGL*
self = FL_VIEW_RENDERER_OPENGL(
254 g_object_new(fl_view_renderer_opengl_get_type(),
nullptr));
255 self->engine = FL_ENGINE(g_object_ref(
engine));
g_autoptr(FlEngine) engine
FlCompositorOpenGL * fl_compositor_opengl_new(FlOpenGLManager *opengl_manager, gboolean shareable)
void fl_compositor_opengl_get_frame_size(FlCompositorOpenGL *self, size_t *width, size_t *height)
gboolean fl_compositor_opengl_render(FlCompositorOpenGL *self, cairo_t *cr, GdkWindow *window)
gboolean fl_compositor_opengl_composite_layers(FlCompositorOpenGL *self, const FlutterLayer **layers, size_t layers_count)
G_BEGIN_DECLS gboolean shareable
FlTaskRunner * fl_engine_get_task_runner(FlEngine *self)
FlOpenGLManager * fl_engine_get_opengl_manager(FlEngine *self)
const uint8_t uint32_t uint32_t GError ** error
void fl_task_runner_stop_wait(FlTaskRunner *self)
void fl_task_runner_wait(FlTaskRunner *self, gint64 expiry_time)
const FlutterLayer size_t layers_count
const FlutterLayer ** layers
void fl_view_renderer_notify_frame(FlViewRenderer *self)
void fl_view_renderer_paint_background(FlViewRenderer *self, cairo_t *cr)
static void fl_view_renderer_opengl_class_init(FlViewRendererOpenGLClass *klass)
static void fl_view_renderer_opengl_present_layers(FlViewRenderer *renderer, const FlutterLayer **layers, size_t layers_count)
static gboolean fl_view_renderer_opengl_draw(GtkWidget *widget, cairo_t *cr)
static void fl_view_renderer_opengl_finalize(GObject *object)
static void fl_view_renderer_opengl_dispose(GObject *object)
FlViewRendererOpenGL * fl_view_renderer_opengl_new(FlEngine *engine, gboolean sized_to_content)
static constexpr gint64 kRenderTimeoutMicroseconds
static void fl_view_renderer_opengl_init(FlViewRendererOpenGL *self)
G_DEFINE_TYPE(FlViewRendererOpenGL, fl_view_renderer_opengl, fl_view_renderer_get_type()) static gboolean redraw_cb(gpointer user_data)
static void fl_view_renderer_opengl_realize(GtkWidget *widget)
static void wait_for_frame(FlViewRendererOpenGL *self, GdkWindow *window, gint scale_factor)
G_BEGIN_DECLS gboolean sized_to_content
GdkDisplay * gtk_widget_get_display(GtkWidget *widget)
void gtk_widget_queue_draw(GtkWidget *widget)
void gtk_window_resize(GtkWindow *window, gint width, gint height)
void gdk_gl_context_clear_current(GdkGLContext *context)
int gdk_window_get_width(GdkWindow *window)
void gtk_widget_get_allocation(GtkWidget *widget, GtkAllocation *allocation)
gint gdk_window_get_scale_factor(GdkWindow *window)
void gdk_gl_context_make_current(GdkGLContext *context)
int gdk_window_get_height(GdkWindow *window)
GtkWidget * gtk_widget_get_toplevel(GtkWidget *widget)
GdkGLContext * gdk_window_create_gl_context(GdkWindow *window, GError **error)
void gdk_gl_context_realize(GdkGLContext *context)
GdkWindow * gtk_widget_get_window(GtkWidget *widget)
gint gtk_widget_get_scale_factor(GtkWidget *widget)
FlViewRenderer parent_instance
FlCompositorOpenGL * compositor
FlTaskRunner * task_runner
GdkGLContext * render_context
gboolean sized_to_content