1 /* gskngldriverprivate.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_NGL_DRIVER_PRIVATE_H__
22 #define __GSK_NGL_DRIVER_PRIVATE_H__
23
24 #include <gdk/gdkgltextureprivate.h>
25
26 #include "gskngltypesprivate.h"
27 #include "gskngltexturepoolprivate.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_NGL_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_NGL_ADD_UNIFORM(pos, KEY, name) UNIFORM_##KEY = UNIFORM_SHARED_LAST + pos,
73 #define GSK_NGL_DEFINE_PROGRAM(name, resource, uniforms) enum { uniforms };
74 # include "gsknglprograms.defs"
75 #undef GSK_NGL_DEFINE_PROGRAM
76 #undef GSK_NGL_ADD_UNIFORM
77 #undef GSK_NGL_NO_UNIFORMS
78 #undef CONCAT_EXPANDED
79 #undef CONCAT_EXPANDED2
80
81 #define GSK_TYPE_NGL_DRIVER (gsk_ngl_driver_get_type())
82
83 G_DECLARE_FINAL_TYPE (GskNglDriver, gsk_ngl_driver, GSK, NGL_DRIVER, GObject)
84
85 struct _GskNglRenderTarget
86 {
87 guint framebuffer_id;
88 guint texture_id;
89 int min_filter;
90 int mag_filter;
91 int width;
92 int height;
93 };
94
95 struct _GskNglDriver
96 {
97 GObject parent_instance;
98
99 GskNglCommandQueue *shared_command_queue;
100 GskNglCommandQueue *command_queue;
101
102 GskNglTexturePool texture_pool;
103
104 GskNglGlyphLibrary *glyphs;
105 GskNglIconLibrary *icons;
106 GskNglShadowLibrary *shadows;
107
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_NGL_NO_UNIFORMS
120 #define GSK_NGL_ADD_UNIFORM(pos, KEY, name)
121 #define GSK_NGL_DEFINE_PROGRAM(name, resource, uniforms) \
122 GskNglProgram *name ## _no_clip; \
123 GskNglProgram *name ## _rect_clip; \
124 GskNglProgram *name;
125 # include "gsknglprograms.defs"
126 #undef GSK_NGL_NO_UNIFORMS
127 #undef GSK_NGL_ADD_UNIFORM
128 #undef GSK_NGL_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 GskNglDriver *gsk_ngl_driver_for_display (GdkDisplay *display,
140 gboolean debug_shaders,
141 GError **error);
142 GskNglCommandQueue *gsk_ngl_driver_create_command_queue (GskNglDriver *self,
143 GdkGLContext *context);
144 GdkGLContext *gsk_ngl_driver_get_context (GskNglDriver *self);
145 gboolean gsk_ngl_driver_create_render_target (GskNglDriver *self,
146 int width,
147 int height,
148 int min_filter,
149 int mag_filter,
150 GskNglRenderTarget **render_target);
151 guint gsk_ngl_driver_release_render_target (GskNglDriver *self,
152 GskNglRenderTarget *render_target,
153 gboolean release_texture);
154 void gsk_ngl_driver_begin_frame (GskNglDriver *self,
155 GskNglCommandQueue *command_queue);
156 void gsk_ngl_driver_end_frame (GskNglDriver *self);
157 void gsk_ngl_driver_after_frame (GskNglDriver *self);
158 GdkTexture *gsk_ngl_driver_create_gdk_texture (GskNglDriver *self,
159 guint texture_id);
160 void gsk_ngl_driver_cache_texture (GskNglDriver *self,
161 const GskTextureKey *key,
162 guint texture_id);
163 guint gsk_ngl_driver_load_texture (GskNglDriver *self,
164 GdkTexture *texture,
165 int min_filter,
166 int mag_filter);
167 GskNglTexture *gsk_ngl_driver_create_texture (GskNglDriver *self,
168 float width,
169 float height,
170 int min_filter,
171 int mag_filter);
172 void gsk_ngl_driver_release_texture (GskNglDriver *self,
173 GskNglTexture *texture);
174 void gsk_ngl_driver_release_texture_by_id (GskNglDriver *self,
175 guint texture_id);
176 GskNglTexture *gsk_ngl_driver_mark_texture_permanent (GskNglDriver *self,
177 guint texture_id);
178 void gsk_ngl_driver_add_texture_slices (GskNglDriver *self,
179 GdkTexture *texture,
180 GskNglTextureSlice **out_slices,
181 guint *out_n_slices);
182 GskNglProgram *gsk_ngl_driver_lookup_shader (GskNglDriver *self,
183 GskGLShader *shader,
184 GError **error);
185 GskNglTextureAtlas *gsk_ngl_driver_create_atlas (GskNglDriver *self);
186
187 #ifdef G_ENABLE_DEBUG
188 void gsk_ngl_driver_save_atlases_to_png (GskNglDriver *self,
189 const char *directory);
190 #endif
191
192 static inline GskNglTexture *
gsk_ngl_driver_get_texture_by_id(GskNglDriver * self,guint texture_id)193 gsk_ngl_driver_get_texture_by_id (GskNglDriver *self,
194 guint texture_id)
195 {
196 return g_hash_table_lookup (self->textures, GUINT_TO_POINTER (texture_id));
197 }
198
199 /**
200 * gsk_ngl_driver_lookup_texture:
201 * @self: a `GskNglDriver`
202 * @key: the key for the texture
203 *
204 * Looks up a texture in the texture cache by @key.
205 *
206 * If the texture could not be found, then zero is returned.
207 *
208 * Returns: a positive integer if the texture was found; otherwise 0.
209 */
210 static inline guint
gsk_ngl_driver_lookup_texture(GskNglDriver * self,const GskTextureKey * key)211 gsk_ngl_driver_lookup_texture (GskNglDriver *self,
212 const GskTextureKey *key)
213 {
214 gpointer id;
215
216 if (g_hash_table_lookup_extended (self->key_to_texture_id, key, NULL, &id))
217 {
218 GskNglTexture *texture = g_hash_table_lookup (self->textures, id);
219
220 if (texture != NULL)
221 texture->last_used_in_frame = self->current_frame_id;
222
223 return GPOINTER_TO_UINT (id);
224 }
225
226 return 0;
227 }
228
229 static inline void
gsk_ngl_driver_slice_texture(GskNglDriver * self,GdkTexture * texture,GskNglTextureSlice ** out_slices,guint * out_n_slices)230 gsk_ngl_driver_slice_texture (GskNglDriver *self,
231 GdkTexture *texture,
232 GskNglTextureSlice **out_slices,
233 guint *out_n_slices)
234 {
235 GskNglTexture *t;
236
237 if ((t = gdk_texture_get_render_data (texture, self)))
238 {
239 *out_slices = t->slices;
240 *out_n_slices = t->n_slices;
241 return;
242 }
243
244 gsk_ngl_driver_add_texture_slices (self, texture, out_slices, out_n_slices);
245 }
246
247 G_END_DECLS
248
249 #endif /* __GSK_NGL_DRIVER_PRIVATE_H__ */
250