| Flutter Linux Embedder |

fl_gl_area.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 "flutter/shell/platform/linux/fl_gl_area.h"
6
7 #include <epoxy/gl.h>
8
9 struct _FlGLArea {
10 GtkWidget parent_instance;
11
12 GdkGLContext* context;
13
14 GPtrArray* textures;
15 };
16
17 G_DEFINE_TYPE(FlGLArea, fl_gl_area, GTK_TYPE_WIDGET)
18
19 static void fl_gl_area_dispose(GObject* gobject) {
20 FlGLArea* self = FL_GL_AREA(gobject);
21
22 g_clear_object(&self->context);
23 g_clear_pointer(&self->textures, g_ptr_array_unref);
24
25 G_OBJECT_CLASS(fl_gl_area_parent_class)->dispose(gobject);
26 }
27
28 // Implements GtkWidget::realize.
29 static void fl_gl_area_realize(GtkWidget* widget) {
30 GtkAllocation allocation;
31 gtk_widget_get_allocation(widget, &allocation);
32
33 gtk_widget_set_realized(widget, TRUE);
34
35 GdkWindowAttr attributes;
36 attributes.window_type = GDK_WINDOW_CHILD;
37 attributes.x = allocation.x;
38 attributes.y = allocation.y;
39 attributes.width = allocation.width;
40 attributes.height = allocation.height;
41 attributes.wclass = GDK_INPUT_OUTPUT;
42 attributes.visual = gtk_widget_get_visual(widget);
43 attributes.event_mask = gtk_widget_get_events(widget);
44 gint attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
45 GdkWindow* window = gdk_window_new(gtk_widget_get_parent_window(widget),
46 &attributes, attributes_mask);
47 gtk_widget_set_window(widget, window);
48 gtk_widget_register_window(widget, window);
49 }
50
51 // Implements GtkWidget::unrealize.
52 static void fl_gl_area_unrealize(GtkWidget* widget) {
53 FlGLArea* self = FL_GL_AREA(widget);
54 gdk_gl_context_make_current(self->context);
55 g_clear_pointer(&self->textures, g_ptr_array_unref);
56
57 /* Make sure to unset the context if current */
58 if (self->context == gdk_gl_context_get_current()) {
59 gdk_gl_context_clear_current();
60 }
61
62 GTK_WIDGET_CLASS(fl_gl_area_parent_class)->unrealize(widget);
63 }
64
65 // Implements GtkWidget::size_allocate.
66 static void fl_gl_area_size_allocate(GtkWidget* widget,
67 GtkAllocation* allocation) {
68 gtk_widget_set_allocation(widget, allocation);
69
70 if (gtk_widget_get_has_window(widget)) {
71 if (gtk_widget_get_realized(widget)) {
72 gdk_window_move_resize(gtk_widget_get_window(widget), allocation->x,
73 allocation->y, allocation->width,
74 allocation->height);
75 }
76 }
77 }
78
79 // Implements GtkWidget::draw.
80 static gboolean fl_gl_area_draw(GtkWidget* widget, cairo_t* cr) {
81 FlGLArea* self = FL_GL_AREA(widget);
82
83 gdk_gl_context_make_current(self->context);
84
85 gint scale = gtk_widget_get_scale_factor(widget);
86
87 if (self->textures == nullptr) {
88 return TRUE;
89 }
90
91 for (guint i = 0; i < self->textures->len; i++) {
92 FlBackingStoreProvider* texture =
93 FL_BACKING_STORE_PROVIDER(g_ptr_array_index(self->textures, i));
94 uint32_t texture_id = fl_backing_store_provider_get_gl_texture_id(texture);
95 GdkRectangle geometry = fl_backing_store_provider_get_geometry(texture);
96 gdk_cairo_draw_from_gl(cr, gtk_widget_get_window(widget), texture_id,
97 GL_TEXTURE, scale, geometry.x, geometry.y,
98 geometry.width, geometry.height);
99 }
100
101 return TRUE;
102 }
103
104 static void fl_gl_area_class_init(FlGLAreaClass* klass) {
105 GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
106 gobject_class->dispose = fl_gl_area_dispose;
107
108 GtkWidgetClass* widget_class = GTK_WIDGET_CLASS(klass);
109 widget_class->realize = fl_gl_area_realize;
110 widget_class->unrealize = fl_gl_area_unrealize;
111 widget_class->size_allocate = fl_gl_area_size_allocate;
112 widget_class->draw = fl_gl_area_draw;
113
114 gtk_widget_class_set_accessible_role(widget_class, ATK_ROLE_DRAWING_AREA);
115 }
116
117 static void fl_gl_area_init(FlGLArea* self) {
118 gtk_widget_set_app_paintable(GTK_WIDGET(self), TRUE);
119 }
120
121 GtkWidget* fl_gl_area_new(GdkGLContext* context) {
122 g_return_val_if_fail(GDK_IS_GL_CONTEXT(context), nullptr);
123 FlGLArea* area =
124 reinterpret_cast<FlGLArea*>(g_object_new(fl_gl_area_get_type(), nullptr));
125 area->context = GDK_GL_CONTEXT(g_object_ref(context));
126 return GTK_WIDGET(area);
127 }
128
129 void fl_gl_area_queue_render(FlGLArea* self, GPtrArray* textures) {
130 g_return_if_fail(FL_IS_GL_AREA(self));
131
132 g_clear_pointer(&self->textures, g_ptr_array_unref);
133 self->textures = g_ptr_array_ref(textures);
134
135 gtk_widget_queue_draw(GTK_WIDGET(self));
136 }
fl_gl_area_class_init
static void fl_gl_area_class_init(FlGLAreaClass *klass)
Definition: fl_gl_area.cc:104
_FlGLArea
Definition: fl_gl_area.cc:9
fl_gl_area_new
GtkWidget * fl_gl_area_new(GdkGLContext *context)
Definition: fl_gl_area.cc:121
fl_gl_area_unrealize
static void fl_gl_area_unrealize(GtkWidget *widget)
Definition: fl_gl_area.cc:52
_FlGLArea::parent_instance
GtkWidget parent_instance
Definition: fl_gl_area.cc:10
_FlGLArea::context
GdkGLContext * context
Definition: fl_gl_area.cc:12
fl_gl_area_draw
static gboolean fl_gl_area_draw(GtkWidget *widget, cairo_t *cr)
Definition: fl_gl_area.cc:80
fl_backing_store_provider_get_gl_texture_id
uint32_t fl_backing_store_provider_get_gl_texture_id(FlBackingStoreProvider *self)
Definition: fl_backing_store_provider.cc:71
G_DEFINE_TYPE
G_DEFINE_TYPE(FlBasicMessageChannelResponseHandle, fl_basic_message_channel_response_handle, G_TYPE_OBJECT) static void fl_basic_message_channel_response_handle_dispose(GObject *object)
Definition: fl_basic_message_channel.cc:37
TRUE
return TRUE
Definition: fl_pixel_buffer_texture_test.cc:53
_FlGLArea::textures
GPtrArray * textures
Definition: fl_gl_area.cc:14
fl_gl_area.h
self
GdkEvent FlView * self
Definition: fl_view.cc:100
fl_gl_area_queue_render
void fl_gl_area_queue_render(FlGLArea *self, GPtrArray *textures)
Definition: fl_gl_area.cc:129
fl_backing_store_provider_get_geometry
GdkRectangle fl_backing_store_provider_get_geometry(FlBackingStoreProvider *self)
Definition: fl_backing_store_provider.cc:104
fl_gl_area_init
static void fl_gl_area_init(FlGLArea *self)
Definition: fl_gl_area.cc:117
fl_gl_area_realize
static void fl_gl_area_realize(GtkWidget *widget)
Definition: fl_gl_area.cc:29
fl_gl_area_dispose
static void fl_gl_area_dispose(GObject *gobject)
Definition: fl_gl_area.cc:19
texture_id
int64_t texture_id
Definition: texture_registrar_unittests.cc:24
fl_gl_area_size_allocate
static void fl_gl_area_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
Definition: fl_gl_area.cc:66