Bugs, Blend and Fonts

August 9, 2010

These weeks have been a little bit crazy for me(my bachelor thesis need to be wrote 🙂 ). And a bug in my fill pattern code was make me crazy. Finally last week I fix it and implement some blend operations(CLEAR, SOURCE, IN, OUT, ATOP, XOR and others)  and in parallel began to learn about font rendering.

I already have something working.

But it is a little bit ugly because it does not have antialiasing =/. So these weeks i have plans to improve the code and fix bugs, bug and bugs. After that work in font support and finally  make some work with anti aliasing techniques. I already have studied some papers[1][2] but if someone had others ones would be fine :).

[1] http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter22.html

[2] http://http.developer.nvidia.com/GPUGems3/gpugems3_ch25.html

Cairo State Tracker what we already have done

July 11, 2010

In my last post I showed how we can fill self intersected polygons using stencil buffer. It is one of the operations I have implemented in Cairo Gallium backend.

We already have many features implemented and others one in WIP.  This week i was working in make the stroke operation styles, like join, caps and dashes. I already have them working, Cairo has a nice helper function called _cairo_path_fixed_stroke_to_shaper, it converts the stroke in polygons like quads and triangles.  The result can be seen below.

We already have the fill operation also working(like you saw in my last post) , mask, clip and paint(solid pattern). Now i am working in blend operations, Cairo has many and some ones i need to write a shader like i did in my openvg branch not commited.

Cairo state tracker: filling rules(the power of stencil buffer)

July 10, 2010

When creating a Cairo Graphics Backend we need to implement some operations, one of them is the fill operation.

Fill operation basically describe how a polygon is filled, and cairo has two fill rules:

Non-Zero Winding:  takes into account the direction of the path. Being enclosed by a clockwise loop counts as +1 and being enclosed by a counter-clockwise loop counts as -1. When of the sum of these counts is zero, it is a hole otherwise it is filled.

Evend-Odd: Every area that is inside of an even number of “interiors” is a hole and every region that is inside a odd number of “interiors” is filled.

These operations are easily implemented using stencil buffer.  About the Even-Odd we just need draw each of the polygons in turn, using the PIPE_STENCIL_OP_INVERT function in the stencil buffer.  This flips the value between zero and a nonzero value every time a triangle is drawn that covers a pixel. After all the triangles are drawn, if a pixel is covered an even number of times, the value in the stencil buffers is zero; otherwise, it’s nonzero. Finally, draw a large polygon over the whole region.[1]

And the No n-Zero rule we need to know using the cull face if we are drawing the polygon into clockwise or counter-clockwise, we increment the stencil(PIPE_STENCIL_OP_INCR_WRAP) if is in clockwise and we decrement(PIPE_STENCIL_OP_INCR_DECR) the stencil if is in counter-clockwise.  After we just need to draw a large polygon over the whole region.

So thinking about a star with the coordinates:

(Remember the star is a self intersected polygon)

cairo_move_to(cr, 0, 1.0);
cairo_line_to(cr, 0.5, 0.0);
cairo_line_to(cr, 1.0, 1.0);
cairo_line_to(cr, 0.0, 0.5);
cairo_line_to(cr, 1.0, 0.5);
cairo_line_to(cr, 0, 1.0);

Using Even odd rule this star is draw with a hole:

Using Winding rule we have the all the star filled:

So see you in the next post :).

[1] Drawing Filled, Concave Polygons Using the Stencil Buffer.


Accelerating 2D with Gallium3D

June 15, 2010

Gallium3D is the Linux/Unix(tm) 3D infrastructure. It can be described as a set of interfaces and a collection of supporting libraries[1].

It has module called state tracker that translate the graphics api states, shaders and primitives in something that the pipe driver can understand.[1]So when you want to create a new Graphics API you need to write a new state tracker.

The pipe driver basically translate the shader, primitives and all others state in something that the hardware can understand. [1]

And finally the Winsys communicates with the OS. This archicture does gallium3d work in every Operating System.

So what i am doing?

Now i am hacking a State Tracker to cairo graphics[2]. With cairo i just care with the Canvas trying to make it fast and fast.

I hope writing the Gallium3d backend improve cairo perfomance in some advanced operations like some kind of Blend or creating a GPU like AA(Anti Aliasing).

So what is the advantage of it?

Well, We are removing a layer. Normally the Graphics ToolKits have the backends implemented over OpenGL, OpenVG or X11. And OpenGL and OpenVG are done over Gallium3D. Creating Cairo State Tracker we can access gallium directly.

But there are problems too. Removing a layer we are adding complexity. With OpenVG we can draw and fill complex paths. Creating the state tracker we need to implement algorithms to draw paths and fill them for example.

What we have right now?

Now we have some basic operations like draw paths, clipping and filling.

It is in the early stages but it is a start.

By the way, In the next post i can explain a little bit about the code. 🙂

[1] http://jrfonseca.blogspot.com/2008/04/gallium3d-introduction.html

[2] http://cgit.freedesktop.org/~igor.oliveira/cairo-drm-gallium/

Fun with OpenGL and Shaders

April 23, 2010

Last week i was having fun with OpenGL(in fact QGL) and creating some interesting effects with it like edge detection, embossing and sharpening. So i decided to work with GLSL(OpenGL Shading Language) and create the same effects using Fragment Shaders(yeah hardware accelerated effects).

So i used QGLShaderProgam that allows me create Fragment shaders in a Qt Way(tm). Initially i create two filters the first one was sharpening and the second was edge detection. Both work in a same way(with little modifications), applying a matrix convolution in the image.

The matrix convolution used in sharpening is:

0 -1 0

-1 5 -1

0 -1 0

And the matrix convolution used in edge dection is:

-1 -1 -1

-1 8 -1

-1 -1 -1

Below you can see the fragment shader used in sharpening.

uniform sampler2D sampler;

uniform vec2 offset[9];

uniform int kernel[9];

void main()
vec4 sum = vec4(0.0);
int i;

for (i = 0; i < 9; i++) {
vec4 color = texture2D(sampler, gl_TexCoord[0].st + offset[i]);
sum += color * kernel[i];

gl_FragColor = sum;

The shader used in edge is almost the same

uniform sampler2D sampler;

uniform vec2 offset[9];

uniform int kernel[9];

void main()
vec4 sum = vec4(0.0);
int i;

for (i = 0; i < 9; i++) {
vec4 color = texture2D(sampler, gl_TexCoord[0].st + offset[i]);
sum += color * kernel[i];

sum += 0.51;

gl_FragColor = sum;

The original image used in my experiments can be seen below:

The result of sharpening filter is:

Yeah we have a little bit improvement on the image.

And the result of edge filter is:

The embossing filter is a little bit complicated as you can see:

uniform sampler2D sampler;
uniform vec2 offset[9];
uniform int kernel[9];

void main()
vec4 sum = vec4(0.0);
int i = 0;
for( i = 0; i < 9; i++) {
vec4 color_tmp = texture2D(sampler, gl_TexCoord[0].st + offset[i]);
float h = (color_tmp.x + color_tmp.y + color_tmp.z + color_tmp.w)/4.0;
if (h > 1)
h = 1.0;

if (h < 0)
h = 0.0;

vec4 color = vec4(h, h, h, h);
sum.x += color.x * kernel[i];

sum.x /= 1.0;
sum.x += 0.51;

if (sum.x > 1)
sum.x = 1;
if (sum.x < 0)
sum.x = 0;

gl_FragColor = vec4(sum.x, sum.x, sum.x, 1);

And the result is:

Qt already do OpenGL accelerated filters in QGraphicsEffects classes(look in qt_top_dir/src/opengl/qglpixmapfilter*) it is not anything new but it is interesting use it in others KDE application like krita filters :).

OpenVG whatz up?

February 7, 2010

KDE has been used SVG images for Themes for a long time. So i begun to have an interest in how i could optimize it and look in OpenVG.

The OpenVG definition by Khronos is:
Cross-platform API that provides a low-level hardware acceleration interface for vector graphics libraries such as Flash and SVG. OpenVG has many low level improvements that can be used in SVG like some blend operations. So i thought “what the best way to learn than implementing something?”
From there on i begun my journey. I started to learn about Vega, an opensource implementation of OpenVG done by Zack Rusin using Gallium3D, and studied the Khronos OpenVG specification. Studying OpenVG especification i discover about extesions espefications and read an interesting especification “advanced blending”.

Advanced Blending OpenVG specifies a larger set of blend modes than those in OpenVG. So i begun to implement it but to do it i need to do some refactoring in OpenVG shaders to use tgsi_ureg, right now i am still working in advanced blending but just in my spare time. I already have some advanced blending working like Blend Overlay and Blend Hardlight.

Blend Overlay is defined as: Multiplies or screens the colors, dependent on the destination color. Source colors overlay the destination whilst preserving its highlights and shadows. The destination color is not replaced, but is mixed with the source color to reflect the lightness or darkness of the destination. And

Blend Hardlight is defined as: Multiplies or screens the colors, dependent on the source color value. If the source color is lighter than 0.5, the destination is lightened as if it were screened. If the source color is darker than 0.5, the destination is darkened, as if it were multiplied. The degree of lightening or darkening is proportional to the difference between the source color and 0.5. If it is equal to 0.5 the destination is unchanged. Painting with pure black or white  produces black or white.

To understand better i added support for those blending operations in an OpenVG demo called lion.

This is the default image without any advanced blending applied on it.

Applying Overlay Blending we have:

And applying Blend hardlight we have:

So, after all, what are the benefits in KDE?

Qt has a OpenVG paint engine. The last time that i saw it was in the early stages. Improving OpenVG paint Engine and OpenVG implementations we could improve KDE performance rendering themes and maybe in future we could use SVG icons.

First Post

November 2, 2009

hello Dudes,

It is my first Post in my new blog(yes i had an old one) and i hope to write things about kde, real time OS and Unix.