| // Copyright 2013 The Flutter Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "flutter/shell/platform/linux/fl_renderer_gdk.h" | |
| struct _FlRendererGdk { | |
| FlRenderer parent_instance; | |
| // Window being rendered on. | |
| GdkWindow* window; | |
| // OpenGL rendering context used by GDK. | |
| GdkGLContext* gdk_context; | |
| // Main OpenGL rendering context used by Flutter. | |
| GdkGLContext* main_context; | |
| // Secondary OpenGL rendering context used by Flutter. | |
| GdkGLContext* resource_context; | |
| }; | |
| G_DEFINE_TYPE(FlRendererGdk, fl_renderer_gdk, fl_renderer_get_type()) | |
| // Implements FlRenderer::make_current. | |
| static void fl_renderer_gdk_make_current(FlRenderer* renderer) { | |
| FlRendererGdk* self = FL_RENDERER_GDK(renderer); | |
| gdk_gl_context_make_current(self->main_context); | |
| } | |
| // Implements FlRenderer::make_resource_current. | |
| static void fl_renderer_gdk_make_resource_current(FlRenderer* renderer) { | |
| FlRendererGdk* self = FL_RENDERER_GDK(renderer); | |
| gdk_gl_context_make_current(self->resource_context); | |
| } | |
| // Implements FlRenderer::clear_current. | |
| static void fl_renderer_gdk_clear_current(FlRenderer* renderer) { | |
| gdk_gl_context_clear_current(); | |
| } | |
| // Implements FlRenderer::get_refresh_rate. | |
| static gdouble fl_renderer_gdk_get_refresh_rate(FlRenderer* renderer) { | |
| FlRendererGdk* self = FL_RENDERER_GDK(renderer); | |
| GdkDisplay* display = gdk_window_get_display(self->window); | |
| GdkMonitor* monitor = | |
| gdk_display_get_monitor_at_window(display, self->window); | |
| if (monitor == nullptr) { | |
| return -1.0; | |
| } | |
| int refresh_rate = gdk_monitor_get_refresh_rate(monitor); | |
| if (refresh_rate <= 0) { | |
| return -1.0; | |
| } | |
| // the return value is in milli-hertz, convert to hertz | |
| return static_cast<gdouble>(refresh_rate) / 1000.0; | |
| } | |
| static void fl_renderer_gdk_dispose(GObject* object) { | |
| FlRendererGdk* self = FL_RENDERER_GDK(object); | |
| g_clear_object(&self->gdk_context); | |
| g_clear_object(&self->main_context); | |
| g_clear_object(&self->resource_context); | |
| G_OBJECT_CLASS(fl_renderer_gdk_parent_class)->dispose(object); | |
| } | |
| static void fl_renderer_gdk_class_init(FlRendererGdkClass* klass) { | |
| G_OBJECT_CLASS(klass)->dispose = fl_renderer_gdk_dispose; | |
| FL_RENDERER_CLASS(klass)->make_current = fl_renderer_gdk_make_current; | |
| FL_RENDERER_CLASS(klass)->make_resource_current = | |
| fl_renderer_gdk_make_resource_current; | |
| FL_RENDERER_CLASS(klass)->clear_current = fl_renderer_gdk_clear_current; | |
| FL_RENDERER_CLASS(klass)->get_refresh_rate = fl_renderer_gdk_get_refresh_rate; | |
| } | |
| static void fl_renderer_gdk_init(FlRendererGdk* self) {} | |
| FlRendererGdk* fl_renderer_gdk_new() { | |
| FlRendererGdk* self = | |
| FL_RENDERER_GDK(g_object_new(fl_renderer_gdk_get_type(), nullptr)); | |
| return self; | |
| } | |
| void fl_renderer_gdk_set_window(FlRendererGdk* self, GdkWindow* window) { | |
| g_return_if_fail(FL_IS_RENDERER_GDK(self)); | |
| g_assert(self->window == nullptr); | |
| self->window = window; | |
| } | |
| gboolean fl_renderer_gdk_create_contexts(FlRendererGdk* self, GError** error) { | |
| g_return_val_if_fail(FL_IS_RENDERER_GDK(self), FALSE); | |
| self->gdk_context = gdk_window_create_gl_context(self->window, error); | |
| if (self->gdk_context == nullptr) { | |
| return FALSE; | |
| } | |
| if (!gdk_gl_context_realize(self->gdk_context, error)) { | |
| return FALSE; | |
| } | |
| self->main_context = gdk_window_create_gl_context(self->window, error); | |
| if (self->main_context == nullptr) { | |
| return FALSE; | |
| } | |
| if (!gdk_gl_context_realize(self->main_context, error)) { | |
| return FALSE; | |
| } | |
| self->resource_context = gdk_window_create_gl_context(self->window, error); | |
| if (self->resource_context == nullptr) { | |
| return FALSE; | |
| } | |
| if (!gdk_gl_context_realize(self->resource_context, error)) { | |
| return FALSE; | |
| } | |
| return TRUE; | |
| } | |
| GdkGLContext* fl_renderer_gdk_get_context(FlRendererGdk* self) { | |
| g_return_val_if_fail(FL_IS_RENDERER_GDK(self), nullptr); | |
| return self->gdk_context; | |
| } |