[cairo] new pattern interface and OpenGL patch

David Reveman c99drn at cs.umu.se
Thu Mar 25 10:35:03 PST 2004


On Thu, 2004-03-25 at 12:11 -0500, Carl Worth wrote: 
> Even though I mentioned it, after some thought, I don't think I like
> this idea. For Owen's wants, only an exposed structure would help. But
> if we expose the structure, then we cannot hide the question of
> premultiplied alpha. So that wouldn't solve the problem, it would only
> move it.
> 
> Plus, we can't hide the fact that the image backend wants data with
> premultiplied alpha. So, maybe the right thing to do is to be
> consistent and just specify that this function accepts premultiplied
> alpha.
> 
> Another issue that needs to be specified is the color space in which
> the gradient is computed. Keith makes a compelling argument to provide
> an interface of just linear sRGB interpolation, letting users that
> want something else approximate it as close as they wish.
> 
> With those two points in mind, maybe we should also change
> cairo_set_rgb_color to also use pre-multiplied and to not require a
> superfluous "rgb":
> 
> 	void
> 	cairo_set_color (cairo_t *cr, double red, double green,
> 			 double blue, double alpha);
> 
> Although this would impact the current behavior of cairo_show_surface
> which does use the current alpha value when compositing the
> surface. We really want a more general way to mask an image anyway, so
> this may not be a big deal.

Ok, in the current pattern patch I also use the current alpha to set the
opacity of the patterns just as with show_surface. The opacity of
linear, radial and surface patterns are effected by the current alpha
value. It would be nice to keep it this way. 

Maybe a cairo_set_opacity would do it.   


>  > the 'options' parameter is a bit mask of the above options, so if we should
>  > use a cairo_gl_option_t type for them, we need to replace the 'options' 
>  > parameter with a list of cairo_gl_option_t's or something.  
> 
> You can still use a bit mask. I was just suggesting a typedef to help
> guide the user to the symbolic mask values.

ok, sorry. Somehow I thought you ment an enumeration. 
a simple
typedef int cairo_gl_options_t;
then. right?

>  > >     +XVisualInfo *
>  > >     +cairo_glx_find_best_visual_info (Display *dpy,
>  > >     +                                 int screen,
>  > >     +                                 int options);
>  > > 
>  > > What's this function? It seems a bit out of place.
>  >
>  > You need the XVisualInfo to create a Window which can be used
>  > with cairo_glx_surface_create_for_window. The 'options' parameter
>  > must be the same for both functions.
>  > 
>  > I'm sure this can be a bit confusing but it shouldn't be to weird
>  > for you who are familiar with GLX. It's similar to:
>  > glXFindVisualInfo and glXCreateWindow.
> 
> I see. The problem is that this function doesn't match cairo's
> argument passing convention, (ie. it looks like it should perhaps
> accept a cairo_glx_t * as a first parameter).
> 
> Well, if the user is going to have to call glXCreateWindow then why
> doesn't the user also call glXFindVisualInfo? Then this cairo_glx
> function could be dropped?
> 
> If so, I suppose that the options parameter cairo_set_target_glx might
> have to change to be compatible with GLX, but that seems like a good
> thing anyway. (Currently, the API exposes the GLC header file which
> would not be necessary if it did not also expose GLC options).

Applications cannot use glXFindVisualInfo or glXCreateWindow with
libglc. libglc needs to have full control over the visuals and contexts
used for glc surfaces. There's no way that we change this.

I can't think of a really clean way to handle this but this is what I'm
proposing:

introduce a cairo_glx_format_t and the following functions:

cairo_glx_format_t *
cairo_gl_find_glx_format (Display *dpy, 
                          int screen, 
                          cairo_gl_options_t options);

XVisualInfo *
cairo_glx_format_get_visual_info (cairo_glx_format_t *format);

The application could then create the X11 window with this visual info
and then use the following surface creation function to create a
cairo_surface_t. 

cairo_surface_t *
cairo_gl_surface_create_for_xlib_window (Window window,
                                         cairo_glx_format *format);

and the same kind of interface for AGL.

OR instead only one function:

cairo_surface_t *
cairo_gl_surface_xlib_create (Display *display, int screen,
                              int width, int height,
                              cairo_gl_options_t options,
                              Window *xlib_window_return);

This way the application would loose control over the x11 window
creation.

I like the first approach much better, the second one is just too
ugly.   

Maybe someone got a better suggestion?

BTW, as you see in my function declarations above, I'd like to change from
cairo_glx_surface_* and cairo_agl_surface* functions to something like:

cairo_gl_surface_create_xlib
cairo_gl_surface_create_carbon
and
./configure --enable-gl

xlib (GLX) and carbon (AGL) interface can never be compiled together anyway.


> I had previously suggested overloading show_page to do buffer
> swapping, and Keith argued that there are enough semantic differences
> that the functions should remain separate. I think he's probably right.
> 
> Also, "surface_show" strikes me as much too similar to "show_surface"
> though the semantics are wildly different. So, I'd prefer a more
> descriptive name. And this is not the only backend that may need some
> sort of flush operation, so I'd prefer to have a top-level
> cairo_flush, (or whatever we decide to call it).
> 
> That may require you to add a cairo_glx_surface_update_size, but that's
> similar to the cairo_xlib_surface_update_size that I was also about to
> add. (Hmmm, maybe we'll want a general cairo_surface_update_size).
> 

A cairo_flush and a cairo_surface_update_size would be great for the OpenGL
backend.

- David

-- 
David Reveman <c99drn at cs.umu.se>





More information about the cairo mailing list