8 # include "evas_cs2_private.h"
10 #include "evas_common_private.h"
11 #include "evas_macros.h"
12 #include "evas_xcb_outbuf.h"
13 #include "evas_xcb_buffer.h"
14 #include "evas_xcb_color.h"
16 /* local structures */
17 typedef struct _Outbuf_Region Outbuf_Region;
20 Xcb_Output_Buffer *xcbob, *mask;
24 /* local function prototypes */
25 static Xcb_Output_Buffer *_find_xcbob(xcb_connection_t *conn, xcb_visualtype_t *vis, int depth, int w, int h, Eina_Bool shm, void *data);
26 static void _unfind_xcbob(Xcb_Output_Buffer *xcbob, Eina_Bool sync);
27 static void _clear_xcbob(Eina_Bool sync);
28 static void _xcbob_sync(xcb_connection_t *conn);
31 static Eina_List *_shmpool = NULL;
32 static int _shmsize = 0;
33 static int _shmlimit = 0;
34 static const unsigned int _shmcountlimit = 32;
36 static Eina_Spinlock shmpool_lock;
37 #define SHMPOOL_LOCK() eina_spinlock_take(&shmpool_lock)
38 #define SHMPOOL_UNLOCK() eina_spinlock_release(&shmpool_lock)
41 evas_software_xcb_outbuf_init(void)
43 eina_spinlock_new(&shmpool_lock);
47 evas_software_xcb_outbuf_free(Outbuf *buf)
50 _shmlimit -= ((buf->w * buf->h * (buf->depth / 8)) * 3) / 2;
52 eina_spinlock_take(&(buf->priv.lock));
53 while (buf->priv.pending_writes)
55 RGBA_Image *im = NULL;
56 Outbuf_Region *obr = NULL;
58 im = buf->priv.pending_writes->data;
59 buf->priv.pending_writes =
60 eina_list_remove_list(buf->priv.pending_writes,
61 buf->priv.pending_writes);
62 obr = im->extended_info;
64 if (evas_cserve2_use_get())
65 evas_cache2_image_close(&im->cache_entry);
68 evas_cache_image_drop(&im->cache_entry);
70 if (obr->xcbob) _unfind_xcbob(obr->xcbob, EINA_FALSE);
71 if (obr->mask) _unfind_xcbob(obr->mask, EINA_FALSE);
74 eina_spinlock_release(&(buf->priv.lock));
76 evas_software_xcb_outbuf_idle_flush(buf);
77 evas_software_xcb_outbuf_flush(buf, NULL, NULL, MODE_FULL);
79 if (buf->priv.x11.xcb.gc)
80 xcb_free_gc(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.gc);
81 if (buf->priv.x11.xcb.gcm)
82 xcb_free_gc(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.gcm);
84 evas_software_xcb_color_deallocate(buf->priv.x11.xcb.conn,
85 buf->priv.x11.xcb.cmap,
86 buf->priv.x11.xcb.visual,
89 eina_array_flush(&buf->priv.onebuf_regions);
90 eina_spinlock_free(&(buf->priv.lock));
92 _clear_xcbob(EINA_TRUE);
96 evas_software_xcb_outbuf_setup(int w, int h, int rot, Outbuf_Depth depth, xcb_connection_t *conn, xcb_screen_t *screen, xcb_drawable_t draw, xcb_visualtype_t *vis, xcb_colormap_t cmap, int xdepth, Eina_Bool grayscale, int max_colors, xcb_drawable_t mask, Eina_Bool shape_dither, Eina_Bool alpha)
99 Gfx_Func_Convert func_conv = NULL;
100 Xcb_Output_Buffer *xob;
101 const xcb_setup_t *setup;
103 if (!(buf = calloc(1, sizeof(Outbuf))))
106 if (xdepth < 15) rot = 0;
108 setup = xcb_get_setup(conn);
114 buf->priv.x11.xcb.conn = conn;
115 buf->priv.x11.xcb.screen = screen;
116 buf->priv.x11.xcb.visual = vis;
117 buf->priv.x11.xcb.cmap = cmap;
118 buf->priv.x11.xcb.depth = xdepth;
119 buf->priv.mask_dither = shape_dither;
120 buf->priv.destination_alpha = alpha;
121 buf->priv.x11.xcb.shm = evas_software_xcb_can_do_shm(conn, screen);
124 evas_software_xcb_output_buffer_new(buf->priv.x11.xcb.conn,
125 buf->priv.x11.xcb.visual,
126 buf->priv.x11.xcb.depth,
127 1, 1, buf->priv.x11.xcb.shm,
129 if (!xob) buf->priv.x11.xcb.shm = 0;
131 evas_software_xcb_output_buffer_new(buf->priv.x11.xcb.conn,
132 buf->priv.x11.xcb.visual,
133 buf->priv.x11.xcb.depth,
134 1, 1, buf->priv.x11.xcb.shm,
141 buf->priv.x11.xcb.imdepth = evas_software_xcb_output_buffer_depth(xob);
142 evas_software_xcb_output_buffer_unref(xob, EINA_FALSE);
144 eina_array_step_set(&buf->priv.onebuf_regions, sizeof(Eina_Array), 8);
146 #ifdef WORDS_BIGENDIAN
147 if (setup->image_byte_order == XCB_IMAGE_ORDER_LSB_FIRST)
148 buf->priv.x11.xcb.swap = EINA_TRUE;
150 if (setup->image_byte_order == XCB_IMAGE_ORDER_MSB_FIRST)
151 buf->priv.x11.xcb.swap = EINA_TRUE;
153 if (setup->bitmap_format_bit_order == XCB_IMAGE_ORDER_MSB_FIRST)
154 buf->priv.x11.xcb.bit_swap = EINA_TRUE;
156 if (((vis->_class == XCB_VISUAL_CLASS_TRUE_COLOR) ||
157 (vis->_class == XCB_VISUAL_CLASS_DIRECT_COLOR)) && (xdepth > 8))
159 buf->priv.mask.r = (DATA32)vis->red_mask;
160 buf->priv.mask.g = (DATA32)vis->green_mask;
161 buf->priv.mask.b = (DATA32)vis->blue_mask;
162 if (buf->priv.x11.xcb.swap)
164 SWAP32(buf->priv.mask.r);
165 SWAP32(buf->priv.mask.g);
166 SWAP32(buf->priv.mask.b);
169 else if ((vis->_class == XCB_VISUAL_CLASS_PSEUDO_COLOR) ||
170 (vis->_class == XCB_VISUAL_CLASS_STATIC_COLOR) ||
171 (vis->_class == XCB_VISUAL_CLASS_GRAY_SCALE) ||
172 (vis->_class == XCB_VISUAL_CLASS_STATIC_GRAY) ||
175 Convert_Pal_Mode pm = PAL_MODE_RGB332;
177 if ((vis->_class == XCB_VISUAL_CLASS_GRAY_SCALE) ||
178 (vis->_class == XCB_VISUAL_CLASS_STATIC_GRAY))
179 grayscale = EINA_TRUE;
182 if (max_colors >= 256)
183 pm = PAL_MODE_GRAY256;
184 else if (max_colors >= 64)
185 pm = PAL_MODE_GRAY64;
186 else if (max_colors >= 16)
187 pm = PAL_MODE_GRAY16;
188 else if (max_colors >= 4)
195 if (max_colors >= 256)
196 pm = PAL_MODE_RGB332;
197 else if (max_colors >= 216)
198 pm = PAL_MODE_RGB666;
199 else if (max_colors >= 128)
200 pm = PAL_MODE_RGB232;
201 else if (max_colors >= 64)
202 pm = PAL_MODE_RGB222;
203 else if (max_colors >= 32)
204 pm = PAL_MODE_RGB221;
205 else if (max_colors >= 16)
206 pm = PAL_MODE_RGB121;
207 else if (max_colors >= 8)
208 pm = PAL_MODE_RGB111;
209 else if (max_colors >= 4)
214 /* FIXME: Only allocate once per display & colormap */
216 evas_software_xcb_color_allocate(conn, cmap, vis, pm);
223 if ((buf->rot == 0) || (buf->rot == 180))
228 else if ((buf->rot == 90) || (buf->rot == 270))
237 evas_common_convert_func_get(0, w, h, xdepth,
241 buf->priv.pal->colors, buf->rot);
246 evas_common_convert_func_get(0, w, h, xdepth,
250 PAL_MODE_NONE, buf->rot);
257 " RGB format mask: %08x, %08x, %08x"
259 " Not supported by any compiled in converters!"
260 " }", buf->priv.x11.xcb.depth, buf->priv.mask.r,
261 buf->priv.mask.g, buf->priv.mask.b,
262 buf->priv.pal ? (int)buf->priv.pal->colors : -1);
265 evas_software_xcb_outbuf_drawable_set(buf, draw);
266 evas_software_xcb_outbuf_mask_set(buf, mask);
267 eina_spinlock_new(&(buf->priv.lock));
270 _shmlimit += ((buf->w * buf->h * (buf->depth / 8)) * 3) / 2;
276 evas_software_xcb_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch)
278 RGBA_Image *im = NULL;
279 Outbuf_Region *obr = NULL;
280 Eina_Bool use_shm = EINA_TRUE;
281 Eina_Bool alpha = EINA_FALSE;
284 eina_spinlock_take(&(buf->priv.lock));
285 if ((buf->onebuf) && (buf->priv.x11.xcb.shm))
287 Eina_Rectangle *rect;
289 RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, buf->w, buf->h);
291 if (!(obr = calloc(1, sizeof(Outbuf_Region))))
293 eina_spinlock_release(&(buf->priv.lock));
297 if (!(rect = eina_rectangle_new(x, y, w, h)))
300 eina_spinlock_release(&(buf->priv.lock));
304 if ((eina_array_push(&buf->priv.onebuf_regions, rect)) &&
311 if (!buf->priv.synced)
313 _xcbob_sync(buf->priv.x11.xcb.conn);
314 buf->priv.synced = EINA_TRUE;
317 eina_spinlock_release(&(buf->priv.lock));
318 return buf->priv.onebuf;
329 alpha = ((buf->priv.x11.xcb.mask) || (buf->priv.destination_alpha));
330 use_shm = buf->priv.x11.xcb.shm;
332 if ((buf->rot == 0) &&
333 (buf->priv.x11.xcb.imdepth == 32) &&
334 (buf->priv.mask.r == 0xff0000) &&
335 (buf->priv.mask.g == 0x00ff00) &&
336 (buf->priv.mask.b == 0x0000ff))
339 evas_software_xcb_output_buffer_new(buf->priv.x11.xcb.conn,
340 buf->priv.x11.xcb.visual,
341 buf->priv.x11.xcb.depth,
342 buf->w, buf->h, use_shm,
347 eina_spinlock_release(&(buf->priv.lock));
351 if (evas_cserve2_use_get())
354 (RGBA_Image *)evas_cache2_image_data(evas_common_image_cache2_get(),
356 (DATA32 *)evas_software_xcb_output_buffer_data(obr->xcbob, &bpl),
357 alpha, EVAS_COLORSPACE_ARGB8888);
363 (RGBA_Image *)evas_cache_image_data(evas_common_image_cache_get(),
365 (DATA32 *)evas_software_xcb_output_buffer_data(obr->xcbob, &bpl),
366 alpha, EVAS_COLORSPACE_ARGB8888);
371 evas_software_xcb_output_buffer_unref(obr->xcbob, EINA_FALSE);
373 eina_spinlock_release(&(buf->priv.lock));
376 im->extended_info = obr;
377 if (buf->priv.x11.xcb.mask)
380 evas_software_xcb_output_buffer_new(buf->priv.x11.xcb.conn,
381 buf->priv.x11.xcb.visual,
391 if (evas_cserve2_use_get())
394 (RGBA_Image *)evas_cache2_image_empty(evas_common_image_cache2_get());
400 (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
406 eina_spinlock_release(&(buf->priv.lock));
409 im->cache_entry.flags.alpha |= (alpha ? 1 : 0);
411 if (evas_cserve2_use_get())
412 evas_cache2_image_surface_alloc(&im->cache_entry, buf->w, buf->h);
415 evas_cache_image_surface_alloc(&im->cache_entry, buf->w, buf->h);
417 im->extended_info = obr;
418 if ((buf->rot == 0) || (buf->rot == 180))
423 else if ((buf->rot == 90) || (buf->rot == 270))
429 evas_software_xcb_output_buffer_new(buf->priv.x11.xcb.conn,
430 buf->priv.x11.xcb.visual,
431 buf->priv.x11.xcb.depth,
432 bw, bh, use_shm, NULL);
436 if (evas_cserve2_use_get())
437 evas_cache2_image_close(&im->cache_entry);
440 evas_cache_image_drop(&im->cache_entry);
443 eina_spinlock_release(&(buf->priv.lock));
446 if (buf->priv.x11.xcb.mask)
449 evas_software_xcb_output_buffer_new(buf->priv.x11.xcb.conn,
450 buf->priv.x11.xcb.visual,
455 /* FIXME: We should be able to remove this memset. */
456 if ((alpha) && (im->image.data))
458 /* FIXME: Faster memset */
459 // memset(im->image.data, 0, (w * h * sizeof(DATA32)));
461 buf->priv.onebuf = im;
462 eina_spinlock_release(&(buf->priv.lock));
466 if (!(obr = calloc(1, sizeof(Outbuf_Region))))
468 eina_spinlock_release(&(buf->priv.lock));
481 use_shm = buf->priv.x11.xcb.shm;
482 alpha = ((buf->priv.x11.xcb.mask) || (buf->priv.destination_alpha));
483 if ((buf->rot == 0) &&
484 (buf->priv.x11.xcb.imdepth == 32) &&
485 (buf->priv.mask.r == 0xff0000) &&
486 (buf->priv.mask.g == 0x00ff00) &&
487 (buf->priv.mask.b == 0x0000ff))
490 _find_xcbob(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.visual,
491 buf->priv.x11.xcb.depth, w, h, use_shm, NULL);
495 eina_spinlock_release(&(buf->priv.lock));
499 if (evas_cserve2_use_get())
502 (RGBA_Image *)evas_cache2_image_data(evas_common_image_cache2_get(),
504 (DATA32 *)evas_software_xcb_output_buffer_data(obr->xcbob, &bpl),
505 alpha, EVAS_COLORSPACE_ARGB8888);
511 (RGBA_Image *)evas_cache_image_data(evas_common_image_cache_get(),
513 (DATA32 *)evas_software_xcb_output_buffer_data(obr->xcbob, &bpl),
514 alpha, EVAS_COLORSPACE_ARGB8888);
519 _unfind_xcbob(obr->xcbob, EINA_FALSE);
521 eina_spinlock_release(&(buf->priv.lock));
524 im->extended_info = obr;
525 if (buf->priv.x11.xcb.mask)
528 _find_xcbob(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.visual,
529 1, w, h, use_shm, NULL);
537 if (evas_cserve2_use_get())
540 (RGBA_Image *)evas_cache2_image_empty(evas_common_image_cache2_get());
546 (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
552 eina_spinlock_release(&(buf->priv.lock));
555 im->cache_entry.flags.alpha |= (alpha ? 1 : 0);
557 if (evas_cserve2_use_get())
558 evas_cache2_image_surface_alloc(&im->cache_entry, w, h);
561 evas_cache_image_surface_alloc(&im->cache_entry, w, h);
563 im->extended_info = obr;
564 if ((buf->rot == 0) || (buf->rot == 180))
569 else if ((buf->rot == 90) || (buf->rot == 270))
575 _find_xcbob(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.visual,
576 buf->priv.x11.xcb.depth, bw, bh, use_shm, NULL);
580 if (evas_cserve2_use_get())
581 evas_cache2_image_close(&im->cache_entry);
584 evas_cache_image_drop(&im->cache_entry);
586 eina_spinlock_release(&(buf->priv.lock));
589 if (buf->priv.x11.xcb.mask)
592 _find_xcbob(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.visual, 1,
593 bw, bh, use_shm, NULL);
596 /* FIXME: We should be able to remove this memset. */
597 if (((buf->priv.x11.xcb.mask) || (buf->priv.destination_alpha)) &&
600 /* FIXME: Faster memset */
601 // memset(im->image.data, 0, (w * h * sizeof(DATA32)));
604 buf->priv.pending_writes = eina_list_append(buf->priv.pending_writes, im);
606 eina_spinlock_release(&(buf->priv.lock));
611 evas_software_xcb_outbuf_free_region_for_update(Outbuf *buf EINA_UNUSED, RGBA_Image *update EINA_UNUSED)
613 /* NOOP: Cleaned up on flush */
617 evas_software_xcb_outbuf_flush(Outbuf *buf, Tilebuf_Rect *surface_damage EINA_UNUSED, Tilebuf_Rect *buffer_damage EINA_UNUSED, Evas_Render_Mode render_mode EINA_UNUSED)
620 RGBA_Image *im = NULL;
621 Outbuf_Region *obr = NULL;
623 eina_spinlock_take(&(buf->priv.lock));
624 if ((buf->priv.onebuf) && (eina_array_count(&buf->priv.onebuf_regions)))
626 Eina_Array_Iterator it;
627 Eina_Rectangle *rect;
629 pixman_region16_t tmpr;
631 im = buf->priv.onebuf;
632 obr = im->extended_info;
633 pixman_region_init(&tmpr);
634 EINA_ARRAY_ITER_NEXT(&buf->priv.onebuf_regions, i, rect, it)
636 Eina_Rectangle xr = { 0, 0, 0, 0 };
638 /* rect = buf->priv.onebuf_regions->data; */
639 /* buf->priv.onebuf_regions = */
640 /* eina_list_remove_list(buf->priv.onebuf_regions, */
641 /* buf->priv.onebuf_regions); */
649 else if (buf->rot == 90)
652 xr.y = buf->w - rect->x - rect->w;
656 else if (buf->rot == 180)
658 xr.x = buf->w - rect->x - rect->w;
659 xr.y = buf->h - rect->y - rect->h;
663 else if (buf->rot == 270)
665 xr.x = buf->h - rect->y - rect->h;
670 pixman_region_union_rect(&tmpr, &tmpr, xr.x, xr.y, xr.w, xr.h);
672 evas_software_xcb_outbuf_debug_show(buf, buf->priv.x11.xcb.win,
673 xr.x, xr.y, xr.w, xr.h);
674 eina_rectangle_free(rect);
676 eina_array_clean(&buf->priv.onebuf_regions);
677 xcb_set_clip_rectangles(buf->priv.x11.xcb.conn,
678 XCB_CLIP_ORDERING_YX_BANDED,
679 buf->priv.x11.xcb.gc, 0, 0,
680 pixman_region_n_rects(&tmpr),
681 (const xcb_rectangle_t *)pixman_region_rectangles(&tmpr, NULL));
684 evas_software_x11_region_push_hook_call(buf, 0, 0, obr->xcbob,
686 evas_software_xcb_output_buffer_paste(obr->xcbob,
687 buf->priv.x11.xcb.win,
688 buf->priv.x11.xcb.gc, 0, 0, 0);
692 xcb_set_clip_rectangles(buf->priv.x11.xcb.conn,
693 XCB_CLIP_ORDERING_YX_BANDED,
694 buf->priv.x11.xcb.gcm, 0, 0,
695 pixman_region_n_rects(&tmpr),
696 (const xcb_rectangle_t *)pixman_region_rectangles(&tmpr, NULL));
697 evas_software_xcb_output_buffer_paste(obr->mask,
698 buf->priv.x11.xcb.mask,
699 buf->priv.x11.xcb.gcm,
702 pixman_region_fini(&tmpr);
703 buf->priv.synced = EINA_FALSE;
708 _xcbob_sync(buf->priv.x11.xcb.conn);
709 EINA_LIST_FOREACH(buf->priv.pending_writes, l, im)
711 obr = im->extended_info;
713 evas_software_xcb_outbuf_debug_show(buf, buf->priv.x11.xcb.win,
714 obr->x, obr->y, obr->w, obr->h);
717 evas_software_x11_region_push_hook_call(buf, obr->x, obr->y,
720 evas_software_xcb_output_buffer_paste(obr->xcbob,
721 buf->priv.x11.xcb.win,
722 buf->priv.x11.xcb.gc,
726 evas_software_xcb_output_buffer_paste(obr->mask,
727 buf->priv.x11.xcb.mask,
728 buf->priv.x11.xcb.gcm,
731 while (buf->priv.prev_pending_writes)
733 im = buf->priv.prev_pending_writes->data;
734 buf->priv.prev_pending_writes =
735 eina_list_remove_list(buf->priv.prev_pending_writes,
736 buf->priv.prev_pending_writes);
737 obr = im->extended_info;
739 if (evas_cserve2_use_get())
740 evas_cache2_image_close(&im->cache_entry);
743 evas_cache_image_drop(&im->cache_entry);
745 if (obr->xcbob) _unfind_xcbob(obr->xcbob, EINA_FALSE);
746 if (obr->mask) _unfind_xcbob(obr->mask, EINA_FALSE);
749 buf->priv.prev_pending_writes = buf->priv.pending_writes;
750 buf->priv.pending_writes = NULL;
751 xcb_flush(buf->priv.x11.xcb.conn);
753 /* FIXME: Async Push Disabled */
755 _xcbob_sync(buf->priv.x11.xcb.conn);
756 while (buf->priv.pending_writes)
758 im = eina_list_data_get(buf->priv.pending_writes);
759 buf->priv.pending_writes =
760 eina_list_remove_list(buf->priv.pending_writes,
761 buf->priv.pending_writes);
762 obr = im->extended_info;
764 if (evas_cserve2_use_get())
765 evas_cache2_image_close(&im->cache_entry);
768 evas_cache_image_drop(&im->cache_entry);
769 if (obr->xcbob) _unfind_xcbob(obr->xcbob, EINA_FALSE);
770 if (obr->mask) _unfind_xcbob(obr->mask, EINA_FALSE);
773 if (evas_cserve2_use_get())
774 evas_cache2_image_close(&im->cache_entry);
777 evas_cache_image_drop(&im->cache_entry);
781 eina_spinlock_release(&(buf->priv.lock));
782 evas_common_cpu_end_opt();
786 evas_software_xcb_outbuf_idle_flush(Outbuf *buf)
788 eina_spinlock_release(&(buf->priv.lock));
789 if (buf->priv.onebuf)
794 im = buf->priv.onebuf;
795 buf->priv.onebuf = NULL;
796 obr = im->extended_info;
800 evas_software_xcb_output_buffer_unref(obr->xcbob, EINA_FALSE);
806 evas_software_xcb_output_buffer_unref(obr->mask, EINA_FALSE);
811 if (evas_cserve2_use_get())
812 evas_cache2_image_close(&im->cache_entry);
815 evas_cache_image_drop(&im->cache_entry);
819 if (buf->priv.prev_pending_writes)
820 _xcbob_sync(buf->priv.x11.xcb.conn);
821 while (buf->priv.prev_pending_writes)
826 im = buf->priv.prev_pending_writes->data;
827 buf->priv.prev_pending_writes =
828 eina_list_remove_list(buf->priv.prev_pending_writes,
829 buf->priv.prev_pending_writes);
830 obr = im->extended_info;
832 if (evas_cserve2_use_get())
833 evas_cache2_image_close(&im->cache_entry);
836 evas_cache_image_drop(&im->cache_entry);
837 if (obr->xcbob) _unfind_xcbob(obr->xcbob, EINA_FALSE);
838 if (obr->mask) _unfind_xcbob(obr->mask, EINA_FALSE);
841 _clear_xcbob(EINA_FALSE);
843 eina_spinlock_release(&(buf->priv.lock));
847 evas_software_xcb_outbuf_push_updated_region(Outbuf *buf, RGBA_Image *update, int x, int y, int w, int h)
849 Gfx_Func_Convert func_conv = NULL;
850 Outbuf_Region *obr = NULL;
851 DATA32 *src_data = NULL;
852 unsigned char *data = NULL;
856 eina_spinlock_release(&(buf->priv.lock));
857 obr = update->extended_info;
860 eina_spinlock_release(&(buf->priv.lock));
864 if ((buf->rot == 0) || (buf->rot == 180))
869 else if ((buf->rot == 90) || (buf->rot == 270))
877 evas_common_convert_func_get(0, bw, bh, buf->depth, buf->priv.mask.r,
878 buf->priv.mask.g, buf->priv.mask.b,
879 buf->priv.pal->colors, buf->rot);
884 evas_common_convert_func_get(0, bw, bh, buf->depth, buf->priv.mask.r,
885 buf->priv.mask.g, buf->priv.mask.b,
886 PAL_MODE_NONE, buf->rot);
890 eina_spinlock_release(&(buf->priv.lock));
894 if (!(data = evas_software_xcb_output_buffer_data(obr->xcbob, &bpl)))
896 eina_spinlock_release(&(buf->priv.lock));
899 if (!(src_data = update->image.data))
901 eina_spinlock_release(&(buf->priv.lock));
911 else if (buf->rot == 90)
914 obr->y = (buf->w - x - w);
918 else if (buf->rot == 180)
920 obr->x = (buf->w - x - w);
921 obr->y = (buf->h - y - h);
925 else if (buf->rot == 270)
927 obr->x = (buf->h - y - h);
934 src_data += x + (y * update->cache_entry.w);
935 data += (bpl * obr->y) + (obr->x * (buf->depth / 8));
937 if (data != (unsigned char *)src_data)
941 func_conv(src_data, data, update->cache_entry.w - w,
942 bpl - obr->w, obr->w, obr->h, x, y,
943 buf->priv.pal->lookup);
947 int pixelb = evas_software_xcb_output_buffer_depth(obr->xcbob) / 8;
953 run = obr->w * pixelb;
956 else if ((pixelb == 2) || (pixelb == 4))
959 dstjump = (bpl / pixelb) - run;
966 func_conv(src_data, data, update->cache_entry.w - w, dstjump,
967 obr->w, obr->h, x, y, NULL);
973 if (!((buf->priv.onebuf) && (eina_array_count(&buf->priv.onebuf_regions))))
976 evas_software_xcb_outbuf_debug_show(buf, buf->priv.x11.xcb.win,
977 obr->x, obr->y, obr->w, obr->h);
980 evas_software_x11_region_push_hook_call(buf, obr->x, obr->y,
983 evas_software_xcb_output_buffer_paste(obr->xcbob,
984 buf->priv.x11.xcb.win,
985 buf->priv.x11.xcb.gc,
994 for (yy = 0; yy < obr->h; yy++)
995 evas_software_xcb_write_mask_line(buf, obr->mask,
996 src_data + (yy * obr->w),
999 else if (buf->rot == 90)
1001 for (yy = 0; yy < obr->h; yy++)
1002 evas_software_xcb_write_mask_line_vert(buf, obr->mask,
1004 h, (obr->h - yy - 1), w);
1006 else if (buf->rot == 180)
1008 for (yy = 0; yy < obr->h; yy++)
1009 evas_software_xcb_write_mask_line_rev(buf, obr->mask,
1010 src_data + (yy * obr->w),
1011 obr->w, (obr->h - yy - 1));
1013 else if (buf->rot == 270)
1015 for (yy = 0; yy < obr->h; yy++)
1016 evas_software_xcb_write_mask_line_vert_rev(buf, obr->mask,
1023 if (!((buf->priv.onebuf) &&
1024 (eina_array_count(&buf->priv.onebuf_regions))))
1025 evas_software_xcb_output_buffer_paste(obr->mask,
1026 buf->priv.x11.xcb.mask,
1027 buf->priv.x11.xcb.gcm,
1033 xcb_flush(buf->priv.x11.xcb.conn);
1035 eina_spinlock_release(&(buf->priv.lock));
1039 evas_software_xcb_outbuf_reconfigure(Outbuf *buf, int w, int h, int rot, Outbuf_Depth depth)
1041 if ((w == buf->w) && (h == buf->h) && (rot == buf->rot) &&
1042 (depth == buf->depth)) return;
1044 _shmlimit -= ((buf->w * buf->h * (buf->depth / 8)) * 3) / 2;
1048 _shmlimit += ((buf->w * buf->h * (buf->depth / 8)) * 3) / 2;
1050 evas_software_xcb_outbuf_idle_flush(buf);
1054 evas_software_xcb_outbuf_width_get(Outbuf *buf)
1060 evas_software_xcb_outbuf_height_get(Outbuf *buf)
1066 evas_software_xcb_outbuf_depth_get(Outbuf *buf)
1072 evas_software_xcb_outbuf_drawable_set(Outbuf *buf, xcb_drawable_t drawable)
1074 if (buf->priv.x11.xcb.win == drawable) return;
1075 if (buf->priv.x11.xcb.gc)
1077 xcb_free_gc(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.gc);
1078 buf->priv.x11.xcb.gc = 0;
1080 buf->priv.x11.xcb.win = drawable;
1081 buf->priv.x11.xcb.gc = xcb_generate_id(buf->priv.x11.xcb.conn);
1082 xcb_create_gc(buf->priv.x11.xcb.conn,
1083 buf->priv.x11.xcb.gc, buf->priv.x11.xcb.win, 0, NULL);
1087 evas_software_xcb_outbuf_mask_set(Outbuf *buf, xcb_drawable_t mask)
1089 if (buf->priv.x11.xcb.mask == mask) return;
1090 if (buf->priv.x11.xcb.gcm)
1092 xcb_free_gc(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.gcm);
1093 buf->priv.x11.xcb.gcm = 0;
1095 buf->priv.x11.xcb.mask = mask;
1096 if (buf->priv.x11.xcb.mask)
1098 buf->priv.x11.xcb.gcm = xcb_generate_id(buf->priv.x11.xcb.conn);
1099 xcb_create_gc(buf->priv.x11.xcb.conn,
1100 buf->priv.x11.xcb.gcm, buf->priv.x11.xcb.mask, 0, NULL);
1105 evas_software_xcb_outbuf_rotation_get(Outbuf *buf)
1111 evas_software_xcb_outbuf_rotation_set(Outbuf *buf, int rotation)
1113 buf->rot = rotation;
1117 evas_software_xcb_outbuf_alpha_get(Outbuf *buf)
1119 return buf->priv.x11.xcb.mask;
1123 evas_software_xcb_outbuf_debug_set(Outbuf *buf, Eina_Bool debug)
1125 buf->priv.debug = debug;
1129 evas_software_xcb_outbuf_debug_show(Outbuf *buf, xcb_drawable_t drawable, int x, int y, int w, int h)
1132 xcb_screen_t *screen = NULL;
1133 xcb_get_geometry_reply_t *geom;
1134 xcb_drawable_t root;
1135 xcb_screen_iterator_t si;
1138 xcb_get_geometry_reply(buf->priv.x11.xcb.conn,
1139 xcb_get_geometry_unchecked(buf->priv.x11.xcb.conn,
1144 xcb_get_geometry_reply(buf->priv.x11.xcb.conn,
1145 xcb_get_geometry_unchecked(buf->priv.x11.xcb.conn,
1148 si = xcb_setup_roots_iterator((xcb_setup_t *)xcb_get_setup(buf->priv.x11.xcb.conn));
1149 for (; si.rem; xcb_screen_next(&si))
1151 if (si.data->root == geom->root)
1159 for (i = 0; i < 20; i++)
1161 xcb_rectangle_t rect = { x, y, w, h};
1165 mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
1166 value[0] = screen->black_pixel;
1167 value[1] = XCB_EXPOSURES_NOT_ALLOWED;
1168 xcb_change_gc(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.gc,
1170 xcb_poly_fill_rectangle(buf->priv.x11.xcb.conn, drawable,
1171 buf->priv.x11.xcb.gc, 1, &rect);
1172 _xcbob_sync(buf->priv.x11.xcb.conn);
1173 _xcbob_sync(buf->priv.x11.xcb.conn);
1175 mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
1176 value[0] = screen->white_pixel;
1177 value[1] = XCB_EXPOSURES_NOT_ALLOWED;
1178 xcb_change_gc(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.gc,
1180 xcb_poly_fill_rectangle(buf->priv.x11.xcb.conn, drawable,
1181 buf->priv.x11.xcb.gc, 1, &rect);
1182 _xcbob_sync(buf->priv.x11.xcb.conn);
1183 _xcbob_sync(buf->priv.x11.xcb.conn);
1188 /* local functions */
1189 static Xcb_Output_Buffer *
1190 _find_xcbob(xcb_connection_t *conn, xcb_visualtype_t *vis, int depth, int w, int h, Eina_Bool shm, void *data)
1192 Eina_List *l = NULL, *xl = NULL;
1193 Xcb_Output_Buffer *xcbob = NULL, *xcbob2 = NULL;
1194 int lbytes = 0, bpp = 0, sz = 0;
1195 int fitness = 0x7fffffff;
1198 return evas_software_xcb_output_buffer_new(conn, vis, depth, w, h,
1204 if (bpp == 3) bpp = 4;
1205 lbytes = ((((w * bpp) + 3) / 4) * 4);
1208 lbytes = (((w + 63) / 64) * 8);
1212 EINA_LIST_FOREACH(_shmpool, l, xcbob2)
1216 if ((xcbob2->xim->depth != depth) || (xcbob2->visual != vis) ||
1217 (xcbob2->connection != conn) || (xcbob2->w != w)) continue;
1218 szdif = (xcbob2->psize - sz);
1219 if (szdif < 0) continue;
1226 if (szdif < fitness)
1234 (fitness > (400 * 400)) ||
1239 return evas_software_xcb_output_buffer_new(conn, vis, depth,
1244 _shmpool = eina_list_remove_list(_shmpool, xl);
1247 // xcbob->bpl = lbytes;
1248 xcbob->xim->width = xcbob->w;
1249 xcbob->xim->height = xcbob->h;
1250 xcbob->xim->stride = xcbob->bpl;
1251 _shmsize -= (xcbob->psize * (xcbob->xim->depth / 8));
1257 _unfind_xcbob(Xcb_Output_Buffer *xcbob, Eina_Bool sync)
1259 if (xcbob->shm_info)
1262 _shmpool = eina_list_prepend(_shmpool, xcbob);
1263 _shmsize += xcbob->psize * xcbob->xim->depth / 8;
1264 while ((_shmsize > _shmlimit) ||
1265 (eina_list_count(_shmpool) > _shmcountlimit))
1267 Eina_List *xl = NULL;
1269 if (!(xl = eina_list_last(_shmpool)))
1275 _shmpool = eina_list_remove_list(_shmpool, xl);
1276 _shmsize -= xcbob->psize * xcbob->xim->depth / 8;
1277 evas_software_xcb_output_buffer_unref(xcbob, sync);
1284 evas_software_xcb_output_buffer_unref(xcbob, sync);
1290 _clear_xcbob(Eina_Bool sync)
1295 Xcb_Output_Buffer *xcbob;
1297 xcbob = _shmpool->data;
1298 _shmpool = eina_list_remove_list(_shmpool, _shmpool);
1299 evas_software_xcb_output_buffer_unref(xcbob, sync);
1306 _xcbob_sync(xcb_connection_t *conn)
1308 free(xcb_get_input_focus_reply(conn,
1309 xcb_get_input_focus_unchecked(conn), NULL));