diff options
author | Matthias Clasen <mclasen@redhat.com> | 2021-10-06 23:15:25 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2021-10-07 13:05:53 -0400 |
commit | 144f727d5aa0f77411835b910759ea3456f6063e (patch) | |
tree | d6e036c9ef7e585c57fe23186c4d31987b0772b0 /gsk/gl/gskgliconlibrary.c | |
parent | db374527873d119225f0915e26822af9ad6f73ea (diff) | |
download | gtk+-144f727d5aa0f77411835b910759ea3456f6063e.tar.gz |
Rename ngl to gl
We have only one gl renderer now, and it is
a bit odd for it not be called gl.
Diffstat (limited to 'gsk/gl/gskgliconlibrary.c')
-rw-r--r-- | gsk/gl/gskgliconlibrary.c | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/gsk/gl/gskgliconlibrary.c b/gsk/gl/gskgliconlibrary.c new file mode 100644 index 0000000000..f4686fd877 --- /dev/null +++ b/gsk/gl/gskgliconlibrary.c @@ -0,0 +1,216 @@ +/* gskgliconlibrary.c + * + * Copyright 2020 Christian Hergert <chergert@redhat.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#include "config.h" + +#include <gdk/gdkglcontextprivate.h> +#include <gdk/gdkmemoryformatprivate.h> +#include <gdk/gdkprofilerprivate.h> +#include <gdk/gdktextureprivate.h> + +#include "gskglcommandqueueprivate.h" +#include "gskgldriverprivate.h" +#include "gskgliconlibraryprivate.h" + +struct _GskGLIconLibrary +{ + GskGLTextureLibrary parent_instance; +}; + +G_DEFINE_TYPE (GskGLIconLibrary, gsk_gl_icon_library, GSK_TYPE_GL_TEXTURE_LIBRARY) + +GskGLIconLibrary * +gsk_gl_icon_library_new (GskGLDriver *driver) +{ + g_return_val_if_fail (GSK_IS_GL_DRIVER (driver), NULL); + + return g_object_new (GSK_TYPE_GL_ICON_LIBRARY, + "driver", driver, + NULL); +} + +static void +gsk_gl_icon_data_free (gpointer data) +{ + GskGLIconData *icon_data = data; + + g_clear_object (&icon_data->source_texture); + g_slice_free (GskGLIconData, icon_data); +} + +static void +gsk_gl_icon_library_class_init (GskGLIconLibraryClass *klass) +{ +} + +static void +gsk_gl_icon_library_init (GskGLIconLibrary *self) +{ + GskGLTextureLibrary *tl = (GskGLTextureLibrary *)self; + + tl->max_entry_size = 128; + gsk_gl_texture_library_set_funcs (tl, + NULL, NULL, NULL, + gsk_gl_icon_data_free); +} + +void +gsk_gl_icon_library_add (GskGLIconLibrary *self, + GdkTexture *key, + const GskGLIconData **out_value) +{ + GskGLTextureLibrary *tl = (GskGLTextureLibrary *)self; + G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME; + cairo_surface_t *surface; + GskGLIconData *icon_data; + guint8 *pixel_data; + guint8 *surface_data; + guint8 *free_data = NULL; + guint gl_format; + guint gl_type; + guint packed_x; + guint packed_y; + int width; + int height; + guint texture_id; + + g_assert (GSK_IS_GL_ICON_LIBRARY (self)); + g_assert (GDK_IS_TEXTURE (key)); + g_assert (out_value != NULL); + + width = key->width; + height = key->height; + + icon_data = gsk_gl_texture_library_pack (tl, + key, + sizeof (GskGLIconData), + width, height, 1, + &packed_x, &packed_y); + icon_data->source_texture = g_object_ref (key); + + /* actually upload the texture */ + surface = gdk_texture_download_surface (key); + surface_data = cairo_image_surface_get_data (surface); + gdk_gl_context_push_debug_group_printf (gdk_gl_context_get_current (), + "Uploading texture"); + + if (gdk_gl_context_get_use_es (gdk_gl_context_get_current ())) + { + pixel_data = free_data = g_malloc (width * height * 4); + gdk_memory_convert (pixel_data, width * 4, + GDK_MEMORY_R8G8B8A8_PREMULTIPLIED, + surface_data, cairo_image_surface_get_stride (surface), + GDK_MEMORY_DEFAULT, width, height); + gl_format = GL_RGBA; + gl_type = GL_UNSIGNED_BYTE; + } + else + { + pixel_data = surface_data; + gl_format = GL_BGRA; + gl_type = GL_UNSIGNED_INT_8_8_8_8_REV; + } + + texture_id = GSK_GL_TEXTURE_ATLAS_ENTRY_TEXTURE (icon_data); + + glBindTexture (GL_TEXTURE_2D, texture_id); + + glTexSubImage2D (GL_TEXTURE_2D, 0, + packed_x + 1, packed_y + 1, + width, height, + gl_format, gl_type, + pixel_data); + /* Padding top */ + glTexSubImage2D (GL_TEXTURE_2D, 0, + packed_x + 1, packed_y, + width, 1, + gl_format, gl_type, + pixel_data); + /* Padding left */ + glTexSubImage2D (GL_TEXTURE_2D, 0, + packed_x, packed_y + 1, + 1, height, + gl_format, gl_type, + pixel_data); + /* Padding top left */ + glTexSubImage2D (GL_TEXTURE_2D, 0, + packed_x, packed_y, + 1, 1, + gl_format, gl_type, + pixel_data); + + /* Padding right */ + glPixelStorei (GL_UNPACK_ROW_LENGTH, width); + glPixelStorei (GL_UNPACK_SKIP_PIXELS, width - 1); + glTexSubImage2D (GL_TEXTURE_2D, 0, + packed_x + width + 1, packed_y + 1, + 1, height, + gl_format, gl_type, + pixel_data); + /* Padding top right */ + glTexSubImage2D (GL_TEXTURE_2D, 0, + packed_x + width + 1, packed_y, + 1, 1, + gl_format, gl_type, + pixel_data); + /* Padding bottom */ + glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0); + glPixelStorei (GL_UNPACK_ROW_LENGTH, 0); + glPixelStorei (GL_UNPACK_SKIP_ROWS, height - 1); + glTexSubImage2D (GL_TEXTURE_2D, 0, + packed_x + 1, packed_y + 1 + height, + width, 1, + gl_format, gl_type, + pixel_data); + /* Padding bottom left */ + glTexSubImage2D (GL_TEXTURE_2D, 0, + packed_x, packed_y + 1 + height, + 1, 1, + gl_format, gl_type, + pixel_data); + /* Padding bottom right */ + glPixelStorei (GL_UNPACK_ROW_LENGTH, width); + glPixelStorei (GL_UNPACK_SKIP_PIXELS, width - 1); + glTexSubImage2D (GL_TEXTURE_2D, 0, + packed_x + 1 + width, packed_y + 1 + height, + 1, 1, + gl_format, gl_type, + pixel_data); + /* Reset this */ + glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0); + glPixelStorei (GL_UNPACK_ROW_LENGTH, 0); + glPixelStorei (GL_UNPACK_SKIP_ROWS, 0); + + gdk_gl_context_pop_debug_group (gdk_gl_context_get_current ()); + + *out_value = icon_data; + + cairo_surface_destroy (surface); + g_free (free_data); + + tl->driver->command_queue->n_uploads++; + + if (gdk_profiler_is_running ()) + { + char message[64]; + g_snprintf (message, sizeof message, "Size %dx%d", width, height); + gdk_profiler_add_mark (start_time, GDK_PROFILER_CURRENT_TIME-start_time, "Upload Icon", message); + } +} |