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
29G_BEGIN_DECLS
30
31enum {
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
42enum {
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
60typedef 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
83G_DECLARE_FINAL_TYPE (GskGLDriver, gsk_gl_driver, GSK, GL_DRIVER, GObject)
84
85struct _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
96struct _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
139GskGLDriver * gsk_gl_driver_for_display (GdkDisplay *display,
140 gboolean debug_shaders,
141 GError **error);
142GskGLCommandQueue * gsk_gl_driver_create_command_queue (GskGLDriver *self,
143 GdkGLContext *context);
144GdkGLContext * gsk_gl_driver_get_context (GskGLDriver *self);
145gboolean 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);
152guint gsk_gl_driver_release_render_target (GskGLDriver *self,
153 GskGLRenderTarget *render_target,
154 gboolean release_texture);
155void gsk_gl_driver_begin_frame (GskGLDriver *self,
156 GskGLCommandQueue *command_queue);
157void gsk_gl_driver_end_frame (GskGLDriver *self);
158void gsk_gl_driver_after_frame (GskGLDriver *self);
159GdkTexture * gsk_gl_driver_create_gdk_texture (GskGLDriver *self,
160 guint texture_id);
161void gsk_gl_driver_cache_texture (GskGLDriver *self,
162 const GskTextureKey *key,
163 guint texture_id);
164guint gsk_gl_driver_load_texture (GskGLDriver *self,
165 GdkTexture *texture,
166 int min_filter,
167 int mag_filter);
168GskGLTexture * gsk_gl_driver_create_texture (GskGLDriver *self,
169 float width,
170 float height,
171 int format,
172 int min_filter,
173 int mag_filter);
174void gsk_gl_driver_release_texture (GskGLDriver *self,
175 GskGLTexture *texture);
176void gsk_gl_driver_release_texture_by_id (GskGLDriver *self,
177 guint texture_id);
178GskGLTexture * gsk_gl_driver_mark_texture_permanent (GskGLDriver *self,
179 guint texture_id);
180void gsk_gl_driver_add_texture_slices (GskGLDriver *self,
181 GdkTexture *texture,
182 GskGLTextureSlice **out_slices,
183 guint *out_n_slices);
184GskGLProgram * gsk_gl_driver_lookup_shader (GskGLDriver *self,
185 GskGLShader *shader,
186 GError **error);
187GskGLTextureAtlas * gsk_gl_driver_create_atlas (GskGLDriver *self);
188
189#ifdef G_ENABLE_DEBUG
190void gsk_gl_driver_save_atlases_to_png (GskGLDriver *self,
191 const char *directory);
192#endif
193
194static inline GskGLTexture *
195gsk_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 */
212static inline guint
213gsk_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
231static inline void
232gsk_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
249G_END_DECLS
250
251#endif /* __GSK_GL_DRIVER_PRIVATE_H__ */
252

source code of gtk/gsk/gl/gskgldriverprivate.h