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