[gtk/wip/otte/color-profiles: 4/4] FIXME: Add a crude way to color-correct GdkRGBAs
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/color-profiles: 4/4] FIXME: Add a crude way to color-correct GdkRGBAs
- Date: Sun, 26 Sep 2021 22:58:26 +0000 (UTC)
commit 34800cebbfe2cabcecca031e1fd942841c9e0f6c
Author: Benjamin Otte <otte redhat com>
Date: Sun Sep 26 03:03:45 2021 +0200
FIXME: Add a crude way to color-correct GdkRGBAs
Only used in gdk_cairo_set_source_rgba() for now, but works as a proof
of concept.
gdk/gdkcairo.c | 30 +++++++++++++---
gsk/gskcairorenderer.c | 96 +++++++++++++++++++++++++++++++-------------------
2 files changed, 86 insertions(+), 40 deletions(-)
---
diff --git a/gdk/gdkcairo.c b/gdk/gdkcairo.c
index 1f1eb58a61..3a60999871 100644
--- a/gdk/gdkcairo.c
+++ b/gdk/gdkcairo.c
@@ -20,9 +20,28 @@
#include "gdkcairoprivate.h"
#include "gdkcolorprofile.h"
+#include "gdkmemoryformatprivate.h"
#include <math.h>
+static void
+gdk_rgba_convert (GdkRGBA *dest,
+ const GdkRGBA *src,
+ GdkColorProfile *profile)
+{
+ gdk_memory_convert ((guchar *) dest,
+ sizeof (float) * 4,
+ GDK_MEMORY_R32G32B32_FLOAT,
+ profile,
+ (guchar *) src,
+ sizeof (float) * 4,
+ GDK_MEMORY_R32G32B32_FLOAT,
+ gdk_color_profile_get_srgb (),
+ 1,
+ 1);
+ dest->alpha = src->alpha;
+}
+
/**
* gdk_cairo_set_source_rgba:
* @cr: a cairo context
@@ -34,14 +53,17 @@ void
gdk_cairo_set_source_rgba (cairo_t *cr,
const GdkRGBA *rgba)
{
+ GdkRGBA tmp;
+
g_return_if_fail (cr != NULL);
g_return_if_fail (rgba != NULL);
+ gdk_rgba_convert (&tmp, rgba, gdk_cairo_get_color_profile (cr));
cairo_set_source_rgba (cr,
- rgba->red,
- rgba->green,
- rgba->blue,
- rgba->alpha);
+ tmp.red,
+ tmp.green,
+ tmp.blue,
+ tmp.alpha);
}
/**
diff --git a/gsk/gskcairorenderer.c b/gsk/gskcairorenderer.c
index 34625c66a8..9e7bd01cd5 100644
--- a/gsk/gskcairorenderer.c
+++ b/gsk/gskcairorenderer.c
@@ -27,6 +27,7 @@
#include "gskrendernodeprivate.h"
#include "gdk/gdkcolorprofileprivate.h"
+#include "gdk/gdkmemorytextureprivate.h"
#include "gdk/gdktextureprivate.h"
#ifdef G_ENABLE_DEBUG
@@ -91,41 +92,7 @@ gsk_cairo_renderer_do_render (GskRenderer *renderer,
gsk_profiler_timer_begin (profiler, self->profile_timers.cpu_time);
#endif
- if (!self->color_managed ||
- gdk_color_profile_is_linear (gdk_cairo_get_color_profile (cr)))
- {
- gsk_render_node_draw (root, cr);
- }
- else
- {
- GdkSurface *surface = gsk_renderer_get_surface (renderer);
- cairo_surface_t *cairo_surface;
- cairo_t *cr2;
- GdkTexture *color_correct;
-
- /* 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,
- gdk_surface_get_width (surface),
- gdk_surface_get_height (surface));
- gdk_cairo_surface_set_color_profile (cairo_surface,
- gdk_color_profile_get_srgb_linear ());
-
- cr2 = cairo_create (cairo_surface);
- gsk_render_node_draw (root, cr2);
- cairo_destroy (cr2);
-
- color_correct = gdk_texture_new_for_surface (cairo_surface);
- cairo_surface_destroy (cairo_surface);
- cairo_surface = gdk_texture_download_surface (color_correct,
- gdk_cairo_get_color_profile (cr));
- g_object_unref (color_correct);
-
- cairo_set_source_surface (cr, cairo_surface, 0, 0);
- cairo_paint (cr);
- cairo_surface_destroy (cairo_surface);
- }
+ gsk_render_node_draw (root, cr);
#ifdef G_ENABLE_DEBUG
cpu_time = gsk_profiler_timer_end (profiler, self->profile_timers.cpu_time);
@@ -140,11 +107,15 @@ 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;
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, ceil (viewport->size.width), ceil
(viewport->size.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 +160,60 @@ 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;
+ guint i, n;
+
+ /* 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,
+ gdk_surface_get_width (surface),
+ gdk_surface_get_height (surface));
+ gdk_cairo_surface_set_color_profile (cairo_surface,
+ gdk_color_profile_get_srgb_linear ());
+ frame_region = gdk_draw_context_get_frame_region (GDK_DRAW_CONTEXT (self->cairo_context));
+
+ cr2 = cairo_create (cairo_surface);
+ 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;
+ GdkMemoryTexture *sub;
+
+ cairo_region_get_rectangle (frame_region, i, &rect);
+
+ sub = gdk_memory_texture_convert (g_object_ref (GDK_MEMORY_TEXTURE (color_correct)),
+ GDK_MEMORY_DEFAULT,
+ target_profile,
+ &rect);
+ cairo_surface = gdk_texture_download_surface (GDK_TEXTURE (sub), target_profile);
+ cairo_set_source_surface (cr, cairo_surface, rect.x, rect.y);
+ cairo_paint (cr);
+ cairo_surface_destroy (cairo_surface);
+ g_object_unref (sub);
+ }
+ g_object_unref (color_correct);
+
+ }
cairo_destroy (cr);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]