mirror of
https://github.com/brl/mutter.git
synced 2024-12-22 19:12:04 +00:00
added clutter_pow2x() and clutter_log2x()
This commit is contained in:
parent
507f04a8f6
commit
a4eeaceda4
@ -673,6 +673,132 @@ clutter_qmulx (ClutterFixed op1, ClutterFixed op2)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The log2x() and pow2x() functions
|
||||||
|
*
|
||||||
|
* The implementation of the log2x() and pow2x() exploits the well-documented
|
||||||
|
* fact that the exponent part of IEEE floating number provides a good estimate
|
||||||
|
* of log2 of that number, while the mantisa serves as a good error-correction.
|
||||||
|
*
|
||||||
|
* The implemenation here uses a quadratic error correction as described by
|
||||||
|
* Ian Stephenson at http://www.dctsystems.co.uk/Software/power.html.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_log2x :
|
||||||
|
* @x: value to calculate base 2 logarithm from
|
||||||
|
*
|
||||||
|
* Calculates base 2 logarithm.
|
||||||
|
*
|
||||||
|
* This function is some 2.5 times faster on x86, and over 12 times faster on
|
||||||
|
* fpu-less arm, than using libc log().
|
||||||
|
*
|
||||||
|
* Return value: base 2 logarithm.
|
||||||
|
*
|
||||||
|
* Since: 0.4
|
||||||
|
*/
|
||||||
|
ClutterFixed
|
||||||
|
clutter_log2x (guint x)
|
||||||
|
{
|
||||||
|
/* Note: we could easily have a version for ClutterFixed x, but the int
|
||||||
|
* precission is enough for the current purposes.
|
||||||
|
*/
|
||||||
|
union
|
||||||
|
{
|
||||||
|
float f;
|
||||||
|
ClutterFixed i;
|
||||||
|
} flt;
|
||||||
|
|
||||||
|
ClutterFixed magic = 0x58bb;
|
||||||
|
ClutterFixed y;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert x to float, then extract exponent.
|
||||||
|
*
|
||||||
|
* We want the result to be 16.16 fixed, so we shift (23-16) bits only
|
||||||
|
*/
|
||||||
|
flt.f = x;
|
||||||
|
flt.i >>= 7;
|
||||||
|
flt.i -= CLUTTER_INT_TO_FIXED (127);
|
||||||
|
|
||||||
|
y = CLUTTER_FIXED_FRACTION (flt.i);
|
||||||
|
|
||||||
|
y = CFX_MUL ((y - CFX_MUL (y, y)), magic);
|
||||||
|
|
||||||
|
return flt.i + y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_pow2x :
|
||||||
|
* @x: exponent
|
||||||
|
*
|
||||||
|
* Calculates 2 to x power.
|
||||||
|
*
|
||||||
|
* This function is around 11 times faster on x86, and around 22 times faster
|
||||||
|
* on fpu-less arm than libc pow(2, x).
|
||||||
|
*
|
||||||
|
* Return value: 2 in x power.
|
||||||
|
*
|
||||||
|
* Since: 0.4
|
||||||
|
*/
|
||||||
|
guint
|
||||||
|
clutter_pow2x (ClutterFixed x)
|
||||||
|
{
|
||||||
|
/* Note: we could easily have a version that produces ClutterFixed result,
|
||||||
|
* but the the range would be limited to x < 15, and the int precission
|
||||||
|
* is enough for the current purposes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
float f;
|
||||||
|
ClutterFixed i;
|
||||||
|
} flt;
|
||||||
|
|
||||||
|
ClutterFixed magic = 0x56f7;
|
||||||
|
ClutterFixed y;
|
||||||
|
|
||||||
|
flt.i = x;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reverse of the log2x function -- convert the fixed value to a suitable
|
||||||
|
* floating point exponent, and mantisa adjusted with quadratic error
|
||||||
|
* correction y.
|
||||||
|
*/
|
||||||
|
y = CLUTTER_FIXED_FRACTION (x);
|
||||||
|
y = CFX_MUL ((y - CFX_MUL (y, y)), magic);
|
||||||
|
|
||||||
|
/* Shift the exponent into it's position in the floating point
|
||||||
|
* representation; as our number is not int but 16.16 fixed, shift only
|
||||||
|
* by (23 - 16)
|
||||||
|
*/
|
||||||
|
flt.i += (CLUTTER_INT_TO_FIXED (127) - y);
|
||||||
|
flt.i <<= 7;
|
||||||
|
|
||||||
|
return CLUTTER_FLOAT_TO_INT (flt.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clutter_powx :
|
||||||
|
* @x: base
|
||||||
|
* @y: #ClutterFixed exponent
|
||||||
|
*
|
||||||
|
* Calculates x to y power. (Note, if x is a constant it will be faster to
|
||||||
|
* calculate the power as clutter_pow2x (CLUTTER_FIXED_MUL(y, log2 (x)))
|
||||||
|
*
|
||||||
|
* Return value: x in y power.
|
||||||
|
*
|
||||||
|
* Since: 0.4
|
||||||
|
*/
|
||||||
|
guint
|
||||||
|
clutter_powx (guint x, ClutterFixed y)
|
||||||
|
{
|
||||||
|
return clutter_pow2x (CFX_MUL (y, clutter_log2x (x)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* <private> */
|
/* <private> */
|
||||||
const double _magic = 68719476736.0*1.5;
|
const double _magic = 68719476736.0*1.5;
|
||||||
|
|
||||||
|
@ -186,6 +186,9 @@ ClutterFixed clutter_tani (ClutterAngle angle);
|
|||||||
ClutterFixed clutter_sqrtx (ClutterFixed x);
|
ClutterFixed clutter_sqrtx (ClutterFixed x);
|
||||||
gint clutter_sqrti (gint x);
|
gint clutter_sqrti (gint x);
|
||||||
|
|
||||||
|
ClutterFixed clutter_log2x (guint x);
|
||||||
|
guint clutter_pow2x (ClutterFixed x);
|
||||||
|
guint clutter_powx (guint x, ClutterFixed y);
|
||||||
|
|
||||||
/* <private> */
|
/* <private> */
|
||||||
extern inline
|
extern inline
|
||||||
|
Loading…
Reference in New Issue
Block a user