[cairo] OpenGL backend news and a few words about shading

David Reveman c99drn at cs.umu.se
Sun Feb 29 16:38:54 PST 2004

On Sun, 2004-02-29 at 20:04 +0100, Thomas Hunger wrote:

> > Shading in Cairo
> > What I've done with the OpenGL patch is that I've added a new type of
> > surface called a cairo_gradient_surface (should probably be programmatic
> Thats what I did first, but had the following problem: The surface size needs 
> to be known before the gradient_surface can be created. So the user has to 
> take care of that. I'd like to have that hidden in the internals.

Yes, absolutely. In my gradient_surface solution the GL backend never
actually used width and height.

> I'd also like to be able to plug in a custom shader callback on the public api 
> side of cairo, although I am not sure how important that is for others.
> It seems that solid color and pattern fill are just a subset of a general 
> shader interface. currently _cairo_source_ensure does make sure that there is 
> a source to composite against. In the case of a user-set pattern, it just 
> keeps source as it is, in the case of a solid color it used create_similar to 
> create a 1x1 (repeat ==1) source to composite against. 
> If the _cairo_ensure_source function would be replaced by the custom shader 
> callback, there would be a solid_shader_func, pattern_shader_func and we 
> could also add linear_shader_func and others.
> In addition to that we would have to add a few callbacks to the 
> cairo_surface_backend_t for standard shaders like linear, radial, gouraud, 
> whatever, to allow surface backends to plug in their own accelerated shaders. 
> Since the shaded surface would be created with the create_similar function,
> e.g. a surface->shade_linear(size_x, size_y, extradata) would be enough within 
> the custom callback function. Right now the glc backend is the only one which 
> supports hardware accelerated shading, so all the other would need to use 
> software-fallbacks.

Good thinking.

Maybe it would be enough with an ensure_source backend function which
would take a cairo_shader_t structure and would return the backends
accelerated source surface. The cairo_shader_t would contain type and a
union of all different shader data structures. Type would be solid,
linear, radial, gouraud or whatever. If the backend cannot create an
accelerated surface it could just return NULL and an image version would
be created.

This way we can add new shader types without adding new backend
functions and solid color fills could be accelerated by the backends
(perfect for the GL backend as we can remove the color_traps backend
function and accelerate solid drawing even more using programmatic

What do you think?

> Also, it could make sense to alter the set_repeat argument from an int to 
> CAIRO_REPEAT_TRIANGULAR, to allow different behaviours for the standard 
> shaders. These repeats do not make sense for a pattern, so I am not quite 
> sure if they are really a good idea.

The best would probably be to have shader repeat behavior as an argument
to the shader creation function or set with a cairo_set_shader_repeat

> Carl said he'd rather not have a cairo_shader_t in the public api, so we would 
> need a way to express shaders through functions. Since they usually take a 
> ridiculous amount of arguments I think it would make sense to split shader 
> creation into seperate functions. I really like color_stop you introduced in 
> the glc-backend introduced for shading. Here are a few functions I can think 
> of to modify surface looks (old ones included):
> cairo_set_pattern (...
> cairo_set_rgb_color (...
> cairo_set_alpha (...
> cairo_set_shader_linear (double x1, double  y1, double x2, double y2)
> cairo_set_shader_radial (double xc, double yc, double t, double focalx, double 
> focaly);
> cairo_set_shader_custom (cairo_shader_callback_t *shader_callback);
> cairo_set_shader_color_stop (double position, double r, g, b, a);
> These functions would internally just alter the callback function or change 
> the internal data.

I like it. Should work fine. 

> I know this is very intrusive and would take some work, since every 
> backend-source would have to modified. Other ideas are welcome :)

With my above suggestions it shouldn't be to much work. We need to
create fall back image versions of at least linear and radial shaders
though, might be some work with that.

> > in their own way or just request an image version of the gradient from
> > the gradient surface backend. You should have a look at the GL backend
> I had a look at it, I think this could integrate well with the framework 
> described above. 
> Tom
> P.s. Do you know how I can make my radeon9000 support programmatic surfaces 
> (and antialiasing)? All the other demos from you work fine and fast - cool!

Programmatic surfaces requires GL_ARB_fragment_program extension and
anti-aliasing requires GL_ARB_multi_sample extension. I'm pretty sure
that none of those are supported on radeon 9000 cards, Sorry.

But it's great that the other stuff works on your radeon 9000. Compared
with NVIDIA's drivers ATI's drivers are very unstable. We're having a
lot of trouble with them (memory leaks, random crashes...). NVIDIA's
drivers work great, especially with geforce FX cards as they support
both GL_ARB_fragment_program and GL_ARB_multi_sample.  

/ David

David Reveman <c99drn at cs.umu.se>

More information about the cairo mailing list