[gtk/matthiasc/color-profile-rebased: 6/22] Add crude color management impl for cairo
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/matthiasc/color-profile-rebased: 6/22] Add crude color management impl for cairo
- Date: Mon, 9 May 2022 01:48:45 +0000 (UTC)
commit 708474d39a1db17698a826eda306efe3efff5143
Author: Benjamin Otte <otte redhat com>
Date: Sun Sep 26 02:44:54 2021 +0200
Add crude color management impl for cairo
gsk/gskcairorenderer.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 71 insertions(+), 4 deletions(-)
---
diff --git a/gsk/gskcairorenderer.c b/gsk/gskcairorenderer.c
index 24675ce35f..52adecfdeb 100644
--- a/gsk/gskcairorenderer.c
+++ b/gsk/gskcairorenderer.c
@@ -1,5 +1,5 @@
/*
- * Copyright © 2016 Endless
+ * Copyright © 2016 Endless
* 2018 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
@@ -25,6 +25,9 @@
#include "gskdebugprivate.h"
#include "gskrendererprivate.h"
#include "gskrendernodeprivate.h"
+
+#include "gdk/gdkcolorprofileprivate.h"
+#include "gdk/gdkmemorytextureprivate.h"
#include "gdk/gdktextureprivate.h"
#ifdef G_ENABLE_DEBUG
@@ -40,6 +43,7 @@ struct _GskCairoRenderer
GdkCairoContext *cairo_context;
+ gboolean color_managed;
#ifdef G_ENABLE_DEBUG
ProfileTimers profile_timers;
#endif
@@ -78,8 +82,8 @@ gsk_cairo_renderer_do_render (GskRenderer *renderer,
cairo_t *cr,
GskRenderNode *root)
{
-#ifdef G_ENABLE_DEBUG
GskCairoRenderer *self = GSK_CAIRO_RENDERER (renderer);
+#ifdef G_ENABLE_DEBUG
GskProfiler *profiler;
gint64 cpu_time;
#endif
@@ -104,6 +108,7 @@ gsk_cairo_renderer_render_texture (GskRenderer *renderer,
GskRenderNode *root,
const graphene_rect_t *viewport)
{
+ GskCairoRenderer *self = GSK_CAIRO_RENDERER (renderer);
GdkTexture *texture;
cairo_surface_t *surface;
cairo_t *cr;
@@ -127,7 +132,7 @@ gsk_cairo_renderer_render_texture (GskRenderer *renderer,
{
for (x = 0; x < width; x += MAX_IMAGE_SIZE)
{
- texture = gsk_cairo_renderer_render_texture (renderer, root,
+ texture = gsk_cairo_renderer_render_texture (renderer, root,
&GRAPHENE_RECT_INIT (x, y,
MIN (MAX_IMAGE_SIZE,
viewport->size.width - x),
MIN (MAX_IMAGE_SIZE,
viewport->size.height - y)));
@@ -145,6 +150,9 @@ gsk_cairo_renderer_render_texture (GskRenderer *renderer,
}
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
+ if (self->color_managed)
+ gdk_cairo_surface_set_color_profile (surface, gdk_color_profile_get_srgb_linear ());
+
cr = cairo_create (surface);
cairo_translate (cr, - viewport->origin.x, - viewport->origin.y);
@@ -189,7 +197,64 @@ gsk_cairo_renderer_render (GskRenderer *renderer,
}
#endif
- gsk_cairo_renderer_do_render (renderer, cr, root);
+ if (!self->color_managed ||
+ gdk_color_profile_is_linear (gdk_cairo_get_color_profile (cr)))
+ {
+ gsk_cairo_renderer_do_render (renderer, cr, root);
+ }
+ else
+ {
+ GdkSurface *surface = gsk_renderer_get_surface (renderer);
+ GdkColorProfile *target_profile = gdk_cairo_get_color_profile (cr);
+ cairo_surface_t *cairo_surface;
+ cairo_t *cr2;
+ GdkTexture *color_correct;
+ const cairo_region_t *frame_region;
+ cairo_rectangle_int_t extents;
+ guint i, n;
+
+ frame_region = gdk_draw_context_get_frame_region (GDK_DRAW_CONTEXT (self->cairo_context));
+ cairo_region_get_extents (frame_region, &extents);
+ /* We can't use cairo_push_group() here, because we'd lose the
+ * color profile information.
+ */
+ cairo_surface = gdk_surface_create_similar_surface (surface,
+ CAIRO_CONTENT_COLOR_ALPHA,
+ extents.width,
+ extents.height);
+ gdk_cairo_surface_set_color_profile (cairo_surface,
+ gdk_color_profile_get_srgb_linear ());
+
+ cr2 = cairo_create (cairo_surface);
+ cairo_translate (cr2, -extents.x, -extents.y);
+ gdk_cairo_region (cr2, frame_region);
+ cairo_clip (cr2);
+ gsk_cairo_renderer_do_render (renderer, cr2, root);
+ cairo_destroy (cr2);
+
+ color_correct = gdk_texture_new_for_surface (cairo_surface);
+ cairo_surface_destroy (cairo_surface);
+ n = cairo_region_num_rectangles (frame_region);
+ for (i = 0; i < n; i++)
+ {
+ cairo_rectangle_int_t rect;
+ GdkTexture *sub;
+
+ cairo_region_get_rectangle (frame_region, i, &rect);
+ rect.x -= extents.x;
+ rect.y -= extents.y;
+
+ sub = gdk_memory_texture_new_subtexture (GDK_MEMORY_TEXTURE (color_correct),
+ rect.x, rect.y, rect.width, rect.height);
+ cairo_surface = gdk_texture_download_surface (sub, target_profile);
+ cairo_set_source_surface (cr, cairo_surface, rect.x + extents.x, rect.y + extents.y);
+ cairo_paint (cr);
+ cairo_surface_destroy (cairo_surface);
+ g_object_unref (sub);
+ }
+ g_object_unref (color_correct);
+
+ }
cairo_destroy (cr);
@@ -210,6 +275,8 @@ gsk_cairo_renderer_class_init (GskCairoRendererClass *klass)
static void
gsk_cairo_renderer_init (GskCairoRenderer *self)
{
+ self->color_managed = TRUE;
+
#ifdef G_ENABLE_DEBUG
GskProfiler *profiler = gsk_renderer_get_profiler (GSK_RENDERER (self));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]