• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <stddef.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <stdint.h>
5 
6 /* Set to 1 to enable debug log traces. */
7 #define DEBUG 0
8 
9 /* Set to 1 to optimize memory stores when generating plasma. */
10 #define OPTIMIZE_WRITES  1
11 
12 /* We're going to perform computations for every pixel of the target
13  * bitmap. floating-point operations are very slow on ARMv5, and not
14  * too bad on ARMv7 with the exception of trigonometric functions.
15  *
16  * For better performance on all platforms, we're going to use fixed-point
17  * arithmetic and all kinds of tricks
18  */
19 
20 typedef int32_t  Fixed;
21 
22 #define  FIXED_BITS           16
23 #define  FIXED_ONE            (1 << FIXED_BITS)
24 #define  FIXED_AVERAGE(x,y)   (((x) + (y)) >> 1)
25 
26 #define  FIXED_FROM_INT(x)    ((x) << FIXED_BITS)
27 #define  FIXED_TO_INT(x)      ((x) >> FIXED_BITS)
28 
29 #define  FIXED_FROM_FLOAT(x)  ((Fixed)((x)*FIXED_ONE))
30 #define  FIXED_TO_FLOAT(x)    ((x)/(1.*FIXED_ONE))
31 
32 #define  FIXED_MUL(x,y)       (((int64_t)(x) * (y)) >> FIXED_BITS)
33 #define  FIXED_DIV(x,y)       (((int64_t)(x) * FIXED_ONE) / (y))
34 
35 #define  FIXED_DIV2(x)        ((x) >> 1)
36 #define  FIXED_AVERAGE(x,y)   (((x) + (y)) >> 1)
37 
38 #define  FIXED_FRAC(x)        ((x) & ((1 << FIXED_BITS)-1))
39 #define  FIXED_TRUNC(x)       ((x) & ~((1 << FIXED_BITS)-1))
40 
41 #define  FIXED_FROM_INT_FLOAT(x,f)   (Fixed)((x)*(FIXED_ONE*(f)))
42 
43 typedef int32_t  Angle;
44 
45 #define  ANGLE_BITS              9
46 
47 #if ANGLE_BITS < 8
48 #  error ANGLE_BITS must be at least 8
49 #endif
50 
51 #define  ANGLE_2PI               (1 << ANGLE_BITS)
52 #define  ANGLE_PI                (1 << (ANGLE_BITS-1))
53 #define  ANGLE_PI2               (1 << (ANGLE_BITS-2))
54 #define  ANGLE_PI4               (1 << (ANGLE_BITS-3))
55 
56 #define  ANGLE_FROM_FLOAT(x)   (Angle)((x)*ANGLE_PI/M_PI)
57 #define  ANGLE_TO_FLOAT(x)     ((x)*M_PI/ANGLE_PI)
58 
59 #if ANGLE_BITS <= FIXED_BITS
60 #  define  ANGLE_FROM_FIXED(x)     (Angle)((x) >> (FIXED_BITS - ANGLE_BITS))
61 #  define  ANGLE_TO_FIXED(x)       (Fixed)((x) << (FIXED_BITS - ANGLE_BITS))
62 #else
63 #  define  ANGLE_FROM_FIXED(x)     (Angle)((x) << (ANGLE_BITS - FIXED_BITS))
64 #  define  ANGLE_TO_FIXED(x)       (Fixed)((x) >> (ANGLE_BITS - FIXED_BITS))
65 #endif
66 
67 static Fixed  *angle_sin_tab;
68 //static Fixed  angle_sin_tab[ANGLE_2PI+1];
69 
angle_sin(Angle a)70 static __inline__ Fixed angle_sin( Angle  a )
71 {
72     return angle_sin_tab[(uint32_t)a & (ANGLE_2PI-1)];
73 }
74 
angle_cos(Angle a)75 static __inline__ Fixed angle_cos( Angle  a )
76 {
77     return angle_sin(a + ANGLE_PI2);
78 }
79 
fixed_sin(Fixed f)80 static __inline__ Fixed fixed_sin( Fixed  f )
81 {
82     return angle_sin(ANGLE_FROM_FIXED(f));
83 }
84 
fixed_cos(Fixed f)85 static __inline__ Fixed  fixed_cos( Fixed  f )
86 {
87     return angle_cos(ANGLE_FROM_FIXED(f));
88 }
89 
90 /* Color palette used for rendering the plasma */
91 #define  PALETTE_BITS   8
92 #define  PALETTE_SIZE   (1 << PALETTE_BITS)
93 
94 #if PALETTE_BITS > FIXED_BITS
95 #  error PALETTE_BITS must be smaller than FIXED_BITS
96 #endif
97 
98 #if 0
99 static uint16_t  make565(int red, int green, int blue)
100 {
101     return (uint16_t)( ((red   << 8) & 0xf800) |
102                        ((green << 2) & 0x03e0) |
103                        ((blue  >> 3) & 0x001f) );
104 }
105 
106 static void init_palette(uint16_t *palette)
107 {
108     int  nn, mm = 0;
109     /* fun with colors */
110     for (nn = 0; nn < PALETTE_SIZE/4; nn++) {
111         int  jj = (nn-mm)*4*255/PALETTE_SIZE;
112         palette[nn] = make565(255, jj, 255-jj);
113     }
114 
115     for ( mm = nn; nn < PALETTE_SIZE/2; nn++ ) {
116         int  jj = (nn-mm)*4*255/PALETTE_SIZE;
117         palette[nn] = make565(255-jj, 255, jj);
118     }
119 
120     for ( mm = nn; nn < PALETTE_SIZE*3/4; nn++ ) {
121         int  jj = (nn-mm)*4*255/PALETTE_SIZE;
122         palette[nn] = make565(0, 255-jj, 255);
123     }
124 
125     for ( mm = nn; nn < PALETTE_SIZE; nn++ ) {
126         int  jj = (nn-mm)*4*255/PALETTE_SIZE;
127         palette[nn] = make565(jj, 0, 255);
128     }
129 }
130 #endif
palette_from_fixed(uint16_t * palette,Fixed x)131 static __inline__ uint16_t  palette_from_fixed(uint16_t* palette, Fixed  x )
132 {
133     if (x < 0) x = -x;
134     if (x >= FIXED_ONE) x = FIXED_ONE-1;
135     int  idx = FIXED_FRAC(x) >> (FIXED_BITS - PALETTE_BITS);
136     return palette[idx & (PALETTE_SIZE-1)];
137 }
138 
139 
root(uint32_t width,uint32_t height,uint32_t stride,double t,uint16_t * palette,void * pixels,void * _angle_sin_tab)140 extern void root(uint32_t width, uint32_t height, uint32_t stride, double  t, uint16_t* palette, void* pixels, void *_angle_sin_tab)
141 {
142     angle_sin_tab = _angle_sin_tab;
143     Fixed ft  = FIXED_FROM_FLOAT(t/1000.);
144     Fixed yt1 = FIXED_FROM_FLOAT(t/1230.);
145     Fixed yt2 = yt1;
146     Fixed xt10 = FIXED_FROM_FLOAT(t/3000.);
147     Fixed xt20 = xt10;
148 
149 #define  YT1_INCR   FIXED_FROM_FLOAT(1/100.)
150 #define  YT2_INCR   FIXED_FROM_FLOAT(1/163.)
151 
152     int  yy;
153     for (yy = 0; yy < height; yy++) {
154         uint16_t*  line = (uint16_t*)pixels;
155         Fixed      base = fixed_sin(yt1) + fixed_sin(yt2);
156         Fixed      xt1 = xt10;
157         Fixed      xt2 = xt20;
158 
159         yt1 += YT1_INCR;
160         yt2 += YT2_INCR;
161 
162 #define  XT1_INCR  FIXED_FROM_FLOAT(1/173.)
163 #define  XT2_INCR  FIXED_FROM_FLOAT(1/242.)
164 
165         uint16_t*  line_end = line + width;
166 
167         if (line < line_end) {
168             if (((uint32_t)line & 3) != 0) {
169                 Fixed ii = base + fixed_sin(xt1) + fixed_sin(xt2);
170 
171                 xt1 += XT1_INCR;
172                 xt2 += XT2_INCR;
173 
174                 line[0] = palette_from_fixed(palette, ii >> 2);
175                 line++;
176             }
177 
178             while (line + 2 <= line_end) {
179                 Fixed i1 = base + fixed_sin(xt1) + fixed_sin(xt2);
180                 xt1 += XT1_INCR;
181                 xt2 += XT2_INCR;
182 
183                 Fixed i2 = base + fixed_sin(xt1) + fixed_sin(xt2);
184                 xt1 += XT1_INCR;
185                 xt2 += XT2_INCR;
186 
187                 uint32_t  pixel = ((uint32_t)palette_from_fixed(palette, i1 >> 2) << 16) |
188                                    (uint32_t)palette_from_fixed(palette, i2 >> 2);
189 
190                 ((uint32_t*)line)[0] = pixel;
191                 line += 2;
192             }
193 
194             if (line < line_end) {
195                 Fixed ii = base + fixed_sin(xt1) + fixed_sin(xt2);
196                 line[0] = palette_from_fixed(palette, ii >> 2);
197                 line++;
198             }
199         }
200 
201         // go to next line
202         pixels = (char*)pixels + stride;
203     }
204 }
205 
206 /* simple stats management */
207 typedef struct {
208     double  renderTime;
209     double  frameTime;
210 } FrameStats;
211 
212 #define  MAX_FRAME_STATS  200
213 #define  MAX_PERIOD_MS    1500
214 
215 typedef struct {
216     double  firstTime;
217     double  lastTime;
218     double  frameTime;
219 
220     int         firstFrame;
221     int         numFrames;
222     FrameStats  frames[ MAX_FRAME_STATS ];
223 } Stats;
224 
225