Module: Demos Branch: master Commit: a6caaff1085e5bb438e66bfc9ae6780b9daccee7 URL: http://cgit.freedesktop.org/mesa/demos/commit/?id=a6caaff1085e5bb438e66bfc9ae6780b9daccee7
Author: Chia-I Wu <[email protected]> Date: Sat Dec 4 19:53:20 2010 +0800 egl/openvg: Verify blend demo rendering with vgReadPixels. Calculate the final colors separately and use vgReadPixels to compare the results when -v is given. --- src/egl/openvg/trivial/blend.c | 124 ++++++++++++++++++++++++++++++++++++++-- 1 files changed, 119 insertions(+), 5 deletions(-) diff --git a/src/egl/openvg/trivial/blend.c b/src/egl/openvg/trivial/blend.c index c69abb8..2724481 100644 --- a/src/egl/openvg/trivial/blend.c +++ b/src/egl/openvg/trivial/blend.c @@ -6,6 +6,7 @@ #include <stdlib.h> #include <stdio.h> +VGboolean verbose; VGPath rect; static void @@ -64,55 +65,160 @@ rectangle(VGint x, VGint y, VGint width, VGint height) } static void -test_blend(VGint x, VGint y, VGint width, VGint height) +check_pixel(VGint x, VGint y, VGfloat ref[4], const char *msg) { - /* src is red with alpha 0.8 */ - /* dst is green with alpha 0.3 */ + VGfloat rgba[4]; + VGint pixel; + VGint i; + + vgReadPixels(&pixel, 0, VG_sRGBA_8888, x, y, 1, 1); + rgba[0] = ((pixel >> 24) & 0xff) / 255.0f; + rgba[1] = ((pixel >> 16) & 0xff) / 255.0f; + rgba[2] = ((pixel >> 8) & 0xff) / 255.0f; + rgba[3] = ((pixel >> 0) & 0xff) / 255.0f; + + for (i = 0; i < 4; i++) { + if (fabs(ref[i] - rgba[i]) > 0.1f) { + printf("Test %s at (%d, %d): expect (%f, %f, %f, %f), got (%f, %f, %f, %f)\n", + msg, x, y, ref[0], ref[1], ref[2], ref[3], + rgba[0], rgba[1], rgba[2], rgba[3]); + break; + } + } +} + +static void +test_blend(VGint x, VGint y, VGint width, VGint height, VGboolean check) +{ + VGfloat src[4] = { 1.0f, 0.0f, 0.0f, 0.8f}; + VGfloat dst[4] = { 0.0f, 1.0f, 0.0f, 0.3f}; + VGfloat out[4]; + VGint i; + + /* premultiply */ + if (check) { + for (i = 0; i < 3; i++) { + src[i] *= src[3]; + dst[i] *= dst[3]; + } + + /* + * OpenVG allows an implementation to perform interpolation and blending + * in linear or non-linear color space. Other factors might also affect + * the rendering result. The checks are for reference only. + */ + printf("Render and check blending result (for reference only)\n"); + } + +#define CHECK(msg) \ + do { \ + /* non-premultiply */ \ + for (i = 0; i < 3; i++) \ + out[i] /= out[3]; \ + check_pixel(x + width / 2, y + height / 2, out, msg); \ + } while (0) /* 0.8 * red */ vgSeti(VG_BLEND_MODE, VG_BLEND_SRC); rectangle(x, y, width, height); + if (check) { + for (i = 0; i < 4; i++) + out[i] = src[i]; + CHECK("VG_BLEND_SRC"); + } x += width + 5; /* 0.8 * red + 0.06 * green */ vgSeti(VG_BLEND_MODE, VG_BLEND_SRC_OVER); rectangle(x, y, width, height); + if (check) { + for (i = 0; i < 4; i++) + out[i] = src[i] + dst[i] * (1.0f - src[3]); + CHECK("VG_BLEND_SRC_OVER"); + } x += width + 5; /* 0.56 * red + 0.3 * green */ vgSeti(VG_BLEND_MODE, VG_BLEND_DST_OVER); rectangle(x, y, width, height); + if (check) { + for (i = 0; i < 4; i++) + out[i] = dst[i] + src[i] * (1.0f - dst[3]); + CHECK("VG_BLEND_DST_OVER"); + } x += width + 5; /* 0.24 * red */ vgSeti(VG_BLEND_MODE, VG_BLEND_SRC_IN); rectangle(x, y, width, height); + if (check) { + for (i = 0; i < 4; i++) + out[i] = src[i] * dst[3]; + CHECK("VG_BLEND_SRC_IN"); + } x += width + 5; /* 0.24 * green */ vgSeti(VG_BLEND_MODE, VG_BLEND_DST_IN); + if (check) { + for (i = 0; i < 4; i++) + out[i] = dst[i] * src[3]; + CHECK("VG_BLEND_DST_IN"); + } rectangle(x, y, width, height); x += width + 5; /* (...) * 0.8 * red + 0.06 * green */ vgSeti(VG_BLEND_MODE, VG_BLEND_MULTIPLY); rectangle(x, y, width, height); + if (check) { + for (i = 0; i < 3; i++) { + out[i] = (1.0f - dst[3]) * src[i] + + (1.0f - src[3]) * dst[i] + src[i] * dst[i]; + } + out[3] = src[3] + dst[3] * (1.0f - src[3]); + CHECK("VG_BLEND_MULTIPLY"); + } x += width + 5; /* 0.8 * red + (white - 0.8 * red) * 0.3 * green */ vgSeti(VG_BLEND_MODE, VG_BLEND_SCREEN); rectangle(x, y, width, height); + if (check) { + for (i = 0; i < 4; i++) + out[i] = src[i] + (1.0f - src[i]) * dst[i]; + CHECK("VG_BLEND_SCREEN"); + } x += width + 5; /* min(SRC_OVER, DST_OVER) */ vgSeti(VG_BLEND_MODE, VG_BLEND_DARKEN); rectangle(x, y, width, height); + if (check) { + for (i = 0; i < 4; i++) { + VGfloat src_over = src[i] + dst[i] * (1.0f - src[3]); + VGfloat dst_over = dst[i] + src[i] * (1.0f - dst[3]); + out[i] = (src_over < dst_over) ? src_over : dst_over; + } + CHECK("VG_BLEND_DARKEN"); + } x += width + 5; /* max(SRC_OVER, DST_OVER) */ vgSeti(VG_BLEND_MODE, VG_BLEND_LIGHTEN); rectangle(x, y, width, height); + if (check) { + for (i = 0; i < 4; i++) { + VGfloat src_over = src[i] + dst[i] * (1.0f - src[3]); + VGfloat dst_over = dst[i] + src[i] * (1.0f - dst[3]); + out[i] = (src_over > dst_over) ? src_over : dst_over; + } + CHECK("VG_BLEND_LIGHTEN"); + } x += width + 5; + + if (check) + printf("done\n"); } static void @@ -129,7 +235,7 @@ draw(void) x = y = 5; vgClear(x, y, window_width(), 20); - test_blend(x, y, 20, 20); + test_blend(x, y, 20, 20, verbose); y += window_height() / 2; vgClear(x, y, window_width(), 20); @@ -137,13 +243,21 @@ draw(void) * This will have more green because * * result = blended * coverage + dst * (1 - coverage) + * + * Note that impplementations may choose a different formula. */ - test_blend(x, y, 20, 20); + test_blend(x, y, 20, 20, VG_FALSE); } int main(int argc, char **argv) { + if (argc > 1) { + const char *arg = argv[1]; + if (!strcmp("-v", arg)) + verbose = VG_TRUE; + } + set_window_size(300, 300); set_window_alpha_size(1); return run(argc, argv, init, reshape, _______________________________________________ mesa-commit mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/mesa-commit
