4
* A Low Level GPU Graphics and Utilities API
6
* Copyright (C) 2007,2008,2009 Intel Corporation.
8
* Permission is hereby granted, free of charge, to any person
9
* obtaining a copy of this software and associated documentation
10
* files (the "Software"), to deal in the Software without
11
* restriction, including without limitation the rights to use, copy,
12
* modify, merge, publish, distribute, sublicense, and/or sell copies
13
* of the Software, and to permit persons to whom the Software is
14
* furnished to do so, subject to the following conditions:
16
* The above copyright notice and this permission notice shall be
17
* included in all copies or substantial portions of the Software.
19
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
23
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
24
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
25
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31
#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION)
32
#error "Only <cogl/cogl.h> can be included directly."
35
#ifndef __COGL_FIXED_H__
36
#define __COGL_FIXED_H__
38
#include <cogl/cogl-types.h>
42
* @short_description: Fixed Point API
44
* COGL has a fixed point API targeted at platforms without a floating
45
* point unit, such as embedded devices. On such platforms this API should
46
* be preferred to the floating point one as it does not trigger the slow
47
* path of software emulation, relying on integer math for fixed-to-floating
48
* and floating-to-fixed notations conversion.
50
* It is not recommened for use on platforms with a floating point unit
51
* (e.g. desktop systems), nor for use in language bindings.
53
* Basic rules of Fixed Point arithmethic:
56
* <para>Two fixed point numbers can be directly added, subtracted and
57
* have their modulus taken.</para>
60
* <para>To add other numerical type to a fixed point number it has to
61
* be first converted to fixed point.</para>
64
* <para>A fixed point number can be directly multiplied or divided by
68
* <para>Two fixed point numbers can only be multiplied and divided by
69
* the provided %COGL_FIXED_MUL and %COGL_FIXED_DIV macros.</para>
73
* The fixed point API is available since COGL 1.0.
81
* Evaluates to the number of bits used by the #CoglFixed type.
85
#define COGL_FIXED_BITS (32)
90
* Evaluates to the number of bits used for the non-integer part
91
* of the #CoglFixed type.
95
#define COGL_FIXED_Q (COGL_FIXED_BITS - 16)
100
* The number 1 expressed as a #CoglFixed number.
104
#define COGL_FIXED_1 (1 << COGL_FIXED_Q)
109
* The number 0.5 expressed as a #CoglFixed number.
113
#define COGL_FIXED_0_5 (32768)
116
* COGL_FIXED_EPSILON:
118
* A very small number expressed as a #CoglFixed number.
122
#define COGL_FIXED_EPSILON (1)
127
* The biggest number representable using #CoglFixed
131
#define COGL_FIXED_MAX (0x7fffffff)
136
* The smallest number representable using #CoglFixed
140
#define COGL_FIXED_MIN (0x80000000)
145
* The number pi, expressed as a #CoglFixed number.
149
#define COGL_FIXED_PI (0x0003243f)
154
* Two times pi, expressed as a #CoglFixed number.
158
#define COGL_FIXED_2_PI (0x0006487f)
163
* Half pi, expressed as a #CoglFixed number.
167
#define COGL_FIXED_PI_2 (0x00019220)
172
* pi / 4, expressed as #CoglFixed number.
176
#define COGL_FIXED_PI_4 (0x0000c910)
181
* Evaluates to the number 360 in fixed point notation.
185
#define COGL_FIXED_360 (COGL_FIXED_FROM_INT (360))
190
* Evaluates to the number 270 in fixed point notation.
194
#define COGL_FIXED_270 (COGL_FIXED_FROM_INT (270))
199
* Evaluates to the number 255 in fixed point notation.
203
#define COGL_FIXED_255 (COGL_FIXED_FROM_INT (255))
208
* Evaluates to the number 240 in fixed point notation.
212
#define COGL_FIXED_240 (COGL_FIXED_FROM_INT (240))
217
* Evaluates to the number 180 in fixed point notation.
221
#define COGL_FIXED_180 (COGL_FIXED_FROM_INT (180))
226
* Evaluates to the number 120 in fixed point notation.
230
#define COGL_FIXED_120 (COGL_FIXED_FROM_INT (120))
235
* Evaluates to the number 90 in fixed point notation.
239
#define COGL_FIXED_90 (COGL_FIXED_FROM_INT (90))
244
* Evaluates to the number 60 in fixed point notation.
248
#define COGL_FIXED_60 (COGL_FIXED_FROM_INT (60))
253
* Evaluates to the number 45 in fixed point notation.
257
#define COGL_FIXED_45 (COGL_FIXED_FROM_INT (45))
262
* Evaluates to the number 30 in fixed point notation.
266
#define COGL_FIXED_30 (COGL_FIXED_FROM_INT (30))
269
* COGL_RADIANS_TO_DEGREES:
271
* Evaluates to 180 / pi in fixed point notation.
275
#define COGL_RADIANS_TO_DEGREES (0x394bb8)
282
* COGL_FIXED_FROM_FLOAT:
283
* @x: a floating point number
285
* Converts @x from a floating point to a fixed point notation.
289
#define COGL_FIXED_FROM_FLOAT(x) ((float) cogl_double_to_fixed (x))
292
* COGL_FIXED_TO_FLOAT:
293
* @x: a #CoglFixed number
295
* Converts @x from a fixed point to a floating point notation, in
300
#define COGL_FIXED_TO_FLOAT(x) ((float) ((int)(x) / 65536.0))
303
* COGL_FIXED_FROM_DOUBLE:
304
* @x: a floating point number
306
* Converts @x from a double precision, floating point to a fixed
311
#define COGL_FIXED_FROM_DOUBLE(x) (cogl_double_to_fixed (x))
314
* COGL_FIXED_TO_DOUBLE:
315
* @x: a #CoglFixed number
317
* Converts @x from a fixed point to a floating point notation, in
322
#define COGL_FIXED_TO_DOUBLE(x) ((double) ((int)(x) / 65536.0))
325
* COGL_FIXED_FROM_INT:
326
* @x: an integer number
328
* Converts @x from an integer to a fixed point notation.
332
#define COGL_FIXED_FROM_INT(x) ((x) << COGL_FIXED_Q)
336
* @x: a #CoglFixed number
338
* Converts @x from a fixed point notation to an integer, dropping
339
* the fractional part without rounding.
343
#define COGL_FIXED_TO_INT(x) ((x) >> COGL_FIXED_Q)
347
* @x: a floatint point number
349
* Converts @x from a floating point notation to a signed integer.
353
#define COGL_FLOAT_TO_INT(x) (cogl_double_to_int ((x)))
356
* COGL_FLOAT_TO_UINT:
357
* @x: a floatint point number
359
* Converts @x from a floating point notation to an unsigned integer.
363
#define COGL_FLOAT_TO_UINT(x) (cogl_double_to_uint ((x)))
366
* fixed point math functions
370
* COGL_FIXED_FRACTION:
371
* @x: a #CoglFixed number
373
* Retrieves the fractionary part of @x.
377
#define COGL_FIXED_FRACTION(x) ((x) & ((1 << COGL_FIXED_Q) - 1))
381
* @x: a #CoglFixed number
383
* Rounds down a fixed point number to the previous integer.
387
#define COGL_FIXED_FLOOR(x) (((x) >= 0) ? ((x) >> COGL_FIXED_Q) \
388
: ~((~(x)) >> COGL_FIXED_Q))
392
* @x: a #CoglFixed number
394
* Rounds up a fixed point number to the next integer.
398
#define COGL_FIXED_CEIL(x) (COGL_FIXED_FLOOR ((x) + 0xffff))
402
* @a: a #CoglFixed number
403
* @b: a #CoglFixed number
409
#define COGL_FIXED_MUL(a,b) (cogl_fixed_mul ((a), (b)))
413
* @a: a #CoglFixed number
414
* @b: a #CoglFixed number
420
#define COGL_FIXED_DIV(a,b) (cogl_fixed_div ((a), (b)))
423
* COGL_FIXED_MUL_DIV:
424
* @a: a #CoglFixed number
425
* @b: a #CoglFixed number
426
* @c: a #CoglFixed number
428
* Computes ((a * b) / c). It is logically equivalent to:
431
* res = COGL_FIXED_DIV (COGL_FIXED_MUL (a, b), c);
434
* But it is shorter to type.
438
#define COGL_FIXED_MUL_DIV(a,b,c) (cogl_fixed_mul_div ((a), (b), (c)))
441
* COGL_FIXED_FAST_MUL:
442
* @a: a #CoglFixed number
443
* @b: a #CoglFixed number
445
* Fast version of %COGL_FIXED_MUL, implemented as a macro.
447
* <note>This macro might lose precision. If the precision of the result
448
* is important use %COGL_FIXED_MUL instead.</note>
452
#define COGL_FIXED_FAST_MUL(a,b) ((a) >> 8) * ((b) >> 8)
455
* COGL_FIXED_FAST_DIV:
456
* @a: a #CoglFixed number
457
* @b: a #CoglFixed number
459
* Fast version of %COGL_FIXED_DIV, implemented as a macro.
461
* <note>This macro might lose precision. If the precision of the result
462
* is important use %COGL_FIXED_DIV instead.</note>
466
#define COGL_FIXED_FAST_DIV(a,b) ((((a) << 8) / (b)) << 8)
470
* @angle: a #CoglFixed number
472
* Computes the sine of @angle.
474
* Return value: the sine of the passed angle, in fixed point notation
479
cogl_fixed_sin (CoglFixed angle);
483
* @angle: a #CoglFixed number
485
* Computes the tangent of @angle.
487
* Return value: the tangent of the passed angle, in fixed point notation
492
cogl_fixed_tan (CoglFixed angle);
496
* @angle: a #CoglFixed number
498
* Computes the cosine of @angle.
500
* Return value: the cosine of the passed angle, in fixed point notation
504
CoglFixed cogl_fixed_cos (CoglFixed angle);
508
* @a: a #CoglFixed number
510
* Computes the arc tangent of @a.
512
* Return value: the arc tangent of the passed value, in fixed point notation
517
cogl_fixed_atan (CoglFixed a);
521
* @a: the numerator as a #CoglFixed number
522
* @b: the denominator as a #CoglFixed number
524
* Computes the arc tangent of @a / @b but uses the sign of both
525
* arguments to return the angle in right quadrant.
527
* Return value: the arc tangent of the passed fraction, in fixed point
533
cogl_fixed_atan2 (CoglFixed a,
538
/* Fixed point math routines */
539
G_INLINE_FUNC CoglFixed
540
cogl_fixed_mul (CoglFixed a,
543
G_INLINE_FUNC CoglFixed
544
cogl_fixed_div (CoglFixed a,
547
G_INLINE_FUNC CoglFixed
548
cogl_fixed_mul_div (CoglFixed a,
553
* COGL_SQRTI_ARG_MAX:
555
* Maximum argument that can be passed to cogl_sqrti() function.
560
#define COGL_SQRTI_ARG_MAX 0x3fffff
562
#define COGL_SQRTI_ARG_MAX INT_MAX
566
* COGL_SQRTI_ARG_5_PERCENT:
568
* Maximum argument that can be passed to cogl_sqrti() for which the
569
* resulting error is < 5%
574
#define COGL_SQRTI_ARG_5_PERCENT 210
576
#define COGL_SQRTI_ARG_5_PERCENT INT_MAX
580
* COGL_SQRTI_ARG_10_PERCENT:
582
* Maximum argument that can be passed to cogl_sqrti() for which the
583
* resulting error is < 10%
588
#define COGL_SQRTI_ARG_10_PERCENT 5590
590
#define COGL_SQRTI_ARG_10_PERCENT INT_MAX
595
* @x: a #CoglFixed number
597
* Computes the square root of @x.
599
* Return value: the square root of the passed value, in floating point
605
cogl_fixed_sqrt (CoglFixed x);
609
* @x: value to calculate base 2 logarithm from
611
* Calculates base 2 logarithm.
613
* This function is some 2.5 times faster on x86, and over 12 times faster on
614
* fpu-less arm, than using libc log().
616
* Return value: base 2 logarithm.
621
cogl_fixed_log2 (unsigned int x);
625
* @x: a #CoglFixed number
627
* Calculates 2 to the @x power.
629
* This function is around 11 times faster on x86, and around 22 times faster
630
* on fpu-less arm than libc pow(2, x).
632
* Return value: the power of 2 to the passed value
637
cogl_fixed_pow2 (CoglFixed x);
642
* @y: #CoglFixed exponent
644
* Calculates @x to the @y power.
646
* Return value: the power of @x to the @y
651
cogl_fixed_pow (unsigned int x,
658
* Very fast fixed point implementation of square root for integers.
660
* This function is at least 6x faster than clib sqrt() on x86, and (this is
661
* not a typo!) about 500x faster on ARM without FPU. It's error is less than
662
* 5% for arguments smaller than %COGL_SQRTI_ARG_5_PERCENT and less than 10%
663
* for narguments smaller than %COGL_SQRTI_ARG_10_PERCENT. The maximum
664
* argument that can be passed to this function is %COGL_SQRTI_ARG_MAX.
666
* Return value: integer square root.
674
* COGL_ANGLE_FROM_DEG:
675
* @x: an angle in degrees in floating point notation
677
* Converts an angle in degrees into a #CoglAngle.
681
#define COGL_ANGLE_FROM_DEG(x) (COGL_FLOAT_TO_INT (((float)(x) * 1024.0f) / 360.0f))
687
* Converts a #CoglAngle into an angle in degrees, using floatint point
692
#define COGL_ANGLE_TO_DEG(x) (((float)(x) * 360.0) / 1024.0)
695
* COGL_ANGLE_FROM_DEGX:
696
* @x: an angle in degrees in fixed point notation
698
* Converts an angle in degrees into a #CoglAngle.
702
#define COGL_ANGLE_FROM_DEGX(x) (COGL_FIXED_TO_INT ((((x) / 360) * 1024) + COGL_FIXED_0_5))
705
* COGL_ANGLE_TO_DEGX:
708
* Converts a #CoglAngle into an angle in degrees, using fixed point notation
712
#define COGL_ANGLE_TO_DEGX(x) (COGL_FIXED_FROM_INT ((x) * 45) / 128)
716
* @angle: an angle expressed using #CoglAngle
718
* Computes the sine of @angle
720
* Return value: the sine of the passed angle
725
cogl_angle_sin (CoglAngle angle);
729
* @angle: an angle expressed using #CoglAngle
731
* Computes the tangent of @angle
733
* Return value: the tangent of the passed angle
738
cogl_angle_tan (CoglAngle angle);
742
* @angle: an angle expressed using #CoglAngle
744
* Computes the cosine of @angle
746
* Return value: the cosine of the passed angle
751
cogl_angle_cos (CoglAngle angle);
755
#if defined (G_CAN_INLINE)
756
G_INLINE_FUNC CoglFixed
757
cogl_fixed_mul (CoglFixed a,
763
__asm__ ("smull %0, %1, %2, %3 \n"
764
"mov %0, %0, lsr %4 \n"
765
"add %1, %0, %1, lsl %5 \n"
766
: "=r"(res_hi), "=r"(res_low)\
767
: "r"(a), "r"(b), "i"(COGL_FIXED_Q), "i"(32 - COGL_FIXED_Q));
769
return (CoglFixed) res_low;
771
long long r = (long long) a * (long long) b;
773
return (unsigned int)(r >> COGL_FIXED_Q);
778
#if defined (G_CAN_INLINE)
779
G_INLINE_FUNC CoglFixed
780
cogl_fixed_div (CoglFixed a,
783
return (CoglFixed) ((((int64_t) a) << COGL_FIXED_Q) / b);
787
#if defined(G_CAN_INLINE)
788
G_INLINE_FUNC CoglFixed
789
cogl_fixed_mul_div (CoglFixed a,
793
CoglFixed ab = cogl_fixed_mul (a, b);
794
CoglFixed quo = cogl_fixed_div (ab, c);
801
cogl_double_to_fixed (double value);
804
cogl_double_to_int (double value);
807
cogl_double_to_uint (double value);
811
#endif /* __COGL_FIXED_H__ */