From b27eaa344b072fe678b27818b0617379a5008842 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 9 Jun 2024 10:17:17 -0400 Subject: [PATCH] gpu: Track color state in the texture cache Keep the color state information around for cached images and handle the necessary conversions when using them. --- gsk/gpu/gskgpudevice.c | 30 ++++++++++++++-------- gsk/gpu/gskgpudeviceprivate.h | 6 +++-- gsk/gpu/gskgpudownloadop.c | 2 +- gsk/gpu/gskgpuframe.c | 5 ++-- gsk/gpu/gskgpunodeprocessor.c | 47 ++++++++++++++++------------------- 5 files changed, 49 insertions(+), 41 deletions(-) diff --git a/gsk/gpu/gskgpudevice.c b/gsk/gpu/gskgpudevice.c index 5e0fcbd4f5..55c7e4b8b6 100644 --- a/gsk/gpu/gskgpudevice.c +++ b/gsk/gpu/gskgpudevice.c @@ -252,6 +252,7 @@ struct _GskGpuCachedTexture GdkTexture *texture; GskGpuImage *image; + GdkColorState *color_state; }; static void @@ -263,6 +264,7 @@ gsk_gpu_cached_texture_free (GskGpuDevice *device, gpointer key, value; g_clear_object (&self->image); + g_clear_pointer (&self->color_state, gdk_color_state_unref); if (g_hash_table_steal_extended (priv->texture_cache, self->texture, &key, &value)) { @@ -325,9 +327,10 @@ gsk_gpu_cached_texture_destroy_cb (gpointer data) } static GskGpuCachedTexture * -gsk_gpu_cached_texture_new (GskGpuDevice *device, - GdkTexture *texture, - GskGpuImage *image) +gsk_gpu_cached_texture_new (GskGpuDevice *device, + GdkTexture *texture, + GskGpuImage *image, + GdkColorState *color_state) { GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (device); GskGpuCachedTexture *self; @@ -340,6 +343,7 @@ gsk_gpu_cached_texture_new (GskGpuDevice *device, self = gsk_gpu_cached_new (device, &GSK_GPU_CACHED_TEXTURE_CLASS, NULL); self->texture = texture; self->image = g_object_ref (image); + self->color_state = gdk_color_state_ref (color_state); ((GskGpuCached *)self)->pixels = gsk_gpu_image_get_width (image) * gsk_gpu_image_get_height (image); self->dead_pixels_counter = &priv->dead_texture_pixels; self->use_count = 2; @@ -850,9 +854,10 @@ gsk_gpu_device_add_atlas_image (GskGpuDevice *self, } GskGpuImage * -gsk_gpu_device_lookup_texture_image (GskGpuDevice *self, - GdkTexture *texture, - gint64 timestamp) +gsk_gpu_device_lookup_texture_image (GskGpuDevice *self, + GdkTexture *texture, + gint64 timestamp, + GdkColorState **out_color_state) { GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self); GskGpuCachedTexture *cache; @@ -866,18 +871,21 @@ gsk_gpu_device_lookup_texture_image (GskGpuDevice *self, gsk_gpu_cached_use (self, (GskGpuCached *) cache, timestamp); + *out_color_state = cache->color_state; + return g_object_ref (cache->image); } void -gsk_gpu_device_cache_texture_image (GskGpuDevice *self, - GdkTexture *texture, - gint64 timestamp, - GskGpuImage *image) +gsk_gpu_device_cache_texture_image (GskGpuDevice *self, + GdkTexture *texture, + gint64 timestamp, + GskGpuImage *image, + GdkColorState *color_state) { GskGpuCachedTexture *cache; - cache = gsk_gpu_cached_texture_new (self, texture, image); + cache = gsk_gpu_cached_texture_new (self, texture, image, color_state); gsk_gpu_cached_use (self, (GskGpuCached *) cache, timestamp); } diff --git a/gsk/gpu/gskgpudeviceprivate.h b/gsk/gpu/gskgpudeviceprivate.h index 3424a26402..86497df943 100644 --- a/gsk/gpu/gskgpudeviceprivate.h +++ b/gsk/gpu/gskgpudeviceprivate.h @@ -73,11 +73,13 @@ GskGpuImage * gsk_gpu_device_create_download_image (GskGpuD void gsk_gpu_device_make_current (GskGpuDevice *self); GskGpuImage * gsk_gpu_device_lookup_texture_image (GskGpuDevice *self, GdkTexture *texture, - gint64 timestamp); + gint64 timestamp, + GdkColorState **out_color_state); void gsk_gpu_device_cache_texture_image (GskGpuDevice *self, GdkTexture *texture, gint64 timestamp, - GskGpuImage *image); + GskGpuImage *image, + GdkColorState *color_state); typedef enum { diff --git a/gsk/gpu/gskgpudownloadop.c b/gsk/gpu/gskgpudownloadop.c index 42ff54c087..0abf7293cc 100644 --- a/gsk/gpu/gskgpudownloadop.c +++ b/gsk/gpu/gskgpudownloadop.c @@ -145,7 +145,7 @@ gsk_gpu_download_op_vk_command (GskGpuOp *op, GskVulkanDevice *device = GSK_VULKAN_DEVICE (gsk_gpu_frame_get_device (frame)); VkDevice vk_device = gsk_vulkan_device_get_vk_device (device); - gsk_gpu_device_cache_texture_image (GSK_GPU_DEVICE (device), self->texture, gsk_gpu_frame_get_timestamp (frame), self->image); + gsk_gpu_device_cache_texture_image (GSK_GPU_DEVICE (device), self->texture, gsk_gpu_frame_get_timestamp (frame), self->image, gdk_texture_get_color_state (self->texture)); if (gsk_vulkan_device_has_feature (device, GDK_VULKAN_FEATURE_SEMAPHORE_EXPORT)) { diff --git a/gsk/gpu/gskgpuframe.c b/gsk/gpu/gskgpuframe.c index c809ab2c9b..1cfc40d163 100644 --- a/gsk/gpu/gskgpuframe.c +++ b/gsk/gpu/gskgpuframe.c @@ -412,7 +412,7 @@ gsk_gpu_frame_upload_texture (GskGpuFrame *self, image = GSK_GPU_FRAME_GET_CLASS (self)->upload_texture (self, with_mipmap, texture); if (image) - gsk_gpu_device_cache_texture_image (priv->device, texture, priv->timestamp, image); + gsk_gpu_device_cache_texture_image (priv->device, texture, priv->timestamp, image, gdk_texture_get_color_state (texture)); return image; } @@ -707,8 +707,9 @@ gsk_gpu_frame_download_texture (GskGpuFrame *self, { GskGpuFramePrivate *priv = gsk_gpu_frame_get_instance_private (self); GskGpuImage *image; + GdkColorState *color_state = NULL; - image = gsk_gpu_device_lookup_texture_image (priv->device, texture, timestamp); + image = gsk_gpu_device_lookup_texture_image (priv->device, texture, timestamp, &color_state); if (image == NULL) image = gsk_gpu_frame_upload_texture (self, FALSE, texture); if (image == NULL) diff --git a/gsk/gpu/gskgpunodeprocessor.c b/gsk/gpu/gskgpunodeprocessor.c index b8f3054121..3a9b282a6c 100644 --- a/gsk/gpu/gskgpunodeprocessor.c +++ b/gsk/gpu/gskgpunodeprocessor.c @@ -856,6 +856,7 @@ gsk_gpu_node_processor_create_offscreen (GskGpuFrame *frame, * @frame: frame to render in * @clip_bounds: region of node that must be included in image * @scale: scale factor to use for the image + * @color_state: the color state to composite in * @node: the node to render * @out_bounds: the actual bounds of the result * @@ -882,6 +883,7 @@ gsk_gpu_get_node_as_image (GskGpuFrame *frame, graphene_rect_t *out_bounds) { GskGpuImage *result; + GdkColorState *orig_color_state = NULL; switch ((guint) gsk_render_node_get_node_type (node)) { @@ -890,18 +892,16 @@ gsk_gpu_get_node_as_image (GskGpuFrame *frame, GdkTexture *texture = gsk_texture_node_get_texture (node); GskGpuDevice *device = gsk_gpu_frame_get_device (frame); gint64 timestamp = gsk_gpu_frame_get_timestamp (frame); - result = gsk_gpu_device_lookup_texture_image (device, texture, timestamp); + result = gsk_gpu_device_lookup_texture_image (device, texture, timestamp, &orig_color_state); if (result == NULL) { result = gsk_gpu_frame_upload_texture (frame, FALSE, texture); - result = gsk_gpu_color_convert (frame, - result, - gdk_texture_get_color_state (texture), - color_state); + orig_color_state = gdk_texture_get_color_state (texture); } if (result) { + result = gsk_gpu_color_convert (frame, result, orig_color_state, color_state); *out_bounds = node->bounds; return result; } @@ -915,10 +915,8 @@ gsk_gpu_get_node_as_image (GskGpuFrame *frame, (GskGpuCairoFunc) gsk_render_node_draw_fallback, gsk_render_node_ref (node), (GDestroyNotify) gsk_render_node_unref); - result = gsk_gpu_color_convert (frame, - result, - gdk_color_state_get_srgb (), - color_state); + + result = gsk_gpu_color_convert (frame, result, GDK_COLOR_STATE_SRGB, color_state); g_object_ref (result); @@ -1089,7 +1087,8 @@ gsk_gpu_node_processor_get_node_as_image (GskGpuNodeProcessor *self, gsk_gpu_device_cache_texture_image (gsk_gpu_frame_get_device (self->frame), gsk_texture_node_get_texture (node), gsk_gpu_frame_get_timestamp (self->frame), - ensure); + ensure, + self->color_state); } return ensure; @@ -2035,12 +2034,13 @@ gsk_gpu_node_processor_add_texture_node (GskGpuNodeProcessor *self, GskGpuImage *image; GdkTexture *texture; gint64 timestamp; + GdkColorState *color_state = NULL; device = gsk_gpu_frame_get_device (self->frame); texture = gsk_texture_node_get_texture (node); timestamp = gsk_gpu_frame_get_timestamp (self->frame); - image = gsk_gpu_device_lookup_texture_image (device, texture, timestamp); + image = gsk_gpu_device_lookup_texture_image (device, texture, timestamp, &color_state); if (image == NULL) { image = gsk_gpu_frame_upload_texture (self->frame, FALSE, texture); @@ -2053,11 +2053,9 @@ gsk_gpu_node_processor_add_texture_node (GskGpuNodeProcessor *self, gsk_gpu_node_processor_add_fallback_node (self, node); return; } - image = gsk_gpu_color_convert (self->frame, - image, - gdk_texture_get_color_state (texture), - self->color_state); + color_state = gdk_texture_get_color_state (texture); } + image = gsk_gpu_color_convert (self->frame, image, color_state, self->color_state); if (gsk_gpu_frame_should_optimize (self->frame, GSK_GPU_OPTIMIZE_MIPMAP) && (gdk_texture_get_width (texture) > 2 * node->bounds.size.width * graphene_vec2_get_x (&self->scale) || @@ -2114,22 +2112,21 @@ gsk_gpu_node_processor_create_texture_pattern (GskGpuPatternWriter *self, guint32 descriptor; GskGpuImage *image; GskGpuSampler sampler; + GdkColorState *color_state = NULL; device = gsk_gpu_frame_get_device (self->frame); texture = gsk_texture_node_get_texture (node); timestamp = gsk_gpu_frame_get_timestamp (self->frame); - image = gsk_gpu_device_lookup_texture_image (device, texture, timestamp); + image = gsk_gpu_device_lookup_texture_image (device, texture, timestamp, &color_state); if (image == NULL) { image = gsk_gpu_frame_upload_texture (self->frame, FALSE, texture); - image = gsk_gpu_color_convert (self->frame, - image, - gdk_texture_get_color_state (texture), - self->color_state); if (image == NULL) return FALSE; + color_state = gdk_texture_get_color_state (texture); } + image = gsk_gpu_color_convert (self->frame, image, color_state, self->color_state); if (gsk_gpu_frame_should_optimize (self->frame, GSK_GPU_OPTIMIZE_MIPMAP) && (gdk_texture_get_width (texture) > 2 * node->bounds.size.width * graphene_vec2_get_x (&self->scale) || @@ -2176,6 +2173,7 @@ gsk_gpu_node_processor_add_texture_scale_node (GskGpuNodeProcessor *self, gint64 timestamp; guint32 descriptor; gboolean need_mipmap, need_offscreen; + GdkColorState *color_state = NULL; need_offscreen = self->modelview != NULL || !graphene_vec2_equal (&self->scale, graphene_vec2_one ()); @@ -2220,7 +2218,7 @@ gsk_gpu_node_processor_add_texture_scale_node (GskGpuNodeProcessor *self, timestamp = gsk_gpu_frame_get_timestamp (self->frame); need_mipmap = scaling_filter == GSK_SCALING_FILTER_TRILINEAR; - image = gsk_gpu_device_lookup_texture_image (device, texture, timestamp); + image = gsk_gpu_device_lookup_texture_image (device, texture, timestamp, &color_state); if (image == NULL) { image = gsk_gpu_frame_upload_texture (self->frame, need_mipmap, texture); @@ -2233,12 +2231,11 @@ gsk_gpu_node_processor_add_texture_scale_node (GskGpuNodeProcessor *self, gsk_gpu_node_processor_add_fallback_node (self, node); return; } - image = gsk_gpu_color_convert (self->frame, - image, - gdk_texture_get_color_state (texture), - self->color_state); + color_state = gdk_texture_get_color_state (texture); } + image = gsk_gpu_color_convert (self->frame, image, color_state, self->color_state); + image = gsk_gpu_node_processor_ensure_image (self->frame, image, self->color_state,