diff --git a/gdk/gdkdmabuf.c b/gdk/gdkdmabuf.c index 862485d470..0b7f01ce98 100644 --- a/gdk/gdkdmabuf.c +++ b/gdk/gdkdmabuf.c @@ -24,6 +24,7 @@ #include "gdkdmabuffourccprivate.h" #include "gdkdmabuftextureprivate.h" #include "gdkmemoryformatprivate.h" +#include "gdkcolorstate.h" #ifdef HAVE_DMABUF #include @@ -2066,8 +2067,10 @@ gdk_dmabuf_download_mmap (GdkTexture *texture, gsize stride) { GdkMemoryFormat src_format = gdk_texture_get_format (texture); + GdkColorState *src_color_state = gdk_texture_get_color_state (texture); - if (format == src_format) + if (format == src_format && + gdk_color_state_equal (gdk_color_state_get_srgb (), src_color_state)) gdk_dmabuf_do_download_mmap (texture, data, stride); else { @@ -2083,8 +2086,10 @@ gdk_dmabuf_download_mmap (GdkTexture *texture, gdk_dmabuf_do_download_mmap (texture, src_data, src_stride); - gdk_memory_convert (data, stride, format, - src_data, src_stride, src_format, + gdk_memory_convert (data, stride, + format, gdk_color_state_get_srgb (), + src_data, src_stride, + src_format, src_color_state, width, height); g_free (src_data); diff --git a/gdk/gdkgltexture.c b/gdk/gdkgltexture.c index bf8866e1a1..c536a0eae8 100644 --- a/gdk/gdkgltexture.c +++ b/gdk/gdkgltexture.c @@ -24,6 +24,7 @@ #include "gdkglcontextprivate.h" #include "gdkmemoryformatprivate.h" #include "gdkmemorytextureprivate.h" +#include "gdkcolorstate.h" #include @@ -185,13 +186,15 @@ gdk_gl_texture_do_download (GdkGLTexture *self, { GdkTexture *texture = GDK_TEXTURE (self); GdkMemoryFormat format; + GdkColorState *color_state; gsize expected_stride; Download *download = download_; GLint gl_internal_format; GLenum gl_format, gl_type; GLint gl_swizzle[4]; - format = gdk_texture_get_format (texture), + format = gdk_texture_get_format (texture); + color_state = gdk_texture_get_color_state (texture); expected_stride = texture->width * gdk_memory_format_bytes_per_pixel (download->format); if (!gdk_gl_context_get_use_es (context) && @@ -225,9 +228,11 @@ gdk_gl_texture_do_download (GdkGLTexture *self, gdk_memory_convert (download->data, download->stride, download->format, + gdk_color_state_get_srgb (), pixels, stride, format, + color_state, texture->width, texture->height); @@ -377,9 +382,11 @@ gdk_gl_texture_do_download (GdkGLTexture *self, gdk_memory_convert (download->data, download->stride, download->format, + gdk_color_state_get_srgb (), pixels, stride, actual_format, + color_state, texture->width, texture->height); diff --git a/gdk/gdkmemoryformat.c b/gdk/gdkmemoryformat.c index c9fdc38192..abd52887d4 100644 --- a/gdk/gdkmemoryformat.c +++ b/gdk/gdkmemoryformat.c @@ -23,8 +23,9 @@ #include "gdkdmabuffourccprivate.h" #include "gdkglcontextprivate.h" - +#include "gdkcolorstateprivate.h" #include "gsk/gl/fp16private.h" +#include "gtk/gtkcolorutilsprivate.h" #include @@ -1734,14 +1735,18 @@ void gdk_memory_convert (guchar *dest_data, gsize dest_stride, GdkMemoryFormat dest_format, + GdkColorState *dest_color_state, const guchar *src_data, gsize src_stride, GdkMemoryFormat src_format, + GdkColorState *src_color_state, gsize width, gsize height) { const GdkMemoryFormatDescription *dest_desc = &memory_formats[dest_format]; const GdkMemoryFormatDescription *src_desc = &memory_formats[src_format]; + GdkColorStateTransform transform; + gboolean has_transform; float *tmp; gsize y; void (*func) (guchar *, const guchar *, gsize) = NULL; @@ -1749,7 +1754,8 @@ gdk_memory_convert (guchar *dest_data, g_assert (dest_format < GDK_MEMORY_N_FORMATS); g_assert (src_format < GDK_MEMORY_N_FORMATS); - if (src_format == dest_format) + if (gdk_color_state_equal (src_color_state, dest_color_state) && + src_format == dest_format) { gsize bytes_per_row = src_desc->bytes_per_pixel * width; @@ -1769,7 +1775,9 @@ gdk_memory_convert (guchar *dest_data, return; } - if (src_format == GDK_MEMORY_R8G8B8A8 && dest_format == GDK_MEMORY_R8G8B8A8_PREMULTIPLIED) + if (!gdk_color_state_equal (src_color_state, dest_color_state)) + func = NULL; + else if (src_format == GDK_MEMORY_R8G8B8A8 && dest_format == GDK_MEMORY_R8G8B8A8_PREMULTIPLIED) func = r8g8b8a8_to_r8g8b8a8_premultiplied; else if (src_format == GDK_MEMORY_B8G8R8A8 && dest_format == GDK_MEMORY_R8G8B8A8_PREMULTIPLIED) func = r8g8b8a8_to_b8g8r8a8_premultiplied; @@ -1817,19 +1825,43 @@ gdk_memory_convert (guchar *dest_data, return; } + if (!gdk_color_state_equal (src_color_state, dest_color_state)) + { + gdk_color_state_transform_init (&transform, src_color_state, dest_color_state, TRUE); + has_transform = TRUE; + } + else + { + has_transform = FALSE; + } + tmp = g_new (float, width * 4); for (y = 0; y < height; y++) { src_desc->to_float (tmp, src_data, width); - if (src_desc->alpha == GDK_MEMORY_ALPHA_PREMULTIPLIED && dest_desc->alpha == GDK_MEMORY_ALPHA_STRAIGHT) - unpremultiply (tmp, width); - else if (src_desc->alpha == GDK_MEMORY_ALPHA_STRAIGHT && dest_desc->alpha != GDK_MEMORY_ALPHA_STRAIGHT) - premultiply (tmp, width); + if (has_transform) + { + if (src_desc->alpha == GDK_MEMORY_ALPHA_PREMULTIPLIED) + unpremultiply (tmp, width); + gdk_color_state_transform (&transform, tmp, tmp, width); + if (dest_desc->alpha != GDK_MEMORY_ALPHA_STRAIGHT) + premultiply (tmp, width); + } + else + { + if (src_desc->alpha == GDK_MEMORY_ALPHA_PREMULTIPLIED && dest_desc->alpha == GDK_MEMORY_ALPHA_STRAIGHT) + unpremultiply (tmp, width); + else if (src_desc->alpha == GDK_MEMORY_ALPHA_STRAIGHT && dest_desc->alpha != GDK_MEMORY_ALPHA_STRAIGHT) + premultiply (tmp, width); + } dest_desc->from_float (dest_data, tmp, width); src_data += src_stride; dest_data += dest_stride; } + if (has_transform) + gdk_color_state_transform_finish (&transform); + g_free (tmp); } diff --git a/gdk/gdkmemoryformatprivate.h b/gdk/gdkmemoryformatprivate.h index 878fd129e0..6002e63ce1 100644 --- a/gdk/gdkmemoryformatprivate.h +++ b/gdk/gdkmemoryformatprivate.h @@ -80,9 +80,11 @@ const char * gdk_memory_format_get_name (GdkMemoryFormat void gdk_memory_convert (guchar *dest_data, gsize dest_stride, GdkMemoryFormat dest_format, + GdkColorState *dest_color_state, const guchar *src_data, gsize src_stride, GdkMemoryFormat src_format, + GdkColorState *src_color_state, gsize width, gsize height); diff --git a/gdk/gdkmemorytexture.c b/gdk/gdkmemorytexture.c index b4380482de..e4b85609b2 100644 --- a/gdk/gdkmemorytexture.c +++ b/gdk/gdkmemorytexture.c @@ -66,9 +66,11 @@ gdk_memory_texture_download (GdkTexture *texture, gdk_memory_convert (data, stride, format, + gdk_color_state_get_srgb (), (guchar *) g_bytes_get_data (self->bytes, NULL), self->stride, texture->format, + texture->color_state, gdk_texture_get_width (texture), gdk_texture_get_height (texture)); } diff --git a/gdk/gdktexture.c b/gdk/gdktexture.c index b8a6cb4f88..1ee11d21df 100644 --- a/gdk/gdktexture.c +++ b/gdk/gdktexture.c @@ -805,6 +805,7 @@ gdk_texture_get_color_state (GdkTexture *texture) return texture->color_state; } + void gdk_texture_do_download (GdkTexture *texture, GdkMemoryFormat format, diff --git a/gsk/gl/gskglglyphlibrary.c b/gsk/gl/gskglglyphlibrary.c index b35a06f049..3e95263ddd 100644 --- a/gsk/gl/gskglglyphlibrary.c +++ b/gsk/gl/gskglglyphlibrary.c @@ -281,9 +281,11 @@ gsk_gl_glyph_library_upload_glyph (GskGLGlyphLibrary *self, pixel_data = free_data = g_malloc (width * height * 4); gdk_memory_convert (pixel_data, width * 4, GDK_MEMORY_R8G8B8A8_PREMULTIPLIED, + gdk_color_state_get_srgb (), cairo_image_surface_get_data (surface), stride, GDK_MEMORY_DEFAULT, + gdk_color_state_get_srgb (), width, height); stride = width * 4; gl_format = GL_RGBA; diff --git a/gsk/gl/gskgliconlibrary.c b/gsk/gl/gskgliconlibrary.c index d10487d684..93504cb6d0 100644 --- a/gsk/gl/gskgliconlibrary.c +++ b/gsk/gl/gskgliconlibrary.c @@ -116,8 +116,11 @@ gsk_gl_icon_library_add (GskGLIconLibrary *self, pixel_data = free_data = g_malloc (width * height * 4); gdk_memory_convert (pixel_data, width * 4, GDK_MEMORY_R8G8B8A8_PREMULTIPLIED, + gdk_color_state_get_srgb (), surface_data, cairo_image_surface_get_stride (surface), - GDK_MEMORY_DEFAULT, width, height); + GDK_MEMORY_DEFAULT, + gdk_texture_get_color_state (key), + width, height); gl_format = GL_RGBA; gl_type = GL_UNSIGNED_BYTE; }