Additive (not linear) compositing when using GLX
Rendaw
rendaw at zarbosoft.com
Sun Oct 17 16:03:28 PDT 2010
I'm using xcompmgr for compositing. A window I paint using OpenGL is
much brighter than a window painted the same way using Cairo.
Specifically, with Red=1, Alpha=0, everything has full red. Using
Cairo, there is no coloration.
I'm not using glxcompmgr, but I noticed the line glBlendFunc(GL_ONE,
GL_ONE_MINUS_SRC_ALPHA); in the code. Compositing like that would cause
the output I showed above.
Does anyone know from which package this behavior might stem? Since
xcompmgr is pretty small, I doubt it is differentiating between GL
rendered windows and xrender/whatever rendered ones, but that would have
been my first guess.
(I'm using Arch linux: xcompmgr 1.1.5-1, xf86-video-intel 2.12.0-1,
xorg-server 1.8.1.902-1)
Here's the code to reproduce. You'll have to change TargetVisual to use
some RGBA supporting visual.
#include <GL/glx.h>
#include <GL/gl.h>
#include <cairo/cairo-xlib.h>
#include <unistd.h>
#include <cassert>
#include <string>
const float ClearColor[4] = {1, 0, 0, 0.0f};
int TargetVisual = 0x5e;
void CairoDraw(Display *Context, Window Canvas, XVisualInfo *VisualData)
{
cairo_surface_t *BaseSurface = cairo_xlib_surface_create(Context,
Canvas, VisualData->visual, 100, 100);
cairo_t *CairoContext = cairo_create(BaseSurface);
cairo_set_operator(CairoContext, CAIRO_OPERATOR_SOURCE);
cairo_set_source_rgba(CairoContext, ClearColor[0], ClearColor[1],
ClearColor[2], ClearColor[3]);
cairo_paint(CairoContext);
cairo_surface_write_to_png(BaseSurface, "Test.png");
}
void GLDraw(Display *Context, Window Canvas, XVisualInfo *VisualData)
{
GLXContext GLContext = glXCreateContext(Context, VisualData, NULL,
GL_TRUE);
glXMakeCurrent(Context, Canvas, GLContext);
glClearColor(ClearColor[0], ClearColor[1], ClearColor[2],
ClearColor[3]);
glClear(GL_COLOR_BUFFER_BIT);
glXSwapBuffers(Context, Canvas);
}
int main(int argc, char **argv)
{
Display *Context = XOpenDisplay(NULL);
XVisualInfo Criteria, *FoundVisuals;
int FoundVisualCount;
Criteria.visualid = TargetVisual;
FoundVisuals = XGetVisualInfo(Context, VisualIDMask, &Criteria,
&FoundVisualCount);
assert(FoundVisualCount != 0);
XSetWindowAttributes NewAttributes;
NewAttributes.colormap = XCreateColormap(Context,
RootWindow(Context, FoundVisuals->screen), FoundVisuals->visual, AllocNone);
NewAttributes.border_pixel = 0;
NewAttributes.event_mask = StructureNotifyMask;
Window TestWindow = XCreateWindow(Context, RootWindow(Context,
FoundVisuals->screen),
0, 0, 100, 100, 0,
FoundVisuals->depth, InputOutput, FoundVisuals->visual,
CWBorderPixel | CWColormap | CWEventMask,
&NewAttributes);
XMapWindow(Context, TestWindow);
XEvent Poll;
do XNextEvent(Context, &Poll); while (Poll.type != MapNotify);
if ((argc >= 2) && (std::string(argv[1]) == "cairo"))
CairoDraw(Context, TestWindow, FoundVisuals);
else GLDraw(Context, TestWindow, FoundVisuals);
sleep(10);
}
More information about the xorg-devel
mailing list