aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/evas/src/modules/engines/software_x11/evas_xlib_outbuf.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/evas/src/modules/engines/software_x11/evas_xlib_outbuf.c')
-rw-r--r--libraries/evas/src/modules/engines/software_x11/evas_xlib_outbuf.c1137
1 files changed, 0 insertions, 1137 deletions
diff --git a/libraries/evas/src/modules/engines/software_x11/evas_xlib_outbuf.c b/libraries/evas/src/modules/engines/software_x11/evas_xlib_outbuf.c
deleted file mode 100644
index 24c45df..0000000
--- a/libraries/evas/src/modules/engines/software_x11/evas_xlib_outbuf.c
+++ /dev/null
@@ -1,1137 +0,0 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <sys/time.h>
6#include <sys/utsname.h>
7
8#include "evas_common.h"
9#include "evas_macros.h"
10#include "evas_xlib_outbuf.h"
11#include "evas_xlib_buffer.h"
12#include "evas_xlib_color.h"
13
14
15typedef struct _Outbuf_Region Outbuf_Region;
16
17struct _Outbuf_Region
18{
19 X_Output_Buffer *xob;
20 X_Output_Buffer *mxob;
21 int x;
22 int y;
23 int w;
24 int h;
25};
26
27static Eina_List *shmpool = NULL;
28static int shmsize = 0;
29static int shmmemlimit = 10 * 1024 * 1024;
30static const unsigned int shmcountlimit = 32;
31
32#ifdef EVAS_FRAME_QUEUING
33static LK(lock_shmpool);
34#define SHMPOOL_LOCK() LKL(lock_shmpool)
35#define SHMPOOL_UNLOCK() LKU(lock_shmpool)
36#else
37#define SHMPOOL_LOCK()
38#define SHMPOOL_UNLOCK()
39#endif
40
41static X_Output_Buffer *
42_find_xob(Display *d, Visual *v, int depth, int w, int h, int shm, void *data)
43{
44 Eina_List *l, *xl = NULL;
45 X_Output_Buffer *xob = NULL;
46 X_Output_Buffer *xob2;
47 int fitness = 0x7fffffff;
48 int sz, lbytes, bpp;
49
50 if (!shm)
51 return evas_software_xlib_x_output_buffer_new(d, v, depth, w, h, shm, data);
52 if (depth > 1)
53 {
54 bpp = depth / 8;
55 if (bpp == 3) bpp = 4;
56 lbytes = (((w * bpp) + 3) / 4) * 4;
57 }
58 else
59 lbytes = ((w + 31) / 32) * 4;
60 sz = lbytes * h;
61 SHMPOOL_LOCK();
62 EINA_LIST_FOREACH(shmpool, l, xob2)
63 {
64 int szdif;
65
66 if ((xob2->xim->depth != depth) || (xob2->visual != v) ||
67 (xob2->display != d))
68 continue;
69 szdif = xob2->psize - sz;
70 if (szdif < 0) continue;
71 if (szdif == 0)
72 {
73 xob = xob2;
74 xl = l;
75 goto have_xob;
76 }
77 if (szdif < fitness)
78 {
79 fitness = szdif;
80 xob = xob2;
81 xl = l;
82 }
83 }
84 if ((fitness > (100 * 100)) || (!xob))
85 {
86 SHMPOOL_UNLOCK();
87 xob = evas_software_xlib_x_output_buffer_new(d, v, depth, w, h, shm, data);
88 return xob;
89 }
90
91 have_xob:
92 shmpool = eina_list_remove_list(shmpool, xl);
93 xob->w = w;
94 xob->h = h;
95 xob->bpl = lbytes;
96 xob->xim->width = xob->w;
97 xob->xim->height = xob->h;
98 xob->xim->bytes_per_line = xob->bpl;
99 shmsize -= xob->psize * (xob->xim->depth / 8);
100 SHMPOOL_UNLOCK();
101 return xob;
102}
103
104static void
105_unfind_xob(X_Output_Buffer *xob, int psync)
106{
107 if (xob->shm_info)
108 {
109 SHMPOOL_LOCK();
110 shmpool = eina_list_prepend(shmpool, xob);
111 shmsize += xob->psize * xob->xim->depth / 8;
112 while ((shmsize > (shmmemlimit)) ||
113 (eina_list_count(shmpool) > shmcountlimit))
114 {
115 Eina_List *xl;
116
117 xl = eina_list_last(shmpool);
118 if (!xl)
119 {
120 shmsize = 0;
121 break;
122 }
123 xob = xl->data;
124 shmpool = eina_list_remove_list(shmpool, xl);
125 shmsize -= xob->psize * xob->xim->depth / 8;
126 evas_software_xlib_x_output_buffer_free(xob, psync);
127 }
128 SHMPOOL_UNLOCK();
129 }
130 else
131 evas_software_xlib_x_output_buffer_free(xob, psync);
132}
133
134static void
135_clear_xob(int psync)
136{
137 SHMPOOL_LOCK();
138 while (shmpool)
139 {
140 X_Output_Buffer *xob;
141
142 xob = shmpool->data;
143 shmpool = eina_list_remove_list(shmpool, shmpool);
144 evas_software_xlib_x_output_buffer_free(xob, psync);
145 }
146 shmsize = 0;
147 SHMPOOL_UNLOCK();
148}
149
150void
151evas_software_xlib_outbuf_init(void)
152{
153#ifdef EVAS_FRAME_QUEUING
154 LKI(lock_shmpool);
155#endif
156}
157
158void
159evas_software_xlib_outbuf_free(Outbuf *buf)
160{
161#ifdef EVAS_FRAME_QUEUING
162 LKL(buf->priv.lock);
163#endif
164 while (buf->priv.pending_writes)
165 {
166 RGBA_Image *im;
167 Outbuf_Region *obr;
168
169 im = buf->priv.pending_writes->data;
170 buf->priv.pending_writes = eina_list_remove_list(buf->priv.pending_writes, buf->priv.pending_writes);
171 obr = im->extended_info;
172 evas_cache_image_drop(&im->cache_entry);
173 if (obr->xob) _unfind_xob(obr->xob, 0);
174 if (obr->mxob) _unfind_xob(obr->mxob, 0);
175 free(obr);
176 }
177#ifdef EVAS_FRAME_QUEUING
178 LKU(buf->priv.lock);
179#endif
180 evas_software_xlib_outbuf_idle_flush(buf);
181 evas_software_xlib_outbuf_flush(buf);
182 if (buf->priv.x11.xlib.gc)
183 XFreeGC(buf->priv.x11.xlib.disp, buf->priv.x11.xlib.gc);
184 if (buf->priv.x11.xlib.gcm)
185 XFreeGC(buf->priv.x11.xlib.disp, buf->priv.x11.xlib.gcm);
186 if (buf->priv.pal)
187 evas_software_xlib_x_color_deallocate(buf->priv.x11.xlib.disp, buf->priv.x11.xlib.cmap,
188 buf->priv.x11.xlib.vis, buf->priv.pal);
189#ifdef EVAS_FRAME_QUEUING
190 LKD(buf->priv.lock);
191#endif
192 free(buf);
193 _clear_xob(0);
194}
195
196Outbuf *
197evas_software_xlib_outbuf_setup_x(int w, int h, int rot, Outbuf_Depth depth,
198 Display *disp, Drawable draw, Visual *vis,
199 Colormap cmap, int x_depth,
200 int grayscale, int max_colors, Pixmap mask,
201 int shape_dither, int destination_alpha)
202{
203 Outbuf *buf;
204
205 buf = calloc(1, sizeof(Outbuf));
206 if (!buf)
207 return NULL;
208
209 buf->w = w;
210 buf->h = h;
211 buf->depth = depth;
212 buf->rot = rot;
213
214 buf->priv.x11.xlib.disp = disp;
215 buf->priv.x11.xlib.vis = vis;
216 buf->priv.x11.xlib.cmap = cmap;
217 buf->priv.x11.xlib.depth = x_depth;
218
219 buf->priv.mask_dither = shape_dither;
220 buf->priv.destination_alpha = destination_alpha;
221
222 {
223 Gfx_Func_Convert conv_func;
224 X_Output_Buffer *xob;
225
226 buf->priv.x11.xlib.shm = evas_software_xlib_x_can_do_shm(buf->priv.x11.xlib.disp);
227 xob = evas_software_xlib_x_output_buffer_new(buf->priv.x11.xlib.disp,
228 buf->priv.x11.xlib.vis,
229 buf->priv.x11.xlib.depth,
230 1, 1, buf->priv.x11.xlib.shm, NULL);
231
232 conv_func = NULL;
233 if (xob)
234 {
235#ifdef WORDS_BIGENDIAN
236 if (evas_software_xlib_x_output_buffer_byte_order(xob) == LSBFirst)
237 buf->priv.x11.xlib.swap = 1;
238 if (evas_software_xlib_x_output_buffer_bit_order(xob) == MSBFirst)
239 buf->priv.x11.xlib.bit_swap = 1;
240#else
241 if (evas_software_xlib_x_output_buffer_byte_order(xob) == MSBFirst)
242 buf->priv.x11.xlib.swap = 1;
243 if (evas_software_xlib_x_output_buffer_bit_order(xob) == MSBFirst)
244 buf->priv.x11.xlib.bit_swap = 1;
245#endif
246 if (((vis->class == TrueColor) || (vis->class == DirectColor)) &&
247 (x_depth > 8))
248 {
249 buf->priv.mask.r = (DATA32) vis->red_mask;
250 buf->priv.mask.g = (DATA32) vis->green_mask;
251 buf->priv.mask.b = (DATA32) vis->blue_mask;
252 if (buf->priv.x11.xlib.swap)
253 {
254 SWAP32(buf->priv.mask.r);
255 SWAP32(buf->priv.mask.g);
256 SWAP32(buf->priv.mask.b);
257 }
258 }
259 else if ((vis->class == PseudoColor) ||
260 (vis->class == StaticColor) ||
261 (vis->class == GrayScale) ||
262 (vis->class == StaticGray) ||
263 (x_depth <= 8))
264 {
265 Convert_Pal_Mode pm = PAL_MODE_RGB332;
266
267 if ((vis->class == GrayScale) || (vis->class == StaticGray))
268 grayscale = 1;
269 if (grayscale)
270 {
271 if (max_colors >= 256)
272 pm = PAL_MODE_GRAY256;
273 else if (max_colors >= 64)
274 pm = PAL_MODE_GRAY64;
275 else if (max_colors >= 16)
276 pm = PAL_MODE_GRAY16;
277 else if (max_colors >= 4)
278 pm = PAL_MODE_GRAY4;
279 else
280 pm = PAL_MODE_MONO;
281 }
282 else
283 {
284 if (max_colors >= 256)
285 pm = PAL_MODE_RGB332;
286 else if (max_colors >= 216)
287 pm = PAL_MODE_RGB666;
288 else if (max_colors >= 128)
289 pm = PAL_MODE_RGB232;
290 else if (max_colors >= 64)
291 pm = PAL_MODE_RGB222;
292 else if (max_colors >= 32)
293 pm = PAL_MODE_RGB221;
294 else if (max_colors >= 16)
295 pm = PAL_MODE_RGB121;
296 else if (max_colors >= 8)
297 pm = PAL_MODE_RGB111;
298 else if (max_colors >= 4)
299 pm = PAL_MODE_GRAY4;
300 else
301 pm = PAL_MODE_MONO;
302 }
303 /* FIXME: only alloc once per display+cmap */
304 buf->priv.pal = evas_software_xlib_x_color_allocate(disp, cmap, vis,
305 pm);
306 if (!buf->priv.pal)
307 {
308 free(buf);
309 return NULL;
310 }
311 }
312 if (buf->priv.pal)
313 {
314 if (buf->rot == 0 || buf->rot == 180)
315 conv_func = evas_common_convert_func_get(0, buf->w, buf->h,
316 evas_software_xlib_x_output_buffer_depth
317 (xob), buf->priv.mask.r,
318 buf->priv.mask.g,
319 buf->priv.mask.b,
320 buf->priv.pal->colors,
321 buf->rot);
322 else if (buf->rot == 90 || buf->rot == 270)
323 conv_func = evas_common_convert_func_get(0, buf->h, buf->w,
324 evas_software_xlib_x_output_buffer_depth
325 (xob), buf->priv.mask.r,
326 buf->priv.mask.g,
327 buf->priv.mask.b,
328 buf->priv.pal->colors,
329 buf->rot);
330 }
331 else
332 {
333 if (buf->rot == 0 || buf->rot == 180)
334 conv_func = evas_common_convert_func_get(0, buf->w, buf->h,
335 evas_software_xlib_x_output_buffer_depth
336 (xob), buf->priv.mask.r,
337 buf->priv.mask.g,
338 buf->priv.mask.b, PAL_MODE_NONE,
339 buf->rot);
340 else if (buf->rot == 90 || buf->rot == 270)
341 conv_func = evas_common_convert_func_get(0, buf->h, buf->w,
342 evas_software_xlib_x_output_buffer_depth
343 (xob), buf->priv.mask.r,
344 buf->priv.mask.g,
345 buf->priv.mask.b, PAL_MODE_NONE,
346 buf->rot);
347 }
348 evas_software_xlib_x_output_buffer_free(xob, 1);
349 if (!conv_func)
350 {
351 ERR("At depth: %i, RGB format mask: %08x %08x %08x, "
352 "Palette mode: %i. "
353 "Not supported by compiled in converters!",
354 buf->priv.x11.xlib.depth,
355 buf->priv.mask.r,
356 buf->priv.mask.g,
357 buf->priv.mask.b,
358 buf->priv.pal ? (int)buf->priv.pal->colors : -1);
359 }
360 }
361 evas_software_xlib_outbuf_drawable_set(buf, draw);
362 evas_software_xlib_outbuf_mask_set(buf, mask);
363 }
364#ifdef EVAS_FRAME_QUEUING
365 LKI(buf->priv.lock);
366#endif
367 return buf;
368}
369
370RGBA_Image *
371evas_software_xlib_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch)
372{
373 RGBA_Image *im;
374 Outbuf_Region *obr;
375 int bpl = 0;
376 int use_shm = 1;
377 int alpha;
378
379 if ((buf->onebuf) && (buf->priv.x11.xlib.shm))
380 {
381 Eina_Rectangle *rect;
382
383 RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, buf->w, buf->h);
384 obr = calloc(1, sizeof(Outbuf_Region));
385 if (!obr) return NULL;
386 rect = eina_rectangle_new(x, y, w, h);
387 if (!rect)
388 {
389 free(obr);
390 return NULL;
391 }
392
393 buf->priv.onebuf_regions = eina_list_append(buf->priv.onebuf_regions, rect);
394 if (buf->priv.onebuf)
395 {
396 *cx = x;
397 *cy = y;
398 *cw = w;
399 *ch = h;
400 if (!buf->priv.synced)
401 {
402 XSync(buf->priv.x11.xlib.disp, False);
403 buf->priv.synced = 1;
404 }
405 return buf->priv.onebuf;
406 }
407 obr->x = 0;
408 obr->y = 0;
409 obr->w = buf->w;
410 obr->h = buf->h;
411 *cx = x;
412 *cy = y;
413 *cw = w;
414 *ch = h;
415
416 alpha = ((buf->priv.x11.xlib.mask) || (buf->priv.destination_alpha));
417
418 use_shm = buf->priv.x11.xlib.shm;
419 if ((buf->rot == 0) &&
420 (buf->priv.mask.r == 0xff0000) &&
421 (buf->priv.mask.g == 0x00ff00) &&
422 (buf->priv.mask.b == 0x0000ff))
423 {
424 obr->xob = evas_software_xlib_x_output_buffer_new(buf->priv.x11.xlib.disp,
425 buf->priv.x11.xlib.vis,
426 buf->priv.x11.xlib.depth,
427 buf->w, buf->h,
428 use_shm,
429 NULL);
430 if (!obr->xob)
431 {
432 free(obr);
433 return NULL;
434 }
435 im = (RGBA_Image *)evas_cache_image_data(evas_common_image_cache_get(),
436 buf->w, buf->h,
437 (DATA32 *) evas_software_xlib_x_output_buffer_data(obr->xob, &bpl),
438 alpha, EVAS_COLORSPACE_ARGB8888);
439 if (!im)
440 {
441 evas_software_xlib_x_output_buffer_free(obr->xob, 0);
442 free(obr);
443 return NULL;
444 }
445 im->extended_info = obr;
446 if (buf->priv.x11.xlib.mask)
447 obr->mxob = evas_software_xlib_x_output_buffer_new(buf->priv.x11.xlib.disp,
448 buf->priv.x11.xlib.vis,
449 1,
450 buf->w, buf->h,
451 use_shm,
452 NULL);
453 }
454 else
455 {
456 im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
457 if (!im)
458 {
459 free(obr);
460 return NULL;
461 }
462 im->cache_entry.flags.alpha |= alpha ? 1 : 0;
463 evas_cache_image_surface_alloc(&im->cache_entry, buf->w, buf->h);
464 im->extended_info = obr;
465 if ((buf->rot == 0) || (buf->rot == 180))
466 {
467 obr->xob = evas_software_xlib_x_output_buffer_new(buf->priv.x11.xlib.disp,
468 buf->priv.x11.xlib.vis,
469 buf->priv.x11.xlib.depth,
470 buf->w, buf->h,
471 use_shm,
472 NULL);
473 if (!obr->xob)
474 {
475 evas_cache_image_drop(&im->cache_entry);
476 free(obr);
477 return NULL;
478 }
479 if (buf->priv.x11.xlib.mask)
480 obr->mxob = evas_software_xlib_x_output_buffer_new(buf->priv.x11.xlib.disp,
481 buf->priv.x11.xlib.vis,
482 1, buf->w, buf->h,
483 use_shm,
484 NULL);
485 }
486 else if ((buf->rot == 90) || (buf->rot == 270))
487 {
488 obr->xob = evas_software_xlib_x_output_buffer_new(buf->priv.x11.xlib.disp,
489 buf->priv.x11.xlib.vis,
490 buf->priv.x11.xlib.depth,
491 buf->h, buf->w,
492 use_shm,
493 NULL);
494 if (!obr->xob)
495 {
496 evas_cache_image_drop(&im->cache_entry);
497 free(obr);
498 return NULL;
499 }
500 if (buf->priv.x11.xlib.mask)
501 obr->mxob = evas_software_xlib_x_output_buffer_new(buf->priv.x11.xlib.disp,
502 buf->priv.x11.xlib.vis,
503 1, buf->h, buf->w,
504 use_shm,
505 NULL);
506 }
507 }
508 /* FIXME: We should be able to remove this memset, but somewhere in the process
509 we copy too much to the destination surface and some area are not cleaned before copy. */
510 if ((alpha) && (im->image.data))
511 {
512 /* FIXME: faster memset! */
513// memset(im->image.data, 0, w * h * sizeof(DATA32));
514 }
515
516 buf->priv.onebuf = im;
517 return im;
518 }
519
520 obr = calloc(1, sizeof(Outbuf_Region));
521 if (!obr) return NULL;
522 obr->x = x;
523 obr->y = y;
524 obr->w = w;
525 obr->h = h;
526 *cx = 0;
527 *cy = 0;
528 *cw = w;
529 *ch = h;
530
531 use_shm = buf->priv.x11.xlib.shm;
532 /* FIXME: magic - i found if shm regions are smaller than 200x200 its
533 * faster to use ximages over unix sockets - trial and error
534 */
535// use_shm = 0; /* 630 -> 1006 fps */
536// if ((w * h) < (200 * 200)) use_shm = 0; /* 630 -> 962 fps */
537
538 alpha = ((buf->priv.x11.xlib.mask) || (buf->priv.destination_alpha));
539
540 if ((buf->rot == 0) &&
541 (buf->priv.mask.r == 0xff0000) &&
542 (buf->priv.mask.g == 0x00ff00) &&
543 (buf->priv.mask.b == 0x0000ff))
544 {
545 obr->xob = _find_xob(buf->priv.x11.xlib.disp,
546 buf->priv.x11.xlib.vis,
547 buf->priv.x11.xlib.depth,
548 w, h,
549 use_shm,
550 NULL);
551 if (!obr->xob)
552 {
553 free(obr);
554 return NULL;
555 }
556 im = (RGBA_Image *)evas_cache_image_data(evas_common_image_cache_get(),
557 w, h,
558 (DATA32 *) evas_software_xlib_x_output_buffer_data(obr->xob, &bpl),
559 alpha, EVAS_COLORSPACE_ARGB8888);
560 if (!im)
561 {
562 _unfind_xob(obr->xob, 0);
563 free(obr);
564 return NULL;
565 }
566 im->extended_info = obr;
567 if (buf->priv.x11.xlib.mask)
568 obr->mxob = _find_xob(buf->priv.x11.xlib.disp,
569 buf->priv.x11.xlib.vis,
570 1, w, h,
571 use_shm,
572 NULL);
573 }
574 else
575 {
576 im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
577 if (!im)
578 {
579 free(obr);
580 return NULL;
581 }
582 im->cache_entry.w = w;
583 im->cache_entry.h = h;
584 im->cache_entry.flags.alpha |= alpha ? 1 : 0;
585 evas_cache_image_surface_alloc(&im->cache_entry, w, h);
586 im->extended_info = obr;
587 if ((buf->rot == 0) || (buf->rot == 180))
588 {
589 obr->xob = _find_xob(buf->priv.x11.xlib.disp,
590 buf->priv.x11.xlib.vis,
591 buf->priv.x11.xlib.depth,
592 w, h,
593 use_shm,
594 NULL);
595 if (!obr->xob)
596 {
597 evas_cache_image_drop(&im->cache_entry);
598 free(obr);
599 return NULL;
600 }
601 if (buf->priv.x11.xlib.mask)
602 obr->mxob = _find_xob(buf->priv.x11.xlib.disp,
603 buf->priv.x11.xlib.vis,
604 1, w, h,
605 use_shm,
606 NULL);
607 }
608 else if ((buf->rot == 90) || (buf->rot == 270))
609 {
610 obr->xob = _find_xob(buf->priv.x11.xlib.disp,
611 buf->priv.x11.xlib.vis,
612 buf->priv.x11.xlib.depth,
613 h, w,
614 use_shm,
615 NULL);
616 if (!obr->xob)
617 {
618 evas_cache_image_drop(&im->cache_entry);
619 free(obr);
620 return NULL;
621 }
622 if (buf->priv.x11.xlib.mask)
623 obr->mxob = _find_xob(buf->priv.x11.xlib.disp,
624 buf->priv.x11.xlib.vis,
625 1, h, w,
626 use_shm,
627 NULL);
628 }
629 }
630 /* FIXME: We should be able to remove this memset, but somewhere in the process
631 we copy too much to the destination surface and some area are not cleaned before copy. */
632 if (((buf->priv.x11.xlib.mask) || (buf->priv.destination_alpha)) &&
633 (im->image.data))
634 {
635 /* FIXME: faster memset! */
636// memset(im->image.data, 0, w * h * sizeof(DATA32));
637 }
638
639#ifdef EVAS_FRAME_QUEUING
640 if (!evas_common_frameq_enabled())
641#endif
642 buf->priv.pending_writes = eina_list_append(buf->priv.pending_writes, im);
643 return im;
644}
645
646void
647evas_software_xlib_outbuf_free_region_for_update(Outbuf *buf __UNUSED__, RGBA_Image *update __UNUSED__)
648{
649 /* no need to do anything - they are cleaned up on flush */
650}
651
652void
653evas_software_xlib_outbuf_flush(Outbuf *buf)
654{
655 Eina_List *l;
656 RGBA_Image *im;
657 Outbuf_Region *obr;
658
659 if ((buf->priv.onebuf) && (buf->priv.onebuf_regions))
660 {
661 Region tmpr;
662
663 im = buf->priv.onebuf;
664 obr = im->extended_info;
665 tmpr = XCreateRegion();
666 while (buf->priv.onebuf_regions)
667 {
668 Eina_Rectangle *rect;
669 XRectangle xr;
670
671 rect = buf->priv.onebuf_regions->data;
672 buf->priv.onebuf_regions = eina_list_remove_list(buf->priv.onebuf_regions, buf->priv.onebuf_regions);
673 if (buf->rot == 0)
674 {
675 xr.x = rect->x;
676 xr.y = rect->y;
677 xr.width = rect->w;
678 xr.height = rect->h;
679 }
680 else if (buf->rot == 90)
681 {
682 xr.x = rect->y;
683 xr.y = buf->w - rect->x - rect->w;
684 xr.width = rect->h;
685 xr.height = rect->w;
686 }
687 else if (buf->rot == 180)
688 {
689 xr.x = buf->w - rect->x - rect->w;
690 xr.y = buf->h - rect->y - rect->h;
691 xr.width = rect->w;
692 xr.height = rect->h;
693 }
694 else if (buf->rot == 270)
695 {
696 xr.x = buf->h - rect->y - rect->h;
697 xr.y = rect->x;
698 xr.width = rect->h;
699 xr.height = rect->w;
700 }
701 XUnionRectWithRegion(&xr, tmpr, tmpr);
702 if (buf->priv.debug)
703 evas_software_xlib_outbuf_debug_show(buf, buf->priv.x11.xlib.win,
704 xr.x, xr.y, xr.width, xr.height);
705 eina_rectangle_free(rect);
706 }
707 XSetRegion(buf->priv.x11.xlib.disp, buf->priv.x11.xlib.gc, tmpr);
708 if (obr->xob)
709 evas_software_xlib_x_output_buffer_paste(obr->xob, buf->priv.x11.xlib.win,
710 buf->priv.x11.xlib.gc,
711 0, 0, 0);
712 if (obr->mxob)
713 {
714 XSetRegion(buf->priv.x11.xlib.disp, buf->priv.x11.xlib.gcm, tmpr);
715 evas_software_xlib_x_output_buffer_paste(obr->mxob,
716 buf->priv.x11.xlib.mask,
717 buf->priv.x11.xlib.gcm,
718 0, 0, 0);
719 }
720 XDestroyRegion(tmpr);
721 buf->priv.synced = 0;
722 }
723 else
724 {
725#if 1
726 XSync(buf->priv.x11.xlib.disp, False);
727 EINA_LIST_FOREACH(buf->priv.pending_writes, l, im)
728 {
729 obr = im->extended_info;
730 if (buf->priv.debug)
731 evas_software_xlib_outbuf_debug_show(buf, buf->priv.x11.xlib.win,
732 obr->x, obr->y, obr->w, obr->h);
733 if (obr->xob)
734 evas_software_xlib_x_output_buffer_paste(obr->xob, buf->priv.x11.xlib.win,
735 buf->priv.x11.xlib.gc,
736 obr->x, obr->y, 0);
737 if (obr->mxob)
738 evas_software_xlib_x_output_buffer_paste(obr->mxob,
739 buf->priv.x11.xlib.mask,
740 buf->priv.x11.xlib.gcm,
741 obr->x, obr->y, 0);
742 }
743#ifdef EVAS_FRAME_QUEUING
744 LKL(buf->priv.lock);
745#endif
746 while (buf->priv.prev_pending_writes)
747 {
748 im = buf->priv.prev_pending_writes->data;
749 buf->priv.prev_pending_writes =
750 eina_list_remove_list(buf->priv.prev_pending_writes,
751 buf->priv.prev_pending_writes);
752 obr = im->extended_info;
753 evas_cache_image_drop(&im->cache_entry);
754 if (obr->xob) _unfind_xob(obr->xob, 0);
755 if (obr->mxob) _unfind_xob(obr->mxob, 0);
756 free(obr);
757 }
758 buf->priv.prev_pending_writes = buf->priv.pending_writes;
759#ifdef EVAS_FRAME_QUEUING
760 LKU(buf->priv.lock);
761#endif
762 buf->priv.pending_writes = NULL;
763 XFlush(buf->priv.x11.xlib.disp);
764#else
765 /* XX async push - disable */
766 /*
767 EINA_LIST_FOREACH(buf->priv.pending_writes, l, im)
768 {
769 obr = im->extended_info;
770 if (buf->priv.debug)
771 evas_software_xlib_outbuf_debug_show(buf, buf->priv.x11.xlib.win,
772 obr->x, obr->y, obr->w, obr->h);
773 evas_software_xlib_x_output_buffer_paste(obr->xob, buf->priv.x11.xlib.win,
774 buf->priv.x11.xlib.gc,
775 obr->x, obr->y, 0);
776 if (obr->mxob)
777 evas_software_xlib_x_output_buffer_paste(obr->mxob,
778 buf->priv.x11.xlib.mask,
779 buf->priv.x11.xlib.gcm,
780 obr->x, obr->y, 0);
781 }
782 */
783 XSync(buf->priv.x11.xlib.disp, False);
784
785 while (buf->priv.pending_writes)
786 {
787 RGBA_Image *im;
788 Outbuf_Region *obr;
789
790 im = eina_list_data_get(buf->priv.pending_writes);
791 buf->priv.pending_writes = eina_list_remove_list(buf->priv.pending_writes, buf->priv.pending_writes);
792 obr = im->extended_info;
793 evas_cache_image_drop(&im->cache_entry);
794 if (obr->xob) _unfind_xob(obr->xob, 0);
795 if (obr->mxob) _unfind_xob(obr->mxob, 0);
796 free(obr);
797 evas_cache_image_drop(&im->cache_entry);
798 }
799#endif
800 }
801 evas_common_cpu_end_opt();
802}
803
804void
805evas_software_xlib_outbuf_idle_flush(Outbuf *buf)
806{
807 if (buf->priv.onebuf)
808 {
809 RGBA_Image *im;
810 Outbuf_Region *obr;
811
812 im = buf->priv.onebuf;
813 buf->priv.onebuf = NULL;
814 obr = im->extended_info;
815 if (obr->xob) evas_software_xlib_x_output_buffer_free(obr->xob, 0);
816 if (obr->mxob) evas_software_xlib_x_output_buffer_free(obr->mxob, 0);
817 free(obr);
818 evas_cache_image_drop(&im->cache_entry);
819 }
820 else
821 {
822#ifdef EVAS_FRAME_QUEUING
823 LKL(buf->priv.lock);
824#endif
825 if (buf->priv.prev_pending_writes) XSync(buf->priv.x11.xlib.disp, False);
826 while (buf->priv.prev_pending_writes)
827 {
828 RGBA_Image *im;
829 Outbuf_Region *obr;
830
831 im = buf->priv.prev_pending_writes->data;
832 buf->priv.prev_pending_writes =
833 eina_list_remove_list(buf->priv.prev_pending_writes,
834 buf->priv.prev_pending_writes);
835 obr = im->extended_info;
836 evas_cache_image_drop(&im->cache_entry);
837 if (obr->xob) _unfind_xob(obr->xob, 0);
838 if (obr->mxob) _unfind_xob(obr->mxob, 0);
839 free(obr);
840 }
841#ifdef EVAS_FRAME_QUEUING
842 LKU(buf->priv.lock);
843#endif
844 _clear_xob(0);
845 }
846}
847
848void
849evas_software_xlib_outbuf_push_updated_region(Outbuf *buf, RGBA_Image *update, int x, int y, int w, int h)
850{
851 Gfx_Func_Convert conv_func = NULL;
852 Outbuf_Region *obr;
853 DATA32 *src_data;
854 unsigned char *data;
855 int bpl = 0, yy;
856
857 obr = update->extended_info;
858 if (buf->priv.pal)
859 {
860 if ((buf->rot == 0) || (buf->rot == 180))
861 conv_func = evas_common_convert_func_get(0, w, h,
862 evas_software_xlib_x_output_buffer_depth
863 (obr->xob), buf->priv.mask.r,
864 buf->priv.mask.g, buf->priv.mask.b,
865 buf->priv.pal->colors, buf->rot);
866 else if ((buf->rot == 90) || (buf->rot == 270))
867 conv_func = evas_common_convert_func_get(0, h, w,
868 evas_software_xlib_x_output_buffer_depth
869 (obr->xob), buf->priv.mask.r,
870 buf->priv.mask.g, buf->priv.mask.b,
871 buf->priv.pal->colors, buf->rot);
872 }
873 else
874 {
875 if ((buf->rot == 0) || (buf->rot == 180))
876 conv_func = evas_common_convert_func_get(0, w, h,
877 evas_software_xlib_x_output_buffer_depth
878 (obr->xob), buf->priv.mask.r,
879 buf->priv.mask.g, buf->priv.mask.b,
880 PAL_MODE_NONE, buf->rot);
881 else if ((buf->rot == 90) || (buf->rot == 270))
882 conv_func = evas_common_convert_func_get(0, h, w,
883 evas_software_xlib_x_output_buffer_depth
884 (obr->xob), buf->priv.mask.r,
885 buf->priv.mask.g, buf->priv.mask.b,
886 PAL_MODE_NONE, buf->rot);
887 }
888 if (!conv_func) return;
889
890 if (!obr->xob) return;
891 data = evas_software_xlib_x_output_buffer_data(obr->xob, &bpl);
892 if (!data) return;
893 src_data = update->image.data;
894 if (!src_data) return;
895 if (buf->rot == 0)
896 {
897 obr->x = x;
898 obr->y = y;
899 }
900 else if (buf->rot == 90)
901 {
902 obr->x = y;
903 obr->y = buf->w - x - w;
904 }
905 else if (buf->rot == 180)
906 {
907 obr->x = buf->w - x - w;
908 obr->y = buf->h - y - h;
909 }
910 else if (buf->rot == 270)
911 {
912 obr->x = buf->h - y - h;
913 obr->y = x;
914 }
915 if ((buf->rot == 0) || (buf->rot == 180))
916 {
917 obr->w = w;
918 obr->h = h;
919 }
920 else if ((buf->rot == 90) || (buf->rot == 270))
921 {
922 obr->w = h;
923 obr->h = w;
924 }
925 if (buf->onebuf)
926 {
927 src_data += x + (y * update->cache_entry.w);
928 data += (bpl * obr->y) +
929 (obr->x * (evas_software_xlib_x_output_buffer_depth(obr->xob) / 8));
930 }
931 if (buf->priv.pal)
932 {
933 if (data != (unsigned char *)src_data)
934 conv_func(src_data, data,
935 update->cache_entry.w - w,
936 bpl /
937 ((evas_software_xlib_x_output_buffer_depth(obr->xob) /
938 8)) - obr->w, obr->w, obr->h, x, y,
939 buf->priv.pal->lookup);
940 }
941 else
942 {
943 if (data != (unsigned char *)src_data)
944 conv_func(src_data, data,
945 update->cache_entry.w - w,
946 bpl /
947 ((evas_software_xlib_x_output_buffer_depth(obr->xob) /
948 8)) - obr->w, obr->w, obr->h, x, y, NULL);
949 }
950#if 1
951#else
952 /* XX async push */
953 if (!((buf->priv.onebuf) && (buf->priv.onebuf_regions)))
954 {
955 if (buf->priv.debug)
956 evas_software_xlib_outbuf_debug_show(buf, buf->priv.x11.xlib.win,
957 obr->x, obr->y, obr->w, obr->h);
958 if (obr->xob)
959 evas_software_xlib_x_output_buffer_paste(obr->xob, buf->priv.x11.xlib.win,
960 buf->priv.x11.xlib.gc,
961 obr->x, obr->y, 0);
962 }
963#endif
964 if (obr->mxob)
965 {
966 if (buf->rot == 0)
967 {
968 for (yy = 0; yy < obr->h; yy++)
969 evas_software_xlib_x_write_mask_line(buf, obr->mxob,
970 src_data +
971 (yy * obr->w), obr->w, yy);
972 }
973 else if (buf->rot == 90)
974 {
975 for (yy = 0; yy < obr->h; yy++)
976 evas_software_xlib_x_write_mask_line_vert(buf, obr->mxob,
977 src_data + yy,
978 h, // h
979 obr->h - yy - 1, // ym
980 w); // w
981 }
982 else if (buf->rot == 180)
983 {
984 for (yy = 0; yy < obr->h; yy++)
985 {
986 evas_software_xlib_x_write_mask_line_rev(buf, obr->mxob,
987 src_data +
988 (yy * obr->w),
989 obr->w, obr->h - yy - 1);
990 }
991 }
992 else if (buf->rot == 270)
993 {
994 for (yy = 0; yy < obr->h; yy++)
995 evas_software_xlib_x_write_mask_line_vert_rev(buf, obr->mxob,
996 src_data + yy,
997 h, // h
998 yy, // ym
999 w); // w
1000 }
1001#if 1
1002#else
1003 /* XX async push */
1004 if (!((buf->priv.onebuf) && (buf->priv.onebuf_regions)))
1005 evas_software_xlib_x_output_buffer_paste(obr->mxob,
1006 buf->priv.x11.xlib.mask,
1007 buf->priv.x11.xlib.gcm,
1008 obr->x, obr->y, 0);
1009#endif
1010 }
1011#if 1
1012#else
1013 XFlush(buf->priv.x11.xlib.disp);
1014#endif
1015}
1016
1017void
1018evas_software_xlib_outbuf_reconfigure(Outbuf * buf, int w, int h, int rot,
1019 Outbuf_Depth depth)
1020{
1021 if ((w == buf->w) &&
1022 (h == buf->h) &&
1023 (rot == buf->rot) &&
1024 (depth == buf->depth)) return;
1025 buf->w = w;
1026 buf->h = h;
1027 buf->rot = rot;
1028 evas_software_xlib_outbuf_idle_flush(buf);
1029}
1030
1031int
1032evas_software_xlib_outbuf_get_width(Outbuf * buf)
1033{
1034 return buf->w;
1035}
1036
1037int
1038evas_software_xlib_outbuf_get_height(Outbuf * buf)
1039{
1040 return buf->h;
1041}
1042
1043Outbuf_Depth
1044evas_software_xlib_outbuf_get_depth(Outbuf * buf)
1045{
1046 return buf->depth;
1047}
1048
1049int
1050evas_software_xlib_outbuf_get_rot(Outbuf * buf)
1051{
1052 return buf->rot;
1053}
1054
1055void
1056evas_software_xlib_outbuf_drawable_set(Outbuf * buf, Drawable draw)
1057{
1058 XGCValues gcv;
1059
1060 if (buf->priv.x11.xlib.win == draw) return;
1061 if (buf->priv.x11.xlib.gc)
1062 {
1063 XFreeGC(buf->priv.x11.xlib.disp, buf->priv.x11.xlib.gc);
1064 buf->priv.x11.xlib.gc = NULL;
1065 }
1066 buf->priv.x11.xlib.win = draw;
1067 buf->priv.x11.xlib.gc = XCreateGC(buf->priv.x11.xlib.disp, buf->priv.x11.xlib.win, 0, &gcv);
1068}
1069
1070void
1071evas_software_xlib_outbuf_mask_set(Outbuf * buf, Pixmap mask)
1072{
1073 XGCValues gcv;
1074
1075 if (buf->priv.x11.xlib.mask == mask) return;
1076 if (buf->priv.x11.xlib.gcm)
1077 {
1078 XFreeGC(buf->priv.x11.xlib.disp, buf->priv.x11.xlib.gcm);
1079 buf->priv.x11.xlib.gcm = NULL;
1080 }
1081 buf->priv.x11.xlib.mask = mask;
1082 if (buf->priv.x11.xlib.mask)
1083 buf->priv.x11.xlib.gcm = XCreateGC(buf->priv.x11.xlib.disp, buf->priv.x11.xlib.mask, 0, &gcv);
1084}
1085
1086void
1087evas_software_xlib_outbuf_debug_set(Outbuf * buf, int debug)
1088{
1089 buf->priv.debug = debug;
1090}
1091
1092void
1093evas_software_xlib_outbuf_debug_show(Outbuf * buf, Drawable draw, int x, int y, int w,
1094 int h)
1095{
1096 int i;
1097 int screen_num = 0;
1098
1099 {
1100 int wx, wy;
1101 unsigned int ww, wh, bd, dp;
1102 Window wdum, root;
1103 XWindowAttributes wattr;
1104
1105 XGetGeometry(buf->priv.x11.xlib.disp, draw, &root, &wx, &wy, &ww, &wh, &bd, &dp);
1106 XGetGeometry(buf->priv.x11.xlib.disp, root, &wdum, &wx, &wy, &ww, &wh, &bd, &dp);
1107 XGetWindowAttributes(buf->priv.x11.xlib.disp, root, &wattr);
1108 screen_num = XScreenNumberOfScreen(wattr.screen);
1109 }
1110 for (i = 0; i < 20; i++)
1111 {
1112 XSetForeground(buf->priv.x11.xlib.disp, buf->priv.x11.xlib.gc,
1113 BlackPixel(buf->priv.x11.xlib.disp, screen_num));
1114 XFillRectangle(buf->priv.x11.xlib.disp, draw, buf->priv.x11.xlib.gc, x, y, w, h);
1115 XSync(buf->priv.x11.xlib.disp, False);
1116 XSync(buf->priv.x11.xlib.disp, False);
1117 XSetForeground(buf->priv.x11.xlib.disp, buf->priv.x11.xlib.gc,
1118 WhitePixel(buf->priv.x11.xlib.disp, screen_num));
1119 XFillRectangle(buf->priv.x11.xlib.disp, draw, buf->priv.x11.xlib.gc, x, y, w, h);
1120 XSync(buf->priv.x11.xlib.disp, False);
1121 XSync(buf->priv.x11.xlib.disp, False);
1122 }
1123}
1124
1125Eina_Bool
1126evas_software_xlib_outbuf_alpha_get(Outbuf *buf)
1127{
1128 return buf->priv.x11.xlib.mask;
1129}
1130
1131#ifdef EVAS_FRAME_QUEUING
1132void
1133evas_software_xlib_outbuf_set_priv(Outbuf *buf, void *cur, void *prev __UNUSED__)
1134{
1135 buf->priv.pending_writes = (Eina_List *)cur;
1136}
1137#endif