1. INTRODUCTION

AmanithVG is a commercial implementation of OpenVG 1.1 and 1.0.1, the application programming interface (API) for hardware accelerated 2D vector and raster graphics, created by the Khronos group. Born as a "OpenVG on OpenGL / OpenGL ES" engine, AmanithVG evolved into two different OpenVG graphic libraries.

AmanithVG GLE is entirely built on top of OpenGL 1.1+ and OpenGL ES 1.x CM, and it uses extensions where available. This engine can grant high quality vector graphics on a wide range of 3D chipset, achieving better performance than software rasterizers in terms of high resolution animations and complex special effects (transparencies, fading, realtime rotoscaling and many others).

AmanithVG SRE is a pure software solution that grants a superlative vector graphics quality without to sacrifice performance on any kind of architecture / platform. Thanks to its original polygon rasterization algorithm and dedicated optimized scanline fillers, this engine constitues the fastest OpenVG software rendering solution available on the market.

2. TECHNICAL CHOICES

AmanithVG has been designed to run everywhere. To accomplish this task the development process has followed strict technical choices:

  • Use of pure ANSI C language, avoiding the use of any third party libraries.
  • Use of advanced caching techniques at different levels (curve flattening, stroking).
  • High and easy customization capability through simple hardware independent thresholds.
  • Modular and flexible architecture to simplify new extensions integration.
  • Fast and robust fixed-point polygon triangulation (GLE).
  • Minimization of the CPU usage, moving the most complex tasks on the 3D chipset / GPU (GLE).
  • Dynamic rendering pipelines, according to underlying 3D hardware features / extensions (GLE).
  • Use of few smart software fallbacks on very old hardware (GLE).
  • Fast and robust fixed-point polygon rasterizer (SRE).
  • Use of dedicated optimized scanline fillers, instead of a slow monolithic pixel pipeline (SRE).

3. QUALITY & RENDERING CORRECTNESS

Quality and correctness are guarenteed by our internal massive testsuite developed to deeply test every single feature and all possible degenerations; to compare the results, the OpenVG 1.1 reference implementation and the OpenVG 1.0.1 reference implementation, have been used.

AmanithVG testsuite results (for OpenVG 1.1), as well as test sources, are available at:

4. FEATURES

AmanithVG SRE and AmanithVG GLE implement the whole OpenVG 1.0.1 and OpenVG 1.1 features, without limitations; while for pure software rendering solutions this is quite common, for solutions that relay on top of OpenGL ES 1.x+ this is an hard task.

AmanithVG GLE is one of the few OpenVG engines that accomplishes this task using 2 texture units and one auxiliary buffer (depth or stencil) only, using few software fallbacks where specific GL extensions aren't available and just to realize a couple of features.

OpenVG feature AmanithVG SRE AmanithVG GLE
Scissoring CPU GPU
Clearing CPU GPU
Alpha Masking CPU GPU
Matrices & transformations CPU GPU
Paths CPU GPU
Fill & stroke (solid, dashed) CPU GPU
Fill rule CPU CPU
Paints (color, gradient, pattern) CPU GPU
Color ramp spread modes CPU GPU
Pattern tiling modes CPU GPU
Images CPU GPU
Image modes (normal, multiply, stencil) CPU GPU
Image quality CPU GPU
Filters CPU CPU
Rendering quality CPU GPU *
Blend modes CPU GPU **
Color transform CPU GPU ***
Font & text CPU GPU
Color spaces CPU GPU ****
Vgu CPU CPU
* antialiasing relays on GL multisampling.
** darken & lighten without GL_EXT_blend_minmax are realized using CPU.
*** color transform on images in multiply mode, when bias != 0, are realized using CPU.
**** except unpremultiplied drawing surfaces format.

5. OPENGL / OPENGLES EXTENSION

To improve performance and reduce memory usage AmanithVG GLE attempts to use the following extensions:

  • GL_EXT_texture_rectangle
  • GL_ARB_texture_mirrored_repeat
  • GL_ARB_texture_border_clamp
  • GL_EXT_blend_minmax
  • GL_EXT_texture_env_dot3
  • GL_ARB_vertex_buffer_object

6. EGL

AmanithVG SRE provides an EGL 1.4 layer supporting a limited set of platform: Linux FB, Linux X11, WindowsCE FB, WindowsCE GDI, Win32 GDI. Both SRE and GLE engines, comes with a standalone version, that doesn't depend on, nor include an EGL implementation. In order to supply EGL functionalities, some additional proprietary calls have been added (to the API) to accomplish the following tasks:

  • vgPrivContextCreateMZT to create and initialize an OpenVG context.
  • vgPrivContextDestroyMZT to destroy a previously createn OpenVG context.
  • vgPrivSurfaceCreateMZT to create a drawing surface.
  • vgPrivSurfaceCreateFromImageMZT to create a drawing surface bound to a given VGImage (SRE).
  • vgPrivSurfaceResizeMZT to resize a drawing surface.
  • vgPrivSurfaceDestroyMZT to destroy a previously created drawing surface.
  • vgPrivGetSurfaceWidthMZT to get width in pixel of a drawing surface.
  • vgPrivGetSurfaceHeightMZT to get height in pixel of a drawing surface.
  • vgPrivGetSurfacePixelsMZT to get the direct access to the pixels of a given drawing surface (SRE).
  • vgPrivMakeCurrentMZT to bind a specified context to a given drawing surface.
  • vgPostSwapBuffersMZT to reset depth and stencil buffers to a valid state for the next frame (GLE).

An Egl 1.4 implementation with OpenVG support can be realized in association with hardware manufacturers and/or operating systems suppliers.

7. MZT EXTENSIONS

OpenVG provides a drawing model similar to those of existing 2D drawing APIs and formats (Adobe PostScript and PDF, Sun Microsystems Java2D, MacroMedia Flash, SVG). It is specifically intended to support all drawing features required by a SVG Tiny 1.2 renderer, and additionally to support functions that may be of use for implementing an SVG Basic renderer. In addition to the base feature set, we introduce a new set of interesting extensions; developers and designers can take advantage of these new features to develop their OpenVG applications.

7.1 Conical gradients

Conical gradients interpolate the color keys counter-clockwise around a point. A conical gradient is defined through the center point, the direction point and the number of repeats. Those points identify the line where the first color key lies on. The number of repeats tells how many times the circle will be split; all the keys take place every slice, following the classic spread mode rules.

Conical gradient, pad spread mode Conical gradient, repeat spread mode Conical gradient, reflect spread mode
Conical gradient, pad spread mode Conical gradient, repeat spread mode Conical gradient, reflect spread mode
VGfloat congrad[5];

conGrad[0] = center.x; conGrad[1] = center.y;
conGrad[2] = target.x; conGrad[3] = target.y;
conGrad[4] = repeats;
vgSetParameteri(paint, VG_PAINT_TYPE,
                VG_PAINT_TYPE_CONICAL_GRADIENT_MZT);
vgSetParameterfv(paint, VG_PAINT_CONICAL_GRADIENT_MZT, 5,
                 conGrad);

7.2 Advancend blend modes

This extension completes the OpenVG 1.1 blend modes to support a full extended Porter-Duff rendering model (the same rendering model used by SVG 1.2). Some of these new modes aren't available in AmanithVG GLE: Overlay, Color Dodge, Color Burn, Hard Light, Soft Light, Difference. In this case a Src Over fallback will be used.

Src blend mode Dst blend mode SrcOver blend mode DstOver blend mode SrcIn blend mode DstIn blend mode
Src

Dst

SrcOver

DstOver

SrcIn

DstIn

SrcOut blend mode DstOut blend mode SrcAtop blend mode DstAtop blend mode Clear blend mode Clear blend mode
SrcOut

DstOut

SrcAtop

DstAtop

Clear

Xor

Screen blend mode Multiply blend mode Difference blend mode Exclusion blend mode Additive blend mode Overlay blend mode
Screen

Multiply

Difference

Exclusion

Additive

Overlay

Darken blend mode Lighten blend mode ColorDodge blend mode ColorBurn blend mode HardLight blend mode SoftLight blend mode
Darken

Lighten

ColorDodge

ColorBurn

HardLight

SoftLight

vgSeti(VG_BLEND_MODE, VG_BLEND_COLOR_DODGE_MZT);

7.3 Separable blend modes

OpenVG 1.1 specifications provide a way to set a single blend mode, that will be used for both stroke and fill drawing. With this extension it is possible to independently specify a blend mode for the stroke and a blend mode for the fill.

Separable blend modes
SrcOver fill - Additive stroke
vgSeti(VG_FILL_BLEND_MODE_MZT, VG_BLEND_SRC_OVER);
vgSeti(VG_STROKE_BLEND_MODE_MZT, VG_BLEND_ADDITIVE);

7.4 Color ramp interpolation

According to OpenVG 1.1 specifications, color and alpha values at offset values between the values given by stops are defined by means of linear interpolation between the values defined at the nearest stops above and below the given offset value. Linear interpolation suffers of the so called 'key highlights' issue; it is very noticeable when large surfaces are filled with a poor of keys gradient. This behaviour could be changed by defining a new color ramp interpolation schema. This extension introduces a smooth color interpolation, based on the Hermite interpolant coupled with Catmull-Rom tangents calculation. The result is a much smoother transition.

Linear and smooth color interpolation Radial gradient, linear color interpolation Radial gradient, smooth color interpolation
Linear and smooth color interpolation Radial gradient, linear color interpolation Radial gradient, smooth color interpolation
vgSetParameteri(paint0,
                VG_PAINT_COLOR_RAMP_INTERPOLATION_TYPE_MZT,
                VG_COLOR_RAMP_INTERPOLATION_SMOOTH_MZT);
vgSetParameteri(paint0,
                VG_PAINT_COLOR_RAMP_INTERPOLATION_TYPE_MZT,
                VG_COLOR_RAMP_INTERPOLATION_LINEAR_MZT);

7.5 Separable cap style

OpenVG 1.1 specifications provide a way to set a single cap style, that will be used for both start-cap and end-cap in a dashed stroke. With this extension it is possible to independently specify a different style for start-cap and end-cap.

Different start/end cap style Round start cap style, square end cap style Square start cap style, round end cap style
Different start/end cap styles Round start cap style, square end cap style Square start cap style, round end cap style
vgSeti(VG_STROKE_START_CAP_STYLE_MZT, VG_CAP_ROUND);
vgSeti(VG_STROKE_END_CAP_STYLE_MZT, VG_CAP_SQUARE);