Merge the OpenVG RI optimisations into the extra copy of sfopenvg EGL_MERGE
authorWilliam Roberts <williamr@symbian.org>
Thu, 03 Jun 2010 17:45:05 +0100
branchEGL_MERGE
changeset 88 a5a3a8cb368e
parent 86 841b49c57c50
Merge the OpenVG RI optimisations into the extra copy of sfopenvg
egl/eglrefimpl/group/eglref.mmp
egl/sfopenvg/riDefs.h
egl/sfopenvg/riMath.cpp
egl/sfopenvg/riMath.h
egl/sfopenvg/riPath.cpp
egl/sfopenvg/riUtils.cpp
egl/sfopenvg/riUtils.h
--- a/egl/eglrefimpl/group/eglref.mmp	Tue Jun 01 15:04:40 2010 +0100
+++ b/egl/eglrefimpl/group/eglref.mmp	Thu Jun 03 17:45:05 2010 +0100
@@ -58,6 +58,7 @@
 source riPath.cpp
 source riPixelPipe.cpp
 source riRasterizer.cpp
+source riUtils.cpp
 source riVGU.cpp
 
 //for EGL
--- a/egl/sfopenvg/riDefs.h	Tue Jun 01 15:04:40 2010 +0100
+++ b/egl/sfopenvg/riDefs.h	Thu Jun 03 17:45:05 2010 +0100
@@ -61,6 +61,8 @@
 
 //=======================================================================
 
+typedef long long       RIint64;
+typedef unsigned long long RIuint64;
 typedef int				RIint32;
 typedef unsigned int	RIuint32;
 typedef short			RIint16;
@@ -121,17 +123,31 @@
 #define RI_MAX_GAUSSIAN_STD_DEVIATION	16.0f
 #define RI_MAX_SCISSOR_RECTANGLES		256
 #define RI_MAX_EDGES					262144
-#define RI_MAX_SAMPLES					32
-#define RI_NUM_TESSELLATED_SEGMENTS		256
+#define RI_MAX_SAMPLES						1
+#define RI_NUM_TESSELLATED_SEGMENTS_QUAD	8
+#define RI_NUM_TESSELLATED_SEGMENTS_CUBIC	8
+#define RI_NUM_TESSELLATED_SEGMENTS_ARC		8
 
+#if defined(__GNUC__) && !defined(SF_PROFILE)
+#	ifndef NDEBUG
+#	define _DEBUG 1
+#	endif
+#endif
+#if _DEBUG
 #define RI_DEBUG
+#endif
 
 #ifdef RI_DEBUG
-#	define RI_ASSERT assert
+#	define RI_ASSERT(X) assert(X)
 #else
-#	define RI_ASSERT
+#	define RI_ASSERT(X) (void(0))
 #endif
 
+#if defined(RI_DEBUG)
+#   define RI_PRINTF(...) printf(__VA_ARGS__)
+#else
+#   define RI_PRINTF(...)
+#endif
 #define RI_UNREF(X) ((void)(X))
 #define RI_APIENTRY EXPORT_C
 
@@ -147,7 +163,16 @@
 
 bool			isValidImageFormat(int format);
 bool      isValidImageFormat(EGLNativePixmapType f);
-
+RI_INLINE void RI_MEM_ZERO(void *dst, size_t n)
+{
+    RI_ASSERT(n > 0);
+    RI_ASSERT((n & 0x3) == 0);
+    RIuint32 *ptr = (RIuint32*)dst;
+    for(size_t i = 0; i < (n>>2); i++)
+    {
+        *ptr++ = 0;
+    }
+}
 //=======================================================================
 
 }	//namespace OpenVGRI
--- a/egl/sfopenvg/riMath.cpp	Tue Jun 01 15:04:40 2010 +0100
+++ b/egl/sfopenvg/riMath.cpp	Thu Jun 03 17:45:05 2010 +0100
@@ -4,6 +4,7 @@
  * -----------------------------------
  *
  * Copyright (c) 2007 The Khronos Group Inc.
+ * Portions Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and /or associated documentation files
@@ -33,6 +34,20 @@
 #include "riDefs.h"
 #include "riMath.h"
 
+#if 0
+#include <stdio.h>
+
+static void printMatrix(const Matrix3x3& m)
+{
+    // For tracing a bug in matrix inverse in release-builds.
+    for(int i = 0; i < 3; i++)
+    {
+        printf("[%.4f %.4f %.4f]\n", m[i][0], m[i][1], m[i][2]);
+    }
+}
+
+#endif
+
 namespace OpenVGRI
 {
 
@@ -45,6 +60,7 @@
 
 bool Matrix3x3::invert()
 {
+    // \todo Save computation on affine matrices?
 	bool affine = isAffine();
 	RIfloat det00 = matrix[1][1]*matrix[2][2] - matrix[2][1]*matrix[1][2];
 	RIfloat det01 = matrix[2][0]*matrix[1][2] - matrix[1][0]*matrix[2][2];
@@ -55,15 +71,26 @@
 	d = 1.0f / d;
 
 	Matrix3x3 t;
-	t[0][0] = d * det00;
-	t[1][0] = d * det01;
-	t[2][0] = d * det02;
-	t[0][1] = d * (matrix[2][1]*matrix[0][2] - matrix[0][1]*matrix[2][2]);
-	t[1][1] = d * (matrix[0][0]*matrix[2][2] - matrix[2][0]*matrix[0][2]);
-	t[2][1] = d * (matrix[2][0]*matrix[0][1] - matrix[0][0]*matrix[2][1]);
-	t[0][2] = d * (matrix[0][1]*matrix[1][2] - matrix[1][1]*matrix[0][2]);
-	t[1][2] = d * (matrix[1][0]*matrix[0][2] - matrix[0][0]*matrix[1][2]);
-	t[2][2] = d * (matrix[0][0]*matrix[1][1] - matrix[1][0]*matrix[0][1]);
+
+    // \note There is some bug (in GCC?) in accessing matrix elements: If data
+    // is accessed like: t[i][j], then the following will produce incorrect
+    // resulst on optimized builds. If the data is accessed through t.matrix,
+    // then the output is correct. Debug build works correctly, and if print
+    // calls are inserted, the code also works correctly. The context to get
+    // this bug appear are fill paints (linear and radial gradient test
+    // functions).
+
+	t.matrix[0][0] = d * det00;
+	t.matrix[1][0] = d * det01;
+	t.matrix[2][0] = d * det02;
+    //printf("t\n");
+    //printMatrix(t);
+	t.matrix[0][1] = d * (matrix[2][1]*matrix[0][2] - matrix[0][1]*matrix[2][2]);
+	t.matrix[1][1] = d * (matrix[0][0]*matrix[2][2] - matrix[2][0]*matrix[0][2]);
+	t.matrix[2][1] = d * (matrix[2][0]*matrix[0][1] - matrix[0][0]*matrix[2][1]);
+	t.matrix[0][2] = d * (matrix[0][1]*matrix[1][2] - matrix[1][1]*matrix[0][2]);
+	t.matrix[1][2] = d * (matrix[1][0]*matrix[0][2] - matrix[0][0]*matrix[1][2]);
+	t.matrix[2][2] = d * (matrix[0][0]*matrix[1][1] - matrix[1][0]*matrix[0][1]);
 	if(affine)
 		t[2].set(0,0,1);	//affine matrix stays affine
 	*this = t;
--- a/egl/sfopenvg/riMath.h	Tue Jun 01 15:04:40 2010 +0100
+++ b/egl/sfopenvg/riMath.h	Thu Jun 03 17:45:05 2010 +0100
@@ -7,6 +7,7 @@
  * -----------------------------------
  *
  * Copyright (c) 2007 The Khronos Group Inc.
+ * Portions Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and /or associated documentation files
@@ -14,10 +15,10 @@
  * including without limitation the rights to use, copy, modify, merge,
  * publish, distribute, sublicense, and/or sell copies of the Materials,
  * and to permit persons to whom the Materials are furnished to do so,
- * subject to the following conditions: 
+ * subject to the following conditions:
  *
- * The above copyright notice and this permission notice shall be included 
- * in all copies or substantial portions of the Materials. 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Materials.
  *
  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
@@ -30,7 +31,7 @@
  *//**
  * \file
  * \brief	Math functions, Vector and Matrix classes.
- * \note	
+ * \note
  *//*-------------------------------------------------------------------*/
 
 #ifndef __RIDEFS_H
@@ -43,21 +44,21 @@
 {
 
 /*-------------------------------------------------------------------*//*!
-* \brief	
-* \param	
-* \return	
-* \note		
+* \brief
+* \param
+* \return
+* \note
 *//*-------------------------------------------------------------------*/
 
 RI_INLINE int		RI_ISNAN(float a)
 {
-	RIfloatInt p;
-	p.f = a;
-	unsigned int exponent = (p.i>>23) & 0xff;
-	unsigned int mantissa = p.i & 0x7fffff;
-	if(exponent == 255 && mantissa)
-		return 1;
-	return 0;
+    RIfloatInt p;
+    p.f = a;
+    unsigned int exponent = (p.i>>23) & 0xff;
+    unsigned int mantissa = p.i & 0x7fffff;
+    if(exponent == 255 && mantissa)
+        return 1;
+    return 0;
 }
 
 #if (RI_MANTISSA_BITS > 23)
@@ -69,77 +70,77 @@
 class RIfloat
 {
 public:
-	RIfloat() : v(0.0f)						{ removeBits(); }
-	RIfloat(float a) : v(a)					{ removeBits(); }
-	RIfloat(double a) : v((float)a)			{ removeBits(); }
-	RIfloat(int a) : v((float)a)			{ removeBits(); }
-	RIfloat(unsigned int a) : v((float)a)	{ removeBits(); }
-	RIfloat&	operator=(const RIfloat &a)	{ v = a.v; removeBits(); return *this; }
-	RIfloat&	operator+=(const RIfloat &a){ v += a.v; removeBits(); return *this; }
-	RIfloat&	operator-=(const RIfloat &a){ v -= a.v; removeBits(); return *this; }
-	RIfloat&	operator*=(const RIfloat &a){ v *= a.v; removeBits(); return *this; }
-	RIfloat&	operator/=(const RIfloat &a){ v /= a.v; removeBits(); return *this; }
-	RIfloat		operator-() const			{ return -v; }
-	operator float() const					{ return v; }
-	operator double() const					{ return (double)v; }
-	operator int() const					{ return (int)v; }
+    RIfloat() : v(0.0f)						{ removeBits(); }
+    RIfloat(float a) : v(a)					{ removeBits(); }
+    RIfloat(double a) : v((float)a)			{ removeBits(); }
+    RIfloat(int a) : v((float)a)			{ removeBits(); }
+    RIfloat(unsigned int a) : v((float)a)	{ removeBits(); }
+    RIfloat&	operator=(const RIfloat &a)	{ v = a.v; removeBits(); return *this; }
+    RIfloat&	operator+=(const RIfloat &a){ v += a.v; removeBits(); return *this; }
+    RIfloat&	operator-=(const RIfloat &a){ v -= a.v; removeBits(); return *this; }
+    RIfloat&	operator*=(const RIfloat &a){ v *= a.v; removeBits(); return *this; }
+    RIfloat&	operator/=(const RIfloat &a){ v /= a.v; removeBits(); return *this; }
+    RIfloat		operator-() const			{ return -v; }
+    operator float() const					{ return v; }
+    operator double() const					{ return (double)v; }
+    operator int() const					{ return (int)v; }
 
-	friend RIfloat	operator+(const RIfloat &a, const RIfloat &b);
-	friend RIfloat	operator+(float a, const RIfloat &b);
-	friend RIfloat	operator+(const RIfloat &a, float b);
-	friend RIfloat	operator-(const RIfloat &a, const RIfloat &b);
-	friend RIfloat	operator-(float a, const RIfloat &b);
-	friend RIfloat	operator-(const RIfloat &a, float b);
-	friend RIfloat	operator*(const RIfloat &a, const RIfloat &b);
-	friend RIfloat	operator*(float a, const RIfloat &b);
-	friend RIfloat	operator*(const RIfloat &a, float b);
-	friend RIfloat	operator/(const RIfloat &a, const RIfloat &b);
-	friend RIfloat	operator/(float a, const RIfloat &b);
-	friend RIfloat	operator/(const RIfloat &a, float b);
+    friend RIfloat	operator+(const RIfloat &a, const RIfloat &b);
+    friend RIfloat	operator+(float a, const RIfloat &b);
+    friend RIfloat	operator+(const RIfloat &a, float b);
+    friend RIfloat	operator-(const RIfloat &a, const RIfloat &b);
+    friend RIfloat	operator-(float a, const RIfloat &b);
+    friend RIfloat	operator-(const RIfloat &a, float b);
+    friend RIfloat	operator*(const RIfloat &a, const RIfloat &b);
+    friend RIfloat	operator*(float a, const RIfloat &b);
+    friend RIfloat	operator*(const RIfloat &a, float b);
+    friend RIfloat	operator/(const RIfloat &a, const RIfloat &b);
+    friend RIfloat	operator/(float a, const RIfloat &b);
+    friend RIfloat	operator/(const RIfloat &a, float b);
 
-	friend bool		operator<(const RIfloat &a, const RIfloat &b);
-	friend bool		operator<(float a, const RIfloat &b);
-	friend bool		operator<(const RIfloat &a, float b);
-	friend bool		operator>(const RIfloat &a, const RIfloat &b);
-	friend bool		operator>(float a, const RIfloat &b);
-	friend bool		operator>(const RIfloat &a, float b);
-	friend bool		operator<=(const RIfloat &a, const RIfloat &b);
-	friend bool		operator<=(float a, const RIfloat &b);
-	friend bool		operator<=(const RIfloat &a, float b);
-	friend bool		operator>=(const RIfloat &a, const RIfloat &b);
-	friend bool		operator>=(float a, const RIfloat &b);
-	friend bool		operator>=(const RIfloat &a, float b);
-	friend bool		operator==(const RIfloat &a, const RIfloat &b);
-	friend bool		operator==(float a, const RIfloat &b);
-	friend bool		operator==(const RIfloat &a, float b);
-	friend bool		operator!=(const RIfloat &a, const RIfloat &b);
-	friend bool		operator!=(float a, const RIfloat &b);
-	friend bool		operator!=(const RIfloat &a, float b);
+    friend bool		operator<(const RIfloat &a, const RIfloat &b);
+    friend bool		operator<(float a, const RIfloat &b);
+    friend bool		operator<(const RIfloat &a, float b);
+    friend bool		operator>(const RIfloat &a, const RIfloat &b);
+    friend bool		operator>(float a, const RIfloat &b);
+    friend bool		operator>(const RIfloat &a, float b);
+    friend bool		operator<=(const RIfloat &a, const RIfloat &b);
+    friend bool		operator<=(float a, const RIfloat &b);
+    friend bool		operator<=(const RIfloat &a, float b);
+    friend bool		operator>=(const RIfloat &a, const RIfloat &b);
+    friend bool		operator>=(float a, const RIfloat &b);
+    friend bool		operator>=(const RIfloat &a, float b);
+    friend bool		operator==(const RIfloat &a, const RIfloat &b);
+    friend bool		operator==(float a, const RIfloat &b);
+    friend bool		operator==(const RIfloat &a, float b);
+    friend bool		operator!=(const RIfloat &a, const RIfloat &b);
+    friend bool		operator!=(float a, const RIfloat &b);
+    friend bool		operator!=(const RIfloat &a, float b);
 private:
-	void	removeBits()
-	{
-		RIfloatInt p;
-		p.f = v;
-		unsigned int exponent = (p.i>>23) & 0xff;
-		if(exponent == 0 || exponent == 255)
-			return;	//zero, denormal, infinite, or NaN
+    void	removeBits()
+    {
+        RIfloatInt p;
+        p.f = v;
+        unsigned int exponent = (p.i>>23) & 0xff;
+        if(exponent == 0 || exponent == 255)
+            return;	//zero, denormal, infinite, or NaN
 
-		p.i &= ~((1<<(23-RI_MANTISSA_BITS))-1);
+        p.i &= ~((1<<(23-RI_MANTISSA_BITS))-1);
 
 #if (RI_EXPONENT_BITS != 8)
-		if (exponent > 127 + (1 << (RI_EXPONENT_BITS-1)))
-			exponent = 127 + (1 << (RI_EXPONENT_BITS-1));
+        if (exponent > 127 + (1 << (RI_EXPONENT_BITS-1)))
+            exponent = 127 + (1 << (RI_EXPONENT_BITS-1));
 
-		if (exponent < 127 + 1 - (1 << (RI_EXPONENT_BITS-1)))
-			exponent = 127 + 1 - (1 << (RI_EXPONENT_BITS-1));
+        if (exponent < 127 + 1 - (1 << (RI_EXPONENT_BITS-1)))
+            exponent = 127 + 1 - (1 << (RI_EXPONENT_BITS-1));
 
-		p.i &= ~(0xff<<23);
-		p.i |= exponent<<23;
+        p.i &= ~(0xff<<23);
+        p.i |= exponent<<23;
 #endif
-		v = p.f;
-	}
+        v = p.f;
+    }
 
-	float		v;
+    float		v;
 };
 
 RI_INLINE RIfloat operator+(const RIfloat &a, const RIfloat &b)	{ return RIfloat(a.v+b.v); }
@@ -180,8 +181,11 @@
 
 #define	PI						3.141592654f
 
+RI_INLINE int       RI_ROUND_TO_INT(RIfloat v)                  { return (v >= 0.0f) ? (int)(v+0.5f) : (int)(v-0.5f); }
 RI_INLINE RIfloat	RI_MAX(RIfloat a, RIfloat b)				{ return (a > b) ? a : b; }
+RI_INLINE int		RI_MAX(int a, int b)						{ return (a > b) ? a : b; }
 RI_INLINE RIfloat	RI_MIN(RIfloat a, RIfloat b)				{ return (a < b) ? a : b; }
+RI_INLINE int		RI_MIN(int a, int b)						{ return (a < b) ? a : b; }
 RI_INLINE RIfloat	RI_CLAMP(RIfloat a, RIfloat l, RIfloat h)	{ if(RI_ISNAN(a)) return l; RI_ASSERT(l <= h); return (a < l) ? l : (a > h) ? h : a; }
 RI_INLINE void		RI_SWAP(RIfloat &a, RIfloat &b)				{ RIfloat tmp = a; a = b; b = tmp; }
 RI_INLINE RIfloat	RI_ABS(RIfloat a)							{ return (a < 0.0f) ? -a : a; }
@@ -190,12 +194,32 @@
 RI_INLINE RIfloat	RI_RAD_TO_DEG(RIfloat a)					{ return a * 180.0f/ PI; }
 RI_INLINE RIfloat	RI_MOD(RIfloat a, RIfloat b)				{ if(RI_ISNAN(a) || RI_ISNAN(b)) return 0.0f; RI_ASSERT(b >= 0.0f); if(b == 0.0f) return 0.0f; RIfloat f = (RIfloat)fmod(a, b); if(f < 0.0f) f += b; RI_ASSERT(f >= 0.0f && f <= b); return f; }
 
+#define RI_ANY_SWAP(type, a, b) {type tmp = a; a = b; b = tmp;}
+
+RI_INLINE void      RI_INT16_SWAP(RIint16 &a, RIint16 &b) {RIint16 tmp = a; a = b; b = tmp;}
+RI_INLINE int       RI_INT_ABS(int a)                   { return (a >= 0) ? a : -a; }
 RI_INLINE int		RI_INT_MAX(int a, int b)			{ return (a > b) ? a : b; }
 RI_INLINE int		RI_INT_MIN(int a, int b)			{ return (a < b) ? a : b; }
+RI_INLINE int       RI_INT_CLAMP(int a, int l, int h)   { return (a < l) ? l : (a > h) ? h : a; }
 RI_INLINE void		RI_INT_SWAP(int &a, int &b)			{ int tmp = a; a = b; b = tmp; }
 RI_INLINE int		RI_INT_MOD(int a, int b)			{ RI_ASSERT(b >= 0); if(!b) return 0; int i = a % b; if(i < 0) i += b; RI_ASSERT(i >= 0 && i < b); return i; }
 RI_INLINE int		RI_INT_ADDSATURATE(int a, int b)	{ RI_ASSERT(b >= 0); int r = a + b; return (r >= a) ? r : RI_INT32_MAX; }
 
+RI_INLINE int       RI_SHL(int a, int sh)
+{
+    RI_ASSERT(sh >= 0 && sh <= 31);
+    int r = a << sh;
+    RI_ASSERT(a >= 0 ? (r >= 0) : (r < 0));
+    return r;
+}
+
+RI_INLINE int RI_SHR(int a, int sh)
+{
+    RI_ASSERT(sh >= 0 && sh <= 31);
+    int r = a >> sh;
+    return r;
+}
+
 class Matrix3x3;
 class Vector2;
 class Vector3;
@@ -209,31 +233,31 @@
 class Matrix3x3
 {
 public:
-	RI_INLINE					Matrix3x3		();						//initialized to identity
-	RI_INLINE					Matrix3x3		( const Matrix3x3& m );
-	RI_INLINE					Matrix3x3		( RIfloat m00, RIfloat m01, RIfloat m02, RIfloat m10, RIfloat m11, RIfloat m12, RIfloat m20, RIfloat m21, RIfloat m22 );
-	RI_INLINE					~Matrix3x3		();
-	RI_INLINE Matrix3x3&		operator=		( const Matrix3x3& m );
-	RI_INLINE Vector3&			operator[]		( int i );				//returns a row vector
-	RI_INLINE const Vector3&	operator[]		( int i ) const;
-	RI_INLINE void				set				( RIfloat m00, RIfloat m01, RIfloat m02, RIfloat m10, RIfloat m11, RIfloat m12, RIfloat m20, RIfloat m21, RIfloat m22 );
-	RI_INLINE const Vector3		getRow			( int i ) const;
-	RI_INLINE const Vector3		getColumn		( int i ) const;
-	RI_INLINE void				setRow			( int i, const Vector3& v );
-	RI_INLINE void				setColumn		( int i, const Vector3& v );
-	RI_INLINE void				operator*=		( const Matrix3x3& m );
-	RI_INLINE void				operator*=		( RIfloat f );
-	RI_INLINE void				operator+=		( const Matrix3x3& m );
-	RI_INLINE void				operator-=		( const Matrix3x3& m );
-	RI_INLINE const Matrix3x3	operator-		() const;
-	RI_INLINE void				identity		();
-	RI_INLINE void				transpose		();
-	bool						invert			();	//if the matrix is singular, returns false and leaves it unmodified
-	RI_INLINE RIfloat				det				() const;
-	RI_INLINE bool				isAffine		() const;
+    RI_INLINE					Matrix3x3		();						//initialized to identity
+    RI_INLINE					Matrix3x3		( const Matrix3x3& m );
+    RI_INLINE					Matrix3x3		( RIfloat m00, RIfloat m01, RIfloat m02, RIfloat m10, RIfloat m11, RIfloat m12, RIfloat m20, RIfloat m21, RIfloat m22 );
+    RI_INLINE					~Matrix3x3		();
+    RI_INLINE Matrix3x3&		operator=		( const Matrix3x3& m );
+    RI_INLINE Vector3&			operator[]		( int i );				//returns a row vector
+    RI_INLINE const Vector3&	operator[]		( int i ) const;
+    RI_INLINE void				set				( RIfloat m00, RIfloat m01, RIfloat m02, RIfloat m10, RIfloat m11, RIfloat m12, RIfloat m20, RIfloat m21, RIfloat m22 );
+    RI_INLINE const Vector3		getRow			( int i ) const;
+    RI_INLINE const Vector3		getColumn		( int i ) const;
+    RI_INLINE void				setRow			( int i, const Vector3& v );
+    RI_INLINE void				setColumn		( int i, const Vector3& v );
+    RI_INLINE void				operator*=		( const Matrix3x3& m );
+    RI_INLINE void				operator*=		( RIfloat f );
+    RI_INLINE void				operator+=		( const Matrix3x3& m );
+    RI_INLINE void				operator-=		( const Matrix3x3& m );
+    RI_INLINE const Matrix3x3	operator-		() const;
+    RI_INLINE void				identity		();
+    RI_INLINE void				transpose		();
+    bool						invert			();	//if the matrix is singular, returns false and leaves it unmodified
+    RI_INLINE RIfloat				det				() const;
+    RI_INLINE bool				isAffine		() const;
 
 private:
-	RIfloat						matrix[3][3];
+    RIfloat						matrix[3][3];
 };
 
 //==============================================================================================
@@ -241,25 +265,25 @@
 class Vector2
 {
 public:
-	RI_INLINE					Vector2			() : x(0.0f), y(0.0f)					{}
-	RI_INLINE					Vector2			( const Vector2& v ) : x(v.x), y(v.y)	{}
-	RI_INLINE					Vector2			( RIfloat fx, RIfloat fy ) : x(fx), y(fy)	{}
-	RI_INLINE					~Vector2		()								{}
-	RI_INLINE Vector2&			operator=		( const Vector2& v )			{ x = v.x; y = v.y; return *this; }
-	RI_INLINE RIfloat&			operator[]		( int i )						{ RI_ASSERT(i>=0&&i<2); return (&x)[i]; }
-	RI_INLINE const RIfloat&	operator[]		( int i ) const					{ RI_ASSERT(i>=0&&i<2); return (&x)[i]; }
-	RI_INLINE void				set				( RIfloat fx, RIfloat fy )			{ x = fx; y = fy; }
-	RI_INLINE void				operator*=		( RIfloat f )						{ x *= f; y *= f; }
-	RI_INLINE void				operator+=		( const Vector2& v )			{ x += v.x; y += v.y; }
-	RI_INLINE void				operator-=		( const Vector2& v )			{ x -= v.x; y -= v.y; }
-	RI_INLINE const Vector2		operator-		() const						{ return Vector2(-x,-y); }
-	//if the vector is zero, returns false and leaves it unmodified
-	RI_INLINE bool				normalize		()								{ double l = (double)x*(double)x+(double)y*(double)y; if( l == 0.0 ) return false; l = 1.0 / sqrt(l); x = (RIfloat)((double)x * l); y = (RIfloat)((double)y * l); return true; }
-	RI_INLINE RIfloat			length			() const						{ return (RIfloat)sqrt((double)x*(double)x+(double)y*(double)y); }
-	RI_INLINE void				scale			( const Vector2& v )			{ x *= v.x; y *= v.y; }	//component-wise scale
-	RI_INLINE void				negate			()								{ x = -x; y = -y; }
+    RI_INLINE					Vector2			() : x(0.0f), y(0.0f)					{}
+    RI_INLINE					Vector2			( const Vector2& v ) : x(v.x), y(v.y)	{}
+    RI_INLINE					Vector2			( RIfloat fx, RIfloat fy ) : x(fx), y(fy)	{}
+    RI_INLINE					~Vector2		()								{}
+    RI_INLINE Vector2&			operator=		( const Vector2& v )			{ x = v.x; y = v.y; return *this; }
+    RI_INLINE RIfloat&			operator[]		( int i )						{ RI_ASSERT(i>=0&&i<2); return (&x)[i]; }
+    RI_INLINE const RIfloat&	operator[]		( int i ) const					{ RI_ASSERT(i>=0&&i<2); return (&x)[i]; }
+    RI_INLINE void				set				( RIfloat fx, RIfloat fy )			{ x = fx; y = fy; }
+    RI_INLINE void				operator*=		( RIfloat f )						{ x *= f; y *= f; }
+    RI_INLINE void				operator+=		( const Vector2& v )			{ x += v.x; y += v.y; }
+    RI_INLINE void				operator-=		( const Vector2& v )			{ x -= v.x; y -= v.y; }
+    RI_INLINE const Vector2		operator-		() const						{ return Vector2(-x,-y); }
+    //if the vector is zero, returns false and leaves it unmodified
+    RI_INLINE bool				normalize		()								{ double l = (double)x*(double)x+(double)y*(double)y; if( l == 0.0 ) return false; l = 1.0 / sqrt(l); x = (RIfloat)((double)x * l); y = (RIfloat)((double)y * l); return true; }
+    RI_INLINE RIfloat			length			() const						{ return (RIfloat)sqrt((double)x*(double)x+(double)y*(double)y); }
+    RI_INLINE void				scale			( const Vector2& v )			{ x *= v.x; y *= v.y; }	//component-wise scale
+    RI_INLINE void				negate			()								{ x = -x; y = -y; }
 
-	RIfloat						x,y;
+    RIfloat						x,y;
 };
 
 //==============================================================================================
@@ -267,25 +291,25 @@
 class Vector3
 {
 public:
-	RI_INLINE					Vector3			() : x(0.0f), y(0.0f), z(0.0f)							{}
-	RI_INLINE					Vector3			( const Vector3& v ) : x(v.x), y(v.y), z(v.z)			{}
-	RI_INLINE					Vector3			( RIfloat fx, RIfloat fy, RIfloat fz ) : x(fx), y(fy), z(fz)	{}
-	RI_INLINE					~Vector3		()								{}
-	RI_INLINE Vector3&			operator=		( const Vector3& v )			{ x = v.x; y = v.y; z = v.z; return *this; }
-	RI_INLINE RIfloat&			operator[]		( int i )						{ RI_ASSERT(i>=0&&i<3); return (&x)[i]; }
-	RI_INLINE const RIfloat&	operator[]		( int i ) const					{ RI_ASSERT(i>=0&&i<3); return (&x)[i]; }
-	RI_INLINE void				set				( RIfloat fx, RIfloat fy, RIfloat fz ){ x = fx; y = fy; z = fz; }
-	RI_INLINE void				operator*=		( RIfloat f )						{ x *= f; y *= f; z *= f; }
-	RI_INLINE void				operator+=		( const Vector3& v )			{ x += v.x; y += v.y; z += v.z; }
-	RI_INLINE void				operator-=		( const Vector3& v )			{ x -= v.x; y -= v.y; z -= v.z; }
-	RI_INLINE const Vector3		operator-		() const						{ return Vector3(-x,-y,-z); }
-	//if the vector is zero, returns false and leaves it unmodified
-	RI_INLINE bool				normalize		()								{ double l = (double)x*(double)x+(double)y*(double)y+(double)z*(double)z; if( l == 0.0 ) return false; l = 1.0 / sqrt(l); x = (RIfloat)((double)x * l); y = (RIfloat)((double)y * l); z = (RIfloat)((double)z * l); return true; }
-	RI_INLINE RIfloat			length			() const						{ return (RIfloat)sqrt((double)x*(double)x+(double)y*(double)y+(double)z*(double)z); }
-	RI_INLINE void				scale			( const Vector3& v )			{ x *= v.x; y *= v.y; z *= v.z; }	//component-wise scale
-	RI_INLINE void				negate			()								{ x = -x; y = -y; z = -z; }
+    RI_INLINE					Vector3			() : x(0.0f), y(0.0f), z(0.0f)							{}
+    RI_INLINE					Vector3			( const Vector3& v ) : x(v.x), y(v.y), z(v.z)			{}
+    RI_INLINE					Vector3			( RIfloat fx, RIfloat fy, RIfloat fz ) : x(fx), y(fy), z(fz)	{}
+    RI_INLINE					~Vector3		()								{}
+    RI_INLINE Vector3&			operator=		( const Vector3& v )			{ x = v.x; y = v.y; z = v.z; return *this; }
+    RI_INLINE RIfloat&			operator[]		( int i )						{ RI_ASSERT(i>=0&&i<3); return (&x)[i]; }
+    RI_INLINE const RIfloat&	operator[]		( int i ) const					{ RI_ASSERT(i>=0&&i<3); return (&x)[i]; }
+    RI_INLINE void				set				( RIfloat fx, RIfloat fy, RIfloat fz ){ x = fx; y = fy; z = fz; }
+    RI_INLINE void				operator*=		( RIfloat f )						{ x *= f; y *= f; z *= f; }
+    RI_INLINE void				operator+=		( const Vector3& v )			{ x += v.x; y += v.y; z += v.z; }
+    RI_INLINE void				operator-=		( const Vector3& v )			{ x -= v.x; y -= v.y; z -= v.z; }
+    RI_INLINE const Vector3		operator-		() const						{ return Vector3(-x,-y,-z); }
+    //if the vector is zero, returns false and leaves it unmodified
+    RI_INLINE bool				normalize		()								{ double l = (double)x*(double)x+(double)y*(double)y+(double)z*(double)z; if( l == 0.0 ) return false; l = 1.0 / sqrt(l); x = (RIfloat)((double)x * l); y = (RIfloat)((double)y * l); z = (RIfloat)((double)z * l); return true; }
+    RI_INLINE RIfloat			length			() const						{ return (RIfloat)sqrt((double)x*(double)x+(double)y*(double)y+(double)z*(double)z); }
+    RI_INLINE void				scale			( const Vector3& v )			{ x *= v.x; y *= v.y; z *= v.z; }	//component-wise scale
+    RI_INLINE void				negate			()								{ x = -x; y = -y; z = -z; }
 
-	RIfloat						x,y,z;
+    RIfloat						x,y,z;
 };
 
 //==============================================================================================
--- a/egl/sfopenvg/riPath.cpp	Tue Jun 01 15:04:40 2010 +0100
+++ b/egl/sfopenvg/riPath.cpp	Thu Jun 03 17:45:05 2010 +0100
@@ -2010,7 +2010,7 @@
 	if(!subpathHasGeometry)
 		startFlags |= START_SUBPATH;
 
-	const int segments = RI_NUM_TESSELLATED_SEGMENTS;
+	const int segments = RI_NUM_TESSELLATED_SEGMENTS_QUAD;
 	Vector2 pp = p0;
 	Vector2 tp = incomingTangent;
 	unsigned int prevFlags = startFlags;
@@ -2074,7 +2074,7 @@
 	if(!subpathHasGeometry)
 		startFlags |= START_SUBPATH;
 
-	const int segments = RI_NUM_TESSELLATED_SEGMENTS;
+	const int segments = RI_NUM_TESSELLATED_SEGMENTS_CUBIC;
 	Vector2 pp = p0;
 	Vector2 tp = incomingTangent;
 	unsigned int prevFlags = startFlags;
@@ -2242,7 +2242,7 @@
 	outgoingTangent = normalize(outgoingTangent);
 	RI_ASSERT(!isZero(incomingTangent) && !isZero(outgoingTangent));
 
-	const int segments = RI_NUM_TESSELLATED_SEGMENTS;
+	const int segments = RI_NUM_TESSELLATED_SEGMENTS_ARC;
 	Vector2 pp = p0;
 	Vector2 tp = incomingTangent;
 	unsigned int prevFlags = startFlags;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/egl/sfopenvg/riUtils.cpp	Thu Jun 03 17:45:05 2010 +0100
@@ -0,0 +1,113 @@
+/*------------------------------------------------------------------------
+ *
+ * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and /or associated documentation files
+ * (the "Materials "), to deal in the Materials without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Materials,
+ * and to permit persons to whom the Materials are furnished to do so,
+ * subject to the following conditions: 
+ *
+ * The above copyright notice and this permission notice shall be included 
+ * in all copies or substantial portions of the Materials. 
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR
+ * THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//*-------------------------------------------------------------------*/
+
+#ifndef __RIUTILS_H_
+#   include "riUtils.h"
+#endif
+
+#include <string.h>
+
+namespace OpenVGRI
+{
+
+/**
+ * \brief   Sets mem areas to byte(s) in c.
+ * \param   dst     Destination pointer.
+ * \param   c       Data to set into dst.
+ * \param   nElements   Amount of elements to set.
+ * \param   nBytesPerElement    Amount of bytes for each element.
+ * \note    This is moslty an image-settings support function. It is assumed that several
+ *          bytes / elements can be set at once, especially in 3-byte case.
+ */
+void riMemSet32(void* dst, RIuint32 c, size_t nElements, size_t nBytesPerElement)
+{
+    // \todo This function should be called from a function that handles npot element sizes.
+    // \todo Investigate the status of (open) std::fill implementations. Some of that code 
+    // did not _seem_ to bundle sets or use SSE, etc.
+    // \todo Use SSE instructions on Intel? 
+    
+    RI_ASSERT(dst);
+    RI_ASSERT(nElements);
+
+    switch(nBytesPerElement)
+    {
+    case 4:
+    {
+        RIuint32* ptr = (RIuint32*)dst;
+        do {
+            *ptr++ = c;
+        } while(--nElements);
+        break;
+    }
+    case 3:
+    {
+        // \todo Endianness.
+        RIuint8* ptr = (RIuint8*)dst;
+        RIuint8 b[3];
+        b[0] = c & 0xff;
+        b[1] = (c >> 8)&0xff;
+        b[2] = (c >> 16)&0xff;
+        do {
+            *ptr++ = b[0];
+            *ptr++ = b[1];
+            *ptr++ = b[2];
+        } while(--nElements);
+        break;
+    }
+    case 2:
+    {
+        size_t dws = nElements / 2; 
+        if (dws)
+        {
+            RIuint32* ptr32 = (RIuint32*)dst;
+            dst = (void*)(((RIuint8*)dst + dws * 4));
+            RIuint32 dw = c | (c<<16);
+            do {
+                *ptr32++ = dw;
+            } while(--dws);
+            nElements &= 0x01;
+        }
+        if (nElements)
+        {
+            RIuint16 *ptr16 = (RIuint16*)dst;
+            const RIuint16 w = (RIuint16)c;
+            do {
+                *ptr16++ = w;
+            } while(--nElements);
+        }
+    }
+    case 1:
+    {
+        memset(dst, c, nElements);
+        break;
+    }
+    default:
+        RI_ASSERT(false);
+    }
+
+}
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/egl/sfopenvg/riUtils.h	Thu Jun 03 17:45:05 2010 +0100
@@ -0,0 +1,46 @@
+/*------------------------------------------------------------------------
+ *
+ * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and /or associated documentation files
+ * (the "Materials "), to deal in the Materials without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Materials,
+ * and to permit persons to whom the Materials are furnished to do so,
+ * subject to the following conditions: 
+ *
+ * The above copyright notice and this permission notice shall be included 
+ * in all copies or substantial portions of the Materials. 
+ *
+ * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR
+ * THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ *
+ *//*-------------------------------------------------------------------*/
+
+#ifndef __RIUTILS_H_
+#define __RIUTILS_H_
+
+#ifndef __RIDEFS_H
+#   include "riDefs.h"
+#endif
+
+// This file contains "utility" functions that did not "fit" into existing RI files.
+// Once more functionality is accumulated, the corresponding functions/classes should be
+// moved to proper files asap. For example, the memcopy functions could go into file
+// "riMemory.xxx".
+
+namespace OpenVGRI
+{
+
+void riMemSet32(void* dst, RIuint32 c, size_t nElements, size_t nBytesPerElement);
+
+}
+
+#endif
+