[gtk/wip/otte/color-profiles: 91/111] gdk: Make gdk_texture_download_surface() take a target colorprofile




commit fe66e57b5fa49c53c4160e62dbfaae43de704aa9
Author: Benjamin Otte <otte redhat com>
Date:   Sun Sep 26 01:04:15 2021 +0200

    gdk: Make gdk_texture_download_surface() take a target colorprofile
    
    This way, the resulting surface can contain the pixels in the desired
    color profile.

 gdk/gdktexture.c                   | 45 +++++++++++++++++++++++++++++++++-----
 gdk/gdktextureprivate.h            |  3 ++-
 gdk/x11/gdksurface-x11.c           |  2 +-
 gsk/broadway/gskbroadwayrenderer.c |  2 +-
 gsk/gskrendernodeimpl.c            |  3 ++-
 gsk/gskrendernodeparser.c          |  3 ++-
 gsk/ngl/gskngliconlibrary.c        |  2 +-
 gsk/vulkan/gskvulkanrenderer.c     |  2 +-
 8 files changed, 49 insertions(+), 13 deletions(-)
---
diff --git a/gdk/gdktexture.c b/gdk/gdktexture.c
index b062667b54..4fac27212e 100644
--- a/gdk/gdktexture.c
+++ b/gdk/gdktexture.c
@@ -43,6 +43,7 @@
 #include "gdkcairo.h"
 #include "gdkcolorprofile.h"
 #include "gdkintl.h"
+#include "gdkmemoryformatprivate.h"
 #include "gdkmemorytextureprivate.h"
 #include "gdkpaintable.h"
 #include "gdksnapshot.h"
@@ -742,23 +743,55 @@ gdk_texture_get_color_profile (GdkTexture *texture)
   return texture->color_profile;
 }
 
+/*<private>
+ * gdk_texture_download_surface:
+ * @texture: the texture to download
+ * @target_profile: (nullable): The target color profile or %NULL for the
+ *   default sRGB.
+ *
+ * Downloads the texture into a newly created Cairo surface.
+ *
+ * Returns: A new Cairo surface.
+ **/
 cairo_surface_t *
-gdk_texture_download_surface (GdkTexture *texture)
+gdk_texture_download_surface (GdkTexture      *texture,
+                              GdkColorProfile *target_profile)
 {
   cairo_surface_t *surface;
   cairo_status_t surface_status;
 
+
   surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
                                         texture->width, texture->height);
+  if (target_profile != NULL)
+    gdk_cairo_surface_set_color_profile (surface, target_profile);
+  else
+    target_profile = gdk_color_profile_get_srgb ();
 
   surface_status = cairo_surface_status (surface);
   if (surface_status != CAIRO_STATUS_SUCCESS)
-    g_warning ("%s: surface error: %s", __FUNCTION__,
-               cairo_status_to_string (surface_status));
+    {
+      g_warning ("%s: surface error: %s", __FUNCTION__,
+                 cairo_status_to_string (surface_status));
+    }
+  else
+    {
+      GdkTexture *download = gdk_texture_download_texture (texture);
+      GdkMemoryTexture *memdownload = GDK_MEMORY_TEXTURE (download);
+
+      gdk_memory_convert (cairo_image_surface_get_data (surface),
+                          cairo_image_surface_get_stride (surface),
+                          GDK_MEMORY_DEFAULT,
+                          target_profile,
+                          gdk_memory_texture_get_data (memdownload),
+                          gdk_memory_texture_get_stride (memdownload),
+                          gdk_memory_texture_get_format (memdownload),
+                          download->color_profile,
+                          download->width,
+                          download->height);
+      g_object_unref (download);
+    }
 
-  gdk_texture_download (texture,
-                        cairo_image_surface_get_data (surface),
-                        cairo_image_surface_get_stride (surface));
   cairo_surface_mark_dirty (surface);
 
   return surface;
diff --git a/gdk/gdktextureprivate.h b/gdk/gdktextureprivate.h
index 324e0f94f3..5c451ec8c8 100644
--- a/gdk/gdktextureprivate.h
+++ b/gdk/gdktextureprivate.h
@@ -39,7 +39,8 @@ struct _GdkTextureClass {
 gboolean                gdk_texture_can_load            (GBytes                 *bytes);
 
 GdkTexture *            gdk_texture_new_for_surface     (cairo_surface_t        *surface);
-cairo_surface_t *       gdk_texture_download_surface    (GdkTexture             *texture);
+cairo_surface_t *       gdk_texture_download_surface    (GdkTexture             *texture,
+                                                         GdkColorProfile        *color_profile);
 /* NB: GdkMemoryTexture */
 GdkTexture *            gdk_texture_download_texture    (GdkTexture             *texture);
 
diff --git a/gdk/x11/gdksurface-x11.c b/gdk/x11/gdksurface-x11.c
index 06bc9cf00e..064e21964e 100644
--- a/gdk/x11/gdksurface-x11.c
+++ b/gdk/x11/gdksurface-x11.c
@@ -3173,7 +3173,7 @@ gdk_surface_update_icon (GdkSurface *surface,
 
       toplevel->icon_pixmap = gdk_x11_surface_create_pixmap_surface (surface, width, height);
 
-      cairo_surface = gdk_texture_download_surface (best_icon);
+      cairo_surface = gdk_texture_download_surface (best_icon, NULL);
 
       cr = cairo_create (toplevel->icon_pixmap);
       cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
diff --git a/gsk/broadway/gskbroadwayrenderer.c b/gsk/broadway/gskbroadwayrenderer.c
index 5ac62e7ee0..92e6f8260a 100644
--- a/gsk/broadway/gskbroadwayrenderer.c
+++ b/gsk/broadway/gskbroadwayrenderer.c
@@ -449,7 +449,7 @@ get_colorized_texture (GdkTexture *texture,
                        const graphene_matrix_t *color_matrix,
                        const graphene_vec4_t *color_offset)
 {
-  cairo_surface_t *surface = gdk_texture_download_surface (texture);
+  cairo_surface_t *surface = gdk_texture_download_surface (texture, NULL);
   cairo_surface_t *image_surface;
   graphene_vec4_t pixel;
   guint32* pixel_data;
diff --git a/gsk/gskrendernodeimpl.c b/gsk/gskrendernodeimpl.c
index fd2a9e5d44..fa0bdb661e 100644
--- a/gsk/gskrendernodeimpl.c
+++ b/gsk/gskrendernodeimpl.c
@@ -1483,7 +1483,8 @@ gsk_texture_node_draw (GskRenderNode *node,
   cairo_pattern_t *pattern;
   cairo_matrix_t matrix;
 
-  surface = gdk_texture_download_surface (self->texture);
+  surface = gdk_texture_download_surface (self->texture,
+                                          gdk_cairo_get_color_profile (cr));
   pattern = cairo_pattern_create_for_surface (surface);
   cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
 
diff --git a/gsk/gskrendernodeparser.c b/gsk/gskrendernodeparser.c
index ed08bd4431..327f4a8e18 100644
--- a/gsk/gskrendernodeparser.c
+++ b/gsk/gskrendernodeparser.c
@@ -1399,7 +1399,8 @@ parse_cairo_node (GtkCssParser *parser)
   else if (pixels != NULL)
     {
       cairo_t *cr = gsk_cairo_node_get_draw_context (node);
-      surface = gdk_texture_download_surface (pixels);
+      surface = gdk_texture_download_surface (pixels,
+                                              gdk_texture_get_color_profile (pixels));
       cairo_set_source_surface (cr, surface, 0, 0);
       cairo_paint (cr);
       cairo_destroy (cr);
diff --git a/gsk/ngl/gskngliconlibrary.c b/gsk/ngl/gskngliconlibrary.c
index 815ab0acd5..cac7ad7dfd 100644
--- a/gsk/ngl/gskngliconlibrary.c
+++ b/gsk/ngl/gskngliconlibrary.c
@@ -106,7 +106,7 @@ gsk_ngl_icon_library_add (GskNglIconLibrary     *self,
   icon_data->source_texture = g_object_ref (key);
 
   /* actually upload the texture */
-  surface = gdk_texture_download_surface (key);
+  surface = gdk_texture_download_surface (key, NULL);
   surface_data = cairo_image_surface_get_data (surface);
   gdk_gl_context_push_debug_group_printf (gdk_gl_context_get_current (),
                                           "Uploading texture");
diff --git a/gsk/vulkan/gskvulkanrenderer.c b/gsk/vulkan/gskvulkanrenderer.c
index c91b14a384..0b40d416fe 100644
--- a/gsk/vulkan/gskvulkanrenderer.c
+++ b/gsk/vulkan/gskvulkanrenderer.c
@@ -335,7 +335,7 @@ gsk_vulkan_renderer_ref_texture_image (GskVulkanRenderer *self,
   if (data)
     return g_object_ref (data->image);
 
-  surface = gdk_texture_download_surface (texture);
+  surface = gdk_texture_download_surface (texture,NULL);
   image = gsk_vulkan_image_new_from_data (uploader,
                                           cairo_image_surface_get_data (surface),
                                           cairo_image_surface_get_width (surface),


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]