gl: Move texture uploading to the renderer
authorBenjamin Otte <otte@redhat.com>
Tue, 12 Oct 2021 13:04:43 +0000 (15:04 +0200)
committerBenjamin Otte <otte@redhat.com>
Wed, 13 Oct 2021 12:33:44 +0000 (14:33 +0200)
It does not belong in GdkGLContext, it's a renderer thing.
It's also the only user of that API.

Introduce gdk_gl_context_check_version() private API to make version
checks simpler.

gdk/gdkglcontext.c
gdk/gdkglcontextprivate.h
gsk/gl/gskglcommandqueue.c

index f719da3aea9ee41d9d33e3919d79278611252012..149e93ff144ef9163577feaccadfa836caf046ce 100644 (file)
@@ -249,86 +249,6 @@ gdk_gl_context_get_property (GObject    *object,
     }
 }
 
-void
-gdk_gl_context_upload_texture (GdkGLContext    *context,
-                               const guchar    *data,
-                               int              width,
-                               int              height,
-                               int              stride,
-                               GdkMemoryFormat  data_format,
-                               guint            texture_target)
-{
-  GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
-  guchar *copy = NULL;
-  GLenum gl_internalformat;
-  GLenum gl_format;
-  GLenum gl_type;
-  gsize bpp;
-
-  g_return_if_fail (GDK_IS_GL_CONTEXT (context));
-
-  if (!gdk_memory_format_gl_format (data_format,
-                                    gdk_gl_context_get_use_es (context),
-                                    &gl_internalformat,
-                                    &gl_format,
-                                    &gl_type))
-    {
-      copy = g_malloc_n (width * 4, height);
-      gdk_memory_convert (copy, width * 4,
-                          GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,
-                          data, stride,
-                          data_format,
-                          width, height);
-      data = copy;
-      data_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
-      stride = width * 4;
-      if (!gdk_memory_format_gl_format (data_format,
-                                        gdk_gl_context_get_use_es (context),
-                                        &gl_internalformat,
-                                        &gl_format,
-                                        &gl_type))
-        {
-          g_assert_not_reached ();
-        }
-    }
-  else
-    {
-      copy = NULL;
-    }
-
-  bpp = gdk_memory_format_bytes_per_pixel (data_format);
-
-  glPixelStorei (GL_UNPACK_ALIGNMENT, gdk_memory_format_alignment (data_format));
-
-  /* GL_UNPACK_ROW_LENGTH is available on desktop GL, OpenGL ES >= 3.0, or if
-   * the GL_EXT_unpack_subimage extension for OpenGL ES 2.0 is available
-   */
-  if (stride == width * bpp)
-    {
-      glTexImage2D (texture_target, 0, gl_internalformat, width, height, 0, gl_format, gl_type, data);
-    }
-  else if (stride % bpp == 0 &&
-           (!gdk_gl_context_get_use_es (context) ||
-            (priv->gl_version >= 30 || priv->has_unpack_subimage)))
-    {
-      glPixelStorei (GL_UNPACK_ROW_LENGTH, stride / bpp);
-
-      glTexImage2D (texture_target, 0, gl_internalformat, width, height, 0, gl_format, gl_type, data);
-
-      glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
-    }
-  else
-    {
-      int i;
-      glTexImage2D (texture_target, 0, gl_internalformat, width, height, 0, gl_format, gl_type, NULL);
-      for (i = 0; i < height; i++)
-        glTexSubImage2D (texture_target, 0, 0, i, width, 1, gl_format, gl_type, data + (i * stride));
-    }
-  glPixelStorei (GL_UNPACK_ALIGNMENT, 4);
-
-  g_free (copy);
-}
-
 #define N_EGL_ATTRS     16
 
 static GdkGLAPI
@@ -1067,6 +987,19 @@ gdk_gl_context_set_required_version (GdkGLContext *context,
   priv->minor = version % 100;
 }
 
+gboolean
+gdk_gl_context_check_version (GdkGLContext *context,
+                              int           required_major,
+                              int           required_minor)
+{
+  GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
+
+  g_return_val_if_fail (GDK_IS_GL_CONTEXT (context), FALSE);
+  g_return_val_if_fail (required_minor < 10, FALSE);
+
+  return priv->gl_version >= required_major * 10 + required_minor;
+}
+
 /**
  * gdk_gl_context_get_required_version:
  * @context: a `GdkGLContext`
index 1879488b4f9e3733ebce431f413869956c217b68..6814fec0bf763138e7327d10be057e5b6a9c8b50 100644 (file)
@@ -108,13 +108,10 @@ gboolean                gdk_gl_context_is_api_allowed           (GdkGLContext
 void                    gdk_gl_context_set_is_legacy            (GdkGLContext    *context,
                                                                  gboolean         is_legacy);
 
-void                    gdk_gl_context_upload_texture           (GdkGLContext    *context,
-                                                                 const guchar    *data,
-                                                                 int              width,
-                                                                 int              height,
-                                                                 int              stride,
-                                                                 GdkMemoryFormat  data_format,
-                                                                 guint            texture_target);
+gboolean                gdk_gl_context_check_version            (GdkGLContext    *context,
+                                                                 int              required_major,
+                                                                 int              required_minor);
+
 gboolean                gdk_gl_context_has_unpack_subimage      (GdkGLContext    *context);
 void                    gdk_gl_context_push_debug_group         (GdkGLContext    *context,
                                                                  const char      *message);
index 2571804726cddd7fdf0e4caa094e5597c850c38a..38f879c5c18c894ae1018fc0e02afbb9bf713c03 100644 (file)
@@ -1339,6 +1339,86 @@ gsk_gl_command_queue_create_framebuffer (GskGLCommandQueue *self)
   return fbo_id;
 }
 
+static void
+gsk_gl_command_queue_do_upload_texture (GskGLCommandQueue *self,
+                                        const guchar      *data,
+                                        int                width,
+                                        int                height,
+                                        int                stride,
+                                        GdkMemoryFormat    data_format)
+{
+  GdkGLContext *context;
+  guchar *copy = NULL;
+  GLenum gl_internalformat;
+  GLenum gl_format;
+  GLenum gl_type;
+  gsize bpp;
+  gboolean use_es;
+
+  context = gdk_gl_context_get_current ();
+  use_es = gdk_gl_context_get_use_es (context);
+
+  if (!gdk_memory_format_gl_format (data_format,
+                                    use_es,
+                                    &gl_internalformat,
+                                    &gl_format,
+                                    &gl_type))
+    {
+      copy = g_malloc_n (width * 4, height);
+      gdk_memory_convert (copy, width * 4,
+                          GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,
+                          data, stride,
+                          data_format,
+                          width, height);
+      data = copy;
+      data_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
+      stride = width * 4;
+      if (!gdk_memory_format_gl_format (data_format,
+                                        use_es,
+                                        &gl_internalformat,
+                                        &gl_format,
+                                        &gl_type))
+        {
+          g_assert_not_reached ();
+        }
+    }
+  else
+    {
+      copy = NULL;
+    }
+
+  bpp = gdk_memory_format_bytes_per_pixel (data_format);
+
+  glPixelStorei (GL_UNPACK_ALIGNMENT, gdk_memory_format_alignment (data_format));
+
+  /* GL_UNPACK_ROW_LENGTH is available on desktop GL, OpenGL ES >= 3.0, or if
+   * the GL_EXT_unpack_subimage extension for OpenGL ES 2.0 is available
+   */
+  if (stride == width * bpp)
+    {
+      glTexImage2D (GL_TEXTURE_2D, 0, gl_internalformat, width, height, 0, gl_format, gl_type, data);
+    }
+  else if (stride % bpp == 0 &&
+           (!use_es || gdk_gl_context_check_version (context, 3, 0) || gdk_gl_context_has_unpack_subimage (context)))
+    {
+      glPixelStorei (GL_UNPACK_ROW_LENGTH, stride / bpp);
+
+      glTexImage2D (GL_TEXTURE_2D, 0, gl_internalformat, width, height, 0, gl_format, gl_type, data);
+
+      glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
+    }
+  else
+    {
+      int i;
+      glTexImage2D (GL_TEXTURE_2D, 0, gl_internalformat, width, height, 0, gl_format, gl_type, NULL);
+      for (i = 0; i < height; i++)
+        glTexSubImage2D (GL_TEXTURE_2D, 0, 0, i, width, 1, gl_format, gl_type, data + (i * stride));
+    }
+  glPixelStorei (GL_UNPACK_ALIGNMENT, 4);
+
+  g_free (copy);
+}
+
 int
 gsk_gl_command_queue_upload_texture (GskGLCommandQueue *self,
                                      GdkTexture        *texture,
@@ -1402,10 +1482,10 @@ gsk_gl_command_queue_upload_texture (GskGLCommandQueue *self,
   glActiveTexture (GL_TEXTURE0);
   glBindTexture (GL_TEXTURE_2D, texture_id);
 
-  gdk_gl_context_upload_texture (gdk_gl_context_get_current (),
-                                 data + x_offset * bpp + y_offset * data_stride,
-                                 width, height, data_stride,
-                                 data_format, GL_TEXTURE_2D);
+  gsk_gl_command_queue_do_upload_texture (self,
+                                          data + x_offset * bpp + y_offset * data_stride,
+                                          width, height, data_stride,
+                                          data_format);
 
   /* Restore previous texture state if any */
   if (self->attachments->textures[0].id > 0)