diff options
author | David Walter Seikel | 2012-01-04 18:41:13 +1000 |
---|---|---|
committer | David Walter Seikel | 2012-01-04 18:41:13 +1000 |
commit | dd7595a3475407a7fa96a97393bae8c5220e8762 (patch) | |
tree | e341e911d7eb911a51684a7412ef7f7c7605d28e /libraries/evas/src/modules/engines/software_ddraw/evas_outbuf.c | |
parent | Add the skeleton. (diff) | |
download | SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.zip SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.gz SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.bz2 SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.xz |
Add the base Enlightenment Foundation Libraries - eina, eet, evas, ecore, embryo, and edje.
Note that embryo wont be used, but I'm not sure yet if you can build edje without it.
Diffstat (limited to 'libraries/evas/src/modules/engines/software_ddraw/evas_outbuf.c')
-rw-r--r-- | libraries/evas/src/modules/engines/software_ddraw/evas_outbuf.c | 460 |
1 files changed, 460 insertions, 0 deletions
diff --git a/libraries/evas/src/modules/engines/software_ddraw/evas_outbuf.c b/libraries/evas/src/modules/engines/software_ddraw/evas_outbuf.c new file mode 100644 index 0000000..5a5f0a2 --- /dev/null +++ b/libraries/evas/src/modules/engines/software_ddraw/evas_outbuf.c | |||
@@ -0,0 +1,460 @@ | |||
1 | #include "evas_common.h" | ||
2 | #include "evas_engine.h" | ||
3 | |||
4 | |||
5 | static Eina_List *ddpool = NULL; | ||
6 | static int ddsize = 0; | ||
7 | static int ddmemlimit = 10 * 1024 * 1024; | ||
8 | static int ddcountlimit = 32; | ||
9 | |||
10 | static DD_Output_Buffer * | ||
11 | _find_ddob(int depth, int w, int h, void *data) | ||
12 | { | ||
13 | Eina_List *l; | ||
14 | Eina_List *ddl; | ||
15 | DD_Output_Buffer *ddob = NULL; | ||
16 | DD_Output_Buffer *ddob2; | ||
17 | int sz; | ||
18 | int lbytes; | ||
19 | int bpp; | ||
20 | |||
21 | bpp = depth / 8; | ||
22 | if (bpp == 3) bpp = 4; | ||
23 | lbytes = (((w * bpp) + 3) / 4) * 4; | ||
24 | sz = lbytes * h; | ||
25 | EINA_LIST_FOREACH(ddpool, l, ddob2) | ||
26 | { | ||
27 | if (ddob2->depth != depth) | ||
28 | continue; | ||
29 | if (ddob2->psize == sz) | ||
30 | { | ||
31 | ddob = ddob2; | ||
32 | ddl = l; | ||
33 | goto have_ddob; | ||
34 | } | ||
35 | } | ||
36 | if (!ddob) | ||
37 | return evas_software_ddraw_output_buffer_new(depth, w, h, data); | ||
38 | |||
39 | have_ddob: | ||
40 | ddpool = eina_list_remove_list(ddpool, ddl); | ||
41 | ddob->width = w; | ||
42 | ddob->height = h; | ||
43 | ddob->pitch = lbytes; | ||
44 | ddsize -= ddob->psize * (ddob->depth / 8); | ||
45 | |||
46 | return ddob; | ||
47 | } | ||
48 | |||
49 | static void | ||
50 | _unfind_ddob(DD_Output_Buffer *ddob) | ||
51 | { | ||
52 | ddpool = eina_list_prepend(ddpool, ddob); | ||
53 | ddsize += ddob->psize * ddob->depth / 8; | ||
54 | while ((ddsize > (ddmemlimit)) || | ||
55 | (eina_list_count(ddpool) > ddcountlimit)) | ||
56 | { | ||
57 | Eina_List *xl; | ||
58 | |||
59 | xl = eina_list_last(ddpool); | ||
60 | if (!xl) | ||
61 | { | ||
62 | ddsize = 0; | ||
63 | break; | ||
64 | } | ||
65 | ddob = xl->data; | ||
66 | ddpool = eina_list_remove_list(ddpool, xl); | ||
67 | evas_software_ddraw_output_buffer_free(ddob); | ||
68 | } | ||
69 | } | ||
70 | |||
71 | static void | ||
72 | _clear_ddob(int sync) | ||
73 | { | ||
74 | while (ddpool) | ||
75 | { | ||
76 | DD_Output_Buffer *ddob; | ||
77 | |||
78 | ddob = ddpool->data; | ||
79 | ddpool = eina_list_remove_list(ddpool, ddpool); | ||
80 | evas_software_ddraw_output_buffer_free(ddob); | ||
81 | } | ||
82 | ddsize = 0; | ||
83 | } | ||
84 | |||
85 | void | ||
86 | evas_software_ddraw_outbuf_init(void) | ||
87 | { | ||
88 | } | ||
89 | |||
90 | void | ||
91 | evas_software_ddraw_outbuf_free(Outbuf *buf) | ||
92 | { | ||
93 | if (!buf) | ||
94 | return; | ||
95 | |||
96 | evas_software_ddraw_shutdown(buf); | ||
97 | free(buf); | ||
98 | } | ||
99 | |||
100 | Outbuf * | ||
101 | evas_software_ddraw_outbuf_setup(int width, | ||
102 | int height, | ||
103 | int rotation, | ||
104 | Outbuf_Depth depth, | ||
105 | HWND window, | ||
106 | int w_depth, | ||
107 | int fullscreen) | ||
108 | { | ||
109 | Outbuf *buf; | ||
110 | |||
111 | buf = (Outbuf *)calloc(1, sizeof(Outbuf)); | ||
112 | if (!buf) | ||
113 | return NULL; | ||
114 | |||
115 | buf->width = width; | ||
116 | buf->height = height; | ||
117 | buf->depth = depth; | ||
118 | buf->rot = rotation; | ||
119 | |||
120 | if (!evas_software_ddraw_init(window, w_depth, fullscreen, buf)) | ||
121 | { | ||
122 | free(buf); | ||
123 | return NULL; | ||
124 | } | ||
125 | |||
126 | { | ||
127 | Gfx_Func_Convert conv_func; | ||
128 | DD_Output_Buffer *ddob; | ||
129 | |||
130 | ddob = evas_software_ddraw_output_buffer_new(w_depth, 1, 1, NULL); | ||
131 | |||
132 | conv_func = NULL; | ||
133 | if (ddob) | ||
134 | { | ||
135 | if (evas_software_ddraw_masks_get(buf)) | ||
136 | { | ||
137 | if ((rotation == 0) || (rotation == 180)) | ||
138 | conv_func = evas_common_convert_func_get(0, | ||
139 | width, | ||
140 | height, | ||
141 | evas_software_ddraw_output_buffer_depth (ddob), | ||
142 | buf->priv.mask.r, | ||
143 | buf->priv.mask.g, | ||
144 | buf->priv.mask.b, | ||
145 | PAL_MODE_NONE, | ||
146 | rotation); | ||
147 | else if ((rotation == 90) || (rotation == 270)) | ||
148 | conv_func = evas_common_convert_func_get(0, | ||
149 | height, | ||
150 | width, | ||
151 | evas_software_ddraw_output_buffer_depth (ddob), | ||
152 | buf->priv.mask.r, | ||
153 | buf->priv.mask.g, | ||
154 | buf->priv.mask.b, | ||
155 | PAL_MODE_NONE, | ||
156 | rotation); | ||
157 | } | ||
158 | |||
159 | evas_software_ddraw_output_buffer_free(ddob); | ||
160 | |||
161 | if (!conv_func) | ||
162 | { | ||
163 | ERR("DDraw engine Error" | ||
164 | " {" | ||
165 | " At depth %i:" | ||
166 | " RGB format mask: %08x, %08x, %08x" | ||
167 | " Not supported by and compiled in converters!" | ||
168 | " }", | ||
169 | buf->priv.dd.depth, | ||
170 | buf->priv.mask.r, | ||
171 | buf->priv.mask.g, | ||
172 | buf->priv.mask.b); | ||
173 | } | ||
174 | } | ||
175 | } | ||
176 | |||
177 | return buf; | ||
178 | } | ||
179 | |||
180 | void | ||
181 | evas_software_ddraw_outbuf_reconfigure(Outbuf *buf, | ||
182 | int width, | ||
183 | int height, | ||
184 | int rotation, | ||
185 | Outbuf_Depth depth) | ||
186 | { | ||
187 | if ((width == buf->width) && (height == buf->height) && | ||
188 | (rotation == buf->rot) && (depth == buf->depth)) | ||
189 | return; | ||
190 | buf->width = width; | ||
191 | buf->height = height; | ||
192 | buf->rot = rotation; | ||
193 | evas_software_ddraw_surface_resize(buf); | ||
194 | } | ||
195 | |||
196 | RGBA_Image * | ||
197 | evas_software_ddraw_outbuf_new_region_for_update(Outbuf *buf, | ||
198 | int x, | ||
199 | int y, | ||
200 | int w, | ||
201 | int h, | ||
202 | int *cx, | ||
203 | int *cy, | ||
204 | int *cw, | ||
205 | int *ch) | ||
206 | { | ||
207 | RGBA_Image *im; | ||
208 | Outbuf_Region *obr; | ||
209 | int bpl = 0; | ||
210 | int alpha = 0; | ||
211 | |||
212 | obr = calloc(1, sizeof(Outbuf_Region)); | ||
213 | obr->x = x; | ||
214 | obr->y = y; | ||
215 | obr->width = w; | ||
216 | obr->height = h; | ||
217 | *cx = 0; | ||
218 | *cy = 0; | ||
219 | *cw = w; | ||
220 | *ch = h; | ||
221 | |||
222 | if ((buf->rot == 0) && | ||
223 | (buf->priv.mask.r == 0xff0000) && | ||
224 | (buf->priv.mask.g == 0x00ff00) && | ||
225 | (buf->priv.mask.b == 0x0000ff)) | ||
226 | { | ||
227 | obr->ddob = _find_ddob(buf->priv.dd.depth, w, h, NULL); | ||
228 | /* obr->ddob = evas_software_x11_x_output_buffer_new(buf->priv.dd.disp, */ | ||
229 | /* buf->priv.dd.vis, */ | ||
230 | /* buf->priv.dd.depth, */ | ||
231 | /* w, h, */ | ||
232 | /* use_shm, */ | ||
233 | /* NULL); */ | ||
234 | im = (RGBA_Image *)evas_cache_image_data(evas_common_image_cache_get(), | ||
235 | w, h, | ||
236 | (DATA32 *) evas_software_ddraw_output_buffer_data(obr->ddob, &bpl), | ||
237 | alpha, EVAS_COLORSPACE_ARGB8888); | ||
238 | im->extended_info = obr; | ||
239 | } | ||
240 | else | ||
241 | { | ||
242 | im = (RGBA_Image *) evas_cache_image_empty(evas_common_image_cache_get()); | ||
243 | im->cache_entry.flags.alpha |= alpha ? 1 : 0; | ||
244 | evas_cache_image_surface_alloc(&im->cache_entry, w, h); | ||
245 | im->extended_info = obr; | ||
246 | if ((buf->rot == 0) || (buf->rot == 180)) | ||
247 | obr->ddob = _find_ddob(buf->priv.dd.depth, w, h, NULL); | ||
248 | /* | ||
249 | obr->ddob = evas_software_x11_x_output_buffer_new(buf->priv.dd.disp, | ||
250 | buf->priv.dd.vis, | ||
251 | buf->priv.dd.depth, | ||
252 | w, h, | ||
253 | use_shm, | ||
254 | NULL); | ||
255 | */ | ||
256 | else if ((buf->rot == 90) || (buf->rot == 270)) | ||
257 | obr->ddob = _find_ddob(buf->priv.dd.depth, h, w, NULL); | ||
258 | /* | ||
259 | obr->ddob = evas_software_x11_x_output_buffer_new(buf->priv.dd.disp, | ||
260 | buf->priv.dd.vis, | ||
261 | buf->priv.dd.depth, | ||
262 | h, w, | ||
263 | use_shm, | ||
264 | NULL); | ||
265 | */ | ||
266 | } | ||
267 | |||
268 | buf->priv.pending_writes = eina_list_append(buf->priv.pending_writes, im); | ||
269 | return im; | ||
270 | } | ||
271 | |||
272 | void | ||
273 | evas_software_ddraw_outbuf_push_updated_region(Outbuf *buf, | ||
274 | RGBA_Image *update, | ||
275 | int x, | ||
276 | int y, | ||
277 | int w, | ||
278 | int h) | ||
279 | { | ||
280 | Gfx_Func_Convert conv_func; | ||
281 | Outbuf_Region *obr; | ||
282 | DATA32 *src_data; | ||
283 | void *data; | ||
284 | int bpl = 0; | ||
285 | |||
286 | conv_func = NULL; | ||
287 | obr = update->extended_info; | ||
288 | |||
289 | if ((buf->rot == 0) || (buf->rot == 180)) | ||
290 | conv_func = evas_common_convert_func_get(0, w, h, | ||
291 | evas_software_ddraw_output_buffer_depth(obr->ddob), | ||
292 | buf->priv.mask.r, | ||
293 | buf->priv.mask.g, | ||
294 | buf->priv.mask.b, | ||
295 | PAL_MODE_NONE, | ||
296 | buf->rot); | ||
297 | else if ((buf->rot == 90) || (buf->rot == 270)) | ||
298 | conv_func = evas_common_convert_func_get(0, h, w, | ||
299 | evas_software_ddraw_output_buffer_depth(obr->ddob), | ||
300 | buf->priv.mask.r, | ||
301 | buf->priv.mask.g, | ||
302 | buf->priv.mask.b, | ||
303 | PAL_MODE_NONE, buf->rot); | ||
304 | if (!conv_func) return; | ||
305 | |||
306 | data = evas_software_ddraw_output_buffer_data(obr->ddob, &bpl); | ||
307 | src_data = update->image.data; | ||
308 | if (buf->rot == 0) | ||
309 | { | ||
310 | obr->x = x; | ||
311 | obr->y = y; | ||
312 | } | ||
313 | else if (buf->rot == 90) | ||
314 | { | ||
315 | obr->x = y; | ||
316 | obr->y = buf->width - x - w; | ||
317 | } | ||
318 | else if (buf->rot == 180) | ||
319 | { | ||
320 | obr->x = buf->width - x - w; | ||
321 | obr->y = buf->height - y - h; | ||
322 | } | ||
323 | else if (buf->rot == 270) | ||
324 | { | ||
325 | obr->x = buf->height - y - h; | ||
326 | obr->y = x; | ||
327 | } | ||
328 | if ((buf->rot == 0) || (buf->rot == 180)) | ||
329 | { | ||
330 | obr->width = w; | ||
331 | obr->height = h; | ||
332 | } | ||
333 | else if ((buf->rot == 90) || (buf->rot == 270)) | ||
334 | { | ||
335 | obr->width = h; | ||
336 | obr->height = w; | ||
337 | } | ||
338 | |||
339 | if (data != src_data) | ||
340 | conv_func(src_data, data, | ||
341 | 0, | ||
342 | bpl / ((evas_software_ddraw_output_buffer_depth(obr->ddob) / 8)) - obr->width, | ||
343 | obr->width, | ||
344 | obr->height, | ||
345 | x, | ||
346 | y, | ||
347 | NULL); | ||
348 | } | ||
349 | |||
350 | void | ||
351 | evas_software_ddraw_outbuf_free_region_for_update(Outbuf *buf, | ||
352 | RGBA_Image *update) | ||
353 | { | ||
354 | /* no need to do anything - they are cleaned up on flush */ | ||
355 | } | ||
356 | |||
357 | void | ||
358 | evas_software_ddraw_outbuf_flush(Outbuf *buf) | ||
359 | { | ||
360 | Eina_List *l; | ||
361 | RGBA_Image *im; | ||
362 | Outbuf_Region *obr; | ||
363 | void *ddraw_data; | ||
364 | int ddraw_width; | ||
365 | int ddraw_height; | ||
366 | int ddraw_pitch; | ||
367 | int ddraw_depth; | ||
368 | |||
369 | /* lock the back surface */ | ||
370 | if (!(ddraw_data = evas_software_ddraw_lock(buf, | ||
371 | &ddraw_width, | ||
372 | &ddraw_height, | ||
373 | &ddraw_pitch, | ||
374 | &ddraw_depth))) | ||
375 | goto free_images; | ||
376 | |||
377 | /* copy safely the images that need to be drawn onto the back surface */ | ||
378 | EINA_LIST_FOREACH(buf->priv.pending_writes, l, im) | ||
379 | { | ||
380 | DD_Output_Buffer *ddob; | ||
381 | |||
382 | obr = im->extended_info; | ||
383 | ddob = obr->ddob; | ||
384 | evas_software_ddraw_output_buffer_paste(ddob, | ||
385 | ddraw_data, | ||
386 | ddraw_width, | ||
387 | ddraw_height, | ||
388 | ddraw_pitch, | ||
389 | ddraw_depth, | ||
390 | obr->x, | ||
391 | obr->y); | ||
392 | } | ||
393 | |||
394 | /* unlock the back surface and flip the surface */ | ||
395 | evas_software_ddraw_unlock_and_flip(buf); | ||
396 | |||
397 | free_images: | ||
398 | while (buf->priv.prev_pending_writes) | ||
399 | { | ||
400 | im = buf->priv.prev_pending_writes->data; | ||
401 | buf->priv.prev_pending_writes = | ||
402 | eina_list_remove_list(buf->priv.prev_pending_writes, | ||
403 | buf->priv.prev_pending_writes); | ||
404 | obr = im->extended_info; | ||
405 | evas_cache_image_drop(&im->cache_entry); | ||
406 | if (obr->ddob) _unfind_ddob(obr->ddob); | ||
407 | /* | ||
408 | if (obr->ddob) evas_software_x11_x_output_buffer_free(obr->ddob); | ||
409 | */ | ||
410 | free(obr); | ||
411 | } | ||
412 | buf->priv.prev_pending_writes = buf->priv.pending_writes; | ||
413 | buf->priv.pending_writes = NULL; | ||
414 | |||
415 | evas_common_cpu_end_opt(); | ||
416 | } | ||
417 | |||
418 | void | ||
419 | evas_software_ddraw_outbuf_idle_flush(Outbuf *buf) | ||
420 | { | ||
421 | while (buf->priv.prev_pending_writes) | ||
422 | { | ||
423 | RGBA_Image *im; | ||
424 | Outbuf_Region *obr; | ||
425 | |||
426 | im = buf->priv.prev_pending_writes->data; | ||
427 | buf->priv.prev_pending_writes = | ||
428 | eina_list_remove_list(buf->priv.prev_pending_writes, | ||
429 | buf->priv.prev_pending_writes); | ||
430 | obr = im->extended_info; | ||
431 | evas_cache_image_drop((Image_Entry *)im); | ||
432 | if (obr->ddob) _unfind_ddob(obr->ddob); | ||
433 | free(obr); | ||
434 | } | ||
435 | _clear_ddob(0); | ||
436 | } | ||
437 | |||
438 | int | ||
439 | evas_software_ddraw_outbuf_width_get(Outbuf *buf) | ||
440 | { | ||
441 | return buf->width; | ||
442 | } | ||
443 | |||
444 | int | ||
445 | evas_software_ddraw_outbuf_height_get(Outbuf *buf) | ||
446 | { | ||
447 | return buf->height; | ||
448 | } | ||
449 | |||
450 | Outbuf_Depth | ||
451 | evas_software_ddraw_outbuf_depth_get(Outbuf *buf) | ||
452 | { | ||
453 | return buf->depth; | ||
454 | } | ||
455 | |||
456 | int | ||
457 | evas_software_ddraw_outbuf_rot_get(Outbuf *buf) | ||
458 | { | ||
459 | return buf->rot; | ||
460 | } | ||