aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/evas/src/modules/engines/software_ddraw/evas_outbuf.c
diff options
context:
space:
mode:
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.c460
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
5static Eina_List *ddpool = NULL;
6static int ddsize = 0;
7static int ddmemlimit = 10 * 1024 * 1024;
8static int ddcountlimit = 32;
9
10static 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
49static 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
71static 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
85void
86evas_software_ddraw_outbuf_init(void)
87{
88}
89
90void
91evas_software_ddraw_outbuf_free(Outbuf *buf)
92{
93 if (!buf)
94 return;
95
96 evas_software_ddraw_shutdown(buf);
97 free(buf);
98}
99
100Outbuf *
101evas_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
180void
181evas_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
196RGBA_Image *
197evas_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
272void
273evas_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
350void
351evas_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
357void
358evas_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
418void
419evas_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
438int
439evas_software_ddraw_outbuf_width_get(Outbuf *buf)
440{
441 return buf->width;
442}
443
444int
445evas_software_ddraw_outbuf_height_get(Outbuf *buf)
446{
447 return buf->height;
448}
449
450Outbuf_Depth
451evas_software_ddraw_outbuf_depth_get(Outbuf *buf)
452{
453 return buf->depth;
454}
455
456int
457evas_software_ddraw_outbuf_rot_get(Outbuf *buf)
458{
459 return buf->rot;
460}