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