1 | /* gskgldriverprivate.h |
2 | * |
3 | * Copyright 2020 Christian Hergert <chergert@redhat.com> |
4 | * |
5 | * This file is free software; you can redistribute it and/or modify it under |
6 | * the terms of the GNU Lesser General Public License as published by the Free |
7 | * Software Foundation; either version 2.1 of the License, or (at your option) |
8 | * any later version. |
9 | * |
10 | * This file is distributed in the hope that it will be useful, but WITHOUT |
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public |
13 | * License for more details. |
14 | * |
15 | * You should have received a copy of the GNU General Public License along |
16 | * with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | * |
18 | * SPDX-License-Identifier: LGPL-2.1-or-later |
19 | */ |
20 | |
21 | #ifndef __GSK_GL_DRIVER_PRIVATE_H__ |
22 | #define __GSK_GL_DRIVER_PRIVATE_H__ |
23 | |
24 | #include <gdk/gdkgltextureprivate.h> |
25 | |
26 | #include "gskgltypesprivate.h" |
27 | #include "gskgltextureprivate.h" |
28 | |
29 | G_BEGIN_DECLS |
30 | |
31 | enum { |
32 | UNIFORM_SHARED_ALPHA, |
33 | UNIFORM_SHARED_SOURCE, |
34 | UNIFORM_SHARED_CLIP_RECT, |
35 | UNIFORM_SHARED_VIEWPORT, |
36 | UNIFORM_SHARED_PROJECTION, |
37 | UNIFORM_SHARED_MODELVIEW, |
38 | |
39 | UNIFORM_SHARED_LAST |
40 | }; |
41 | |
42 | enum { |
43 | UNIFORM_CUSTOM_SIZE = UNIFORM_SHARED_LAST, |
44 | UNIFORM_CUSTOM_TEXTURE1, |
45 | UNIFORM_CUSTOM_TEXTURE2, |
46 | UNIFORM_CUSTOM_TEXTURE3, |
47 | UNIFORM_CUSTOM_TEXTURE4, |
48 | UNIFORM_CUSTOM_ARG0, |
49 | UNIFORM_CUSTOM_ARG1, |
50 | UNIFORM_CUSTOM_ARG2, |
51 | UNIFORM_CUSTOM_ARG3, |
52 | UNIFORM_CUSTOM_ARG4, |
53 | UNIFORM_CUSTOM_ARG5, |
54 | UNIFORM_CUSTOM_ARG6, |
55 | UNIFORM_CUSTOM_ARG7, |
56 | |
57 | UNIFORM_CUSTOM_LAST |
58 | }; |
59 | |
60 | typedef struct { |
61 | gconstpointer pointer; |
62 | float scale_x; |
63 | float scale_y; |
64 | int filter; |
65 | int pointer_is_child; |
66 | graphene_rect_t parent_rect; /* Valid when pointer_is_child */ |
67 | } GskTextureKey; |
68 | |
69 | #define GSK_GL_NO_UNIFORMS CONCAT_EXPANDED(UNIFORM_INVALID_,__COUNTER__) |
70 | #define CONCAT_EXPANDED(a,b) CONCAT_EXPANDED2(a,b) |
71 | #define CONCAT_EXPANDED2(a,b) a##b |
72 | #define GSK_GL_ADD_UNIFORM(pos, KEY, name) UNIFORM_##KEY = UNIFORM_SHARED_LAST + pos, |
73 | #define GSK_GL_DEFINE_PROGRAM(name, resource, uniforms) enum { uniforms }; |
74 | # include "gskglprograms.defs" |
75 | #undef GSK_GL_DEFINE_PROGRAM |
76 | #undef GSK_GL_ADD_UNIFORM |
77 | #undef GSK_GL_NO_UNIFORMS |
78 | #undef CONCAT_EXPANDED |
79 | #undef CONCAT_EXPANDED2 |
80 | |
81 | #define GSK_TYPE_GL_DRIVER (gsk_gl_driver_get_type()) |
82 | |
83 | G_DECLARE_FINAL_TYPE (GskGLDriver, gsk_gl_driver, GSK, GL_DRIVER, GObject) |
84 | |
85 | struct _GskGLRenderTarget |
86 | { |
87 | guint framebuffer_id; |
88 | guint texture_id; |
89 | int min_filter; |
90 | int mag_filter; |
91 | int format; |
92 | int width; |
93 | int height; |
94 | }; |
95 | |
96 | struct _GskGLDriver |
97 | { |
98 | GObject parent_instance; |
99 | |
100 | GskGLCommandQueue *shared_command_queue; |
101 | GskGLCommandQueue *command_queue; |
102 | |
103 | GskGLGlyphLibrary *glyphs; |
104 | GskGLIconLibrary *icons; |
105 | GskGLShadowLibrary *shadows; |
106 | |
107 | GArray *texture_pool; |
108 | GHashTable *textures; |
109 | GHashTable *key_to_texture_id; |
110 | GHashTable *texture_id_to_key; |
111 | |
112 | GPtrArray *atlases; |
113 | |
114 | GHashTable *shader_cache; |
115 | |
116 | GArray *autorelease_framebuffers; |
117 | GPtrArray *render_targets; |
118 | |
119 | #define GSK_GL_NO_UNIFORMS |
120 | #define GSK_GL_ADD_UNIFORM(pos, KEY, name) |
121 | #define GSK_GL_DEFINE_PROGRAM(name, resource, uniforms) \ |
122 | GskGLProgram *name ## _no_clip; \ |
123 | GskGLProgram *name ## _rect_clip; \ |
124 | GskGLProgram *name; |
125 | # include "gskglprograms.defs" |
126 | #undef GSK_GL_NO_UNIFORMS |
127 | #undef GSK_GL_ADD_UNIFORM |
128 | #undef GSK_GL_DEFINE_PROGRAM |
129 | |
130 | gint64 current_frame_id; |
131 | |
132 | /* Used to reduce number of comparisons */ |
133 | guint stamps[UNIFORM_SHARED_LAST]; |
134 | |
135 | guint debug : 1; |
136 | guint in_frame : 1; |
137 | }; |
138 | |
139 | GskGLDriver * gsk_gl_driver_for_display (GdkDisplay *display, |
140 | gboolean debug_shaders, |
141 | GError **error); |
142 | GskGLCommandQueue * gsk_gl_driver_create_command_queue (GskGLDriver *self, |
143 | GdkGLContext *context); |
144 | GdkGLContext * gsk_gl_driver_get_context (GskGLDriver *self); |
145 | gboolean gsk_gl_driver_create_render_target (GskGLDriver *self, |
146 | int width, |
147 | int height, |
148 | int format, |
149 | int min_filter, |
150 | int mag_filter, |
151 | GskGLRenderTarget **render_target); |
152 | guint gsk_gl_driver_release_render_target (GskGLDriver *self, |
153 | GskGLRenderTarget *render_target, |
154 | gboolean release_texture); |
155 | void gsk_gl_driver_begin_frame (GskGLDriver *self, |
156 | GskGLCommandQueue *command_queue); |
157 | void gsk_gl_driver_end_frame (GskGLDriver *self); |
158 | void gsk_gl_driver_after_frame (GskGLDriver *self); |
159 | GdkTexture * gsk_gl_driver_create_gdk_texture (GskGLDriver *self, |
160 | guint texture_id); |
161 | void gsk_gl_driver_cache_texture (GskGLDriver *self, |
162 | const GskTextureKey *key, |
163 | guint texture_id); |
164 | guint gsk_gl_driver_load_texture (GskGLDriver *self, |
165 | GdkTexture *texture, |
166 | int min_filter, |
167 | int mag_filter); |
168 | GskGLTexture * gsk_gl_driver_create_texture (GskGLDriver *self, |
169 | float width, |
170 | float height, |
171 | int format, |
172 | int min_filter, |
173 | int mag_filter); |
174 | void gsk_gl_driver_release_texture (GskGLDriver *self, |
175 | GskGLTexture *texture); |
176 | void gsk_gl_driver_release_texture_by_id (GskGLDriver *self, |
177 | guint texture_id); |
178 | GskGLTexture * gsk_gl_driver_mark_texture_permanent (GskGLDriver *self, |
179 | guint texture_id); |
180 | void gsk_gl_driver_add_texture_slices (GskGLDriver *self, |
181 | GdkTexture *texture, |
182 | GskGLTextureSlice **out_slices, |
183 | guint *out_n_slices); |
184 | GskGLProgram * gsk_gl_driver_lookup_shader (GskGLDriver *self, |
185 | GskGLShader *shader, |
186 | GError **error); |
187 | GskGLTextureAtlas * gsk_gl_driver_create_atlas (GskGLDriver *self); |
188 | |
189 | #ifdef G_ENABLE_DEBUG |
190 | void gsk_gl_driver_save_atlases_to_png (GskGLDriver *self, |
191 | const char *directory); |
192 | #endif |
193 | |
194 | static inline GskGLTexture * |
195 | gsk_gl_driver_get_texture_by_id (GskGLDriver *self, |
196 | guint texture_id) |
197 | { |
198 | return g_hash_table_lookup (hash_table: self->textures, GUINT_TO_POINTER (texture_id)); |
199 | } |
200 | |
201 | /** |
202 | * gsk_gl_driver_lookup_texture: |
203 | * @self: a `GskGLDriver` |
204 | * @key: the key for the texture |
205 | * |
206 | * Looks up a texture in the texture cache by @key. |
207 | * |
208 | * If the texture could not be found, then zero is returned. |
209 | * |
210 | * Returns: a positive integer if the texture was found; otherwise 0. |
211 | */ |
212 | static inline guint |
213 | gsk_gl_driver_lookup_texture (GskGLDriver *self, |
214 | const GskTextureKey *key) |
215 | { |
216 | gpointer id; |
217 | |
218 | if (g_hash_table_lookup_extended (hash_table: self->key_to_texture_id, lookup_key: key, NULL, value: &id)) |
219 | { |
220 | GskGLTexture *texture = g_hash_table_lookup (hash_table: self->textures, key: id); |
221 | |
222 | if (texture != NULL) |
223 | texture->last_used_in_frame = self->current_frame_id; |
224 | |
225 | return GPOINTER_TO_UINT (id); |
226 | } |
227 | |
228 | return 0; |
229 | } |
230 | |
231 | static inline void |
232 | gsk_gl_driver_slice_texture (GskGLDriver *self, |
233 | GdkTexture *texture, |
234 | GskGLTextureSlice **out_slices, |
235 | guint *out_n_slices) |
236 | { |
237 | GskGLTexture *t; |
238 | |
239 | if ((t = gdk_texture_get_render_data (self: texture, key: self))) |
240 | { |
241 | *out_slices = t->slices; |
242 | *out_n_slices = t->n_slices; |
243 | return; |
244 | } |
245 | |
246 | gsk_gl_driver_add_texture_slices (self, texture, out_slices, out_n_slices); |
247 | } |
248 | |
249 | G_END_DECLS |
250 | |
251 | #endif /* __GSK_GL_DRIVER_PRIVATE_H__ */ |
252 | |