diff options
author | David Walter Seikel | 2013-01-13 17:29:19 +1000 |
---|---|---|
committer | David Walter Seikel | 2013-01-13 17:29:19 +1000 |
commit | 07274513e984f0b5544586c74508ccd16e7dcafa (patch) | |
tree | b32ff2a9136fbc1a4a6a0ed1e4d79cde0f5f16d9 /libraries/evas/src/modules/engines/software_x11/evas_xcb_outbuf.c | |
parent | Added Irrlicht 1.8, but without all the Windows binaries. (diff) | |
download | SledjHamr-07274513e984f0b5544586c74508ccd16e7dcafa.zip SledjHamr-07274513e984f0b5544586c74508ccd16e7dcafa.tar.gz SledjHamr-07274513e984f0b5544586c74508ccd16e7dcafa.tar.bz2 SledjHamr-07274513e984f0b5544586c74508ccd16e7dcafa.tar.xz |
Remove EFL, since it's been released now.
Diffstat (limited to 'libraries/evas/src/modules/engines/software_x11/evas_xcb_outbuf.c')
-rw-r--r-- | libraries/evas/src/modules/engines/software_x11/evas_xcb_outbuf.c | 1092 |
1 files changed, 0 insertions, 1092 deletions
diff --git a/libraries/evas/src/modules/engines/software_x11/evas_xcb_outbuf.c b/libraries/evas/src/modules/engines/software_x11/evas_xcb_outbuf.c deleted file mode 100644 index 71759be..0000000 --- a/libraries/evas/src/modules/engines/software_x11/evas_xcb_outbuf.c +++ /dev/null | |||
@@ -1,1092 +0,0 @@ | |||
1 | #include "evas_common.h" | ||
2 | #include "evas_macros.h" | ||
3 | #include "evas_xcb_outbuf.h" | ||
4 | #include "evas_xcb_buffer.h" | ||
5 | #include "evas_xcb_color.h" | ||
6 | #include <pixman.h> | ||
7 | |||
8 | /* local structures */ | ||
9 | typedef struct _Outbuf_Region Outbuf_Region; | ||
10 | struct _Outbuf_Region | ||
11 | { | ||
12 | Xcb_Output_Buffer *xcbob, *mask; | ||
13 | int x, y, w, h; | ||
14 | }; | ||
15 | |||
16 | /* local function prototypes */ | ||
17 | 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); | ||
18 | static void _unfind_xcbob(Xcb_Output_Buffer *xcbob, Eina_Bool sync); | ||
19 | static void _clear_xcbob(Eina_Bool sync); | ||
20 | static void _xcbob_sync(xcb_connection_t *conn); | ||
21 | |||
22 | /* local variables */ | ||
23 | static Eina_List *_shmpool = NULL; | ||
24 | static int _shmsize = 0; | ||
25 | static int _shmlimit = (10 * 1024 * 1024); | ||
26 | static const unsigned int _shmcountlimit = 32; | ||
27 | |||
28 | #ifdef EVAS_FRAME_QUEUING | ||
29 | static LK(lock_shmpool); | ||
30 | # define SHMPOOL_LOCK() LKL(lock_shmpool); | ||
31 | # define SHMPOOL_UNLOCK() LKU(lock_shmpool); | ||
32 | #else | ||
33 | # define SHMPOOL_LOCK() | ||
34 | # define SHMPOOL_UNLOCK() | ||
35 | #endif | ||
36 | |||
37 | void | ||
38 | evas_software_xcb_outbuf_init(void) | ||
39 | { | ||
40 | #ifdef EVAS_FRAME_QUEUING | ||
41 | LKI(lock_shmpool); | ||
42 | #endif | ||
43 | } | ||
44 | |||
45 | void | ||
46 | evas_software_xcb_outbuf_free(Outbuf *buf) | ||
47 | { | ||
48 | #ifdef EVAS_FRAME_QUEUING | ||
49 | LKL(buf->priv.lock); | ||
50 | #endif | ||
51 | while (buf->priv.pending_writes) | ||
52 | { | ||
53 | RGBA_Image *im = NULL; | ||
54 | Outbuf_Region *obr = NULL; | ||
55 | |||
56 | im = buf->priv.pending_writes->data; | ||
57 | buf->priv.pending_writes = | ||
58 | eina_list_remove_list(buf->priv.pending_writes, | ||
59 | buf->priv.pending_writes); | ||
60 | obr = im->extended_info; | ||
61 | evas_cache_image_drop(&im->cache_entry); | ||
62 | if (obr->xcbob) _unfind_xcbob(obr->xcbob, EINA_FALSE); | ||
63 | if (obr->mask) _unfind_xcbob(obr->mask, EINA_FALSE); | ||
64 | free(obr); | ||
65 | } | ||
66 | #ifdef EVAS_FRAME_QUEUING | ||
67 | LKU(buf->priv.lock); | ||
68 | #endif | ||
69 | evas_software_xcb_outbuf_idle_flush(buf); | ||
70 | evas_software_xcb_outbuf_flush(buf); | ||
71 | if (buf->priv.x11.xcb.gc) | ||
72 | xcb_free_gc(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.gc); | ||
73 | if (buf->priv.x11.xcb.gcm) | ||
74 | xcb_free_gc(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.gcm); | ||
75 | if (buf->priv.pal) | ||
76 | evas_software_xcb_color_deallocate(buf->priv.x11.xcb.conn, | ||
77 | buf->priv.x11.xcb.cmap, | ||
78 | buf->priv.x11.xcb.visual, | ||
79 | buf->priv.pal); | ||
80 | #ifdef EVAS_FRAME_QUEUING | ||
81 | LKD(buf->priv.lock); | ||
82 | #endif | ||
83 | free(buf); | ||
84 | _clear_xcbob(EINA_FALSE); | ||
85 | } | ||
86 | |||
87 | Outbuf * | ||
88 | 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) | ||
89 | { | ||
90 | Outbuf *buf = NULL; | ||
91 | Gfx_Func_Convert func_conv= NULL; | ||
92 | const xcb_setup_t *setup; | ||
93 | |||
94 | if (!(buf = calloc(1, sizeof(Outbuf)))) | ||
95 | return NULL; | ||
96 | |||
97 | setup = xcb_get_setup(conn); | ||
98 | |||
99 | buf->w = w; | ||
100 | buf->h = h; | ||
101 | buf->depth = depth; | ||
102 | buf->rot = rot; | ||
103 | buf->priv.x11.xcb.conn = conn; | ||
104 | buf->priv.x11.xcb.screen = screen; | ||
105 | buf->priv.x11.xcb.visual = vis; | ||
106 | buf->priv.x11.xcb.cmap = cmap; | ||
107 | buf->priv.x11.xcb.depth = xdepth; | ||
108 | buf->priv.mask_dither = shape_dither; | ||
109 | buf->priv.destination_alpha = alpha; | ||
110 | buf->priv.x11.xcb.shm = evas_software_xcb_can_do_shm(conn, screen); | ||
111 | |||
112 | #ifdef WORDS_BIGENDIAN | ||
113 | if (setup->image_byte_order == XCB_IMAGE_ORDER_LSB_FIRST) | ||
114 | buf->priv.x11.xcb.swap = EINA_TRUE; | ||
115 | #else | ||
116 | if (setup->image_byte_order == XCB_IMAGE_ORDER_MSB_FIRST) | ||
117 | buf->priv.x11.xcb.swap = EINA_TRUE; | ||
118 | #endif | ||
119 | if (setup->bitmap_format_bit_order == XCB_IMAGE_ORDER_MSB_FIRST) | ||
120 | buf->priv.x11.xcb.bit_swap = EINA_TRUE; | ||
121 | |||
122 | if (((vis->_class == XCB_VISUAL_CLASS_TRUE_COLOR) || | ||
123 | (vis->_class == XCB_VISUAL_CLASS_DIRECT_COLOR)) && (xdepth > 8)) | ||
124 | { | ||
125 | buf->priv.mask.r = (DATA32)vis->red_mask; | ||
126 | buf->priv.mask.g = (DATA32)vis->green_mask; | ||
127 | buf->priv.mask.b = (DATA32)vis->blue_mask; | ||
128 | if (buf->priv.x11.xcb.swap) | ||
129 | { | ||
130 | SWAP32(buf->priv.mask.r); | ||
131 | SWAP32(buf->priv.mask.g); | ||
132 | SWAP32(buf->priv.mask.b); | ||
133 | } | ||
134 | } | ||
135 | else if ((vis->_class == XCB_VISUAL_CLASS_PSEUDO_COLOR) || | ||
136 | (vis->_class == XCB_VISUAL_CLASS_STATIC_COLOR) || | ||
137 | (vis->_class == XCB_VISUAL_CLASS_GRAY_SCALE) || | ||
138 | (vis->_class == XCB_VISUAL_CLASS_STATIC_GRAY) || | ||
139 | (xdepth <= 8)) | ||
140 | { | ||
141 | Convert_Pal_Mode pm = PAL_MODE_RGB332; | ||
142 | |||
143 | if ((vis->_class == XCB_VISUAL_CLASS_GRAY_SCALE) || | ||
144 | (vis->_class == XCB_VISUAL_CLASS_STATIC_GRAY)) | ||
145 | grayscale = EINA_TRUE; | ||
146 | if (grayscale) | ||
147 | { | ||
148 | if (max_colors >= 256) | ||
149 | pm = PAL_MODE_GRAY256; | ||
150 | else if (max_colors >= 64) | ||
151 | pm = PAL_MODE_GRAY64; | ||
152 | else if (max_colors >= 16) | ||
153 | pm = PAL_MODE_GRAY16; | ||
154 | else if (max_colors >= 4) | ||
155 | pm = PAL_MODE_GRAY4; | ||
156 | else | ||
157 | pm = PAL_MODE_MONO; | ||
158 | } | ||
159 | else | ||
160 | { | ||
161 | if (max_colors >= 256) | ||
162 | pm = PAL_MODE_RGB332; | ||
163 | else if (max_colors >= 216) | ||
164 | pm = PAL_MODE_RGB666; | ||
165 | else if (max_colors >= 128) | ||
166 | pm = PAL_MODE_RGB232; | ||
167 | else if (max_colors >= 64) | ||
168 | pm = PAL_MODE_RGB222; | ||
169 | else if (max_colors >= 32) | ||
170 | pm = PAL_MODE_RGB221; | ||
171 | else if (max_colors >= 16) | ||
172 | pm = PAL_MODE_RGB121; | ||
173 | else if (max_colors >= 8) | ||
174 | pm = PAL_MODE_RGB111; | ||
175 | else if (max_colors >= 4) | ||
176 | pm = PAL_MODE_GRAY4; | ||
177 | else | ||
178 | pm = PAL_MODE_MONO; | ||
179 | } | ||
180 | /* FIXME: Only allocate once per display & colormap */ | ||
181 | buf->priv.pal = | ||
182 | evas_software_xcb_color_allocate(conn, cmap, vis, pm); | ||
183 | if (!buf->priv.pal) | ||
184 | { | ||
185 | free(buf); | ||
186 | return NULL; | ||
187 | } | ||
188 | } | ||
189 | if ((buf->rot == 0) || (buf->rot == 180)) | ||
190 | { | ||
191 | w = buf->w; | ||
192 | h = buf->h; | ||
193 | } | ||
194 | else if ((buf->rot == 90) || (buf->rot == 270)) | ||
195 | { | ||
196 | w = buf->h; | ||
197 | h = buf->w; | ||
198 | } | ||
199 | |||
200 | if (buf->priv.pal) | ||
201 | { | ||
202 | func_conv = | ||
203 | evas_common_convert_func_get(0, w, h, xdepth, | ||
204 | buf->priv.mask.r, | ||
205 | buf->priv.mask.g, | ||
206 | buf->priv.mask.b, | ||
207 | buf->priv.pal->colors, buf->rot); | ||
208 | } | ||
209 | else | ||
210 | { | ||
211 | func_conv = | ||
212 | evas_common_convert_func_get(0, w, h, xdepth, | ||
213 | buf->priv.mask.r, | ||
214 | buf->priv.mask.g, | ||
215 | buf->priv.mask.b, | ||
216 | PAL_MODE_NONE, buf->rot); | ||
217 | } | ||
218 | if (!func_conv) | ||
219 | { | ||
220 | ERR("XCB Engine" | ||
221 | " {" | ||
222 | " At depth %i:" | ||
223 | " RGB format mask: %08x, %08x, %08x" | ||
224 | " Palette mode: %i" | ||
225 | " Not supported by any compiled in converters!" | ||
226 | " }", buf->priv.x11.xcb.depth, buf->priv.mask.r, | ||
227 | buf->priv.mask.g, buf->priv.mask.b, | ||
228 | buf->priv.pal ? (int)buf->priv.pal->colors : -1); | ||
229 | } | ||
230 | |||
231 | evas_software_xcb_outbuf_drawable_set(buf, draw); | ||
232 | evas_software_xcb_outbuf_mask_set(buf, mask); | ||
233 | |||
234 | #ifdef EVAS_FRAME_QUEUING | ||
235 | LKI(buf->priv.lock); | ||
236 | #endif | ||
237 | |||
238 | return buf; | ||
239 | } | ||
240 | |||
241 | RGBA_Image * | ||
242 | 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) | ||
243 | { | ||
244 | RGBA_Image *im = NULL; | ||
245 | Outbuf_Region *obr = NULL; | ||
246 | Eina_Bool use_shm = EINA_TRUE; | ||
247 | Eina_Bool alpha = EINA_FALSE; | ||
248 | int bpl = 0; | ||
249 | |||
250 | if ((buf->onebuf) && (buf->priv.x11.xcb.shm)) | ||
251 | { | ||
252 | Eina_Rectangle *rect; | ||
253 | |||
254 | RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, buf->w, buf->h); | ||
255 | |||
256 | if (!(obr = calloc(1, sizeof(Outbuf_Region)))) | ||
257 | return NULL; | ||
258 | |||
259 | if (!(rect = eina_rectangle_new(x, y, w, h))) | ||
260 | { | ||
261 | free(obr); | ||
262 | return NULL; | ||
263 | } | ||
264 | |||
265 | buf->priv.onebuf_regions = | ||
266 | eina_list_append(buf->priv.onebuf_regions, rect); | ||
267 | if (buf->priv.onebuf) | ||
268 | { | ||
269 | if (cx) *cx = x; | ||
270 | if (cy) *cy = y; | ||
271 | if (cw) *cw = w; | ||
272 | if (ch) *ch = h; | ||
273 | if (!buf->priv.synced) | ||
274 | { | ||
275 | _xcbob_sync(buf->priv.x11.xcb.conn); | ||
276 | buf->priv.synced = EINA_TRUE; | ||
277 | } | ||
278 | return buf->priv.onebuf; | ||
279 | } | ||
280 | obr->x = 0; | ||
281 | obr->y = 0; | ||
282 | obr->w = buf->w; | ||
283 | obr->h = buf->h; | ||
284 | if (cx) *cx = x; | ||
285 | if (cy) *cy = y; | ||
286 | if (cw) *cw = w; | ||
287 | if (ch) *ch = h; | ||
288 | |||
289 | alpha = ((buf->priv.x11.xcb.mask) || (buf->priv.destination_alpha)); | ||
290 | use_shm = buf->priv.x11.xcb.shm; | ||
291 | |||
292 | if ((buf->rot == 0) && (buf->priv.mask.r == 0xff0000) && | ||
293 | (buf->priv.mask.g == 0x00ff00) && (buf->priv.mask.b == 0x0000ff)) | ||
294 | { | ||
295 | obr->xcbob = | ||
296 | evas_software_xcb_output_buffer_new(buf->priv.x11.xcb.conn, | ||
297 | buf->priv.x11.xcb.visual, | ||
298 | buf->priv.x11.xcb.depth, | ||
299 | buf->w, buf->h, use_shm, | ||
300 | NULL); | ||
301 | if (!obr->xcbob) | ||
302 | { | ||
303 | free(obr); | ||
304 | return NULL; | ||
305 | } | ||
306 | im = | ||
307 | (RGBA_Image *)evas_cache_image_data(evas_common_image_cache_get(), | ||
308 | buf->w, buf->h, | ||
309 | (DATA32 *)evas_software_xcb_output_buffer_data(obr->xcbob, &bpl), | ||
310 | alpha, EVAS_COLORSPACE_ARGB8888); | ||
311 | if (!im) | ||
312 | { | ||
313 | evas_software_xcb_output_buffer_free(obr->xcbob, EINA_FALSE); | ||
314 | free(obr); | ||
315 | return NULL; | ||
316 | } | ||
317 | im->extended_info = obr; | ||
318 | if (buf->priv.x11.xcb.mask) | ||
319 | { | ||
320 | obr->mask = | ||
321 | evas_software_xcb_output_buffer_new(buf->priv.x11.xcb.conn, | ||
322 | buf->priv.x11.xcb.visual, | ||
323 | 1, buf->w, buf->h, | ||
324 | use_shm, NULL); | ||
325 | } | ||
326 | } | ||
327 | else | ||
328 | { | ||
329 | int bw = 0, bh = 0; | ||
330 | |||
331 | im = | ||
332 | (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get()); | ||
333 | if (!im) | ||
334 | { | ||
335 | free(obr); | ||
336 | return NULL; | ||
337 | } | ||
338 | im->cache_entry.flags.alpha |= (alpha ? 1 : 0); | ||
339 | evas_cache_image_surface_alloc(&im->cache_entry, buf->w, buf->h); | ||
340 | im->extended_info = obr; | ||
341 | if ((buf->rot == 0) || (buf->rot == 180)) | ||
342 | { | ||
343 | bw = buf->w; | ||
344 | bh = buf->h; | ||
345 | } | ||
346 | else if ((buf->rot == 90) || (buf->rot == 270)) | ||
347 | { | ||
348 | bw = buf->h; | ||
349 | bh = buf->w; | ||
350 | } | ||
351 | obr->xcbob = | ||
352 | evas_software_xcb_output_buffer_new(buf->priv.x11.xcb.conn, | ||
353 | buf->priv.x11.xcb.visual, | ||
354 | buf->priv.x11.xcb.depth, | ||
355 | bw, bh, use_shm, NULL); | ||
356 | if (!obr->xcbob) | ||
357 | { | ||
358 | evas_cache_image_drop(&im->cache_entry); | ||
359 | free(obr); | ||
360 | return NULL; | ||
361 | } | ||
362 | if (buf->priv.x11.xcb.mask) | ||
363 | { | ||
364 | obr->mask = | ||
365 | evas_software_xcb_output_buffer_new(buf->priv.x11.xcb.conn, | ||
366 | buf->priv.x11.xcb.visual, | ||
367 | 1, bw, bh, use_shm, | ||
368 | NULL); | ||
369 | } | ||
370 | } | ||
371 | /* FIXME: We should be able to remove this memset. */ | ||
372 | if ((alpha) && (im->image.data)) | ||
373 | { | ||
374 | /* FIXME: Faster memset */ | ||
375 | // memset(im->image.data, 0, (w * h * sizeof(DATA32))); | ||
376 | } | ||
377 | buf->priv.onebuf = im; | ||
378 | return im; | ||
379 | } | ||
380 | |||
381 | if (!(obr = calloc(1, sizeof(Outbuf_Region)))) | ||
382 | return NULL; | ||
383 | |||
384 | obr->x = x; | ||
385 | obr->y = y; | ||
386 | obr->w = w; | ||
387 | obr->h = h; | ||
388 | if (cx) *cx = 0; | ||
389 | if (cy) *cy = 0; | ||
390 | if (cw) *cw = w; | ||
391 | if (ch) *ch = h; | ||
392 | |||
393 | use_shm = buf->priv.x11.xcb.shm; | ||
394 | alpha = ((buf->priv.x11.xcb.mask) || (buf->priv.destination_alpha)); | ||
395 | if ((buf->rot == 0) && (buf->priv.mask.r == 0xff0000) && | ||
396 | (buf->priv.mask.g == 0x00ff00) && (buf->priv.mask.b == 0x0000ff)) | ||
397 | { | ||
398 | obr->xcbob = | ||
399 | _find_xcbob(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.visual, | ||
400 | buf->priv.x11.xcb.depth, w, h, use_shm, NULL); | ||
401 | if (!obr->xcbob) | ||
402 | { | ||
403 | free(obr); | ||
404 | return NULL; | ||
405 | } | ||
406 | im = | ||
407 | (RGBA_Image *)evas_cache_image_data(evas_common_image_cache_get(), | ||
408 | w, h, | ||
409 | (DATA32 *)evas_software_xcb_output_buffer_data(obr->xcbob, &bpl), | ||
410 | alpha, EVAS_COLORSPACE_ARGB8888); | ||
411 | if (!im) | ||
412 | { | ||
413 | _unfind_xcbob(obr->xcbob, EINA_FALSE); | ||
414 | free(obr); | ||
415 | return NULL; | ||
416 | } | ||
417 | im->extended_info = obr; | ||
418 | if (buf->priv.x11.xcb.mask) | ||
419 | { | ||
420 | obr->mask = | ||
421 | _find_xcbob(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.visual, | ||
422 | 1, w, h, use_shm, NULL); | ||
423 | } | ||
424 | } | ||
425 | else | ||
426 | { | ||
427 | int bw = 0, bh = 0; | ||
428 | |||
429 | im = | ||
430 | (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get()); | ||
431 | if (!im) | ||
432 | { | ||
433 | free(obr); | ||
434 | return NULL; | ||
435 | } | ||
436 | im->cache_entry.flags.alpha |= (alpha ? 1 : 0); | ||
437 | evas_cache_image_surface_alloc(&im->cache_entry, w, h); | ||
438 | im->extended_info = obr; | ||
439 | if ((buf->rot == 0) || (buf->rot == 180)) | ||
440 | { | ||
441 | bw = w; | ||
442 | bh = h; | ||
443 | } | ||
444 | else if ((buf->rot == 90) || (buf->rot == 270)) | ||
445 | { | ||
446 | bw = h; | ||
447 | bh = w; | ||
448 | } | ||
449 | obr->xcbob = | ||
450 | _find_xcbob(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.visual, | ||
451 | buf->priv.x11.xcb.depth, bw, bh, use_shm, NULL); | ||
452 | if (!obr->xcbob) | ||
453 | { | ||
454 | evas_cache_image_drop(&im->cache_entry); | ||
455 | free(obr); | ||
456 | return NULL; | ||
457 | } | ||
458 | if (buf->priv.x11.xcb.mask) | ||
459 | { | ||
460 | obr->mask = | ||
461 | _find_xcbob(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.visual, 1, | ||
462 | bw, bh, use_shm, NULL); | ||
463 | } | ||
464 | } | ||
465 | /* FIXME: We should be able to remove this memset. */ | ||
466 | if (((buf->priv.x11.xcb.mask) || (buf->priv.destination_alpha)) && | ||
467 | (im->image.data)) | ||
468 | { | ||
469 | /* FIXME: Faster memset */ | ||
470 | // memset(im->image.data, 0, (w * h * sizeof(DATA32))); | ||
471 | } | ||
472 | |||
473 | #ifdef EVAS_FRAME_QUEUING | ||
474 | if (!evas_common_frameq_enabled()) | ||
475 | #endif | ||
476 | buf->priv.pending_writes = eina_list_append(buf->priv.pending_writes, im); | ||
477 | |||
478 | return im; | ||
479 | } | ||
480 | |||
481 | void | ||
482 | evas_software_xcb_outbuf_free_region_for_update(Outbuf *buf __UNUSED__, RGBA_Image *update __UNUSED__) | ||
483 | { | ||
484 | /* NOOP: Cleaned up on flush */ | ||
485 | } | ||
486 | |||
487 | void | ||
488 | evas_software_xcb_outbuf_flush(Outbuf *buf) | ||
489 | { | ||
490 | Eina_List *l = NULL; | ||
491 | RGBA_Image *im = NULL; | ||
492 | Outbuf_Region *obr = NULL; | ||
493 | |||
494 | if ((buf->priv.onebuf) && (buf->priv.onebuf_regions)) | ||
495 | { | ||
496 | pixman_region16_t tmpr; | ||
497 | |||
498 | im = buf->priv.onebuf; | ||
499 | obr = im->extended_info; | ||
500 | pixman_region_init(&tmpr); | ||
501 | while (buf->priv.onebuf_regions) | ||
502 | { | ||
503 | Eina_Rectangle *rect, xr = { 0, 0, 0, 0 }; | ||
504 | |||
505 | rect = buf->priv.onebuf_regions->data; | ||
506 | buf->priv.onebuf_regions = | ||
507 | eina_list_remove_list(buf->priv.onebuf_regions, | ||
508 | buf->priv.onebuf_regions); | ||
509 | if (buf->rot == 0) | ||
510 | { | ||
511 | xr.x = rect->x; | ||
512 | xr.y = rect->y; | ||
513 | xr.w = rect->w; | ||
514 | xr.h = rect->h; | ||
515 | } | ||
516 | else if (buf->rot == 90) | ||
517 | { | ||
518 | xr.x = rect->y; | ||
519 | xr.y = buf->w - rect->x - rect->w; | ||
520 | xr.w = rect->h; | ||
521 | xr.h = rect->w; | ||
522 | } | ||
523 | else if (buf->rot == 180) | ||
524 | { | ||
525 | xr.x = buf->w - rect->x - rect->w; | ||
526 | xr.y = buf->h - rect->y - rect->h; | ||
527 | xr.w = rect->w; | ||
528 | xr.h = rect->h; | ||
529 | } | ||
530 | else if (buf->rot == 270) | ||
531 | { | ||
532 | xr.x = buf->h - rect->y - rect->h; | ||
533 | xr.y = rect->x; | ||
534 | xr.w = rect->h; | ||
535 | xr.h = rect->w; | ||
536 | } | ||
537 | pixman_region_union_rect(&tmpr, &tmpr, xr.x, xr.y, xr.w, xr.h); | ||
538 | if (buf->priv.debug) | ||
539 | evas_software_xcb_outbuf_debug_show(buf, buf->priv.x11.xcb.win, | ||
540 | xr.x, xr.y, xr.w, xr.h); | ||
541 | eina_rectangle_free(rect); | ||
542 | } | ||
543 | xcb_set_clip_rectangles(buf->priv.x11.xcb.conn, | ||
544 | XCB_CLIP_ORDERING_YX_BANDED, | ||
545 | buf->priv.x11.xcb.gc, 0, 0, | ||
546 | pixman_region_n_rects(&tmpr), | ||
547 | (const xcb_rectangle_t *)pixman_region_rectangles(&tmpr, NULL)); | ||
548 | if (obr->xcbob) | ||
549 | evas_software_xcb_output_buffer_paste(obr->xcbob, | ||
550 | buf->priv.x11.xcb.win, | ||
551 | buf->priv.x11.xcb.gc, 0, 0, 0); | ||
552 | if (obr->mask) | ||
553 | { | ||
554 | xcb_set_clip_rectangles(buf->priv.x11.xcb.conn, | ||
555 | XCB_CLIP_ORDERING_YX_BANDED, | ||
556 | buf->priv.x11.xcb.gcm, 0, 0, | ||
557 | pixman_region_n_rects(&tmpr), | ||
558 | (const xcb_rectangle_t *)pixman_region_rectangles(&tmpr, NULL)); | ||
559 | evas_software_xcb_output_buffer_paste(obr->mask, | ||
560 | buf->priv.x11.xcb.mask, | ||
561 | buf->priv.x11.xcb.gcm, | ||
562 | 0, 0, 0); | ||
563 | } | ||
564 | pixman_region_fini(&tmpr); | ||
565 | buf->priv.synced = EINA_FALSE; | ||
566 | } | ||
567 | else | ||
568 | { | ||
569 | #if 1 | ||
570 | _xcbob_sync(buf->priv.x11.xcb.conn); | ||
571 | EINA_LIST_FOREACH(buf->priv.pending_writes, l, im) | ||
572 | { | ||
573 | obr = im->extended_info; | ||
574 | if (buf->priv.debug) | ||
575 | evas_software_xcb_outbuf_debug_show(buf, buf->priv.x11.xcb.win, | ||
576 | obr->x, obr->y, obr->w, obr->h); | ||
577 | if (obr->xcbob) | ||
578 | evas_software_xcb_output_buffer_paste(obr->xcbob, | ||
579 | buf->priv.x11.xcb.win, | ||
580 | buf->priv.x11.xcb.gc, | ||
581 | obr->x, obr->y, 0); | ||
582 | if (obr->mask) | ||
583 | evas_software_xcb_output_buffer_paste(obr->mask, | ||
584 | buf->priv.x11.xcb.mask, | ||
585 | buf->priv.x11.xcb.gcm, | ||
586 | obr->x, obr->y, 0); | ||
587 | } | ||
588 | # ifdef EVAS_FRAME_QUEUING | ||
589 | LKL(buf->priv.lock); | ||
590 | # endif | ||
591 | while (buf->priv.prev_pending_writes) | ||
592 | { | ||
593 | im = buf->priv.prev_pending_writes->data; | ||
594 | buf->priv.prev_pending_writes = | ||
595 | eina_list_remove_list(buf->priv.prev_pending_writes, | ||
596 | buf->priv.prev_pending_writes); | ||
597 | obr = im->extended_info; | ||
598 | evas_cache_image_drop(&im->cache_entry); | ||
599 | if (obr->xcbob) _unfind_xcbob(obr->xcbob, EINA_FALSE); | ||
600 | if (obr->mask) _unfind_xcbob(obr->mask, EINA_FALSE); | ||
601 | free(obr); | ||
602 | } | ||
603 | buf->priv.prev_pending_writes = buf->priv.pending_writes; | ||
604 | # ifdef EVAS_FRAME_QUEUING | ||
605 | LKU(buf->priv.lock); | ||
606 | # endif | ||
607 | buf->priv.pending_writes = NULL; | ||
608 | xcb_flush(buf->priv.x11.xcb.conn); | ||
609 | #else | ||
610 | /* FIXME: Async Push Disabled */ | ||
611 | |||
612 | _xcbob_sync(buf->priv.x11.xcb.conn); | ||
613 | while (buf->priv.pending_writes) | ||
614 | { | ||
615 | im = eina_list_data_get(buf->priv.pending_writes); | ||
616 | buf->priv.pending_writes = | ||
617 | eina_list_remove_list(buf->priv.pending_writes, | ||
618 | buf->priv.pending_writes); | ||
619 | obr = im->extended_info; | ||
620 | evas_cache_image_drop(&im->cache_entry); | ||
621 | if (obr->xcbob) _unfind_xcbob(obr->xcbob, EINA_FALSE); | ||
622 | if (obr->mask) _unfind_xcbob(obr->mask, EINA_FALSE); | ||
623 | free(obr); | ||
624 | evas_cache_image_drop(&im->cache_entry); | ||
625 | } | ||
626 | #endif | ||
627 | } | ||
628 | evas_common_cpu_end_opt(); | ||
629 | } | ||
630 | |||
631 | void | ||
632 | evas_software_xcb_outbuf_idle_flush(Outbuf *buf) | ||
633 | { | ||
634 | if (buf->priv.onebuf) | ||
635 | { | ||
636 | RGBA_Image *im; | ||
637 | Outbuf_Region *obr; | ||
638 | |||
639 | im = buf->priv.onebuf; | ||
640 | buf->priv.onebuf = NULL; | ||
641 | obr = im->extended_info; | ||
642 | if (obr->xcbob) | ||
643 | evas_software_xcb_output_buffer_free(obr->xcbob, EINA_FALSE); | ||
644 | if (obr->mask) | ||
645 | evas_software_xcb_output_buffer_free(obr->mask, EINA_FALSE); | ||
646 | free(obr); | ||
647 | evas_cache_image_drop(&im->cache_entry); | ||
648 | } | ||
649 | else | ||
650 | { | ||
651 | #ifdef EVAS_FRAME_QUEUING | ||
652 | LKL(buf->priv.lock); | ||
653 | #endif | ||
654 | if (buf->priv.prev_pending_writes) | ||
655 | _xcbob_sync(buf->priv.x11.xcb.conn); | ||
656 | while (buf->priv.prev_pending_writes) | ||
657 | { | ||
658 | RGBA_Image *im; | ||
659 | Outbuf_Region *obr; | ||
660 | |||
661 | im = buf->priv.prev_pending_writes->data; | ||
662 | buf->priv.prev_pending_writes = | ||
663 | eina_list_remove_list(buf->priv.prev_pending_writes, | ||
664 | buf->priv.prev_pending_writes); | ||
665 | obr = im->extended_info; | ||
666 | evas_cache_image_drop(&im->cache_entry); | ||
667 | if (obr->xcbob) _unfind_xcbob(obr->xcbob, EINA_FALSE); | ||
668 | if (obr->mask) _unfind_xcbob(obr->mask, EINA_FALSE); | ||
669 | free(obr); | ||
670 | } | ||
671 | #ifdef EVAS_FRAME_QUEUING | ||
672 | LKU(buf->priv.lock); | ||
673 | #endif | ||
674 | _clear_xcbob(EINA_FALSE); | ||
675 | } | ||
676 | } | ||
677 | |||
678 | void | ||
679 | evas_software_xcb_outbuf_push_updated_region(Outbuf *buf, RGBA_Image *update, int x, int y, int w, int h) | ||
680 | { | ||
681 | Gfx_Func_Convert func_conv = NULL; | ||
682 | Outbuf_Region *obr = NULL; | ||
683 | DATA32 *src_data = NULL; | ||
684 | unsigned char *data = NULL; | ||
685 | int bpl = 0, yy = 0; | ||
686 | int bw = 0, bh = 0; | ||
687 | |||
688 | obr = update->extended_info; | ||
689 | if (!obr->xcbob) return; | ||
690 | |||
691 | if ((buf->rot == 0) || (buf->rot == 180)) | ||
692 | { | ||
693 | bw = w; | ||
694 | bh = h; | ||
695 | } | ||
696 | else if ((buf->rot == 90) || (buf->rot == 270)) | ||
697 | { | ||
698 | bw = h; | ||
699 | bh = w; | ||
700 | } | ||
701 | if (buf->priv.pal) | ||
702 | { | ||
703 | func_conv = | ||
704 | evas_common_convert_func_get(0, bw, bh, buf->depth, buf->priv.mask.r, | ||
705 | buf->priv.mask.g, buf->priv.mask.b, | ||
706 | buf->priv.pal->colors, buf->rot); | ||
707 | } | ||
708 | else | ||
709 | { | ||
710 | func_conv = | ||
711 | evas_common_convert_func_get(0, bw, bh, buf->depth, buf->priv.mask.r, | ||
712 | buf->priv.mask.g, buf->priv.mask.b, | ||
713 | PAL_MODE_NONE, buf->rot); | ||
714 | } | ||
715 | if (!func_conv) return; | ||
716 | |||
717 | if (!(data = evas_software_xcb_output_buffer_data(obr->xcbob, &bpl))) | ||
718 | return; | ||
719 | if (!(src_data = update->image.data)) return; | ||
720 | if (buf->rot == 0) | ||
721 | { | ||
722 | obr->x = x; | ||
723 | obr->y = y; | ||
724 | obr->w = w; | ||
725 | obr->h = h; | ||
726 | } | ||
727 | else if (buf->rot == 90) | ||
728 | { | ||
729 | obr->x = y; | ||
730 | obr->y = (buf->w - x - w); | ||
731 | obr->w = h; | ||
732 | obr->h = w; | ||
733 | } | ||
734 | else if (buf->rot == 180) | ||
735 | { | ||
736 | obr->x = (buf->w - x - w); | ||
737 | obr->y = (buf->h - y - h); | ||
738 | obr->w = w; | ||
739 | obr->h = h; | ||
740 | } | ||
741 | else if (buf->rot == 270) | ||
742 | { | ||
743 | obr->x = (buf->h - y - h); | ||
744 | obr->y = x; | ||
745 | obr->w = h; | ||
746 | obr->h = w; | ||
747 | } | ||
748 | if (buf->onebuf) | ||
749 | { | ||
750 | src_data += x + (y * update->cache_entry.w); | ||
751 | data += (bpl * obr->y) + (obr->x * (buf->depth / 8)); | ||
752 | } | ||
753 | if (data != (unsigned char *)src_data) | ||
754 | { | ||
755 | if (buf->priv.pal) | ||
756 | func_conv(src_data, data, update->cache_entry.w - w, | ||
757 | (bpl / (buf->depth / 8)) - obr->w, | ||
758 | obr->w, obr->h, x, y, buf->priv.pal->lookup); | ||
759 | else | ||
760 | func_conv(src_data, data, update->cache_entry.w - w, | ||
761 | (bpl / (buf->depth / 8)) - obr->w, | ||
762 | obr->w, obr->h, x, y, NULL); | ||
763 | } | ||
764 | #if 1 | ||
765 | #else | ||
766 | /* Async Push */ | ||
767 | if (!((buf->priv.onebuf) && (buf->priv.onebuf_regions))) | ||
768 | { | ||
769 | if (buf->priv.debug) | ||
770 | evas_software_xcb_outbuf_debug_show(buf, buf->priv.x11.xcb.win, | ||
771 | obr->x, obr->y, obr->w, obr->h); | ||
772 | if (obr->xcbob) | ||
773 | evas_software_xcb_output_buffer_paste(obr->xcbob, | ||
774 | buf->priv.x11.xcb.win, | ||
775 | buf->priv.x11.xcb.gc, | ||
776 | obr->x, obr->y, 0); | ||
777 | } | ||
778 | #endif | ||
779 | if (obr->mask) | ||
780 | { | ||
781 | if (buf->rot == 0) | ||
782 | { | ||
783 | for (yy = 0; yy < obr->h; yy++) | ||
784 | evas_software_xcb_write_mask_line(buf, obr->mask, | ||
785 | src_data + (yy * obr->w), | ||
786 | obr->w, yy); | ||
787 | } | ||
788 | else if (buf->rot == 90) | ||
789 | { | ||
790 | for (yy = 0; yy < obr->h; yy++) | ||
791 | evas_software_xcb_write_mask_line_vert(buf, obr->mask, | ||
792 | src_data + yy, | ||
793 | h, (obr->h - yy - 1), w); | ||
794 | } | ||
795 | else if (buf->rot == 180) | ||
796 | { | ||
797 | for (yy = 0; yy < obr->h; yy++) | ||
798 | evas_software_xcb_write_mask_line_rev(buf, obr->mask, | ||
799 | src_data + (yy * obr->w), | ||
800 | obr->w, (obr->h - yy - 1)); | ||
801 | } | ||
802 | else if (buf->rot == 270) | ||
803 | { | ||
804 | for (yy = 0; yy < obr->h; yy++) | ||
805 | evas_software_xcb_write_mask_line_vert_rev(buf, obr->mask, | ||
806 | src_data + yy, | ||
807 | h, yy, w); | ||
808 | } | ||
809 | #if 1 | ||
810 | #else | ||
811 | /* Async Push */ | ||
812 | if (!((buf->priv.onebuf) && (buf->priv.onebuf_regions))) | ||
813 | evas_software_xcb_output_buffer_paste(obr->mask, | ||
814 | buf->priv.x11.xcb.mask, | ||
815 | buf->priv.x11.xcb.gcm, | ||
816 | obr->x, obr->y, 0); | ||
817 | #endif | ||
818 | } | ||
819 | #if 1 | ||
820 | #else | ||
821 | xcb_flush(buf->priv.x11.xcb.conn); | ||
822 | #endif | ||
823 | } | ||
824 | |||
825 | void | ||
826 | evas_software_xcb_outbuf_reconfigure(Outbuf *buf, int w, int h, int rot, Outbuf_Depth depth) | ||
827 | { | ||
828 | if ((w == buf->w) && (h == buf->h) && (rot == buf->rot) && | ||
829 | (depth == buf->depth)) return; | ||
830 | buf->w = w; | ||
831 | buf->h = h; | ||
832 | buf->rot = rot; | ||
833 | evas_software_xcb_outbuf_idle_flush(buf); | ||
834 | } | ||
835 | |||
836 | int | ||
837 | evas_software_xcb_outbuf_width_get(Outbuf *buf) | ||
838 | { | ||
839 | return buf->w; | ||
840 | } | ||
841 | |||
842 | int | ||
843 | evas_software_xcb_outbuf_height_get(Outbuf *buf) | ||
844 | { | ||
845 | return buf->h; | ||
846 | } | ||
847 | |||
848 | Outbuf_Depth | ||
849 | evas_software_xcb_outbuf_depth_get(Outbuf *buf) | ||
850 | { | ||
851 | return buf->depth; | ||
852 | } | ||
853 | |||
854 | void | ||
855 | evas_software_xcb_outbuf_drawable_set(Outbuf *buf, xcb_drawable_t drawable) | ||
856 | { | ||
857 | if (buf->priv.x11.xcb.win == drawable) return; | ||
858 | if (buf->priv.x11.xcb.gc) | ||
859 | { | ||
860 | xcb_free_gc(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.gc); | ||
861 | buf->priv.x11.xcb.gc = 0; | ||
862 | } | ||
863 | buf->priv.x11.xcb.win = drawable; | ||
864 | buf->priv.x11.xcb.gc = xcb_generate_id(buf->priv.x11.xcb.conn); | ||
865 | xcb_create_gc(buf->priv.x11.xcb.conn, | ||
866 | buf->priv.x11.xcb.gc, buf->priv.x11.xcb.win, 0, NULL); | ||
867 | } | ||
868 | |||
869 | void | ||
870 | evas_software_xcb_outbuf_mask_set(Outbuf *buf, xcb_drawable_t mask) | ||
871 | { | ||
872 | if (buf->priv.x11.xcb.mask == mask) return; | ||
873 | if (buf->priv.x11.xcb.gcm) | ||
874 | { | ||
875 | xcb_free_gc(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.gcm); | ||
876 | buf->priv.x11.xcb.gcm = 0; | ||
877 | } | ||
878 | buf->priv.x11.xcb.mask = mask; | ||
879 | if (buf->priv.x11.xcb.mask) | ||
880 | { | ||
881 | buf->priv.x11.xcb.gcm = xcb_generate_id(buf->priv.x11.xcb.conn); | ||
882 | xcb_create_gc(buf->priv.x11.xcb.conn, | ||
883 | buf->priv.x11.xcb.gcm, buf->priv.x11.xcb.mask, 0, NULL); | ||
884 | } | ||
885 | } | ||
886 | |||
887 | int | ||
888 | evas_software_xcb_outbuf_rotation_get(Outbuf *buf) | ||
889 | { | ||
890 | return buf->rot; | ||
891 | } | ||
892 | |||
893 | void | ||
894 | evas_software_xcb_outbuf_rotation_set(Outbuf *buf, int rotation) | ||
895 | { | ||
896 | buf->rot = rotation; | ||
897 | } | ||
898 | |||
899 | Eina_Bool | ||
900 | evas_software_xcb_outbuf_alpha_get(Outbuf *buf) | ||
901 | { | ||
902 | return buf->priv.x11.xcb.mask; | ||
903 | } | ||
904 | |||
905 | void | ||
906 | evas_software_xcb_outbuf_debug_set(Outbuf *buf, Eina_Bool debug) | ||
907 | { | ||
908 | buf->priv.debug = debug; | ||
909 | } | ||
910 | |||
911 | void | ||
912 | evas_software_xcb_outbuf_debug_show(Outbuf *buf, xcb_drawable_t drawable, int x, int y, int w, int h) | ||
913 | { | ||
914 | int i; | ||
915 | xcb_screen_t *screen = NULL; | ||
916 | xcb_get_geometry_reply_t *geom; | ||
917 | xcb_drawable_t root; | ||
918 | xcb_screen_iterator_t si; | ||
919 | |||
920 | geom = | ||
921 | xcb_get_geometry_reply(buf->priv.x11.xcb.conn, | ||
922 | xcb_get_geometry_unchecked(buf->priv.x11.xcb.conn, | ||
923 | drawable), 0); | ||
924 | root = geom->root; | ||
925 | free(geom); | ||
926 | geom = | ||
927 | xcb_get_geometry_reply(buf->priv.x11.xcb.conn, | ||
928 | xcb_get_geometry_unchecked(buf->priv.x11.xcb.conn, | ||
929 | root), 0); | ||
930 | |||
931 | si = xcb_setup_roots_iterator((xcb_setup_t *)xcb_get_setup(buf->priv.x11.xcb.conn)); | ||
932 | for (; si.rem; xcb_screen_next(&si)) | ||
933 | { | ||
934 | if (si.data->root == geom->root) | ||
935 | { | ||
936 | screen = si.data; | ||
937 | break; | ||
938 | } | ||
939 | } | ||
940 | free(geom); | ||
941 | |||
942 | for (i = 0; i < 20; i++) | ||
943 | { | ||
944 | xcb_rectangle_t rect = { x, y, w, h}; | ||
945 | uint32_t mask; | ||
946 | uint32_t value[2]; | ||
947 | |||
948 | mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES; | ||
949 | value[0] = screen->black_pixel; | ||
950 | value[1] = XCB_EXPOSURES_NOT_ALLOWED; | ||
951 | xcb_change_gc(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.gc, | ||
952 | mask, value); | ||
953 | xcb_poly_fill_rectangle(buf->priv.x11.xcb.conn, drawable, | ||
954 | buf->priv.x11.xcb.gc, 1, &rect); | ||
955 | _xcbob_sync(buf->priv.x11.xcb.conn); | ||
956 | _xcbob_sync(buf->priv.x11.xcb.conn); | ||
957 | |||
958 | mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES; | ||
959 | value[0] = screen->white_pixel; | ||
960 | value[1] = XCB_EXPOSURES_NOT_ALLOWED; | ||
961 | xcb_change_gc(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.gc, | ||
962 | mask, value); | ||
963 | xcb_poly_fill_rectangle(buf->priv.x11.xcb.conn, drawable, | ||
964 | buf->priv.x11.xcb.gc, 1, &rect); | ||
965 | _xcbob_sync(buf->priv.x11.xcb.conn); | ||
966 | _xcbob_sync(buf->priv.x11.xcb.conn); | ||
967 | } | ||
968 | } | ||
969 | |||
970 | #ifdef EVAS_FRAME_QUEUING | ||
971 | void | ||
972 | evas_software_xcb_outbuf_priv_set(Outbuf *buf, void *cur, void *prev __UNUSED__) | ||
973 | { | ||
974 | buf->priv.pending_writes = (Eina_List *)cur; | ||
975 | } | ||
976 | #endif | ||
977 | |||
978 | /* local functions */ | ||
979 | static Xcb_Output_Buffer * | ||
980 | _find_xcbob(xcb_connection_t *conn, xcb_visualtype_t *vis, int depth, int w, int h, Eina_Bool shm, void *data) | ||
981 | { | ||
982 | Eina_List *l = NULL, *xl = NULL; | ||
983 | Xcb_Output_Buffer *xcbob = NULL, *xcbob2 = NULL; | ||
984 | int lbytes = 0, bpp = 0, sz = 0; | ||
985 | int fitness = 0x7fffffff; | ||
986 | |||
987 | if (!shm) | ||
988 | return evas_software_xcb_output_buffer_new(conn, vis, depth, w, h, | ||
989 | shm, data); | ||
990 | |||
991 | lbytes = (((w + 31) / 32) * 4); | ||
992 | if (depth > 1) | ||
993 | { | ||
994 | bpp = (depth / 8); | ||
995 | if (bpp == 3) bpp = 4; | ||
996 | lbytes = ((((w * bpp) + 3) / 4) * 4); | ||
997 | } | ||
998 | |||
999 | sz = (lbytes * h); | ||
1000 | SHMPOOL_LOCK(); | ||
1001 | EINA_LIST_FOREACH(_shmpool, l, xcbob2) | ||
1002 | { | ||
1003 | int szdif = 0; | ||
1004 | |||
1005 | if ((xcbob2->xim->depth != depth) || (xcbob2->visual != vis) || | ||
1006 | (xcbob2->connection != conn)) continue; | ||
1007 | szdif = (xcbob2->psize - sz); | ||
1008 | if (szdif < 0) continue; | ||
1009 | if (szdif == 0) | ||
1010 | { | ||
1011 | xcbob = xcbob2; | ||
1012 | xl = l; | ||
1013 | goto have_xcbob; | ||
1014 | } | ||
1015 | if (szdif < fitness) | ||
1016 | { | ||
1017 | xcbob = xcbob2; | ||
1018 | xl = l; | ||
1019 | fitness = szdif; | ||
1020 | } | ||
1021 | } | ||
1022 | if ((fitness > (100 * 100)) || (!xcbob)) | ||
1023 | { | ||
1024 | SHMPOOL_UNLOCK(); | ||
1025 | return evas_software_xcb_output_buffer_new(conn, vis, depth, | ||
1026 | w, h, shm, data); | ||
1027 | } | ||
1028 | |||
1029 | have_xcbob: | ||
1030 | _shmpool = eina_list_remove_list(_shmpool, xl); | ||
1031 | xcbob->w = w; | ||
1032 | xcbob->h = h; | ||
1033 | xcbob->bpl = lbytes; | ||
1034 | xcbob->xim->width = xcbob->w; | ||
1035 | xcbob->xim->height = xcbob->h; | ||
1036 | xcbob->xim->stride = xcbob->bpl; | ||
1037 | _shmsize -= (xcbob->psize * (xcbob->xim->depth / 8)); | ||
1038 | SHMPOOL_UNLOCK(); | ||
1039 | return xcbob; | ||
1040 | } | ||
1041 | |||
1042 | static void | ||
1043 | _unfind_xcbob(Xcb_Output_Buffer *xcbob, Eina_Bool sync) | ||
1044 | { | ||
1045 | if (xcbob->shm_info) | ||
1046 | { | ||
1047 | SHMPOOL_LOCK(); | ||
1048 | _shmpool = eina_list_prepend(_shmpool, xcbob); | ||
1049 | _shmsize += xcbob->psize * xcbob->xim->depth / 8; | ||
1050 | while ((_shmsize > _shmlimit) || | ||
1051 | (eina_list_count(_shmpool) > _shmcountlimit)) | ||
1052 | { | ||
1053 | Eina_List *xl = NULL; | ||
1054 | |||
1055 | if (!(xl = eina_list_last(_shmpool))) | ||
1056 | { | ||
1057 | _shmsize = 0; | ||
1058 | break; | ||
1059 | } | ||
1060 | xcbob = xl->data; | ||
1061 | _shmpool = eina_list_remove_list(_shmpool, xl); | ||
1062 | _shmsize -= xcbob->psize * xcbob->xim->depth / 8; | ||
1063 | evas_software_xcb_output_buffer_free(xcbob, sync); | ||
1064 | } | ||
1065 | SHMPOOL_UNLOCK(); | ||
1066 | } | ||
1067 | else | ||
1068 | evas_software_xcb_output_buffer_free(xcbob, sync); | ||
1069 | } | ||
1070 | |||
1071 | static void | ||
1072 | _clear_xcbob(Eina_Bool sync) | ||
1073 | { | ||
1074 | SHMPOOL_LOCK(); | ||
1075 | while (_shmpool) | ||
1076 | { | ||
1077 | Xcb_Output_Buffer *xcbob; | ||
1078 | |||
1079 | xcbob = _shmpool->data; | ||
1080 | _shmpool = eina_list_remove_list(_shmpool, _shmpool); | ||
1081 | evas_software_xcb_output_buffer_free(xcbob, sync); | ||
1082 | } | ||
1083 | _shmsize = 0; | ||
1084 | SHMPOOL_UNLOCK(); | ||
1085 | } | ||
1086 | |||
1087 | static void | ||
1088 | _xcbob_sync(xcb_connection_t *conn) | ||
1089 | { | ||
1090 | free(xcb_get_input_focus_reply(conn, | ||
1091 | xcb_get_input_focus_unchecked(conn), NULL)); | ||
1092 | } | ||