Home | History | Annotate | Download | only in jni
      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 
     70 static __inline__ Fixed angle_sin( Angle  a )
     71 {
     72     return angle_sin_tab[(uint32_t)a & (ANGLE_2PI-1)];
     73 }
     74 
     75 static __inline__ Fixed angle_cos( Angle  a )
     76 {
     77     return angle_sin(a + ANGLE_PI2);
     78 }
     79 
     80 static __inline__ Fixed fixed_sin( Fixed  f )
     81 {
     82     return angle_sin(ANGLE_FROM_FIXED(f));
     83 }
     84 
     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
    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 
    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