Compare commits

...

32 Commits

Author SHA1 Message Date
Matthias Clasen ec271b47fb wip 2024-08-07 19:18:35 -04:00
Matthias Clasen 80bee35ab7 download op: wip 2024-08-07 18:13:34 -04:00
Matthias Clasen 4be4e53bdd memory convert: debug spew 2024-08-07 18:13:34 -04:00
Matthias Clasen d10c55c748 node processor: spew 2024-08-07 18:13:34 -04:00
Matthias Clasen 60d9d79bcc renderer: debug spew 2024-08-07 18:13:33 -04:00
Matthias Clasen d0fbe1db5a download op: debug spew 2024-08-07 18:13:33 -04:00
Matthias Clasen 44aca0cecf Add a test for render_texture 2024-08-07 18:13:33 -04:00
Matthias Clasen f8afc60c9b Some more color tests 2024-08-07 18:11:35 -04:00
Matthias Clasen 2f26bd9842 colorstate: Change the rendering color state api
Pass an extra boolean that tells whether the target image is GL_SRGB,
in which case, the rendering color state must be srgb-linear.

Update all callers to pass FALSE, except for the one call in
the node processor, where we want to take GL_LINEAR into account.
2024-08-07 18:11:35 -04:00
Matthias Clasen 449fc749e6 Add a compare test for handling of pq colors
The node file here has a pq color that is far out of range for
sRGB, and will produce widely different result if we don't clamp
things properly.
2024-08-07 13:34:45 -04:00
Matthias Clasen 56ea1754bf gsk: Pass color state to download op
This lets us create a texture in the desired color state.
2024-08-07 13:34:45 -04:00
Matthias Clasen cd18bb9fd1 renderer: Make hdr textures if necessary
Take the preferred color state of the content into account
when deciding what color state to use for the texture we
generate.
2024-08-07 13:34:45 -04:00
Matthias Clasen 9f3927e7a7 gsk: Adapt to new rendering colorstate api
Since we now handle the GL_SRGB case when the  node processor calls
get_rendering_color_state, we can just pass SRGB as input here.
2024-08-07 13:34:45 -04:00
Matthias Clasen df18749d6d colorstate: Change the rendering color state api
Pass an extra boolean that tells whether the target image is GL_SRGB,
in which case, the rendering color state must be srgb-linear.

Update all callers to pass FALSE, except for the one call in
the node processor, where we want to take GL_LINEAR into account.
2024-08-07 13:34:45 -04:00
Matthias Clasen 50c19a6534 Merge branch 'hdr-content' into 'main'
gsk: Track whether nodes require wide gamut

See merge request GNOME/gtk!7575
2024-08-07 17:34:02 +00:00
Matthias Clasen 6edb526561 Merge branch 'plug-gtask-leaks' into 'main'
Plug GTask leaks

See merge request GNOME/gtk!7551
2024-08-07 16:26:52 +00:00
Matthias Clasen ee18156675 gsk: Add gsk_render_node_is_hdr
Add a function that tracks whether a render node's content is
in a wide gamut color state (in practice, that means non-sRGB).

This will be used in render_texture to determine the color
state to use when creating a texture.
2024-08-07 11:14:21 -04:00
Matthias Clasen e70a961ac1 Merge branch 'matthiasc/for-main' into 'main'
memoryformat: Add a debug helper

See merge request GNOME/gtk!7571
2024-08-07 14:51:05 +00:00
Matthias Clasen ffdc8c8f60 gsk: Drop some unused code
Nobody is using gsk_gpu_download_png_op, and we are going to
refactor the download op code.
2024-08-07 08:39:53 -04:00
Matthias Clasen fd78bd3eaf memoryformat: Add a debug helper
I need this often enough that I'll just put it here.
2024-08-07 08:22:05 -04:00
Matthias Clasen f2ccba0988 Merge branch 'wip/test-parser-data-additions' into 'main'
testsuite: add more files to test_data

See merge request GNOME/gtk!7569
2024-08-07 03:30:20 +00:00
Jeremy Bícha 8ee465c630 testsuite: add more files to test_data 2024-08-06 20:28:58 -04:00
Matthias Clasen 31b655c9eb Merge branch 'wip/dont-leak-egl-surface' into 'main'
gdk/surface: Don't leak the EGLSurface

See merge request GNOME/gtk!7568
2024-08-06 22:54:31 +00:00
Jonas Ådahl 7fd65cc3c1 gdk/surface: Don't leak the EGLSurface
Each time we create a new window, we create a new EGLSurface. Each time
we destroy a window, we failed to destroy the EGLSurface, due to passing
a GdkDisplay instead of a EGLDisplay to eglDestroySurface().

This effectively leaked not only the EGL surface metadata, but also the
associated DMA buffers. For applications where one opens and closes many
windows over the lifetime of the application, and where the application
runs for a long time; for example a terminal emulator server, this
causes a significant memory leak, as the memory will only ever be freed
once once the application process itself exits, if ever.

Fix this passing an actual EGLDisplay instead of an GdkDisplay, to
eglDestroySurface().
2024-08-06 23:42:11 +02:00
Jonas Ådahl 8089222fc3 gsk/gpu/downloadop: Include glib-unix.h
It's needed by g_close().
2024-08-06 23:41:46 +02:00
Benjamin Otte 0667bd39fb Merge branch 'wip/otte/for-main' into 'main'
gpu: Consult target colorstate for depth

See merge request GNOME/gtk!7567
2024-08-06 21:07:44 +00:00
Benjamin Otte a4854dfa9e memoryformat: Use "(p)" as premultiplied indicator in names
This matches what the gpu renderer does when printing
colorstates.

It also avoids it printing "S*RGBA8" for the format and instead prints
"SRGBA8(p)" now.
2024-08-06 22:15:17 +02:00
Benjamin Otte 6c54d0a7e2 gpu: Consult target colorstate for depth
When creating images for use with different colorstates, ensure that
they have the depth of that colorstate. Otherwise we might lose accuracy
due to quantization.

Fixes mipmaps in rec2100 being rendered as RGBA8.
2024-08-06 22:15:17 +02:00
Matthias Clasen 341860eb4d Merge branch 'small-fixes' into 'main'
colorstate: Drop xyz for now

See merge request GNOME/gtk!7565
2024-08-06 20:06:38 +00:00
Matthias Clasen 876445f080 inspector: Show color states of textures 2024-08-06 15:38:31 -04:00
Matthias Clasen 03ef6a7719 colorstate: Drop xyz for now
Converting to and from xyz turns out to be more difficult than
expected, depending on what whitepoint you choose, And different
specs choose different whitepoints, so we can't directly map
css xyz to cicp xyz anyway.
2024-08-06 15:38:31 -04:00
Sergey Bugaev 85830c059e Plug GTask leaks
The error-prone pattern seems to be:

  GTask *task = g_task_new (...);

  if (condition)
    {
      g_task_return_... (task, ...);
      /* need g_object_unref (task) here! */
      return;
    }

Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
2024-08-05 14:38:23 +03:00
35 changed files with 569 additions and 96 deletions
-1
View File
@@ -168,7 +168,6 @@ gdk_cicp_params_class_init (GdkCicpParamsClass *klass)
* - 5: PAL
* - 6,7: BT.601 / NTSC
* - 9: BT.2020
* - 10: CIE XYZ
* - 12: Display P3
*
* Since: 4.16
-4
View File
@@ -676,10 +676,6 @@ gdk_color_state_new_for_cicp (const GdkCicp *cicp,
to_xyz = rec2020_to_xyz;
from_xyz = xyz_to_rec2020;
break;
case 10:
to_xyz = identity;
from_xyz = identity;
break;
case 12:
to_xyz = p3_to_xyz;
from_xyz = xyz_to_p3;
+8 -1
View File
@@ -78,8 +78,15 @@ GdkColorState * gdk_color_state_new_for_cicp (const GdkCicp
GError **error);
static inline GdkColorState *
gdk_color_state_get_rendering_color_state (GdkColorState *self)
gdk_color_state_get_rendering_color_state (GdkColorState *self,
gboolean srgb)
{
if (srgb)
{
self = gdk_color_state_get_no_srgb_tf (self);
g_assert (self);
}
if (GDK_DEBUG_CHECK (HDR))
self = GDK_COLOR_STATE_REC2100_PQ;
+1 -4
View File
@@ -637,10 +637,7 @@ gdk_gl_context_real_begin_frame (GdkDrawContext *draw_context,
else
*out_depth = GDK_MEMORY_U8;
if (*out_depth == GDK_MEMORY_U8_SRGB)
*out_color_state = gdk_color_state_get_no_srgb_tf (color_state);
else
*out_color_state = color_state;
*out_color_state = color_state;
#else
*out_color_state = gdk_color_state_get_srgb ();
*out_depth = GDK_MEMORY_U8;
+31 -9
View File
@@ -358,7 +358,7 @@ struct _GdkMemoryFormatDescription
static const GdkMemoryFormatDescription memory_formats[] = {
[GDK_MEMORY_B8G8R8A8_PREMULTIPLIED] = {
.name = "*BGRA8",
.name = "BGRA8(p)",
.alpha = GDK_MEMORY_ALPHA_PREMULTIPLIED,
.premultiplied = GDK_MEMORY_B8G8R8A8_PREMULTIPLIED,
.straight = GDK_MEMORY_B8G8R8A8,
@@ -389,7 +389,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
.from_float = b8g8r8a8_premultiplied_from_float,
},
[GDK_MEMORY_A8R8G8B8_PREMULTIPLIED] = {
.name = "*ARGB8",
.name = "ARGB8(p)",
.alpha = GDK_MEMORY_ALPHA_PREMULTIPLIED,
.premultiplied = GDK_MEMORY_A8R8G8B8_PREMULTIPLIED,
.straight = GDK_MEMORY_A8R8G8B8,
@@ -420,7 +420,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
.from_float = a8r8g8b8_premultiplied_from_float,
},
[GDK_MEMORY_R8G8B8A8_PREMULTIPLIED] = {
.name = "*RGBA8",
.name = "RGBA8(p)",
.alpha = GDK_MEMORY_ALPHA_PREMULTIPLIED,
.premultiplied = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,
.straight = GDK_MEMORY_R8G8B8A8,
@@ -450,7 +450,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
.from_float = r8g8b8a8_premultiplied_from_float,
},
[GDK_MEMORY_A8B8G8R8_PREMULTIPLIED] = {
.name = "*ABGR8",
.name = "ABGR8(p)",
.alpha = GDK_MEMORY_ALPHA_PREMULTIPLIED,
.premultiplied = GDK_MEMORY_A8B8G8R8_PREMULTIPLIED,
.straight = GDK_MEMORY_A8B8G8R8,
@@ -828,7 +828,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
.from_float = r16g16b16_from_float,
},
[GDK_MEMORY_R16G16B16A16_PREMULTIPLIED] = {
.name = "*RGBA16",
.name = "RGBA16(p)",
.alpha = GDK_MEMORY_ALPHA_PREMULTIPLIED,
.premultiplied = GDK_MEMORY_R16G16B16A16_PREMULTIPLIED,
.straight = GDK_MEMORY_R16G16B16A16,
@@ -927,7 +927,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
.from_float = r16g16b16_float_from_float,
},
[GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED] = {
.name = "*RGBA16f",
.name = "RGBA16f(p)",
.alpha = GDK_MEMORY_ALPHA_PREMULTIPLIED,
.premultiplied = GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED,
.straight = GDK_MEMORY_R16G16B16A16_FLOAT,
@@ -1024,7 +1024,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
.from_float = r32g32b32_float_from_float,
},
[GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED] = {
.name = "*RGBA32f",
.name = "RGBA32f(p)",
.alpha = GDK_MEMORY_ALPHA_PREMULTIPLIED,
.premultiplied = GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED,
.straight = GDK_MEMORY_R32G32B32A32_FLOAT,
@@ -1088,7 +1088,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
.from_float = r32g32b32a32_float_from_float,
},
[GDK_MEMORY_G8A8_PREMULTIPLIED] = {
.name = "*GA8",
.name = "GA8(p)",
.alpha = GDK_MEMORY_ALPHA_PREMULTIPLIED,
.premultiplied = GDK_MEMORY_G8A8_PREMULTIPLIED,
.straight = GDK_MEMORY_G8A8,
@@ -1181,7 +1181,7 @@ static const GdkMemoryFormatDescription memory_formats[] = {
.from_float = g8_from_float,
},
[GDK_MEMORY_G16A16_PREMULTIPLIED] = {
.name = "*GA16",
.name = "GA16(p)",
.alpha = GDK_MEMORY_ALPHA_PREMULTIPLIED,
.premultiplied = GDK_MEMORY_G16A16_PREMULTIPLIED,
.straight = GDK_MEMORY_G16A16,
@@ -1524,6 +1524,14 @@ gdk_memory_format_get_depth (GdkMemoryFormat format,
return depth;
}
const char *
gdk_memory_depth_get_name (GdkMemoryDepth depth)
{
const char *names[] = { "none", "u8", "u8-srgb", "u16", "f16", "f32" };
return names[depth];
}
/*<private>
* gdk_memory_depth_merge:
* @depth1: the first depth
@@ -1871,6 +1879,12 @@ gdk_memory_convert (guchar *dest_data,
g_assert (dest_data + gdk_memory_format_min_buffer_size (dest_format, dest_stride, width, height) <= src_data ||
src_data + gdk_memory_format_min_buffer_size (src_format, src_stride, width, height) <= dest_data);
g_print ("memory convert %s %s -> %s %s\n",
gdk_memory_format_get_name (src_format),
gdk_color_state_get_name (src_cs),
gdk_memory_format_get_name (dest_format),
gdk_color_state_get_name (dest_cs));
if (src_format == dest_format && gdk_color_state_equal (dest_cs, src_cs))
{
gsize bytes_per_row = src_desc->bytes_per_pixel * width;
@@ -1944,6 +1958,7 @@ gdk_memory_convert (guchar *dest_data,
if (func != NULL)
{
g_print ("convert format\n");
for (y = 0; y < height; y++)
{
func (dest_data, src_data, width);
@@ -1966,10 +1981,13 @@ gdk_memory_convert (guchar *dest_data,
needs_premultiply = src_desc->alpha == GDK_MEMORY_ALPHA_STRAIGHT && dest_desc->alpha != GDK_MEMORY_ALPHA_STRAIGHT;
}
g_print ("convert color %lu %lu\n", width, height);
for (y = 0; y < height; y++)
{
src_desc->to_float (tmp, src_data, width);
g_print ("after to_float: %f %f %f %f\n", tmp[0][0], tmp[0][1], tmp[0][2], tmp[0][3]);
if (needs_unpremultiply)
unpremultiply (tmp, width);
@@ -2151,6 +2169,10 @@ gdk_memory_convert_color_state (guchar *data,
if (gdk_color_state_equal (src_cs, dest_cs))
return;
g_print ("memory convert color state %s -> %s\n",
gdk_color_state_get_name (src_cs),
gdk_color_state_get_name (dest_cs));
if (format == GDK_MEMORY_B8G8R8A8_PREMULTIPLIED &&
src_cs == GDK_COLOR_STATE_SRGB &&
dest_cs == GDK_COLOR_STATE_SRGB_LINEAR)
+1
View File
@@ -66,6 +66,7 @@ GdkMemoryDepth gdk_memory_depth_merge (GdkMemoryDepth
GdkMemoryDepth depth2) G_GNUC_CONST;
GdkMemoryFormat gdk_memory_depth_get_format (GdkMemoryDepth depth) G_GNUC_CONST;
GdkMemoryFormat gdk_memory_depth_get_alpha_format (GdkMemoryDepth depth) G_GNUC_CONST;
const char * gdk_memory_depth_get_name (GdkMemoryDepth depth);
void gdk_memory_format_gl_format (GdkMemoryFormat format,
gboolean gles,
GLint *out_internal_format,
+3 -1
View File
@@ -1132,8 +1132,10 @@ gdk_surface_set_egl_native_window (GdkSurface *self,
if (priv->egl_surface != NULL)
{
GdkDisplay *display = gdk_surface_get_display (self);
gdk_gl_context_clear_current_if_surface (self);
eglDestroySurface (gdk_surface_get_display (self), priv->egl_surface);
eglDestroySurface (gdk_display_get_egl_display (display), priv->egl_surface);
priv->egl_surface = NULL;
}
+1 -4
View File
@@ -678,10 +678,7 @@ gdk_vulkan_context_begin_frame (GdkDrawContext *draw_context,
cairo_region_union (region, priv->regions[priv->draw_index]);
if (priv->current_depth == GDK_MEMORY_U8_SRGB)
*out_color_state = gdk_color_state_get_no_srgb_tf (color_state);
else
*out_color_state = color_state;
*out_color_state = color_state;
*out_depth = priv->current_depth;
}
+3
View File
@@ -236,6 +236,7 @@ gdk_wayland_clipboard_read_async (GdkClipboard *clipboard,
{
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
_("No compatible transfer format found"));
g_object_unref (task);
return;
}
/* offer formats should be empty if we have no offer */
@@ -246,6 +247,7 @@ gdk_wayland_clipboard_read_async (GdkClipboard *clipboard,
if (!g_unix_open_pipe (pipe_fd, O_CLOEXEC, &error))
{
g_task_return_error (task, error);
g_object_unref (task);
return;
}
@@ -253,6 +255,7 @@ gdk_wayland_clipboard_read_async (GdkClipboard *clipboard,
stream = g_unix_input_stream_new (pipe_fd[0], TRUE);
close (pipe_fd[1]);
g_task_return_pointer (task, stream, g_object_unref);
g_object_unref (task);
}
static GInputStream *
+3
View File
@@ -203,6 +203,7 @@ gdk_wayland_drop_read_async (GdkDrop *drop,
{
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
_("No compatible transfer format found"));
g_object_unref (task);
return;
}
@@ -211,6 +212,7 @@ gdk_wayland_drop_read_async (GdkDrop *drop,
if (!g_unix_open_pipe (pipe_fd, O_CLOEXEC, &error))
{
g_task_return_error (task, error);
g_object_unref (task);
return;
}
@@ -218,6 +220,7 @@ gdk_wayland_drop_read_async (GdkDrop *drop,
stream = g_unix_input_stream_new (pipe_fd[0], TRUE);
close (pipe_fd[1]);
g_task_return_pointer (task, stream, g_object_unref);
g_object_unref (task);
}
static GInputStream *
+3
View File
@@ -335,6 +335,7 @@ gdk_wayland_primary_read_async (GdkClipboard *clipboard,
{
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
_("No compatible transfer format found"));
g_object_unref (task);
return;
}
/* offer formats should be empty if we have no offer */
@@ -345,6 +346,7 @@ gdk_wayland_primary_read_async (GdkClipboard *clipboard,
if (!g_unix_open_pipe (pipe_fd, O_CLOEXEC, &error))
{
g_task_return_error (task, error);
g_object_unref (task);
return;
}
@@ -352,6 +354,7 @@ gdk_wayland_primary_read_async (GdkClipboard *clipboard,
stream = g_unix_input_stream_new (pipe_fd[0], TRUE);
close (pipe_fd[1]);
g_task_return_pointer (task, stream, g_object_unref);
g_object_unref (task);
}
static GInputStream *
+9
View File
@@ -1016,6 +1016,7 @@ gdk_win32_drop_read_async (GdkDrop *drop,
{
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
_("No compatible transfer format found"));
g_object_unref (task);
g_clear_pointer (&drop_win32->dropfiles_list, g_free);
return;
@@ -1025,6 +1026,7 @@ gdk_win32_drop_read_async (GdkDrop *drop,
drop_win32->dropfiles_list = NULL;
g_object_set_data (G_OBJECT (stream), "gdk-dnd-stream-contenttype", (gpointer) "text/uri-list");
g_task_return_pointer (task, stream, g_object_unref);
g_object_unref (task);
return;
}
@@ -1035,6 +1037,7 @@ gdk_win32_drop_read_async (GdkDrop *drop,
{
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED,
_("GDK surface 0x%p is not registered as a drop target"), gdk_drop_get_surface (drop));
g_object_unref (task);
return;
}
@@ -1042,6 +1045,7 @@ gdk_win32_drop_read_async (GdkDrop *drop,
{
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED,
_("Target context record 0x%p has no data object"), tctx);
g_object_unref (task);
return;
}
@@ -1061,6 +1065,7 @@ gdk_win32_drop_read_async (GdkDrop *drop,
{
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
_("No compatible transfer format found"));
g_object_unref (task);
return;
}
@@ -1080,6 +1085,7 @@ gdk_win32_drop_read_async (GdkDrop *drop,
{
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED,
_("IDataObject_GetData (0x%x) failed, returning 0x%lx"), fmt.cfFormat, hr);
g_object_unref (task);
return;
}
@@ -1092,6 +1098,7 @@ gdk_win32_drop_read_async (GdkDrop *drop,
if (data == NULL)
{
ReleaseStgMedium (&storage);
g_object_unref (task);
return;
}
@@ -1112,12 +1119,14 @@ gdk_win32_drop_read_async (GdkDrop *drop,
{
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_FAILED,
_("Failed to transmute DnD data W32 format 0x%x to %p (%s)"), pair->w32format, pair->contentformat, pair->contentformat);
g_object_unref (task);
return;
}
stream = g_memory_input_stream_new_from_data (data, data_len, g_free);
g_object_set_data (G_OBJECT (stream), "gdk-dnd-stream-contenttype", (gpointer) pair->contentformat);
g_task_return_pointer (task, stream, g_object_unref);
g_object_unref (task);
}
static GInputStream *
+1
View File
@@ -797,6 +797,7 @@ gdk_x11_clipboard_read_async (GdkClipboard *clipboard,
{
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
_("No compatible transfer format found"));
g_object_unref (task);
return;
}
+1
View File
@@ -233,6 +233,7 @@ gdk_x11_drop_read_async (GdkDrop *drop,
{
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
_("No compatible transfer format found"));
g_object_unref (task);
return;
}
+102 -36
View File
@@ -20,6 +20,7 @@
#include "gdk/gdkglcontextprivate.h"
#ifdef HAVE_DMABUF
#include <glib-unix.h>
#include <linux/dma-buf.h>
#endif
@@ -32,6 +33,8 @@ struct _GskGpuDownloadOp
GskGpuOp op;
GskGpuImage *image;
GdkColorState *image_cs;
GdkColorState *download_cs;
gboolean allow_dmabuf;
GdkGpuDownloadOpCreateFunc create_func;
GskGpuDownloadFunc func;
@@ -52,8 +55,60 @@ gsk_gpu_download_op_finish (GskGpuOp *op)
if (self->create_func)
self->create_func (self);
g_print ("downloaded texture: %s %.4s depth %s format %s color state %s\n",
GDK_IS_DMABUF_TEXTURE (self->texture)
? "dmabuf"
: (GDK_IS_GL_TEXTURE (self->texture)
? "gl"
: "memory"),
GDK_IS_DMABUF_TEXTURE (self->texture)
? (char *) &gdk_dmabuf_texture_get_dmabuf (GDK_DMABUF_TEXTURE (self->texture))->fourcc
: "",
gdk_memory_depth_get_name (gdk_memory_format_get_depth (gdk_texture_get_format (self->texture), FALSE)),
gdk_memory_format_get_name (gdk_texture_get_format (self->texture)),
gdk_color_state_get_name (gdk_texture_get_color_state (self->texture)));
if (!gdk_color_state_equal (gdk_texture_get_color_state (self->texture), self->download_cs))
{
GdkTextureDownloader *downloader;
GdkMemoryTextureBuilder *builder;
GBytes *bytes;
gsize stride;
GdkTexture *texture;
g_print ("converting rendered %s texture after download: %s -> %s\n",
GDK_IS_DMABUF_TEXTURE (self->texture) ? "dmabuf" :
(GDK_IS_GL_TEXTURE (self->texture) ? "gl" : "memory"),
gdk_color_state_get_name (gdk_texture_get_color_state (self->texture)),
gdk_color_state_get_name (self->download_cs));
downloader = gdk_texture_downloader_new (self->texture);
gdk_texture_downloader_set_format (downloader, gdk_texture_get_format (self->texture));
gdk_texture_downloader_set_color_state (downloader, self->download_cs);
bytes = gdk_texture_downloader_download_bytes (downloader, &stride);
gdk_texture_downloader_free (downloader);
builder = gdk_memory_texture_builder_new ();
gdk_memory_texture_builder_set_bytes (builder, bytes);
gdk_memory_texture_builder_set_stride (builder, stride);
gdk_memory_texture_builder_set_width (builder, gdk_texture_get_width (self->texture));
gdk_memory_texture_builder_set_height (builder, gdk_texture_get_height (self->texture));
gdk_memory_texture_builder_set_format (builder, gdk_texture_get_format (self->texture));
gdk_memory_texture_builder_set_color_state (builder, self->download_cs);
texture = gdk_memory_texture_builder_build (builder);
g_object_unref (builder);
g_set_object (&self->texture, texture);
g_bytes_unref (bytes);
g_object_unref (texture);
}
self->func (self->user_data, self->texture);
gdk_color_state_unref (self->image_cs);
gdk_color_state_unref (self->download_cs);
g_object_unref (self->texture);
g_object_unref (self->image);
g_clear_object (&self->buffer);
@@ -69,6 +124,7 @@ gsk_gpu_download_op_print (GskGpuOp *op,
gsk_gpu_print_op (string, indent, "download");
gsk_gpu_print_image (string, self->image);
gsk_gpu_print_string (string, gdk_color_state_get_name (self->download_cs));
gsk_gpu_print_newline (string);
}
@@ -117,6 +173,7 @@ gsk_gpu_download_op_vk_create (GskGpuDownloadOp *self)
guchar *data;
gsize width, height, stride;
GdkMemoryFormat format;
GdkMemoryTextureBuilder *builder;
data = gsk_gpu_buffer_map (self->buffer);
width = gsk_gpu_image_get_width (self->image);
@@ -124,11 +181,18 @@ gsk_gpu_download_op_vk_create (GskGpuDownloadOp *self)
format = gsk_gpu_image_get_format (self->image);
stride = width * gdk_memory_format_bytes_per_pixel (format);
bytes = g_bytes_new (data, stride * height);
self->texture = gdk_memory_texture_new (width,
height,
format,
bytes,
stride);
builder = gdk_memory_texture_builder_new ();
gdk_memory_texture_builder_set_bytes (builder, bytes);
gdk_memory_texture_builder_set_stride (builder, stride);
gdk_memory_texture_builder_set_width (builder, width);
gdk_memory_texture_builder_set_height (builder, height);
gdk_memory_texture_builder_set_format (builder, format);
gdk_memory_texture_builder_set_color_state (builder, self->image_cs);
self->texture = gdk_memory_texture_builder_build (builder);
g_object_unref (builder);
g_bytes_unref (bytes);
gsk_gpu_buffer_unmap (self->buffer, 0);
}
@@ -143,7 +207,17 @@ gsk_gpu_download_op_vk_command (GskGpuOp *op,
#ifdef HAVE_DMABUF
if (self->allow_dmabuf)
self->texture = gsk_vulkan_image_to_dmabuf_texture (GSK_VULKAN_IMAGE (self->image));
{
GdkColorState *cs;
if (gsk_gpu_image_get_flags (self->image) & GSK_GPU_IMAGE_SRGB)
cs = GDK_COLOR_STATE_SRGB;
else
cs = self->image_cs;
self->texture = gsk_vulkan_image_to_dmabuf_texture (GSK_VULKAN_IMAGE (self->image), cs);
}
if (self->texture)
{
GskGpuDevice *device = gsk_gpu_frame_get_device (frame);
@@ -294,10 +368,16 @@ gsk_gpu_download_op_gl_command (GskGpuOp *op,
GskGLTextureData *data;
GdkGLContext *context;
guint texture_id;
GdkColorState *cs;
context = GDK_GL_CONTEXT (gsk_gpu_frame_get_context (frame));
texture_id = gsk_gl_image_steal_texture (GSK_GL_IMAGE (self->image));
if (gsk_gpu_image_get_flags (self->image) & GSK_GPU_IMAGE_SRGB)
cs = GDK_COLOR_STATE_SRGB_LINEAR;
else
cs = self->image_cs;
#ifdef HAVE_DMABUF
if (self->allow_dmabuf)
{
@@ -316,12 +396,20 @@ gsk_gpu_download_op_gl_command (GskGpuOp *op,
gdk_dmabuf_texture_builder_set_width (db, gsk_gpu_image_get_width (self->image));
gdk_dmabuf_texture_builder_set_height (db, gsk_gpu_image_get_height (self->image));
self->texture = gdk_dmabuf_texture_builder_build (db, release_dmabuf_texture, texture, NULL);
gdk_dmabuf_texture_builder_set_color_state (db, cs);
g_print ("dmabuf downloader color state: %s\n", gdk_color_state_get_name (gdk_dmabuf_texture_builder_get_color_state (db)));
self->texture = gdk_dmabuf_texture_builder_build (db,
release_dmabuf_texture,
texture,
NULL);
g_object_unref (db);
if (self->texture)
return op->next;
else
g_print ("failed to build dmabuf texture\n");
}
g_free (texture);
@@ -342,6 +430,7 @@ gsk_gpu_download_op_gl_command (GskGpuOp *op,
gdk_gl_texture_builder_set_width (builder, gsk_gpu_image_get_width (self->image));
gdk_gl_texture_builder_set_height (builder, gsk_gpu_image_get_height (self->image));
gdk_gl_texture_builder_set_sync (builder, data->sync);
gdk_gl_texture_builder_set_color_state (builder, cs);
self->texture = gdk_gl_texture_builder_build (builder,
gsk_gl_texture_data_free,
@@ -366,6 +455,8 @@ static const GskGpuOpClass GSK_GPU_DOWNLOAD_OP_CLASS = {
void
gsk_gpu_download_op (GskGpuFrame *frame,
GskGpuImage *image,
GdkColorState *image_cs,
GdkColorState *download_cs,
gboolean allow_dmabuf,
GskGpuDownloadFunc func,
gpointer user_data)
@@ -376,35 +467,10 @@ gsk_gpu_download_op (GskGpuFrame *frame,
self->image = g_object_ref (image);
self->allow_dmabuf = allow_dmabuf;
self->image_cs = gdk_color_state_ref (image_cs);
self->download_cs = gdk_color_state_ref (download_cs);
self->func = func,
self->user_data = user_data;
}
static void
gsk_gpu_download_save_png_cb (gpointer filename,
GdkTexture *texture)
{
gdk_texture_save_to_png (texture, filename);
g_free (filename);
}
void
gsk_gpu_download_png_op (GskGpuFrame *frame,
GskGpuImage *image,
const char *filename_format,
...)
{
va_list args;
char *filename;
va_start (args, filename_format);
filename = g_strdup_vprintf (filename_format, args);
va_end (args);
gsk_gpu_download_op (frame,
image,
FALSE,
gsk_gpu_download_save_png_cb,
filename);
}
+2 -5
View File
@@ -9,14 +9,11 @@ typedef void (* GskGpuDownloadFunc) (gpointe
void gsk_gpu_download_op (GskGpuFrame *frame,
GskGpuImage *image,
GdkColorState *image_cs,
GdkColorState *download_cs,
gboolean allow_dmabuf,
GskGpuDownloadFunc func,
gpointer user_data);
void gsk_gpu_download_png_op (GskGpuFrame *frame,
GskGpuImage *image,
const char *filename_format,
...) G_GNUC_PRINTF(3, 4);
G_END_DECLS
+16 -1
View File
@@ -671,7 +671,20 @@ gsk_gpu_frame_record (GskGpuFrame *self,
}
if (texture)
gsk_gpu_download_op (self, target, TRUE, copy_texture, texture);
{
GdkColorState *image_cs;
GdkColorState *download_cs;
image_cs = gdk_color_state_get_rendering_color_state (target_color_state,
gsk_gpu_image_get_flags (target) & GSK_GPU_IMAGE_SRGB);
if (image_cs == GDK_COLOR_STATE_SRGB_LINEAR)
download_cs = GDK_COLOR_STATE_SRGB;
else
download_cs = image_cs;
gsk_gpu_download_op (self, target, target_color_state, download_cs, TRUE, copy_texture, texture);
}
}
static void
@@ -778,6 +791,8 @@ gsk_gpu_frame_download_texture (GskGpuFrame *self,
gsk_gpu_download_op (self,
image,
gdk_texture_get_color_state (texture),
color_state,
FALSE,
do_download,
g_memdup (&(Download) {
+20 -3
View File
@@ -620,15 +620,18 @@ gsk_gpu_copy_image (GskGpuFrame *frame,
GskGpuImage *copy;
gsize width, height;
GskGpuImageFlags flags;
GdkMemoryDepth depth;
width = gsk_gpu_image_get_width (image);
height = gsk_gpu_image_get_height (image);
flags = gsk_gpu_image_get_flags (image);
depth = gdk_memory_format_get_depth (gsk_gpu_image_get_format (image),
flags & GSK_GPU_IMAGE_SRGB);
depth = gdk_memory_depth_merge (depth, gdk_color_state_get_depth (ccs));
copy = gsk_gpu_device_create_offscreen_image (gsk_gpu_frame_get_device (frame),
prepare_mipmap,
gdk_memory_format_get_depth (gsk_gpu_image_get_format (image),
flags & GSK_GPU_IMAGE_SRGB),
depth,
width, height);
if (gsk_gpu_frame_should_optimize (frame, GSK_GPU_OPTIMIZE_BLIT) &&
@@ -1581,10 +1584,18 @@ gsk_gpu_node_processor_add_color_node (GskGpuNodeProcessor *self,
}
gdk_color_to_float (gsk_color_node_get_color2 (node), self->ccs, clear_color);
g_print ("node processor: add color via clear %s -> %s %f %f %f %f\n",
gdk_color_to_string (gsk_color_node_get_color2 (node)),
gdk_color_state_get_name (self->ccs),
clear_color[0], clear_color[1], clear_color[2], clear_color[3]);
gsk_gpu_clear_op (self->frame, &int_clipped, clear_color);
return;
}
g_print ("node processor: add color %s -> %s\n",
gdk_color_to_string (gsk_color_node_get_color2 (node)),
gdk_color_state_get_name (self->ccs));
gsk_gpu_color_op (self->frame,
gsk_gpu_clip_get_shader_clip (&self->clip, &self->offset, &node->bounds),
self->ccs,
@@ -1612,6 +1623,10 @@ gsk_gpu_node_processor_add_first_color_node (GskGpuNodeProcessor *self,
return FALSE;
gdk_color_to_float (gsk_color_node_get_color2 (node), self->ccs, clear_color);
g_print ("node processor: add first color %s -> %s %f %f %f %f\n",
gdk_color_to_string (gsk_color_node_get_color2 (node)),
gdk_color_state_get_name (self->ccs),
clear_color[0], clear_color[1], clear_color[2], clear_color[3]);
gsk_gpu_render_pass_begin_op (self->frame,
target,
clip,
@@ -3902,7 +3917,9 @@ gsk_gpu_node_processor_process (GskGpuFrame *frame,
clip,
viewport);
ccs = gdk_color_state_get_rendering_color_state (target_color_state);
ccs = gdk_color_state_get_rendering_color_state (target_color_state, gsk_gpu_image_get_flags (target) & GSK_GPU_IMAGE_SRGB);
g_print ("node processor: rendering color state %s\n", gdk_color_state_get_name (ccs));
if (gdk_color_state_equal (ccs, target_color_state))
{
+14 -9
View File
@@ -299,10 +299,7 @@ gsk_gpu_renderer_fallback_render_texture (GskGpuRenderer *self,
MIN (image_width, width - x),
MIN (image_height, height - y));
if (gsk_gpu_image_get_flags (image) & GSK_GPU_IMAGE_SRGB)
color_state = GDK_COLOR_STATE_SRGB_LINEAR;
else
color_state = GDK_COLOR_STATE_SRGB;
color_state = GDK_COLOR_STATE_SRGB;
frame = gsk_gpu_renderer_create_frame (self);
gsk_gpu_frame_render (frame,
@@ -352,6 +349,7 @@ gsk_gpu_renderer_render_texture (GskRenderer *renderer,
GdkTexture *texture;
graphene_rect_t rounded_viewport;
GdkColorState *color_state;
GdkMemoryDepth depth;
gsk_gpu_device_maybe_gc (priv->device);
@@ -361,18 +359,25 @@ gsk_gpu_renderer_render_texture (GskRenderer *renderer,
viewport->origin.y,
ceil (viewport->size.width),
ceil (viewport->size.height));
if (gsk_render_node_is_hdr (root))
color_state = GDK_COLOR_STATE_REC2100_PQ;
else
color_state = GDK_COLOR_STATE_SRGB;
depth = gdk_memory_depth_merge (gsk_render_node_get_preferred_depth (root),
gdk_color_state_get_depth (color_state));
image = gsk_gpu_device_create_download_image (priv->device,
gsk_render_node_get_preferred_depth (root),
depth,
rounded_viewport.size.width,
rounded_viewport.size.height);
if (image == NULL)
return gsk_gpu_renderer_fallback_render_texture (self, root, &rounded_viewport);
if (gsk_gpu_image_get_flags (image) & GSK_GPU_IMAGE_SRGB)
color_state = GDK_COLOR_STATE_SRGB_LINEAR;
else
color_state = GDK_COLOR_STATE_SRGB;
g_print ("render_texture: image depth %s, target color state %s\n",
gdk_memory_depth_get_name (depth), gdk_color_state_get_name (color_state));
frame = gsk_gpu_renderer_create_frame (self);
+3 -1
View File
@@ -1176,7 +1176,8 @@ gsk_vulkan_image_get_n_planes (GskVulkanImage *self,
}
GdkTexture *
gsk_vulkan_image_to_dmabuf_texture (GskVulkanImage *self)
gsk_vulkan_image_to_dmabuf_texture (GskVulkanImage *self,
GdkColorState *color_state)
{
GskGpuImage *image = GSK_GPU_IMAGE (self);
GdkDmabufTextureBuilder *builder;
@@ -1226,6 +1227,7 @@ gsk_vulkan_image_to_dmabuf_texture (GskVulkanImage *self)
gdk_dmabuf_texture_builder_set_display (builder, gsk_gpu_device_get_display (GSK_GPU_DEVICE (self->device)));
gdk_dmabuf_texture_builder_set_width (builder, gsk_gpu_image_get_width (image));
gdk_dmabuf_texture_builder_set_height (builder, gsk_gpu_image_get_height (image));
gdk_dmabuf_texture_builder_set_color_state (builder, color_state);
gdk_dmabuf_texture_builder_set_fourcc (builder, fourcc);
gdk_dmabuf_texture_builder_set_modifier (builder, properties.drmFormatModifier);
gdk_dmabuf_texture_builder_set_premultiplied (builder, !(gsk_gpu_image_get_flags (image) & GSK_GPU_IMAGE_STRAIGHT_ALPHA));
+2 -1
View File
@@ -44,7 +44,8 @@ GskGpuImage * gsk_vulkan_image_new_for_dmabuf (GskVulk
gsize height,
const GdkDmabuf *dmabuf,
gboolean premultiplied);
GdkTexture * gsk_vulkan_image_to_dmabuf_texture (GskVulkanImage *self);
GdkTexture * gsk_vulkan_image_to_dmabuf_texture (GskVulkanImage *self,
GdkColorState *color_state);
#endif
guchar * gsk_vulkan_image_get_data (GskVulkanImage *self,
+8 -2
View File
@@ -380,7 +380,7 @@ gsk_render_node_draw_ccs (GskRenderNode *node,
GdkColorState *ccs)
{
/* Check that the calling function did pass a correct color state */
g_assert (ccs == gdk_color_state_get_rendering_color_state (ccs));
g_assert (ccs == gdk_color_state_get_rendering_color_state (ccs, FALSE));
cairo_save (cr);
@@ -413,7 +413,7 @@ gsk_render_node_draw_with_color_state (GskRenderNode *node,
{
GdkColorState *ccs;
ccs = gdk_color_state_get_rendering_color_state (color_state);
ccs = gdk_color_state_get_rendering_color_state (color_state, FALSE);
if (gdk_color_state_equal (color_state, ccs))
{
@@ -827,6 +827,12 @@ gsk_render_node_get_preferred_depth (const GskRenderNode *node)
return node->preferred_depth;
}
gboolean
gsk_render_node_is_hdr (const GskRenderNode *node)
{
return node->is_hdr;
}
/* Whether we need an offscreen to handle opacity correctly for this node.
* We don't if there is only one drawing node inside (could be child
* node, or grandchild, or...).
+38 -1
View File
@@ -91,6 +91,17 @@ my_color_stops_get_depth (const GskColorStop *stops,
return gdk_color_state_get_depth (GDK_COLOR_STATE_SRGB);
}
static inline gboolean
color_state_is_hdr (GdkColorState *color_state)
{
GdkColorState *rendering_cs;
rendering_cs = gdk_color_state_get_rendering_color_state (color_state, FALSE);
return rendering_cs != GDK_COLOR_STATE_SRGB &&
rendering_cs != GDK_COLOR_STATE_SRGB_LINEAR;
}
/* apply a rectangle that bounds @rect in
* pixel-aligned device coordinates.
*
@@ -316,6 +327,7 @@ gsk_color_node_new2 (const GdkColor *color,
node->offscreen_for_opacity = FALSE;
node->fully_opaque = gdk_color_is_opaque (color);
node->preferred_depth = gdk_color_get_depth (color);
node->is_hdr = color_state_is_hdr (color->color_state);
gdk_color_init_copy (&self->color, color);
@@ -1978,6 +1990,7 @@ gsk_texture_node_new (GdkTexture *texture,
node = (GskRenderNode *) self;
node->offscreen_for_opacity = FALSE;
node->fully_opaque = gdk_memory_format_alpha (gdk_texture_get_format (texture)) == GDK_MEMORY_ALPHA_OPAQUE;
node->is_hdr = color_state_is_hdr (gdk_texture_get_color_state (texture));
self->texture = g_object_ref (texture);
gsk_rect_init_from_rect (&node->bounds, bounds);
@@ -2200,6 +2213,7 @@ gsk_texture_scale_node_new (GdkTexture *texture,
node->fully_opaque = gdk_memory_format_alpha (gdk_texture_get_format (texture)) == GDK_MEMORY_ALPHA_OPAQUE &&
bounds->size.width == floor (bounds->size.width) &&
bounds->size.height == floor (bounds->size.height);
node->is_hdr = color_state_is_hdr (gdk_texture_get_color_state (texture));
self->texture = g_object_ref (texture);
gsk_rect_init_from_rect (&node->bounds, bounds);
@@ -3481,6 +3495,7 @@ gsk_container_node_new (GskRenderNode **children,
{
graphene_rect_t child_opaque;
gboolean have_opaque;
gboolean is_hdr;
self->children = g_malloc_n (n_children, sizeof (GskRenderNode *));
@@ -3489,6 +3504,7 @@ gsk_container_node_new (GskRenderNode **children,
node->preferred_depth = children[0]->preferred_depth;
gsk_rect_init_from_rect (&node->bounds, &(children[0]->bounds));
have_opaque = gsk_render_node_get_opaque_rect (self->children[0], &self->opaque);
is_hdr = gsk_render_node_is_hdr (self->children[0]);
for (guint i = 1; i < n_children; i++)
{
@@ -3507,10 +3523,13 @@ gsk_container_node_new (GskRenderNode **children,
have_opaque = TRUE;
}
}
is_hdr |= gsk_render_node_is_hdr (self->children[i]);
}
node->offscreen_for_opacity = node->offscreen_for_opacity || !self->disjoint;
}
node->is_hdr = is_hdr;
}
return node;
}
@@ -3805,6 +3824,7 @@ gsk_transform_node_new (GskRenderNode *child,
&node->bounds);
node->preferred_depth = gsk_render_node_get_preferred_depth (child);
node->is_hdr = gsk_render_node_is_hdr (child);
return node;
}
@@ -3957,6 +3977,7 @@ gsk_opacity_node_new (GskRenderNode *child,
gsk_rect_init_from_rect (&node->bounds, &child->bounds);
node->preferred_depth = gsk_render_node_get_preferred_depth (child);
node->is_hdr = gsk_render_node_is_hdr (child);
return node;
}
@@ -4190,6 +4211,7 @@ gsk_color_matrix_node_new (GskRenderNode *child,
gsk_rect_init_from_rect (&node->bounds, &child->bounds);
node->preferred_depth = gsk_render_node_get_preferred_depth (child);
node->is_hdr = gsk_render_node_is_hdr (child);
return node;
}
@@ -4497,6 +4519,7 @@ gsk_repeat_node_new (const graphene_rect_t *bounds,
}
node->preferred_depth = gsk_render_node_get_preferred_depth (child);
node->is_hdr = gsk_render_node_is_hdr (child);
node->fully_opaque = child->fully_opaque && gsk_rect_contains_rect (&child->bounds, &self->child_bounds);
return node;
@@ -4664,6 +4687,7 @@ gsk_clip_node_new (GskRenderNode *child,
gsk_rect_intersection (&self->clip, &child->bounds, &node->bounds);
node->preferred_depth = gsk_render_node_get_preferred_depth (child);
node->is_hdr = gsk_render_node_is_hdr (child);
return node;
}
@@ -4847,6 +4871,7 @@ gsk_rounded_clip_node_new (GskRenderNode *child,
gsk_rect_intersection (&self->clip.bounds, &child->bounds, &node->bounds);
node->preferred_depth = gsk_render_node_get_preferred_depth (child);
node->is_hdr = gsk_render_node_is_hdr (child);
return node;
}
@@ -5017,6 +5042,7 @@ gsk_fill_node_new (GskRenderNode *child,
node = (GskRenderNode *) self;
node->offscreen_for_opacity = child->offscreen_for_opacity;
node->preferred_depth = gsk_render_node_get_preferred_depth (child);
node->is_hdr = gsk_render_node_is_hdr (child);
self->child = gsk_render_node_ref (child);
self->path = gsk_path_ref (path);
@@ -5227,6 +5253,7 @@ gsk_stroke_node_new (GskRenderNode *child,
node = (GskRenderNode *) self;
node->offscreen_for_opacity = child->offscreen_for_opacity;
node->preferred_depth = gsk_render_node_get_preferred_depth (child);
node->is_hdr = gsk_render_node_is_hdr (child);
self->child = gsk_render_node_ref (child);
self->path = gsk_path_ref (path);
@@ -5504,6 +5531,7 @@ gsk_shadow_node_new (GskRenderNode *child,
gsk_shadow_node_get_bounds (self, &node->bounds);
node->preferred_depth = gsk_render_node_get_preferred_depth (child);
node->is_hdr = gsk_render_node_is_hdr (child);
for (i = 0; i < n_shadows; i++)
{
node->preferred_depth = gdk_memory_depth_merge (node->preferred_depth,
@@ -5727,6 +5755,8 @@ gsk_blend_node_new (GskRenderNode *bottom,
node->preferred_depth = gdk_memory_depth_merge (gsk_render_node_get_preferred_depth (bottom),
gsk_render_node_get_preferred_depth (top));
node->is_hdr = gsk_render_node_is_hdr (bottom) ||
gsk_render_node_is_hdr (top);
return node;
}
@@ -5914,6 +5944,8 @@ gsk_cross_fade_node_new (GskRenderNode *start,
node->preferred_depth = gdk_memory_depth_merge (gsk_render_node_get_preferred_depth (start),
gsk_render_node_get_preferred_depth (end));
node->is_hdr = gsk_render_node_is_hdr (start) ||
gsk_render_node_is_hdr (end);
return node;
}
@@ -6566,6 +6598,7 @@ gsk_blur_node_new (GskRenderNode *child,
graphene_rect_inset (&self->render_node.bounds, - clip_radius, - clip_radius);
node->preferred_depth = gsk_render_node_get_preferred_depth (child);
node->is_hdr = gsk_render_node_is_hdr (child);
return node;
}
@@ -6802,6 +6835,8 @@ gsk_mask_node_new (GskRenderNode *source,
self->render_node.bounds = *graphene_rect_zero ();
self->render_node.preferred_depth = gsk_render_node_get_preferred_depth (source);
self->render_node.is_hdr = gsk_render_node_is_hdr (source) ||
gsk_render_node_is_hdr (mask);
return &self->render_node;
}
@@ -6980,6 +7015,7 @@ gsk_debug_node_new (GskRenderNode *child,
gsk_rect_init_from_rect (&node->bounds, &child->bounds);
node->preferred_depth = gsk_render_node_get_preferred_depth (child);
self->render_node.is_hdr = gsk_render_node_is_hdr (child);
return node;
}
@@ -7402,6 +7438,7 @@ gsk_subsurface_node_new (GskRenderNode *child,
gsk_rect_init_from_rect (&node->bounds, &child->bounds);
node->preferred_depth = gsk_render_node_get_preferred_depth (child);
node->is_hdr = gsk_render_node_is_hdr (child);
return node;
}
+2
View File
@@ -36,6 +36,7 @@ struct _GskRenderNode
guint preferred_depth : GDK_MEMORY_DEPTH_BITS;
guint offscreen_for_opacity : 1;
guint fully_opaque : 1;
guint is_hdr : 1;
};
typedef struct
@@ -106,6 +107,7 @@ void gsk_transform_node_get_translate (const GskRenderNode
float *dx,
float *dy);
GdkMemoryDepth gsk_render_node_get_preferred_depth (const GskRenderNode *node) G_GNUC_PURE;
gboolean gsk_render_node_is_hdr (const GskRenderNode *node) G_GNUC_PURE;
gboolean gsk_container_node_is_disjoint (const GskRenderNode *node) G_GNUC_PURE;
+1
View File
@@ -222,6 +222,7 @@ gtk_color_picker_win32_pick (GtkColorPicker *cp,
G_IO_ERROR,
G_IO_ERROR_FAILED,
"Cannot capture the mouse pointer");
g_object_unref (picker->task);
return;
}
+3
View File
@@ -485,6 +485,7 @@ gtk_file_launcher_launch (GtkFileLauncher *self,
g_task_return_new_error (task,
GTK_DIALOG_ERROR, GTK_DIALOG_ERROR_FAILED,
"No file to launch");
g_object_unref (task);
return;
}
@@ -576,6 +577,7 @@ gtk_file_launcher_open_containing_folder (GtkFileLauncher *self,
g_task_return_new_error (task,
GTK_DIALOG_ERROR, GTK_DIALOG_ERROR_FAILED,
"No file to open");
g_object_unref (task);
return;
}
@@ -584,6 +586,7 @@ gtk_file_launcher_open_containing_folder (GtkFileLauncher *self,
g_task_return_new_error (task,
GTK_DIALOG_ERROR, GTK_DIALOG_ERROR_FAILED,
"Operation not supported on non-native files");
g_object_unref (task);
return;
}
+2
View File
@@ -292,6 +292,7 @@ gtk_uri_launcher_launch (GtkUriLauncher *self,
g_task_return_new_error (task,
GTK_DIALOG_ERROR, GTK_DIALOG_ERROR_FAILED,
"No uri to launch");
g_object_unref (task);
return;
}
@@ -301,6 +302,7 @@ gtk_uri_launcher_launch (GtkUriLauncher *self,
GTK_DIALOG_ERROR, GTK_DIALOG_ERROR_FAILED,
"%s is not a valid uri: %s", self->uri, error->message);
g_error_free (error);
g_object_unref (task);
return;
}
+2
View File
@@ -990,6 +990,8 @@ add_texture_rows (GListStore *store,
add_text_row (store, "Type", "%s", G_OBJECT_TYPE_NAME (texture));
add_text_row (store, "Size", "%u x %u", gdk_texture_get_width (texture), gdk_texture_get_height (texture));
add_text_row (store, "Format", "%s", enum_to_nick (GDK_TYPE_MEMORY_FORMAT, gdk_texture_get_format (texture)));
add_text_row (store, "Color State", "%s", gdk_color_state_get_name (gdk_texture_get_color_state (texture)));
if (GDK_IS_MEMORY_TEXTURE (texture))
{
GBytes *bytes;
+7
View File
@@ -128,6 +128,7 @@ test_data = [
'at-valid-16.errors',
'at-valid-16.ref.css',
'at-valid-17.css',
'at-valid-17.errors',
'at-valid-18.css',
'at-valid-18.ref.css',
'background-blend-mode.css',
@@ -147,6 +148,7 @@ test_data = [
'background-repeat.css',
'background-repeat.ref.css',
'background-shorthand.css',
'background-shorthand.errors',
'background-shorthand.ref.css',
'background-shorthand-single.css',
'background-shorthand-single.ref.css',
@@ -207,6 +209,7 @@ test_data = [
'close-at-end-of-file.errors',
'close-at-end-of-file.ref.css',
'color.css',
'color.errors',
'color.ref.css',
'colors-errors.css',
'colors-errors.errors',
@@ -229,6 +232,8 @@ test_data = [
'css-21-malformed-statements.errors',
'css-21-malformed-statements.ref.css',
'currentcolor-everywhere.css',
'currentcolor-everywhere.ref.css',
'currentcolor-everywhere.errors',
'dash-backslash-eof-is-identifier.ref.css',
'dash-backslash-eof-is-identifier.css',
'dash-backslash-eof-is-identifier.errors',
@@ -286,6 +291,7 @@ test_data = [
'declarations-valid-08.css',
'declarations-valid-08.ref.css',
'declarations-valid-09.css',
'declarations-valid-09.errors',
'declarations-valid-09.ref.css',
'declarations-valid-10.css',
'declarations-valid-10.ref.css',
@@ -493,6 +499,7 @@ test_data = [
'selector-original.css',
'selector-original.ref.css',
'shadow.css',
'shadow.errors',
'shadow.ref.css',
'shadow-ordering.css',
'shadow-ordering.ref.css',
+84 -1
View File
@@ -1,6 +1,7 @@
#include <gdk/gdk.h>
#include <gtk.h>
#include "gdkcolorstateprivate.h"
#include "gdkcolorprivate.h"
#include "gdkdebugprivate.h"
#include <math.h>
#include "gdkcolordefs.h"
@@ -158,9 +159,88 @@ test_color_mislabel (void)
g_assert_true (red1 != red2);
}
static void
test_rendering_colorstate (void)
{
struct {
GdkColorState *surface;
gboolean srgb;
GdkColorState *rendering;
} tests[] = {
{ GDK_COLOR_STATE_SRGB, 0, GDK_COLOR_STATE_SRGB },
{ GDK_COLOR_STATE_SRGB, 1, GDK_COLOR_STATE_SRGB_LINEAR },
{ GDK_COLOR_STATE_SRGB_LINEAR, 0, GDK_COLOR_STATE_SRGB_LINEAR },
{ GDK_COLOR_STATE_SRGB_LINEAR, 1, GDK_COLOR_STATE_SRGB_LINEAR },
{ GDK_COLOR_STATE_REC2100_PQ, 0, GDK_COLOR_STATE_REC2100_PQ },
{ GDK_COLOR_STATE_REC2100_PQ, 1, GDK_COLOR_STATE_SRGB_LINEAR },
{ GDK_COLOR_STATE_REC2100_LINEAR, 0, GDK_COLOR_STATE_REC2100_LINEAR },
{ GDK_COLOR_STATE_REC2100_LINEAR, 1, GDK_COLOR_STATE_SRGB_LINEAR },
};
if (GDK_DEBUG_CHECK (HDR) || GDK_DEBUG_CHECK (LINEAR))
{
g_test_skip ("Skip because GDK_DEBUG flags hdr or linear are set");
return;
}
for (int i = 0; i < G_N_ELEMENTS (tests); i++)
{
GdkColorState *res = gdk_color_state_get_rendering_color_state (tests[i].surface, tests[i].srgb);
g_assert_true (gdk_color_state_equal (res, tests[i].rendering));
}
}
static void
test_color_conversion (void)
{
GdkColor color;
GdkColor color2;
GdkColor color3;
gdk_color_init (&color, GDK_COLOR_STATE_REC2100_PQ, (float[4]) { 0, 0.5, 1, 1 });
gdk_color_convert (&color2, GDK_COLOR_STATE_REC2100_LINEAR, &color);
g_assert_cmpfloat_with_epsilon (0, color2.values[0], 0.005);
g_assert_cmpfloat_with_epsilon (0.45, color2.values[1], 0.005);
g_assert_cmpfloat_with_epsilon (49.26, color2.values[2], 0.005);
g_assert_cmpfloat_with_epsilon (1, color2.values[3], 0.005);
gdk_color_convert (&color3, GDK_COLOR_STATE_REC2100_PQ, &color2);
g_assert_cmpfloat_with_epsilon (color3.values[0], color.values[0], 0.005);
g_assert_cmpfloat_with_epsilon (color3.values[1], color.values[1], 0.005);
g_assert_cmpfloat_with_epsilon (color3.values[2], color.values[2], 0.005);
g_assert_cmpfloat_with_epsilon (color3.values[3], color.values[3], 0.005);
gdk_color_finish (&color);
gdk_color_finish (&color2);
gdk_color_finish (&color3);
gdk_color_init (&color, GDK_COLOR_STATE_SRGB, (float[4]) { 0, 0.5, 1, 1 });
gdk_color_convert (&color2, GDK_COLOR_STATE_REC2100_LINEAR, &color);
g_assert_cmpfloat_with_epsilon (0.114, color2.values[0], 0.005);
g_assert_cmpfloat_with_epsilon (0.208, color2.values[1], 0.005);
g_assert_cmpfloat_with_epsilon (0.914, color2.values[2], 0.005);
g_assert_cmpfloat_with_epsilon (1, color2.values[3], 0.005);
gdk_color_convert (&color3, GDK_COLOR_STATE_SRGB, &color2);
g_assert_cmpfloat_with_epsilon (color3.values[0], color.values[0], 0.005);
g_assert_cmpfloat_with_epsilon (color3.values[1], color.values[1], 0.005);
g_assert_cmpfloat_with_epsilon (color3.values[2], color.values[2], 0.005);
g_assert_cmpfloat_with_epsilon (color3.values[3], color.values[3], 0.005);
gdk_color_finish (&color);
gdk_color_finish (&color2);
gdk_color_finish (&color3);
}
int
main (int argc, char *argv[])
{
gtk_init ();
(g_test_init) (&argc, &argv, NULL);
for (guint i = 0; i < G_N_ELEMENTS (transfers); i++)
@@ -181,7 +261,10 @@ main (int argc, char *argv[])
g_test_add_func ("/colorstate/matrix/srgb_to_rec2020", test_srgb_to_rec2020);
g_test_add_func ("/colorstate/matrix/rec2020_to_srgb", test_rec2020_to_srgb);
g_test_add_func ("/colorstate/rendering", test_rendering_colorstate);
g_test_add_func ("/color/mislabel", test_color_mislabel);
g_test_add_func ("/color/conversion", test_color_conversion);
return g_test_run ();
}
@@ -0,0 +1,4 @@
color {
bounds: 0 0 50 50;
color: color(rec2100-pq 1 0 0 / 0.2);
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 222 B

+2
View File
@@ -46,6 +46,7 @@ compare_render_tests = [
'color-matrix-identity',
'color-matrix-merge',
'color-matrix-parsing',
'color-pq-transparency',
'color-states',
'conic-gradient-with-64-colorstops',
'container-single-child-offscreen-for-opacity',
@@ -530,6 +531,7 @@ tests = [
[ 'path', [ 'path-utils.c' ], [ 'flaky'] ],
[ 'path-special-cases' ],
[ 'scaling' ],
[ 'rendertexture' ],
]
test_cargs = []
+191
View File
@@ -0,0 +1,191 @@
#include <gtk/gtk.h>
enum {
GDK_COLOR_STATE_SRGB,
GDK_COLOR_STATE_SRGB_LINEAR,
GDK_COLOR_STATE_REC2100_PQ,
GDK_COLOR_STATE_REC2100_LINEAR,
};
typedef struct {
const char *renderer;
const char *debug;
gboolean hdr_content;
guint expected;
} TextureTest;
static TextureTest tests[] = {
{ "ngl", "", 0, GDK_COLOR_STATE_SRGB },
{ "ngl", "", 1, GDK_COLOR_STATE_REC2100_PQ },
{ "ngl", "linear", 0, GDK_COLOR_STATE_SRGB },
{ "ngl", "linear", 1, GDK_COLOR_STATE_REC2100_LINEAR },
{ "ngl", "hdr", 0, GDK_COLOR_STATE_REC2100_PQ },
{ "ngl", "hdr", 1, GDK_COLOR_STATE_REC2100_PQ },
{ "ngl", "hdr:linear", 0, GDK_COLOR_STATE_REC2100_LINEAR },
{ "ngl", "hdr:linear", 1, GDK_COLOR_STATE_REC2100_LINEAR },
{ "vulkan", "", 0, GDK_COLOR_STATE_SRGB },
{ "vulkan", "", 1, GDK_COLOR_STATE_REC2100_PQ },
{ "vulkan", "linear", 0, GDK_COLOR_STATE_SRGB },
{ "vulkan", "linear", 1, GDK_COLOR_STATE_REC2100_LINEAR },
{ "vulkan", "hdr", 0, GDK_COLOR_STATE_REC2100_PQ },
{ "vulkan", "hdr", 1, GDK_COLOR_STATE_REC2100_PQ },
{ "vulkan", "hdr:linear", 0, GDK_COLOR_STATE_REC2100_LINEAR },
{ "vulkan", "hdr:linear", 1, GDK_COLOR_STATE_REC2100_LINEAR },
};
static GdkColorState *
get_color_state (guint id)
{
switch (id)
{
case GDK_COLOR_STATE_SRGB: return gdk_color_state_get_srgb ();
case GDK_COLOR_STATE_SRGB_LINEAR: return gdk_color_state_get_srgb_linear ();
case GDK_COLOR_STATE_REC2100_PQ: return gdk_color_state_get_rec2100_pq ();
case GDK_COLOR_STATE_REC2100_LINEAR: return gdk_color_state_get_rec2100_linear ();
default: g_assert_not_reached ();
}
}
static const char *
color_state_name (GdkColorState *cs)
{
if (cs == gdk_color_state_get_srgb ())
return "srgb";
else if (cs == gdk_color_state_get_srgb_linear ())
return "srgb-linear";
else if (cs == gdk_color_state_get_rec2100_pq ())
return "rec2100-pq";
else if (cs == gdk_color_state_get_rec2100_linear ())
return "rec2100-linear";
else
return "???";
}
static void
test_render_texture (gconstpointer testdata)
{
const TextureTest *test = testdata;
if (g_test_subprocess ())
{
GError *error = NULL;
const char *text;
GBytes *bytes;
GskRenderNode *node;
GskRenderer *renderer;
GdkTexture *texture;
GdkTextureDownloader *downloader;
GdkColorState *expected = get_color_state (test->expected);
gtk_init ();
text = test->hdr_content
? "color { color: color(rec2100-pq 1 0.5 0); }"
: "color { color: color(srgb 0 0.5 1); }";
bytes = g_bytes_new_static (text, strlen (text));
node = gsk_render_node_deserialize (bytes, NULL, NULL);
g_bytes_unref (bytes);
g_assert_nonnull (node);
if (strcmp (test->renderer, "ngl") == 0)
renderer = gsk_ngl_renderer_new ();
else if (strcmp (test->renderer, "vulkan") == 0)
renderer = gsk_vulkan_renderer_new ();
else
g_assert_not_reached ();
gsk_renderer_realize_for_display (renderer, gdk_display_get_default (), &error);
g_assert_no_error (error);
texture = gsk_renderer_render_texture (renderer, node, &GRAPHENE_RECT_INIT (0, 0, 1, 1));
if (!gdk_color_state_equal (expected, gdk_texture_get_color_state (texture)))
{
g_print ("test: expected %s, got %s\n",
color_state_name (expected),
color_state_name (gdk_texture_get_color_state (texture)));
exit (1);
}
else
{
g_print ("test: got color state %s\n",
color_state_name (gdk_texture_get_color_state (texture)));
}
g_assert_true (gdk_texture_get_width (texture) == 1);
g_assert_true (gdk_texture_get_height (texture) == 1);
downloader = gdk_texture_downloader_new (texture);
gdk_texture_downloader_set_format (downloader, GDK_MEMORY_R32G32B32A32_FLOAT);
/* Convert the data to the colorstate we used in the node */
if (test->hdr_content)
gdk_texture_downloader_set_color_state (downloader, gdk_color_state_get_rec2100_pq ());
else
gdk_texture_downloader_set_color_state (downloader, gdk_color_state_get_srgb ());
float data[4];
gdk_texture_downloader_download_into (downloader, (guchar *) data, 4 * sizeof (float));
gdk_texture_downloader_free (downloader);
g_print ("test: got %s content: %f %f %f %f\n",
test->hdr_content ? "rec2100-pq" : "srgb",
data[0], data[1], data[2], data[3]);
if (test->hdr_content)
{
g_assert_cmpfloat_with_epsilon (data[0], 1, 0.005);
g_assert_cmpfloat_with_epsilon (data[1], 0.5, 0.005);
g_assert_cmpfloat_with_epsilon (data[2], 0, 0.005);
g_assert_cmpfloat_with_epsilon (data[3], 1, 0.005);
}
else
{
g_assert_cmpfloat_with_epsilon (data[0], 0, 0.005);
g_assert_cmpfloat_with_epsilon (data[1], 0.5, 0.005);
g_assert_cmpfloat_with_epsilon (data[2], 1, 0.005);
g_assert_cmpfloat_with_epsilon (data[3], 1, 0.005);
}
gsk_render_node_unref (node);
gsk_renderer_unrealize (renderer);
g_object_unref (renderer);
return;
}
char **envp = g_get_environ ();
const char *str = g_getenv ("GDK_DEBUG") ? g_getenv ("GDK_DEBUG") : "";
char *str2 = g_strconcat (test->debug, test->debug[0] && str[0] ? ":" : "", str, NULL);
envp = g_environ_setenv (g_steal_pointer (&envp), "GDK_DEBUG", str2, TRUE);
g_free (str2);
g_test_trap_subprocess_with_envp (NULL, (const char * const *) envp, 0, G_TEST_SUBPROCESS_INHERIT_STDOUT | G_TEST_SUBPROCESS_INHERIT_STDERR);
if (!g_test_trap_has_passed ())
g_test_fail ();
}
int
main (int argc, char *argv[])
{
gtk_init ();
g_test_init (&argc, &argv, NULL);
for (int i = 0; i < G_N_ELEMENTS (tests); i++)
{
TextureTest *test = &tests[i];
char *path;
path = g_strconcat ("/rendertexture",
"/renderer:", test->renderer,
"/content:", test->hdr_content ? "hdr" : "sdr",
"/flags:", test->debug[0] ? test->debug : "none", NULL);
g_test_add_data_func (path, test, test_render_texture);
g_free (path);
}
return g_test_run ();
}
+1 -12
View File
@@ -115,17 +115,6 @@ find_color_state_by_name (const char *name)
gdk_cicp_params_set_matrix_coefficients (params, 0);
gdk_cicp_params_set_range (params, GDK_CICP_RANGE_FULL);
color_state = gdk_cicp_params_build_color_state (params, &error);
}
else if (g_strcmp0 (name, "xyz") == 0)
{
params = gdk_cicp_params_new ();
gdk_cicp_params_set_color_primaries (params, 10);
gdk_cicp_params_set_transfer_function (params, 8);
gdk_cicp_params_set_matrix_coefficients (params, 0);
gdk_cicp_params_set_range (params, GDK_CICP_RANGE_FULL);
color_state = gdk_cicp_params_build_color_state (params, &error);
}
else if (g_strcmp0 (name, "rec2020") == 0)
@@ -190,7 +179,7 @@ char **
get_color_state_names (void)
{
static const char *names[] = {
"srgb", "srgb-linear", "display-p3", "xyz", "rec2020",
"srgb", "srgb-linear", "display-p3", "rec2020",
"rec2100-pq", "rec2100-linear", "rec2100-hlg",
"yuv", "bt601", "bt709",
NULL,