Demos (master): egl/openvg: Verify blend demo rendering with vgReadPixels.
Chia-I Wu
olv at kemper.freedesktop.org
Sat Dec 4 16:01:06 UTC 2010
Module: Demos
Branch: master
Commit: a6caaff1085e5bb438e66bfc9ae6780b9daccee7
URL: http://cgit.freedesktop.org/mesa/demos/commit/?id=a6caaff1085e5bb438e66bfc9ae6780b9daccee7
Author: Chia-I Wu <olvaffe at gmail.com>
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,
More information about the mesa-commit
mailing list