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