49efe05d18fe32ce3e1662c9f5ad4b74159100d2
[framework/uifw/elementary.git] / src / examples / efl_thread_6.c
1 #include <Elementary.h>
2
3 static Evas_Object *win = NULL;
4 static Evas_Object *rect = NULL;
5
6 struct info
7 {
8    Evas_Object *obj;
9    int *pix;
10 };
11
12 // BEGIN - code running in my custom pthread instance
13 //
14 static void
15 mandel(int *pix, int w, int h)
16 {
17    double x, xx, y, cx, cy, cox, coy;
18    int iteration, hx, hy, val, r, g, b, rr, gg, bb;
19    int itermax = 10000;
20    double magnify = 0.02;
21
22    // this mandel calc is run in the worker threads so it's here. it is
23    // just here to calculate something and consume cpu to demonstrate the
24    // ecore thread worker queue. don't pay much attention to the below code
25    magnify += ((double)(rand() % 100) / 100.0) / 4.0;
26    cox = (double)(rand() % 100) / 100.0;
27    coy = (double)(rand() % 100) / 100.0;
28    cox /= (magnify * 3.0);
29    r = rand() % 255; g = rand() % 255; b = rand() % 255;
30    for (hy = 0; hy < h; hy++)
31      {
32         for (hx = 0; hx < w; hx++)
33           {
34              cx = (((float)hx) / ((float)w) - 0.5) / (magnify * 3.0);
35              cy = (((float)hy) / ((float)h) - 0.5) / (magnify * 3.0);
36              cx += cox;
37              cy += coy;
38              x = 0.0;
39              y = 0.0;
40              for (iteration = 1; iteration < itermax; iteration++)
41                {
42                   xx = (x * x) - (y * y) + cx;
43                   y = (2.0 * x * y) + cy;
44                   x = xx;
45                   if (((x * x) + (y * y)) > 100.0) iteration = 999999;
46                }
47              val = (((x * x) + (y * y)) * 2.55) / 100.0;
48              if (val > 255) val = 255;
49              if (iteration >= 99999) 
50                {
51                   rr = (r * val) / 255;
52                   gg = (g * val) / 255;
53                   bb = (b * val) / 255;
54                   pix[(hy * w) + hx] = 
55                      (val  << 24) | (rr << 16) | (gg << 8) | (bb);
56                }
57              else
58                 pix[(hy * w) + hx] = 0xffffffff;
59           }
60      }
61 }
62
63 static void
64 th_do(void *data, Ecore_Thread *th)
65 {
66    struct info *inf = data;
67    // CANNOT TOUCH inf->obj here! just inf->pix which is 256x256 @ 32bpp
68    // quick and dirty to consume some cpu - do a mandelbrot calc
69    mandel(inf->pix, 256, 256);
70 }
71 //
72 // END - code running in my custom pthread instance
73
74 static void // thread job finished - collect results and put in img obj
75 th_end(void *data, Ecore_Thread *th)
76 {
77    struct info *inf = data;
78
79    // copy data to object, free calculated data and info struc
80    evas_object_image_data_copy_set(inf->obj, inf->pix);
81    evas_object_show(inf->obj);
82    free(inf->pix);
83    free(inf);
84 }
85
86 static void // if the thread is cancelled - free pix, keep obj tho
87 th_cancel(void *data, Ecore_Thread *th)
88 {
89    struct info *inf = data;
90
91    // just free pixel data and info struct
92    free(inf->pix);
93    free(inf);
94 }
95
96 static Eina_Bool // animate the objects so you see all the madels move
97 anim(void *data)
98 {
99    Evas_Object *o = data;
100    double t, z;
101    int w, h, v;
102    Evas_Coord x, y;
103
104    // just calculate some position using the pointer value of the object as
105    // a seed value to make different objects go into different places over time
106    v = ((int)o) & 0xff;
107    t = ecore_loop_time_get();
108    w = 100 + ((v * 100) >> 8);
109    h = 100 + ((v * 100) >> 8);
110    z = (double)(v) / 100.0;
111    x = (w * sin(t));
112    y = (h * cos(t + z));
113    // do the actual move
114    evas_object_move(o, 200 + x - 128, 200 + y - 128);
115    // keep looping - return true
116    return EINA_TRUE;
117 }
118
119 int
120 elm_main(int argc, char **argv)
121 {
122    Evas_Object *o, *bg;
123    int i;
124
125    win = elm_win_add(NULL, "efl-thread-6", ELM_WIN_BASIC);
126    elm_win_title_set(win, "EFL Thread 6");
127    evas_object_resize(win, 400, 400);
128    evas_object_show(win);
129
130    bg = elm_bg_add(win);
131    elm_win_resize_object_add(win, bg);
132    evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
133    evas_object_show(bg);
134
135    // queue up 64 mandel generation thread jobs
136    for (i = 0; i < 64; i++)
137      {
138         struct info *inf;
139
140         // create ecore thread to do some threaded job inside the worker pool
141         inf = malloc(sizeof(struct info));
142         if (inf)
143           {
144              Evas_Object *o;
145
146              o = evas_object_image_filled_add(evas_object_evas_get(win));
147              evas_object_image_size_set(o, 256, 256);
148              evas_object_image_alpha_set(o, EINA_TRUE);
149              evas_object_resize(o, 256, 256);
150              inf->obj = o;
151              inf->pix = malloc(256 * 256 * sizeof(int));
152              ecore_thread_run(th_do, th_end, th_cancel, inf);
153              // bonus - slide the objects around all the time with an
154              // animator that ticks off every frame.
155              ecore_animator_add(anim, o);
156           }
157      }
158
159    elm_run();
160    return 0;
161 }
162
163 ELM_MAIN()
164