[Piglit] [PATCH 2/2] glx-tfp: Use XRender to correctly set up alpha channel.

Eric Anholt eric at anholt.net
Wed Jun 1 12:18:58 PDT 2011


The previous way of initializing the "alpha" channel of the pixmap was
to just set the pixel bits other than r, g, b, to 1.0 or 0.5 times
their maximum value.  However, thanks to the delights of xlib, a pixel
value is a long, not a sized integer.  So, when we set alpha to half
of ~(r, g, b,), on 64-bit that was half of 0xffffffffff000000 instead
of half of 0xff000000, which resulted in black.

XRender is the correct X rendering API for working with alpha
channels, so use that instead.  The ugly bit here is that to preserve
the existing test behavior, we have one of the colors filled be (1.0,
0.0, 0.0, 0.5), which is non-premultiplied and thus not really proper
Render rendering.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=24491
---
 tests/glx/CMakeLists.gl.txt |    1 +
 tests/glx/glx-tfp.c         |   58 +++++++++++++++---------------------------
 2 files changed, 22 insertions(+), 37 deletions(-)

diff --git a/tests/glx/CMakeLists.gl.txt b/tests/glx/CMakeLists.gl.txt
index d364cb2..2cbc046 100644
--- a/tests/glx/CMakeLists.gl.txt
+++ b/tests/glx/CMakeLists.gl.txt
@@ -36,6 +36,7 @@ IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
 	add_executable (glx-make-glxdrawable-current glx-make-glxdrawable-current.c)
 	add_executable (glx-swap-exchange glx-swap-exchange.c)
 	add_executable (glx-tfp glx-tfp.c)
+	target_link_libraries(glx-tfp Xrender)
 
 	add_executable (glx-pixmap-life glx-pixmap-life.c)
 	add_executable (glx-pixmap13-life glx-pixmap13-life.c)
diff --git a/tests/glx/glx-tfp.c b/tests/glx/glx-tfp.c
index db7f94c..204933e 100644
--- a/tests/glx/glx-tfp.c
+++ b/tests/glx/glx-tfp.c
@@ -38,6 +38,7 @@
 #include "piglit-util.h"
 #include "piglit-glx-util.h"
 #include "GL/glx.h"
+#include "X11/extensions/Xrender.h"
 
 GLfloat tex_data[4][4] = {
 	{ 1.0, 0.0, 0.0, 1.0 },
@@ -183,25 +184,17 @@ draw(Display *dpy)
 }
 
 static void
-set_pixel(Display *dpy, Pixmap pixmap, int x, int y, GLfloat *color,
-	  unsigned long *masks)
+set_pixel(Display *dpy, Picture picture, int x, int y, GLfloat *color)
 {
-	unsigned long pixel = 0;
-	XGCValues gc_values;
-	GC gc;
+	XRectangle rect = {x, y, 1, 1};
+	XRenderColor render_color;
 
-	pixel |= (unsigned long)(color[0] * masks[0]) & masks[0];
-	pixel |= (unsigned long)(color[1] * masks[1]) & masks[1];
-	pixel |= (unsigned long)(color[2] * masks[2]) & masks[2];
-	pixel |= (unsigned long)(color[3] * masks[3]) & masks[3];
+	render_color.red = 0xffff * color[0];
+	render_color.green = 0xffff * color[1];
+	render_color.blue = 0xffff * color[2];
+	render_color.alpha = 0xffff * color[3];
 
-	gc_values.foreground = pixel;
-	gc_values.background = pixel;
-	gc = XCreateGC(dpy, pixmap, GCForeground | GCBackground, &gc_values);
-
-	XFillRectangle(dpy, pixmap, gc, x, y, 1, 1);
-
-	XFreeGC(dpy, gc);
+	XRenderFillRectangles(dpy, PictOpSrc, picture, &render_color, &rect, 1);
 }
 
 /**
@@ -247,14 +240,19 @@ create_pixmap(GLenum format)
 	Pixmap pixmap;
 	GLXPixmap glx_pixmap;
 	XVisualInfo *vis;
-	unsigned long channel_masks[4];
+	XRenderPictFormat *render_format;
+	Picture picture;
 
 	if (format == GL_RGBA) {
 		fb_config_attribs = rgba_fb_config_attribs;
 		pixmap_attribs = rgba_pixmap_attribs;
+		render_format = XRenderFindStandardFormat(dpy,
+							  PictStandardARGB32);
 	} else {
 		fb_config_attribs = rgb_fb_config_attribs;
 		pixmap_attribs = rgb_pixmap_attribs;
+		render_format = XRenderFindStandardFormat(dpy,
+							  PictStandardRGB24);
 	}
 
 	fb_configs = glXChooseFBConfig(dpy, DefaultScreen(dpy),
@@ -270,27 +268,17 @@ create_pixmap(GLenum format)
 	fb_config = fb_configs[n_fb_configs - 1];
 
 	pixmap = XCreatePixmap(dpy, RootWindow(dpy, DefaultScreen(dpy)),
-			       2, 2,
-			       format == GL_RGBA ? 32 : 24);
+			       2, 2, render_format->depth);
+	picture = XRenderCreatePicture(dpy, pixmap, render_format, 0, NULL);
 
 	glx_pixmap = glXCreatePixmap(dpy, fb_config, pixmap, pixmap_attribs);
 
 	vis = glXGetVisualFromFBConfig(dpy, fb_config);
 
-	channel_masks[0] = vis->red_mask;
-	channel_masks[1] = vis->green_mask;
-	channel_masks[2] = vis->blue_mask;
-	if (format == GL_RGBA) {
-		channel_masks[3] = ~(vis->red_mask | vis->green_mask |
-				     vis->blue_mask);
-	} else {
-		channel_masks[3] = 0;
-	}
-
-	set_pixel(dpy, pixmap, 0, 0, tex_data[0], channel_masks);
-	set_pixel(dpy, pixmap, 1, 0, tex_data[1], channel_masks);
-	set_pixel(dpy, pixmap, 0, 1, tex_data[2], channel_masks);
-	set_pixel(dpy, pixmap, 1, 1, tex_data[3], channel_masks);
+	set_pixel(dpy, picture, 0, 0, tex_data[0]);
+	set_pixel(dpy, picture, 1, 0, tex_data[1]);
+	set_pixel(dpy, picture, 0, 1, tex_data[2]);
+	set_pixel(dpy, picture, 1, 1, tex_data[3]);
 
 	XFree(fb_configs);
 	XFree(vis);
@@ -311,8 +299,6 @@ int main(int argc, char**argv)
 	XVisualInfo *visinfo;
 	GLXContext ctx;
 	int i;
-	int screen;
-	Window root_win;
 
 	for(i = 1; i < argc; ++i) {
 		if (!strcmp(argv[i], "-auto"))
@@ -326,8 +312,6 @@ int main(int argc, char**argv)
 		fprintf(stderr, "couldn't open display\n");
 		piglit_report_result(PIGLIT_FAIL);
 	}
-	screen = DefaultScreen(dpy);
-	root_win = RootWindow(dpy, screen);
 
 	visinfo = piglit_get_glx_visual(dpy);
 	ctx = piglit_get_glx_context(dpy, visinfo);
-- 
1.7.5.1



More information about the Piglit mailing list