mirror of
https://github.com/brl/mutter.git
synced 2024-11-25 17:40:40 -05:00
ClutterBezier: Make a private copy of sqrti from cogl
We didn't include clutter-build-config.h, meaning we included a different API of cogl than the rest of clutter. This API contains the function cogl_sqrti which was the only thing used. Lets include the build config file and stop depending on the API that is no longer exposed to us. https://bugzilla.gnome.org/show_bug.cgi?id=768977
This commit is contained in:
parent
b4b13ac996
commit
2547a7cd9c
@ -21,6 +21,8 @@
|
|||||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "clutter-build-config.h"
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "clutter-bezier.h"
|
#include "clutter-bezier.h"
|
||||||
@ -57,6 +59,10 @@
|
|||||||
#define CBZ_T_STEP (CBZ_T_ONE / CBZ_T_SAMPLES)
|
#define CBZ_T_STEP (CBZ_T_ONE / CBZ_T_SAMPLES)
|
||||||
#define CBZ_L_STEP (CBZ_T_ONE / CBZ_T_SAMPLES)
|
#define CBZ_L_STEP (CBZ_T_ONE / CBZ_T_SAMPLES)
|
||||||
|
|
||||||
|
#define FIXED_BITS (32)
|
||||||
|
#define FIXED_Q (FIXED_BITS - 16)
|
||||||
|
#define FIXED_FROM_INT(x) ((x) << FIXED_Q)
|
||||||
|
|
||||||
typedef gint32 _FixedT;
|
typedef gint32 _FixedT;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -186,6 +192,90 @@ _clutter_bezier_advance (const ClutterBezier *b, gint L, ClutterKnot * knot)
|
|||||||
knot->x, knot->y);
|
knot->x, knot->y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
sqrti (int number)
|
||||||
|
{
|
||||||
|
#if defined __SSE2__
|
||||||
|
/* The GCC built-in with SSE2 (sqrtsd) is up to twice as fast as
|
||||||
|
* the pure integer code below. It is also more accurate.
|
||||||
|
*/
|
||||||
|
return __builtin_sqrt (number);
|
||||||
|
#else
|
||||||
|
/* This is a fixed point implementation of the Quake III sqrt algorithm,
|
||||||
|
* described, for example, at
|
||||||
|
* http://www.codemaestro.com/reviews/review00000105.html
|
||||||
|
*
|
||||||
|
* While the original QIII is extremely fast, the use of floating division
|
||||||
|
* and multiplication makes it perform very on arm processors without FPU.
|
||||||
|
*
|
||||||
|
* The key to successfully replacing the floating point operations with
|
||||||
|
* fixed point is in the choice of the fixed point format. The QIII
|
||||||
|
* algorithm does not calculate the square root, but its reciprocal ('y'
|
||||||
|
* below), which is only at the end turned to the inverse value. In order
|
||||||
|
* for the algorithm to produce satisfactory results, the reciprocal value
|
||||||
|
* must be represented with sufficient precission; the 16.16 we use
|
||||||
|
* elsewhere in clutter is not good enough, and 10.22 is used instead.
|
||||||
|
*/
|
||||||
|
_FixedT x;
|
||||||
|
uint32_t y_1; /* 10.22 fixed point */
|
||||||
|
uint32_t f = 0x600000; /* '1.5' as 10.22 fixed */
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
float f;
|
||||||
|
uint32_t i;
|
||||||
|
} flt, flt2;
|
||||||
|
|
||||||
|
flt.f = number;
|
||||||
|
|
||||||
|
x = FIXED_FROM_INT (number) / 2;
|
||||||
|
|
||||||
|
/* The QIII initial estimate */
|
||||||
|
flt.i = 0x5f3759df - ( flt.i >> 1 );
|
||||||
|
|
||||||
|
/* Now, we convert the float to 10.22 fixed. We exploit the mechanism
|
||||||
|
* described at http://www.d6.com/users/checker/pdfs/gdmfp.pdf.
|
||||||
|
*
|
||||||
|
* We want 22 bit fraction; a single precission float uses 23 bit
|
||||||
|
* mantisa, so we only need to add 2^(23-22) (no need for the 1.5
|
||||||
|
* multiplier as we are only dealing with positive numbers).
|
||||||
|
*
|
||||||
|
* Note: we have to use two separate variables here -- for some reason,
|
||||||
|
* if we try to use just the flt variable, gcc on ARM optimises the whole
|
||||||
|
* addition out, and it all goes pear shape, since without it, the bits
|
||||||
|
* in the float will not be correctly aligned.
|
||||||
|
*/
|
||||||
|
flt2.f = flt.f + 2.0;
|
||||||
|
flt2.i &= 0x7FFFFF;
|
||||||
|
|
||||||
|
/* Now we correct the estimate */
|
||||||
|
y_1 = (flt2.i >> 11) * (flt2.i >> 11);
|
||||||
|
y_1 = (y_1 >> 8) * (x >> 8);
|
||||||
|
|
||||||
|
y_1 = f - y_1;
|
||||||
|
flt2.i = (flt2.i >> 11) * (y_1 >> 11);
|
||||||
|
|
||||||
|
/* If the original argument is less than 342, we do another
|
||||||
|
* iteration to improve precission (for arguments >= 342, the single
|
||||||
|
* iteration produces generally better results).
|
||||||
|
*/
|
||||||
|
if (x < 171)
|
||||||
|
{
|
||||||
|
y_1 = (flt2.i >> 11) * (flt2.i >> 11);
|
||||||
|
y_1 = (y_1 >> 8) * (x >> 8);
|
||||||
|
|
||||||
|
y_1 = f - y_1;
|
||||||
|
flt2.i = (flt2.i >> 11) * (y_1 >> 11);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Invert, round and convert from 10.22 to an integer
|
||||||
|
* 0x1e3c68 is a magical rounding constant that produces slightly
|
||||||
|
* better results than 0x200000.
|
||||||
|
*/
|
||||||
|
return (number * flt2.i + 0x1e3c68) >> 22;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_clutter_bezier_init (ClutterBezier *b,
|
_clutter_bezier_init (ClutterBezier *b,
|
||||||
gint x_0, gint y_0,
|
gint x_0, gint y_0,
|
||||||
@ -250,7 +340,7 @@ _clutter_bezier_init (ClutterBezier *b,
|
|||||||
int x = _clutter_bezier_t2x (b, t);
|
int x = _clutter_bezier_t2x (b, t);
|
||||||
int y = _clutter_bezier_t2y (b, t);
|
int y = _clutter_bezier_t2y (b, t);
|
||||||
|
|
||||||
guint l = cogl_sqrti ((y - yp)*(y - yp) + (x - xp)*(x - xp));
|
guint l = sqrti ((y - yp)*(y - yp) + (x - xp)*(x - xp));
|
||||||
|
|
||||||
l += length[i-1];
|
l += length[i-1];
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user