gl: Make texture slicing more flexible
authorMatthias Clasen <mclasen@redhat.com>
Sat, 11 Feb 2023 12:46:38 +0000 (07:46 -0500)
committerMatthias Clasen <mclasen@redhat.com>
Sat, 11 Feb 2023 20:09:38 +0000 (15:09 -0500)
Allow to specify the filtering to use for the slices,
and allow forcing the number of slices. This will be
used in the next commit.

gsk/gl/gskgldriver.c
gsk/gl/gskgldriverprivate.h
gsk/gl/gskglrenderjob.c

index 3d58ee71e0fbe5334dee107d2562987cf69fb11a..4e38dad68506ae7dbce0891c561368d003fbc66b 100644 (file)
@@ -753,7 +753,7 @@ gsk_gl_driver_load_texture (GskGLDriver *self,
     {
       if ((t = gdk_texture_get_render_data (texture, self)))
         {
-          if (t->min_filter == min_filter && t->mag_filter == mag_filter)
+          if (t->min_filter == min_filter && t->mag_filter == mag_filter && t->texture_id)
             return t->texture_id;
         }
 
@@ -1195,6 +1195,10 @@ gsk_gl_driver_create_command_queue (GskGLDriver *self,
 void
 gsk_gl_driver_add_texture_slices (GskGLDriver        *self,
                                   GdkTexture         *texture,
+                                  int                 min_filter,
+                                  int                 mag_filter,
+                                  guint               min_cols,
+                                  guint               min_rows,
                                   GskGLTextureSlice **out_slices,
                                   guint              *out_n_slices)
 {
@@ -1216,31 +1220,37 @@ gsk_gl_driver_add_texture_slices (GskGLDriver        *self,
 
   /* XXX: Too much? */
   max_texture_size = self->command_queue->max_texture_size / 4;
-
   tex_width = texture->width;
   tex_height = texture->height;
-  cols = (texture->width / max_texture_size) + 1;
-  rows = (texture->height / max_texture_size) + 1;
+
+  cols = MAX ((texture->width / max_texture_size) + 1, min_cols);
+  rows = MAX ((texture->height / max_texture_size) + 1, min_rows);
+
+  n_slices = cols * rows;
 
   if ((t = gdk_texture_get_render_data (texture, self)))
     {
-      *out_slices = t->slices;
-      *out_n_slices = t->n_slices;
-      return;
+      if (t->n_slices == n_slices)
+        {
+          *out_slices = t->slices;
+          *out_n_slices = t->n_slices;
+          return;
+        }
+
+      gdk_texture_clear_render_data (texture);
     }
 
-  n_slices = cols * rows;
   slices = g_new0 (GskGLTextureSlice, n_slices);
   memtex = gdk_memory_texture_from_texture (texture,
                                             gdk_texture_get_format (texture));
 
-  for (guint col = 0; col < cols; col ++)
+  for (guint col = 0; col < cols; col++)
     {
-      int slice_width = MIN (max_texture_size, texture->width - x);
+      int slice_width = col + 1 < cols ? tex_width / cols : tex_width - x;
 
-      for (guint row = 0; row < rows; row ++)
+      for (guint row = 0; row < rows; row++)
         {
-          int slice_height = MIN (max_texture_size, texture->height - y);
+          int slice_height = row + 1 < rows ? tex_height / rows : tex_height - y;
           int slice_index = (col * rows) + row;
           GdkTexture *subtex;
           guint texture_id;
@@ -1250,7 +1260,7 @@ gsk_gl_driver_add_texture_slices (GskGLDriver        *self,
                                                       slice_width, slice_height);
           texture_id = gsk_gl_command_queue_upload_texture (self->command_queue,
                                                             subtex,
-                                                            GL_NEAREST, GL_NEAREST);
+                                                            min_filter, mag_filter);
           g_object_unref (subtex);
 
           slices[slice_index].rect.x = x;
index accae5b3bba1212df3b0fe531b8af85a2878344a..2b39217919149a583bc9b565bddda185d46eb88f 100644 (file)
@@ -177,6 +177,10 @@ GskGLTexture      * gsk_gl_driver_mark_texture_permanent (GskGLDriver         *s
                                                           guint                texture_id);
 void                gsk_gl_driver_add_texture_slices     (GskGLDriver         *self,
                                                           GdkTexture          *texture,
+                                                          int                  min_filter,
+                                                          int                  mag_filter,
+                                                          guint                min_cols,
+                                                          guint                min_rows,
                                                           GskGLTextureSlice  **out_slices,
                                                           guint               *out_n_slices);
 GskGLProgram      * gsk_gl_driver_lookup_shader          (GskGLDriver         *self,
@@ -228,6 +232,10 @@ gsk_gl_driver_lookup_texture (GskGLDriver         *self,
 static inline void
 gsk_gl_driver_slice_texture (GskGLDriver        *self,
                              GdkTexture         *texture,
+                             int                 min_filter,
+                             int                 mag_filter,
+                             guint               min_cols,
+                             guint               min_rows,
                              GskGLTextureSlice **out_slices,
                              guint              *out_n_slices)
 {
@@ -235,12 +243,15 @@ gsk_gl_driver_slice_texture (GskGLDriver        *self,
 
   if ((t = gdk_texture_get_render_data (texture, self)))
     {
-      *out_slices = t->slices;
-      *out_n_slices = t->n_slices;
-      return;
+      if (min_cols == 0 && min_rows == 0)
+        {
+          *out_slices = t->slices;
+          *out_n_slices = t->n_slices;
+          return;
+        }
     }
 
-  gsk_gl_driver_add_texture_slices (self, texture, out_slices, out_n_slices);
+  gsk_gl_driver_add_texture_slices (self, texture, min_filter, mag_filter, min_cols, min_rows, out_slices, out_n_slices);
 }
 
 G_END_DECLS
index 325278df8cdb98744f9d081c8390a3cdadb07444..cbfe07576d78590839f42ae9f0120d24e282eed5 100644 (file)
@@ -3506,7 +3506,7 @@ gsk_gl_render_job_visit_texture_node (GskGLRenderJob      *job,
       GskGLTextureSlice *slices = NULL;
       guint n_slices = 0;
 
-      gsk_gl_driver_slice_texture (job->driver, texture, &slices, &n_slices);
+      gsk_gl_driver_slice_texture (job->driver, texture, GL_NEAREST, GL_NEAREST, 0, 0, &slices, &n_slices);
 
       g_assert (slices != NULL);
       g_assert (n_slices > 0);