summaryrefslogtreecommitdiff
path: root/legacy/evas/src/modules/engines/software_gdi/evas_outbuf.c
diff options
context:
space:
mode:
authorVincent Torri <vincent.torri@gmail.com>2009-04-23 03:20:51 +0000
committerVincent Torri <vincent.torri@gmail.com>2009-04-23 03:20:51 +0000
commit7f98415206b33adbf0fba3c21e2df28e7f520559 (patch)
tree955a2d5f003cf2a295bf2506182b51256ee091b9 /legacy/evas/src/modules/engines/software_gdi/evas_outbuf.c
parent7f1bde6cf42c5e886ec0ba987e1f45aff5ac4486 (diff)
add GDI engine.
todo: fullscreen and shape support SVN revision: 40310
Diffstat (limited to '')
-rw-r--r--legacy/evas/src/modules/engines/software_gdi/evas_outbuf.c509
1 files changed, 509 insertions, 0 deletions
diff --git a/legacy/evas/src/modules/engines/software_gdi/evas_outbuf.c b/legacy/evas/src/modules/engines/software_gdi/evas_outbuf.c
new file mode 100644
index 0000000..bc56dfd
--- /dev/null
+++ b/legacy/evas/src/modules/engines/software_gdi/evas_outbuf.c
@@ -0,0 +1,509 @@
1#include "evas_common.h"
2#include "evas_engine.h"
3
4
5static Eina_List *gdipool = NULL;
6static int gdisize = 0;
7static int gdimemlimit = 10 * 1024 * 1024;
8static int gdicountlimit = 32;
9
10static Gdi_Output_Buffer *
11_find_gdiob(HDC dc, BITMAPINFO_GDI *bitmap_info, int depth, int w, int h, void *data)
12{
13 Eina_List *l;
14 Eina_List *gdil;
15 Gdi_Output_Buffer *gdiob = NULL;
16 Gdi_Output_Buffer *gdiob2;
17 int sz;
18 int lbytes;
19 int bpp;
20 int fitness = 0x7fffffff;
21
22 bpp = depth >> 3;
23 if (bpp == 3) bpp = 4;
24 lbytes = (((w * bpp) + 3) / 4) * 4;
25 sz = lbytes * h;
26 EINA_LIST_FOREACH(gdipool, l, gdiob2)
27 {
28 int szdif;
29
30 if ((gdiob2->dc != dc) ||
31 (gdiob2->bitmap_info != bitmap_info) ||
32 (gdiob2->depth != depth))
33 continue;
34 szdif = gdiob2->psize - sz;
35 if (szdif < 0) continue;
36 if (szdif == 0)
37 {
38 gdiob = gdiob2;
39 gdil = l;
40 goto have_gdiob;
41 }
42 if (szdif < fitness)
43 {
44 fitness = szdif;
45 gdiob = gdiob2;
46 gdil = l;
47 }
48 }
49 if ((fitness > (100 * 100)) || (!gdiob))
50 return evas_software_gdi_output_buffer_new(dc, bitmap_info, depth, w, h, data);
51
52 have_gdiob:
53 gdipool = eina_list_remove_list(gdipool, gdil);
54 gdiob->width = w;
55 gdiob->height = h;
56 gdiob->pitch = lbytes;
57 gdisize -= gdiob->psize * (gdiob->depth >> 3);
58
59 return gdiob;
60}
61
62static void
63_unfind_gdiob(Gdi_Output_Buffer *gdiob)
64{
65 gdipool = eina_list_prepend(gdipool, gdiob);
66 gdisize += gdiob->psize * (gdiob->depth >> 3);
67 while ((gdisize > (gdimemlimit)) ||
68 (eina_list_count(gdipool) > gdicountlimit))
69 {
70 Eina_List *xl;
71
72 xl = eina_list_last(gdipool);
73 if (!xl)
74 {
75 gdisize = 0;
76 break;
77 }
78 gdiob = xl->data;
79 gdipool = eina_list_remove_list(gdipool, xl);
80 evas_software_gdi_output_buffer_free(gdiob);
81 }
82}
83
84static void
85_clear_gdiob()
86{
87 while (gdipool)
88 {
89 Gdi_Output_Buffer *gdiob;
90
91 gdiob = gdipool->data;
92 gdipool = eina_list_remove_list(gdipool, gdipool);
93 evas_software_gdi_output_buffer_free(gdiob);
94 }
95 gdisize = 0;
96}
97
98void
99evas_software_gdi_outbuf_init(void)
100{
101}
102
103void
104evas_software_gdi_outbuf_free(Outbuf *buf)
105{
106 if (!buf)
107 return;
108
109 while (buf->priv.pending_writes)
110 {
111 RGBA_Image *im;
112 Outbuf_Region *obr;
113
114 im = buf->priv.pending_writes->data;
115 buf->priv.pending_writes = eina_list_remove_list(buf->priv.pending_writes, buf->priv.pending_writes);
116 obr = im->extended_info;
117 evas_cache_image_drop(&im->cache_entry);
118 if (obr->gdiob) _unfind_gdiob(obr->gdiob);
119/* if (obr->mxob) _unfind_xob(obr->mxob, 0); */
120 free(obr);
121 }
122 evas_software_gdi_outbuf_idle_flush(buf);
123 evas_software_gdi_outbuf_flush(buf);
124
125 evas_software_gdi_shutdown(buf);
126 free(buf);
127}
128
129Outbuf *
130evas_software_gdi_outbuf_setup(int width,
131 int height,
132 int rotation,
133 Outbuf_Depth depth,
134 HWND window,
135 HBITMAP mask,
136 int w_depth,
137 unsigned int layered,
138 unsigned int fullscreen,
139 int mask_dither,
140 int destination_alpha)
141{
142 Outbuf *buf;
143
144 buf = (Outbuf *)calloc(1, sizeof(Outbuf));
145 if (!buf)
146 return NULL;
147
148 buf->width = width;
149 buf->height = height;
150 buf->depth = depth;
151 buf->rot = rotation;
152
153 buf->priv.mask_dither = mask_dither;
154 buf->priv.destination_alpha = destination_alpha;
155
156 if (!evas_software_gdi_init(window, mask, w_depth, layered, fullscreen, buf))
157 {
158 free(buf);
159 return NULL;
160 }
161
162 {
163 Gfx_Func_Convert conv_func;
164 Gdi_Output_Buffer *gdiob;
165
166 gdiob = evas_software_gdi_output_buffer_new(buf->priv.gdi.dc, buf->priv.gdi.bitmap_info, w_depth, 1, 1, NULL);
167
168 conv_func = NULL;
169 if (gdiob)
170 {
171 if ((rotation == 0) || (rotation == 180))
172 conv_func = evas_common_convert_func_get(0,
173 width,
174 height,
175 evas_software_gdi_output_buffer_depth (gdiob),
176 buf->priv.gdi.bitmap_info->masks[0],
177 buf->priv.gdi.bitmap_info->masks[1],
178 buf->priv.gdi.bitmap_info->masks[2],
179 PAL_MODE_NONE,
180 rotation);
181 else if ((rotation == 90) || (rotation == 270))
182 conv_func = evas_common_convert_func_get(0,
183 height,
184 width,
185 evas_software_gdi_output_buffer_depth (gdiob),
186 buf->priv.gdi.bitmap_info->masks[0],
187 buf->priv.gdi.bitmap_info->masks[1],
188 buf->priv.gdi.bitmap_info->masks[2],
189 PAL_MODE_NONE,
190 rotation);
191
192 evas_software_gdi_output_buffer_free(gdiob);
193
194 if (!conv_func)
195 {
196 fprintf(stderr, ".[ Evas Error ].\n"
197 " {\n"
198 " At depth %i:\n"
199 " RGB format mask: %08lx, %08lx, %08lx\n"
200 " Not supported by and compiled in converters!\n"
201 " }\n",
202 buf->priv.gdi.depth,
203 buf->priv.gdi.bitmap_info->masks[0],
204 buf->priv.gdi.bitmap_info->masks[1],
205 buf->priv.gdi.bitmap_info->masks[2]);
206 }
207 }
208 if (buf->priv.gdi.mask != mask)
209 buf->priv.gdi.mask = mask;
210 }
211
212 return buf;
213}
214
215void
216evas_software_gdi_outbuf_reconfigure(Outbuf *buf,
217 int width,
218 int height,
219 int rotation,
220 Outbuf_Depth depth)
221{
222 if ((width == buf->width) && (height == buf->height) &&
223 (rotation == buf->rot) && (depth == buf->depth))
224 return;
225 buf->width = width;
226 buf->height = height;
227 buf->rot = rotation;
228 evas_software_gdi_bitmap_resize(buf);
229}
230
231RGBA_Image *
232evas_software_gdi_outbuf_new_region_for_update(Outbuf *buf,
233 int x,
234 int y,
235 int w,
236 int h,
237 int *cx,
238 int *cy,
239 int *cw,
240 int *ch)
241{
242 RGBA_Image *im;
243 Outbuf_Region *obr;
244 int bpl = 0;
245 int alpha = 0;
246
247 obr = calloc(1, sizeof(Outbuf_Region));
248 obr->x = x;
249 obr->y = y;
250 obr->width = w;
251 obr->height = h;
252 *cx = 0;
253 *cy = 0;
254 *cw = w;
255 *ch = h;
256
257 alpha = ((buf->priv.gdi.mask) || (buf->priv.destination_alpha));
258
259 if ((buf->rot == 0) &&
260 (buf->priv.gdi.bitmap_info->masks[0] == 0xff0000) &&
261 (buf->priv.gdi.bitmap_info->masks[1] == 0x00ff00) &&
262 (buf->priv.gdi.bitmap_info->masks[2] == 0x0000ff))
263 {
264 obr->gdiob = _find_gdiob(buf->priv.gdi.dc,
265 buf->priv.gdi.bitmap_info,
266 buf->priv.gdi.depth,
267 w, h, NULL);
268/* obr->gdiob = evas_software_gdi_output_buffer_new(buf->priv.gdi.dc, */
269/* buf->priv.gdi.bitmap_info, */
270/* buf->priv.gdi.depth, */
271/* w, h, */
272/* NULL); */
273 im = (RGBA_Image *)evas_cache_image_data(evas_common_image_cache_get(),
274 w, h,
275 (DATA32 *)evas_software_gdi_output_buffer_data(obr->gdiob, &bpl),
276 alpha, EVAS_COLORSPACE_ARGB8888);
277 im->extended_info = obr;
278/* if (buf->priv.gdi.mask) */
279/* obr->mgdiob = _find_gdiob(buf->priv.gdi.dc, */
280/* buf->priv.gdi.bitmap_info, */
281/* 1, */
282/* w, h, NULL); */
283 }
284 else
285 {
286 im = (RGBA_Image *) evas_cache_image_empty(evas_common_image_cache_get());
287 im->cache_entry.flags.alpha |= alpha ? 1 : 0;
288 evas_cache_image_surface_alloc(&im->cache_entry, w, h);
289 im->extended_info = obr;
290 if ((buf->rot == 0) || (buf->rot == 180))
291 obr->gdiob = _find_gdiob(buf->priv.gdi.dc,
292 buf->priv.gdi.bitmap_info,
293 buf->priv.gdi.depth,
294 w, h, NULL);
295/*
296 obr->gdiob = evas_software_x11_x_output_buffer_new(buf->priv.dd.disp,
297 buf->priv.dd.vis,
298 buf->priv.dd.depth,
299 w, h,
300 use_shm,
301 NULL);
302 */
303 else if ((buf->rot == 90) || (buf->rot == 270))
304 obr->gdiob = _find_gdiob(buf->priv.gdi.dc,
305 buf->priv.gdi.bitmap_info,
306 buf->priv.gdi.depth,
307 w, h, NULL);
308/*
309 obr->gdiob = evas_software_x11_x_output_buffer_new(buf->priv.dd.disp,
310 buf->priv.dd.vis,
311 buf->priv.dd.depth,
312 h, w,
313 use_shm,
314 NULL);
315 */
316/* if (buf->priv.gdi.mask) */
317/* obr->mgdiob = _find_gdiob(buf->priv.gdi.dc, */
318/* buf->priv.gdi.bitmap_info, */
319/* 1, */
320/* w, h, NULL); */
321 }
322 if ((buf->priv.gdi.mask) || (buf->priv.destination_alpha))
323 /* FIXME: faster memset! */
324 memset(im->image.data, 0, w * h * sizeof(DATA32));
325
326 buf->priv.pending_writes = eina_list_append(buf->priv.pending_writes, im);
327 return im;
328}
329
330void
331evas_software_gdi_outbuf_push_updated_region(Outbuf *buf,
332 RGBA_Image *update,
333 int x,
334 int y,
335 int w,
336 int h)
337{
338 Gfx_Func_Convert conv_func;
339 Outbuf_Region *obr;
340 DATA32 *src_data;
341 void *data;
342 int bpl = 0;
343
344 conv_func = NULL;
345 obr = update->extended_info;
346
347 if ((buf->rot == 0) || (buf->rot == 180))
348 conv_func = evas_common_convert_func_get(0, w, h,
349 evas_software_gdi_output_buffer_depth(obr->gdiob),
350 buf->priv.gdi.bitmap_info->masks[0],
351 buf->priv.gdi.bitmap_info->masks[1],
352 buf->priv.gdi.bitmap_info->masks[2],
353 PAL_MODE_NONE,
354 buf->rot);
355 else if ((buf->rot == 90) || (buf->rot == 270))
356 conv_func = evas_common_convert_func_get(0, h, w,
357 evas_software_gdi_output_buffer_depth(obr->gdiob),
358 buf->priv.gdi.bitmap_info->masks[0],
359 buf->priv.gdi.bitmap_info->masks[1],
360 buf->priv.gdi.bitmap_info->masks[2],
361 PAL_MODE_NONE,
362 buf->rot);
363 if (!conv_func) return;
364
365 data = evas_software_gdi_output_buffer_data(obr->gdiob, &bpl);
366 src_data = update->image.data;
367 if (buf->rot == 0)
368 {
369 obr->x = x;
370 obr->y = y;
371 }
372 else if (buf->rot == 90)
373 {
374 obr->x = y;
375 obr->y = buf->width - x - w;
376 }
377 else if (buf->rot == 180)
378 {
379 obr->x = buf->width - x - w;
380 obr->y = buf->height - y - h;
381 }
382 else if (buf->rot == 270)
383 {
384 obr->x = buf->height - y - h;
385 obr->y = x;
386 }
387 if ((buf->rot == 0) || (buf->rot == 180))
388 {
389 obr->width = w;
390 obr->height = h;
391 }
392 else if ((buf->rot == 90) || (buf->rot == 270))
393 {
394 obr->width = h;
395 obr->height = w;
396 }
397
398 if (data != src_data)
399 conv_func(src_data, data,
400 0,
401 bpl / (evas_software_gdi_output_buffer_depth(obr->gdiob) >> 3) - obr->width,
402 obr->width,
403 obr->height,
404 x,
405 y,
406 NULL);
407/* if (obr->mxob) */
408/* { */
409/* int yy; */
410/* for (yy = 0; yy < obr->h; yy++) */
411/* evas_software_xlib_x_write_mask_line(buf, obr->mxob, */
412/* src_data + */
413/* (yy * obr->w), obr->w, yy); */
414}
415
416void
417evas_software_gdi_outbuf_free_region_for_update(Outbuf *buf __UNUSED__,
418 RGBA_Image *update __UNUSED__)
419{
420 /* no need to do anything - they are cleaned up on flush */
421}
422
423void
424evas_software_gdi_outbuf_flush(Outbuf *buf)
425{
426 Eina_List *l;
427 RGBA_Image *im;
428 Outbuf_Region *obr;
429
430 /* copy safely the images that need to be drawn onto the back surface */
431 EINA_LIST_FOREACH(buf->priv.pending_writes, l, im)
432 {
433 Gdi_Output_Buffer *gdiob;
434
435 obr = im->extended_info;
436 gdiob = obr->gdiob;
437 evas_software_gdi_output_buffer_paste(gdiob,
438 obr->x,
439 obr->y);
440/* if (obr->mgdiob) */
441/* evas_software_gdi_output_buffer_paste(obr->mgdiob, */
442/* buf->priv.x11.xlib.mask, */
443/* buf->priv.x11.xlib.gcm, */
444/* obr->x, obr->y, 0); */
445 }
446
447 while (buf->priv.prev_pending_writes)
448 {
449 im = buf->priv.prev_pending_writes->data;
450 buf->priv.prev_pending_writes =
451 eina_list_remove_list(buf->priv.prev_pending_writes,
452 buf->priv.prev_pending_writes);
453 obr = im->extended_info;
454 evas_cache_image_drop(&im->cache_entry);
455 if (obr->gdiob) _unfind_gdiob(obr->gdiob);
456/* if (obr->mgdiob) _unfind_gdiob(obr->mgdiob); */
457/* if (obr->gdiob) evas_software_x11_x_output_buffer_free(obr->gdiob); */
458 free(obr);
459 }
460 buf->priv.prev_pending_writes = buf->priv.pending_writes;
461 buf->priv.pending_writes = NULL;
462
463 evas_common_cpu_end_opt();
464}
465
466void
467evas_software_gdi_outbuf_idle_flush(Outbuf *buf)
468{
469 while (buf->priv.prev_pending_writes)
470 {
471 RGBA_Image *im;
472 Outbuf_Region *obr;
473
474 im = buf->priv.prev_pending_writes->data;
475 buf->priv.prev_pending_writes =
476 eina_list_remove_list(buf->priv.prev_pending_writes,
477 buf->priv.prev_pending_writes);
478 obr = im->extended_info;
479 evas_cache_image_drop((Image_Entry *)im);
480 if (obr->gdiob) _unfind_gdiob(obr->gdiob);
481/* if (obr->mxob) _unfind_xob(obr->mxob, 0); */
482 free(obr);
483 }
484 _clear_gdiob();
485}
486
487int
488evas_software_gdi_outbuf_width_get(Outbuf *buf)
489{
490 return buf->width;
491}
492
493int
494evas_software_gdi_outbuf_height_get(Outbuf *buf)
495{
496 return buf->height;
497}
498
499Outbuf_Depth
500evas_software_gdi_outbuf_depth_get(Outbuf *buf)
501{
502 return buf->depth;
503}
504
505int
506evas_software_gdi_outbuf_rot_get(Outbuf *buf)
507{
508 return buf->rot;
509}