Merge branch 'wip/otte/compare-render' into 'main'
Bring compare-render into 21st century See merge request GNOME/gtk!7648
@@ -1,10 +1,10 @@
|
||||
border {
|
||||
colors: rgb(255,0,0) color(srgb-linear 1 0 0) color(rec2100-pq 0.792 0.231 0.0738) rgb(255,0,0);
|
||||
colors: rgb(255,0,0) color(srgb-linear 1 0 0) color(rec2100-pq 0.5325 0.327 0.2201) rgb(255,0,0);
|
||||
outline: 0 0 100 100;
|
||||
widths: 50;
|
||||
}
|
||||
border {
|
||||
colors: rgb(255,0,0) color(srgb-linear 1 0 0) color(rec2100-pq 0.792 0.231 0.0738) rgb(255,0,0);
|
||||
colors: rgb(255,0,0) color(srgb-linear 1 0 0) color(rec2100-pq 0.5325 0.327 0.2201) rgb(255,0,0);
|
||||
outline: -50 -50 200 200;
|
||||
widths: 5;
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 836 B After Width: | Height: | Size: 836 B |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 879 B After Width: | Height: | Size: 879 B |
@@ -15,7 +15,7 @@ color {
|
||||
}
|
||||
color {
|
||||
bounds: 0 100 100 100;
|
||||
color: color(rec2100-pq 0.792 0.231 0.0738);
|
||||
color: color(rec2100-pq 0.5325 0.327 0.2201);
|
||||
}
|
||||
color {
|
||||
bounds: 100 100 100 100;
|
||||
|
||||
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 689 B After Width: | Height: | Size: 689 B |
|
Before Width: | Height: | Size: 657 B After Width: | Height: | Size: 657 B |
@@ -30,7 +30,7 @@ compare_render_tests = [
|
||||
'border-opacity',
|
||||
'border-zero-width-color',
|
||||
'borders-rotated',
|
||||
'borders-scaled',
|
||||
'borders-scaled-nogl',
|
||||
'clip-contained',
|
||||
'clip-coordinates-2d',
|
||||
'clip-coordinates-nocairo',
|
||||
@@ -39,9 +39,9 @@ compare_render_tests = [
|
||||
'clip-in-rounded-clip3',
|
||||
'clip-in-smaller-rounded-clip',
|
||||
'clip-intersection-fail-opacity-nogl',
|
||||
'clipped-repeat',
|
||||
'clipped-repeat-nogl',
|
||||
'clipped_rounded_clip',
|
||||
'clip-nested1',
|
||||
'clip-nested1-nogl',
|
||||
'clip-translate-offscreen',
|
||||
'color-blur0',
|
||||
'color-matrix-identity',
|
||||
@@ -55,7 +55,7 @@ compare_render_tests = [
|
||||
'cross-fade-clipped-with-huge-children-nogl',
|
||||
'cross-fade-in-opacity',
|
||||
'cross-fade-in-rotate',
|
||||
'css-background',
|
||||
'css-background-nogl',
|
||||
'dihedral',
|
||||
'empty-blend',
|
||||
'empty-blur',
|
||||
@@ -86,7 +86,7 @@ compare_render_tests = [
|
||||
'fill-opacity',
|
||||
'fill-scaled-up',
|
||||
'fill-with-3d-contents-nogl-nocairo',
|
||||
'glyph-cache-overflow',
|
||||
'glyph-cache-overflow-nogl',
|
||||
'glyph-cache-overflow-slices',
|
||||
'glyph-hinting-none',
|
||||
'glyph-hinting-slight',
|
||||
@@ -94,8 +94,8 @@ compare_render_tests = [
|
||||
'glyph-subpixel-position',
|
||||
'glyph-scaling',
|
||||
'glyph-antialias',
|
||||
'huge-height',
|
||||
'huge-width',
|
||||
'huge-height-nogl',
|
||||
'huge-width-nogl',
|
||||
'inset-shadow-multiple',
|
||||
'invalid-transform',
|
||||
'issue-3615',
|
||||
@@ -230,43 +230,43 @@ compare_xfails_small_texture = [
|
||||
|
||||
variants = {
|
||||
'plain': '--plain',
|
||||
'flipped': '--flip',
|
||||
'rotated': '--rotate',
|
||||
'repeated': '--repeat',
|
||||
'masked': '--mask',
|
||||
'replayed': '--replay',
|
||||
'clipped': '--clip',
|
||||
'colorflipped': '--colorflip',
|
||||
'flip': '--flip',
|
||||
'rotate': '--rotate',
|
||||
'repeat': '--repeat',
|
||||
'mask': '--mask',
|
||||
'replay': '--replay',
|
||||
'clip': '--clip',
|
||||
'colorflip': '--colorflip',
|
||||
}
|
||||
|
||||
compare_xfails = {
|
||||
'ngl': {
|
||||
# the gradients are prone to rounding errors which become
|
||||
# more pronounced in small clips, it seems
|
||||
'radial-gradient-with-64-colorstops': ['plain','flipped','rotated','repeated','masked','replayed','clipped','colorflipped'],
|
||||
'conic-gradient-with-64-colorstops': ['plain','flipped','rotated','repeated','masked','replayed','clipped','colorflipped'],
|
||||
'blur-child-bounds-oversize-nogl': ['clipped'], # 6450
|
||||
'rounded-clip-with-huge-bounds-nogl': ['plain','flipped','rotated','repeated','masked','replayed','clipped','colorflipped'], # 6532
|
||||
'radial-gradient-with-64-colorstops': ['plain','flip','rotate','repeate','mask','replay','clip','colorflip'],
|
||||
'conic-gradient-with-64-colorstops': ['plain','flip','rotate','repeate','mask','replay','clip','colorflip'],
|
||||
'blur-child-bounds-oversize-nogl': ['clip'], # 6450
|
||||
'rounded-clip-with-huge-bounds-nogl': ['plain','flip','rotate','repeat','mask','replay','clip','colorflip'], # 6532
|
||||
'big-checkerboard': ['clipped'], # 6444
|
||||
},
|
||||
'vulkan': {
|
||||
'radial-gradient-with-64-colorstops': ['clipped', 'colorflipped'],
|
||||
'conic-gradient-with-64-colorstops': ['clipped', 'colorflipped'],
|
||||
'blur-child-bounds-oversize-nogl': ['clipped'], # 6450
|
||||
'repeat-repeats-nested-nogl': ['clipped'], # 6522
|
||||
'repeating-radial-gradient-edge-colors': ['colorflipped'],
|
||||
'rounded-clip-with-huge-bounds-nogl': ['plain','flipped','rotated','repeated','masked','replayed','clipped','colorflipped'], # 6532
|
||||
'big-checkerboard': ['clipped'], # 6444
|
||||
'radial-gradient-with-64-colorstops': ['clip', 'colorflip'],
|
||||
'conic-gradient-with-64-colorstops': ['clip', 'colorflip'],
|
||||
'blur-child-bounds-oversize-nogl': ['clip'], # 6450
|
||||
'repeat-repeats-nested-nogl': ['clip'], # 6522
|
||||
'repeating-radial-gradient-edge-colors': ['colorflip'],
|
||||
'rounded-clip-with-huge-bounds-nogl': ['plain','flip','rotate','repeat','mask','replay','clip','colorflip'], # 6532
|
||||
'big-checkerboard': ['clip'], # 6444
|
||||
},
|
||||
'gl': {
|
||||
# 6525
|
||||
'container-single-child-offscreen-for-opacity': ['rotated'],
|
||||
'cross-fade-in-opacity': ['rotated'],
|
||||
'mask-modes-in-opacity': ['rotated'],
|
||||
'opacity-overlapping-children': ['rotated'],
|
||||
'scaled-texture-scale': ['rotated'],
|
||||
'shadow-opacity': ['rotated'],
|
||||
'texture-scale-nearest-vs-linear': ['rotated'],
|
||||
'container-single-child-offscreen-for-opacity': ['rotate'],
|
||||
'cross-fade-in-opacity': ['rotate'],
|
||||
'mask-modes-in-opacity': ['rotate'],
|
||||
'opacity-overlapping-children': ['rotate'],
|
||||
'scaled-texture-scale': ['rotate'],
|
||||
'shadow-opacity': ['rotate'],
|
||||
'texture-scale-nearest-vs-linear': ['rotate'],
|
||||
},
|
||||
}
|
||||
|
||||
@@ -303,11 +303,14 @@ foreach renderer : renderers
|
||||
|
||||
foreach variant : variants.keys()
|
||||
extra_suites = [ 'gsk-compare-' + variant + '-' + renderer_name ]
|
||||
if test_xfails.contains(variant) or (renderer_name == 'cairo' and variant == 'clipped')
|
||||
if test_xfails.contains(variant) or (renderer_name == 'cairo' and variant == 'clip')
|
||||
extra_suites += ['failing']
|
||||
endif
|
||||
test('compare ' + renderer_name + ' ' + testname + ' ' + variant, compare_render,
|
||||
protocol: 'tap',
|
||||
args: [
|
||||
'--tap',
|
||||
'-k',
|
||||
variants.get(variant),
|
||||
'--output', join_paths(meson.current_build_dir(), 'compare', renderer_name),
|
||||
join_paths(meson.current_source_dir(), 'compare', testname + '.node'),
|
||||
|
||||
@@ -22,6 +22,55 @@
|
||||
|
||||
#include "reftest-compare.h"
|
||||
|
||||
static gboolean
|
||||
memory_format_is_high_depth (GdkMemoryFormat format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case GDK_MEMORY_R8G8B8:
|
||||
case GDK_MEMORY_B8G8R8:
|
||||
case GDK_MEMORY_B8G8R8A8_PREMULTIPLIED:
|
||||
case GDK_MEMORY_A8R8G8B8_PREMULTIPLIED:
|
||||
case GDK_MEMORY_R8G8B8A8_PREMULTIPLIED:
|
||||
case GDK_MEMORY_A8B8G8R8_PREMULTIPLIED:
|
||||
case GDK_MEMORY_B8G8R8A8:
|
||||
case GDK_MEMORY_A8R8G8B8:
|
||||
case GDK_MEMORY_R8G8B8A8:
|
||||
case GDK_MEMORY_A8B8G8R8:
|
||||
case GDK_MEMORY_B8G8R8X8:
|
||||
case GDK_MEMORY_X8R8G8B8:
|
||||
case GDK_MEMORY_R8G8B8X8:
|
||||
case GDK_MEMORY_X8B8G8R8:
|
||||
case GDK_MEMORY_G8:
|
||||
case GDK_MEMORY_G8A8:
|
||||
case GDK_MEMORY_G8A8_PREMULTIPLIED:
|
||||
case GDK_MEMORY_A8:
|
||||
return FALSE;
|
||||
|
||||
case GDK_MEMORY_R16G16B16:
|
||||
case GDK_MEMORY_R16G16B16A16_PREMULTIPLIED:
|
||||
case GDK_MEMORY_R16G16B16A16:
|
||||
case GDK_MEMORY_G16:
|
||||
case GDK_MEMORY_G16A16:
|
||||
case GDK_MEMORY_G16A16_PREMULTIPLIED:
|
||||
case GDK_MEMORY_A16:
|
||||
case GDK_MEMORY_R16G16B16_FLOAT:
|
||||
case GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED:
|
||||
case GDK_MEMORY_R16G16B16A16_FLOAT:
|
||||
case GDK_MEMORY_A16_FLOAT:
|
||||
case GDK_MEMORY_R32G32B32_FLOAT:
|
||||
case GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED:
|
||||
case GDK_MEMORY_R32G32B32A32_FLOAT:
|
||||
case GDK_MEMORY_A32_FLOAT:
|
||||
return TRUE;
|
||||
|
||||
case GDK_MEMORY_N_FORMATS:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Compares two GDK_MEMORY_DEFAULT buffers, returning NULL if the
|
||||
* buffers are equal or a surface containing a diff between the two
|
||||
* surfaces.
|
||||
@@ -30,12 +79,13 @@
|
||||
* Copyright © 2004 Richard D. Worth
|
||||
*/
|
||||
static GdkTexture *
|
||||
buffer_diff_core (const guchar *buf_a,
|
||||
int stride_a,
|
||||
const guchar *buf_b,
|
||||
int stride_b,
|
||||
int width,
|
||||
int height)
|
||||
buffer_diff_u8 (GdkColorState *color_state,
|
||||
const guchar *buf_a,
|
||||
int stride_a,
|
||||
const guchar *buf_b,
|
||||
int stride_b,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
int x, y;
|
||||
guchar *buf_diff = NULL;
|
||||
@@ -64,15 +114,21 @@ buffer_diff_core (const guchar *buf_a,
|
||||
|
||||
if (diff == NULL)
|
||||
{
|
||||
GdkMemoryTextureBuilder *builder;
|
||||
GBytes *bytes;
|
||||
|
||||
stride_diff = 4 * width;
|
||||
buf_diff = g_malloc0_n (stride_diff, height);
|
||||
bytes = g_bytes_new_take (buf_diff, stride_diff * height);
|
||||
diff = gdk_memory_texture_new (width, height,
|
||||
GDK_MEMORY_DEFAULT,
|
||||
bytes,
|
||||
stride_diff);
|
||||
builder = gdk_memory_texture_builder_new ();
|
||||
gdk_memory_texture_builder_set_width (builder, width);
|
||||
gdk_memory_texture_builder_set_height (builder, height);
|
||||
gdk_memory_texture_builder_set_format (builder, GDK_MEMORY_DEFAULT);
|
||||
gdk_memory_texture_builder_set_color_state (builder, color_state);
|
||||
gdk_memory_texture_builder_set_bytes (builder, bytes);
|
||||
gdk_memory_texture_builder_set_stride (builder, stride_diff);
|
||||
diff = gdk_memory_texture_builder_build (builder);
|
||||
g_object_unref (builder);
|
||||
row = (guint32 *) (buf_diff + y * stride_diff);
|
||||
}
|
||||
|
||||
@@ -108,25 +164,150 @@ buffer_diff_core (const guchar *buf_a,
|
||||
return diff;
|
||||
}
|
||||
|
||||
/* Compares two FLOAT buffers, returning NULL if the
|
||||
* buffers are equal or a surface containing a diff between the two
|
||||
* surfaces.
|
||||
*/
|
||||
static GdkTexture *
|
||||
buffer_diff_float (GdkColorState *color_state,
|
||||
const guchar *buf_a,
|
||||
int stride_a,
|
||||
const guchar *buf_b,
|
||||
int stride_b,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
int x, y;
|
||||
guchar *buf_diff = NULL;
|
||||
int stride_diff = 0;
|
||||
GdkTexture *diff = NULL;
|
||||
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
const float *row_a = (const float *) (buf_a + y * stride_a);
|
||||
const float *row_b = (const float *) (buf_b + y * stride_b);
|
||||
float *row = (float *) (buf_diff + y * stride_diff);
|
||||
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
int channel;
|
||||
|
||||
/* check if the pixels are the same */
|
||||
if (G_APPROX_VALUE (row_a[4 * x + 0], row_b[4 * x + 0], 1. / 255) &&
|
||||
G_APPROX_VALUE (row_a[4 * x + 1], row_b[4 * x + 1], 1. / 255) &&
|
||||
G_APPROX_VALUE (row_a[4 * x + 2], row_b[4 * x + 2], 1. / 255) &&
|
||||
G_APPROX_VALUE (row_a[4 * x + 3], row_b[4 * x + 3], 1. / 255))
|
||||
continue;
|
||||
|
||||
/* even if they're not literally the same, fully-transparent
|
||||
* pixels are effectively the same regardless of colour */
|
||||
if (G_APPROX_VALUE (row_a[4 * x + 3], 0.0, 1. / 255) &&
|
||||
G_APPROX_VALUE (row_b[4 * x + 3], 0.0, 1. / 255))
|
||||
continue;
|
||||
|
||||
if (diff == NULL)
|
||||
{
|
||||
GdkMemoryTextureBuilder *builder;
|
||||
GBytes *bytes;
|
||||
|
||||
stride_diff = 4 * width * sizeof (float);
|
||||
buf_diff = g_malloc0_n (stride_diff, height);
|
||||
bytes = g_bytes_new_take (buf_diff, stride_diff * height);
|
||||
builder = gdk_memory_texture_builder_new ();
|
||||
gdk_memory_texture_builder_set_width (builder, width);
|
||||
gdk_memory_texture_builder_set_height (builder, height);
|
||||
gdk_memory_texture_builder_set_format (builder, GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED);
|
||||
gdk_memory_texture_builder_set_color_state (builder, color_state);
|
||||
gdk_memory_texture_builder_set_bytes (builder, bytes);
|
||||
gdk_memory_texture_builder_set_stride (builder, stride_diff);
|
||||
diff = gdk_memory_texture_builder_build (builder);
|
||||
g_object_unref (builder);
|
||||
row = (float *) (buf_diff + y * stride_diff);
|
||||
}
|
||||
|
||||
/* calculate a difference value for all 4 channels */
|
||||
for (channel = 0; channel < 4; channel++)
|
||||
{
|
||||
float value_a = row_a[4 * x + channel];
|
||||
float value_b = row_b[4 * x + channel];\
|
||||
float channel_diff;
|
||||
|
||||
channel_diff = ABS (value_a - value_b);
|
||||
channel_diff *= 4; /* emphasize */
|
||||
if (channel_diff)
|
||||
channel_diff += 0.5; /* make sure it's visible */
|
||||
if (channel_diff > 1.0)
|
||||
channel_diff = 1.0;
|
||||
row[4 * x + channel] = channel_diff;
|
||||
}
|
||||
|
||||
if (row[4 * x + 0] < 0.5 &&
|
||||
row[4 * x + 1] < 0.5 &&
|
||||
row[4 * x + 2] < 0.5)
|
||||
{
|
||||
/* alpha only difference, convert to luminance */
|
||||
row[4 * x + 0] = row[4 * x + 3];
|
||||
row[4 * x + 1] = row[4 * x + 3];
|
||||
row[4 * x + 2] = row[4 * x + 3];
|
||||
}
|
||||
/* make the pixel fully opaque */
|
||||
row[4 * x + 3] = 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
return diff;
|
||||
}
|
||||
|
||||
GdkTexture *
|
||||
reftest_compare_textures (GdkTexture *texture1,
|
||||
GdkTexture *texture2)
|
||||
{
|
||||
int w, h;
|
||||
int w, h, stride;
|
||||
guchar *data1, *data2;
|
||||
GdkTextureDownloader *downloader;
|
||||
GdkColorState *color_state;
|
||||
GdkTexture *diff;
|
||||
gboolean high_depth;
|
||||
|
||||
w = MAX (gdk_texture_get_width (texture1), gdk_texture_get_width (texture2));
|
||||
h = MAX (gdk_texture_get_height (texture1), gdk_texture_get_height (texture2));
|
||||
color_state = gdk_texture_get_color_state (texture1);
|
||||
|
||||
data1 = g_malloc_n (w * 4, h);
|
||||
gdk_texture_download (texture1, data1, w * 4);
|
||||
data2 = g_malloc_n (w * 4, h);
|
||||
gdk_texture_download (texture2, data2, w * 4);
|
||||
downloader = gdk_texture_downloader_new (texture1);
|
||||
gdk_texture_downloader_set_color_state (downloader, color_state);
|
||||
high_depth = memory_format_is_high_depth (gdk_texture_get_format (texture1)) ||
|
||||
memory_format_is_high_depth (gdk_texture_get_format (texture1));
|
||||
if (high_depth)
|
||||
{
|
||||
gdk_texture_downloader_set_format (downloader, GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED);
|
||||
stride = w * 4 * sizeof (float);
|
||||
}
|
||||
else
|
||||
{
|
||||
gdk_texture_downloader_set_format (downloader, GDK_MEMORY_DEFAULT);
|
||||
stride = w * 4 * sizeof (float);
|
||||
}
|
||||
|
||||
diff = buffer_diff_core (data1, w * 4,
|
||||
data2, w * 4,
|
||||
w, h);
|
||||
data1 = g_malloc_n (stride, h);
|
||||
gdk_texture_downloader_download_into (downloader, data1, stride);
|
||||
data2 = g_malloc_n (stride, h);
|
||||
gdk_texture_downloader_set_texture (downloader, texture2);
|
||||
gdk_texture_downloader_download_into (downloader, data2, stride);
|
||||
|
||||
if (high_depth)
|
||||
{
|
||||
diff = buffer_diff_float (color_state,
|
||||
data1, stride,
|
||||
data2, stride,
|
||||
w, h);
|
||||
}
|
||||
else
|
||||
{
|
||||
diff = buffer_diff_u8 (color_state,
|
||||
data1, stride,
|
||||
data2, stride,
|
||||
w, h);
|
||||
}
|
||||
|
||||
g_free (data1);
|
||||
g_free (data2);
|
||||
|
||||