aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/evas/src/modules/engines/software_x11/evas_engine.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/evas/src/modules/engines/software_x11/evas_engine.c')
-rw-r--r--libraries/evas/src/modules/engines/software_x11/evas_engine.c929
1 files changed, 929 insertions, 0 deletions
diff --git a/libraries/evas/src/modules/engines/software_x11/evas_engine.c b/libraries/evas/src/modules/engines/software_x11/evas_engine.c
new file mode 100644
index 0000000..0a2d2a3
--- /dev/null
+++ b/libraries/evas/src/modules/engines/software_x11/evas_engine.c
@@ -0,0 +1,929 @@
1#include "evas_common.h"
2#include "evas_private.h"
3
4#include "Evas_Engine_Software_X11.h"
5#include "evas_engine.h"
6
7#ifdef BUILD_ENGINE_SOFTWARE_XLIB
8# include "evas_xlib_outbuf.h"
9# include "evas_xlib_color.h"
10#endif
11
12#ifdef BUILD_ENGINE_SOFTWARE_XCB
13# include "evas_xcb_outbuf.h"
14# include "evas_xcb_color.h"
15# include "evas_xcb_xdefaults.h"
16#endif
17
18int _evas_engine_soft_x11_log_dom = -1;
19
20/* function tables - filled in later (func and parent func) */
21static Evas_Func func, pfunc;
22
23#ifdef BUILD_ENGINE_SOFTWARE_XLIB
24/*
25struct xrdb_user
26{
27 time_t last_stat;
28 time_t last_mtime;
29 XrmDatabase db;
30};
31static struct xrdb_user xrdb_user = {0, 0, NULL};
32
33static Eina_Bool
34xrdb_user_query(const char *name, const char *cls, char **type, XrmValue *val)
35{
36 time_t last, now;
37
38 last = xrdb_user.last_stat;
39 now = time(NULL);
40
41 xrdb_user.last_stat = now;
42 if (last != now) // don't stat() more than once every second
43 {
44 struct stat st;
45 const char *home;
46 char tmp[PATH_MAX];
47
48 if (!(home = getenv("HOME")))
49 goto failed;
50
51 snprintf(tmp, sizeof(tmp), "%s/.Xdefaults", home);
52 if (stat(tmp, &st) != 0) goto failed;
53 if (xrdb_user.last_mtime != st.st_mtime)
54 {
55 if (xrdb_user.db) XrmDestroyDatabase(xrdb_user.db);
56 xrdb_user.db = XrmGetFileDatabase(tmp);
57 if (!xrdb_user.db) goto failed;
58 xrdb_user.last_mtime = st.st_mtime;
59 }
60 }
61
62 if (!xrdb_user.db) return EINA_FALSE;
63 return XrmGetResource(xrdb_user.db, name, cls, type, val);
64
65 failed:
66 if (xrdb_user.db)
67 {
68 XrmDestroyDatabase(xrdb_user.db);
69 xrdb_user.db = NULL;
70 }
71 xrdb_user.last_mtime = 0;
72 return EINA_FALSE;
73}
74*/
75#endif
76
77/* engine struct data */
78typedef struct _Render_Engine Render_Engine;
79
80struct _Render_Engine
81{
82 Tilebuf *tb;
83 Outbuf *ob;
84 Tilebuf_Rect *rects;
85 Eina_Inlist *cur_rect;
86 unsigned char end : 1;
87/*
88#ifdef BUILD_ENGINE_SOFTWARE_XLIB
89 XrmDatabase xrdb;
90#endif
91 struct
92 {
93 int dpi;
94 } xr;
95 */
96#ifdef EVAS_FRAME_QUEUING
97 Evas_Engine_Render_Mode render_mode;
98#endif
99
100 void (*outbuf_free)(Outbuf *ob);
101 void (*outbuf_reconfigure)(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth);
102 int (*outbuf_get_rot)(Outbuf *ob);
103 RGBA_Image *(*outbuf_new_region_for_update)(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch);
104 void (*outbuf_push_updated_region)(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h);
105 void (*outbuf_free_region_for_update)(Outbuf *ob, RGBA_Image *update);
106 void (*outbuf_flush)(Outbuf *ob);
107 void (*outbuf_idle_flush)(Outbuf *ob);
108 Eina_Bool (*outbuf_alpha_get)(Outbuf *ob);
109#ifdef EVAS_FRAME_QUEUING
110 void (*outbuf_set_priv)(Outbuf *ob, void *cur, void *prev);
111#endif
112};
113
114/* prototypes we will use here */
115static void *_best_visual_get(int backend, void *connection, int screen);
116static unsigned int _best_colormap_get(int backend, void *connection, int screen);
117static int _best_depth_get(int backend, void *connection, int screen);
118
119static void *eng_info(Evas *e);
120static void eng_info_free(Evas *e, void *info);
121static int eng_setup(Evas *e, void *info);
122static void eng_output_free(void *data);
123static void eng_output_resize(void *data, int w, int h);
124static void eng_output_tile_size_set(void *data, int w, int h);
125static void eng_output_redraws_rect_add(void *data, int x, int y, int w, int h);
126static void eng_output_redraws_rect_del(void *data, int x, int y, int w, int h);
127static void eng_output_redraws_clear(void *data);
128static void *eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch);
129static void eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h);
130static void eng_output_flush(void *data);
131static void eng_output_idle_flush(void *data);
132
133/* internal engine routines */
134
135#ifdef BUILD_ENGINE_SOFTWARE_XLIB
136static void *
137_output_xlib_setup(int w, int h, int rot, Display *disp, Drawable draw,
138 Visual *vis, Colormap cmap, int depth, int debug,
139 int grayscale, int max_colors, Pixmap mask,
140 int shape_dither, int destination_alpha)
141{
142 Render_Engine *re;
143// int status;
144// char *type = NULL;
145// XrmValue val;
146
147 if (!(re = calloc(1, sizeof(Render_Engine)))) return NULL;
148
149 evas_software_xlib_x_init();
150 evas_software_xlib_x_color_init();
151 evas_software_xlib_outbuf_init();
152/*
153 re->xr.dpi = 75000; // dpy * 1000
154
155 status = xrdb_user_query("Xft.dpi", "Xft.Dpi", &type, &val);
156 if ((!status) || (!type))
157 {
158 if (!re->xrdb) re->xrdb = XrmGetDatabase(disp);
159 if (re->xrdb)
160 status = XrmGetResource(re->xrdb,
161 "Xft.dpi", "Xft.Dpi", &type, &val);
162 }
163
164 if ((status) && (type))
165 {
166 if (!strcmp(type, "String"))
167 {
168 const char *str, *dp;
169
170 str = val.addr;
171 dp = strchr(str, '.');
172 if (!dp) dp = strchr(str, ',');
173
174 if (dp)
175 {
176 int subdpi, len, i;
177 char *buf;
178
179 buf = alloca(dp - str + 1);
180 strncpy(buf, str, dp - str);
181 buf[dp - str] = 0;
182 len = strlen(dp + 1);
183 subdpi = atoi(dp + 1);
184
185 if (len < 3)
186 {
187 for (i = len; i < 3; i++)
188 subdpi *= 10;
189 }
190 else if (len > 3)
191 {
192 for (i = len; i > 3; i--)
193 subdpi /= 10;
194 }
195 re->xr.dpi = atoi(buf) * 1000;
196 }
197 else
198 re->xr.dpi = atoi(str) * 1000;
199 evas_common_font_dpi_set(re->xr.dpi / 1000);
200 }
201 }
202 */
203 re->ob =
204 evas_software_xlib_outbuf_setup_x(w, h, rot, OUTBUF_DEPTH_INHERIT, disp,
205 draw, vis, cmap, depth, grayscale,
206 max_colors, mask, shape_dither,
207 destination_alpha);
208 if (!re->ob)
209 {
210 free(re);
211 return NULL;
212 }
213
214 /* for updates return 1 big buffer, but only use portions of it, also cache
215 * it and keepit around until an idle_flush */
216
217 /* disable for now - i am hunting down why some expedite tests are slower,
218 * as well as shaped stuff is broken and probable non-32bpp is broken as
219 * convert funcs dont do the right thing
220 *
221 */
222// re->ob->onebuf = 1;
223
224 evas_software_xlib_outbuf_debug_set(re->ob, debug);
225 re->tb = evas_common_tilebuf_new(w, h);
226 if (!re->tb)
227 {
228 evas_software_xlib_outbuf_free(re->ob);
229 free(re);
230 return NULL;
231 }
232
233 /* in preliminary tests 16x16 gave highest framerates */
234 evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
235 return re;
236}
237#endif
238
239#ifdef BUILD_ENGINE_SOFTWARE_XCB
240static void *
241_output_xcb_setup(int w, int h, int rot, xcb_connection_t *conn,
242 xcb_screen_t *screen, xcb_drawable_t draw,
243 xcb_visualtype_t *vis, xcb_colormap_t cmap, int depth,
244 int debug, int grayscale, int max_colors, xcb_drawable_t mask,
245 int shape_dither, int destination_alpha)
246{
247 Render_Engine *re;
248// int v = 0;
249
250 if (!(re = calloc(1, sizeof(Render_Engine)))) return NULL;
251
252 evas_software_xcb_init();
253 evas_software_xcb_color_init();
254 evas_software_xcb_outbuf_init();
255/*
256 // FIXME: re->xrdb
257 _evas_xcb_xdefaults_init();
258 v = _evas_xcb_xdefaults_int_get("Xft", "dpi");
259 _evas_xcb_xdefaults_shutdown();
260 if (v) re->xr.dpi = (v * 1000);
261 else re->xr.dpi = 75000; // dpy * 1000
262
263 evas_common_font_dpi_set(re->xr.dpi / 1000);
264 */
265 re->ob =
266 evas_software_xcb_outbuf_setup(w, h, rot, OUTBUF_DEPTH_INHERIT, conn,
267 screen, draw, vis, cmap, depth,
268 grayscale, max_colors, mask,
269 shape_dither, destination_alpha);
270 if (!re->ob)
271 {
272 free(re);
273 return NULL;
274 }
275
276 /* for updates return 1 big buffer, but only use portions of it, also cache
277 * it and keepit around until an idle_flush */
278
279 /* disable for now - i am hunting down why some expedite tests are slower,
280 * as well as shaped stuff is broken and probable non-32bpp is broken as
281 * convert funcs dont do the right thing
282 *
283 */
284// re->ob->onebuf = 1;
285
286 evas_software_xcb_outbuf_debug_set(re->ob, debug);
287
288 re->tb = evas_common_tilebuf_new(w, h);
289 if (!re->tb)
290 {
291 evas_software_xcb_outbuf_free(re->ob);
292 free(re);
293 return NULL;
294 }
295
296 /* in preliminary tests 16x16 gave highest framerates */
297 evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
298 return re;
299}
300#endif
301
302static void *
303_best_visual_get(int backend, void *connection, int screen)
304{
305 if (!connection) return NULL;
306
307#ifdef BUILD_ENGINE_SOFTWARE_XLIB
308 if (backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XLIB)
309 return DefaultVisual((Display *)connection, screen);
310#endif
311
312#ifdef BUILD_ENGINE_SOFTWARE_XCB
313 if (backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XCB)
314 {
315 xcb_screen_iterator_t iter_screen;
316 xcb_depth_iterator_t iter_depth;
317 xcb_screen_t *s = NULL;
318
319 iter_screen =
320 xcb_setup_roots_iterator(xcb_get_setup((xcb_connection_t *)connection));
321 for (; iter_screen.rem; --screen, xcb_screen_next(&iter_screen))
322 if (screen == 0)
323 {
324 s = iter_screen.data;
325 break;
326 }
327
328 iter_depth = xcb_screen_allowed_depths_iterator(s);
329 for (; iter_depth.rem; xcb_depth_next(&iter_depth))
330 {
331 xcb_visualtype_iterator_t iter_vis;
332
333 iter_vis = xcb_depth_visuals_iterator(iter_depth.data);
334 for (; iter_vis.rem; xcb_visualtype_next(&iter_vis))
335 {
336 if (s->root_visual == iter_vis.data->visual_id)
337 return iter_vis.data;
338 }
339 }
340 }
341#endif
342
343 return NULL;
344}
345
346static unsigned int
347_best_colormap_get(int backend, void *connection, int screen)
348{
349 if (!connection) return 0;
350
351#ifdef BUILD_ENGINE_SOFTWARE_XLIB
352 if (backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XLIB)
353 return DefaultColormap((Display *)connection, screen);
354#endif
355
356#ifdef BUILD_ENGINE_SOFTWARE_XCB
357 if (backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XCB)
358 {
359 xcb_screen_iterator_t iter_screen;
360 xcb_screen_t *s = NULL;
361
362 iter_screen =
363 xcb_setup_roots_iterator(xcb_get_setup((xcb_connection_t *)connection));
364 for (; iter_screen.rem; --screen, xcb_screen_next(&iter_screen))
365 if (screen == 0)
366 {
367 s = iter_screen.data;
368 break;
369 }
370
371 return s->default_colormap;
372 }
373#endif
374
375 return 0;
376}
377
378static int
379_best_depth_get(int backend, void *connection, int screen)
380{
381 if (!connection) return 0;
382
383#ifdef BUILD_ENGINE_SOFTWARE_XLIB
384 if (backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XLIB)
385 return DefaultDepth((Display *)connection, screen);
386#endif
387
388#ifdef BUILD_ENGINE_SOFTWARE_XCB
389 if (backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XCB)
390 {
391 xcb_screen_iterator_t iter_screen;
392 xcb_screen_t *s = NULL;
393
394 iter_screen =
395 xcb_setup_roots_iterator(xcb_get_setup((xcb_connection_t *)connection));
396 for (; iter_screen.rem; --screen, xcb_screen_next(&iter_screen))
397 if (screen == 0)
398 {
399 s = iter_screen.data;
400 break;
401 }
402
403 return s->root_depth;
404 }
405#endif
406
407 return 0;
408}
409
410/* engine api this module provides */
411static void *
412eng_info(Evas *e __UNUSED__)
413{
414 Evas_Engine_Info_Software_X11 *info;
415
416 if (!(info = calloc(1, sizeof(Evas_Engine_Info_Software_X11))))
417 return NULL;
418
419 info->magic.magic = rand();
420 info->info.debug = 0;
421 info->info.alloc_grayscale = 0;
422 info->info.alloc_colors_max = 216;
423 info->func.best_visual_get = _best_visual_get;
424 info->func.best_colormap_get = _best_colormap_get;
425 info->func.best_depth_get = _best_depth_get;
426 info->render_mode = EVAS_RENDER_MODE_BLOCKING;
427 return info;
428}
429
430static void
431eng_info_free(Evas *e __UNUSED__, void *info)
432{
433 Evas_Engine_Info_Software_X11 *in;
434
435 in = (Evas_Engine_Info_Software_X11 *)info;
436 free(in);
437}
438
439static int
440eng_setup(Evas *e, void *in)
441{
442 Evas_Engine_Info_Software_X11 *info;
443 Render_Engine *re = NULL;
444
445 info = (Evas_Engine_Info_Software_X11 *)in;
446 if (!e->engine.data.output)
447 {
448 /* if we haven't initialized - init (automatic abort if already done) */
449 evas_common_cpu_init();
450 evas_common_blend_init();
451 evas_common_image_init();
452 evas_common_convert_init();
453 evas_common_scale_init();
454 evas_common_rectangle_init();
455 evas_common_polygon_init();
456 evas_common_line_init();
457 evas_common_font_init();
458 evas_common_draw_init();
459 evas_common_tilebuf_init();
460
461#ifdef BUILD_ENGINE_SOFTWARE_XLIB
462 if (info->info.backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XLIB)
463 {
464 re = _output_xlib_setup(e->output.w, e->output.h,
465 info->info.rotation, info->info.connection,
466 info->info.drawable, info->info.visual,
467 info->info.colormap,
468 info->info.depth, info->info.debug,
469 info->info.alloc_grayscale,
470 info->info.alloc_colors_max,
471 info->info.mask, info->info.shape_dither,
472 info->info.destination_alpha);
473
474 re->outbuf_free = evas_software_xlib_outbuf_free;
475 re->outbuf_reconfigure = evas_software_xlib_outbuf_reconfigure;
476 re->outbuf_get_rot = evas_software_xlib_outbuf_get_rot;
477 re->outbuf_new_region_for_update =
478 evas_software_xlib_outbuf_new_region_for_update;
479 re->outbuf_push_updated_region =
480 evas_software_xlib_outbuf_push_updated_region;
481 re->outbuf_free_region_for_update =
482 evas_software_xlib_outbuf_free_region_for_update;
483 re->outbuf_flush = evas_software_xlib_outbuf_flush;
484 re->outbuf_idle_flush = evas_software_xlib_outbuf_idle_flush;
485 re->outbuf_alpha_get = evas_software_xlib_outbuf_alpha_get;
486# ifdef EVAS_FRAME_QUEUING
487 re->outbuf_set_priv = evas_software_xlib_outbuf_set_priv;
488 re->render_mode = info->render_mode;
489# endif
490 }
491#endif
492
493#ifdef BUILD_ENGINE_SOFTWARE_XCB
494 if (info->info.backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XCB)
495 {
496 re = _output_xcb_setup(e->output.w, e->output.h,
497 info->info.rotation, info->info.connection,
498 info->info.screen, info->info.drawable,
499 info->info.visual, info->info.colormap,
500 info->info.depth, info->info.debug,
501 info->info.alloc_grayscale,
502 info->info.alloc_colors_max,
503 info->info.mask, info->info.shape_dither,
504 info->info.destination_alpha);
505
506 re->outbuf_free = evas_software_xcb_outbuf_free;
507 re->outbuf_reconfigure = evas_software_xcb_outbuf_reconfigure;
508 re->outbuf_get_rot = evas_software_xcb_outbuf_rotation_get;
509 re->outbuf_new_region_for_update =
510 evas_software_xcb_outbuf_new_region_for_update;
511 re->outbuf_push_updated_region =
512 evas_software_xcb_outbuf_push_updated_region;
513 re->outbuf_free_region_for_update =
514 evas_software_xcb_outbuf_free_region_for_update;
515 re->outbuf_flush = evas_software_xcb_outbuf_flush;
516 re->outbuf_idle_flush = evas_software_xcb_outbuf_idle_flush;
517 re->outbuf_alpha_get = evas_software_xcb_outbuf_alpha_get;
518# ifdef EVAS_FRAME_QUEUING
519 re->outbuf_set_priv = evas_software_xcb_outbuf_priv_set;
520 re->render_mode = info->render_mode;
521# endif
522 }
523#endif
524
525 e->engine.data.output = re;
526 }
527 else
528 {
529 int ponebuf = 0;
530
531#ifdef EVAS_FRAME_QUEUING
532 evas_common_frameq_flush();
533#endif
534 re = e->engine.data.output;
535 ponebuf = re->ob->onebuf;
536
537#ifdef BUILD_ENGINE_SOFTWARE_XLIB
538 if (info->info.backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XLIB)
539 {
540 evas_software_xlib_outbuf_free(re->ob);
541 re->ob =
542 evas_software_xlib_outbuf_setup_x(e->output.w, e->output.h,
543 info->info.rotation,
544 OUTBUF_DEPTH_INHERIT,
545 info->info.connection,
546 info->info.drawable,
547 info->info.visual,
548 info->info.colormap,
549 info->info.depth,
550 info->info.alloc_grayscale,
551 info->info.alloc_colors_max,
552 info->info.mask,
553 info->info.shape_dither,
554 info->info.destination_alpha);
555
556 evas_software_xlib_outbuf_debug_set(re->ob, info->info.debug);
557# ifdef EVAS_FRAME_QUEUING
558 re->render_mode = info->render_mode;
559# endif
560 }
561#endif
562
563#ifdef BUILD_ENGINE_SOFTWARE_XCB
564 if (info->info.backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XCB)
565 {
566 evas_software_xcb_outbuf_free(re->ob);
567 re->ob =
568 evas_software_xcb_outbuf_setup(e->output.w, e->output.h,
569 info->info.rotation,
570 OUTBUF_DEPTH_INHERIT,
571 info->info.connection,
572 info->info.screen,
573 info->info.drawable,
574 info->info.visual,
575 info->info.colormap,
576 info->info.depth,
577 info->info.alloc_grayscale,
578 info->info.alloc_colors_max,
579 info->info.mask,
580 info->info.shape_dither,
581 info->info.destination_alpha);
582
583 evas_software_xcb_outbuf_debug_set(re->ob, info->info.debug);
584#ifdef EVAS_FRAME_QUEUING
585 re->render_mode = info->render_mode;
586#endif
587 }
588#endif
589 re->ob->onebuf = ponebuf;
590 }
591 if (!e->engine.data.output) return 0;
592 if (!e->engine.data.context)
593 {
594 e->engine.data.context =
595 e->engine.func->context_new(e->engine.data.output);
596 }
597
598 re = e->engine.data.output;
599
600 return 1;
601}
602
603static void
604eng_output_free(void *data)
605{
606 Render_Engine *re;
607
608#ifdef BUILD_ENGINE_SOFTWARE_XLIB
609// NOTE: XrmGetDatabase() result is shared per connection, do not free it.
610// if (re->xrdb) XrmDestroyDatabase(re->xrdb);
611#endif
612
613 if ((re = (Render_Engine *)data))
614 {
615 re->outbuf_free(re->ob);
616 evas_common_tilebuf_free(re->tb);
617 if (re->rects) evas_common_tilebuf_free_render_rects(re->rects);
618 free(re);
619 }
620
621 evas_common_font_shutdown();
622 evas_common_image_shutdown();
623}
624
625static void
626eng_output_resize(void *data, int w, int h)
627{
628 Render_Engine *re;
629
630 re = (Render_Engine *)data;
631 re->outbuf_reconfigure(re->ob, w, h, re->outbuf_get_rot(re->ob),
632 OUTBUF_DEPTH_INHERIT);
633 evas_common_tilebuf_free(re->tb);
634 re->tb = evas_common_tilebuf_new(w, h);
635 if (re->tb)
636 evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
637}
638
639static void
640eng_output_tile_size_set(void *data, int w, int h)
641{
642 Render_Engine *re;
643
644 re = (Render_Engine *)data;
645 evas_common_tilebuf_set_tile_size(re->tb, w, h);
646}
647
648static void
649eng_output_redraws_rect_add(void *data, int x, int y, int w, int h)
650{
651 Render_Engine *re;
652
653 re = (Render_Engine *)data;
654 evas_common_tilebuf_add_redraw(re->tb, x, y, w, h);
655}
656
657static void
658eng_output_redraws_rect_del(void *data, int x, int y, int w, int h)
659{
660 Render_Engine *re;
661
662 re = (Render_Engine *)data;
663 evas_common_tilebuf_del_redraw(re->tb, x, y, w, h);
664}
665
666static void
667eng_output_redraws_clear(void *data)
668{
669 Render_Engine *re;
670
671 re = (Render_Engine *)data;
672 evas_common_tilebuf_clear(re->tb);
673}
674
675static void *
676eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch)
677{
678 Render_Engine *re;
679 RGBA_Image *surface;
680 Tilebuf_Rect *rect;
681 int ux, uy, uw, uh;
682
683 re = (Render_Engine *)data;
684 if (re->end)
685 {
686 re->end = 0;
687 return NULL;
688 }
689 if (!re->rects)
690 {
691 re->rects = evas_common_tilebuf_get_render_rects(re->tb);
692 re->cur_rect = EINA_INLIST_GET(re->rects);
693 }
694 if (!re->cur_rect) return NULL;
695 rect = (Tilebuf_Rect *)re->cur_rect;
696 ux = rect->x; uy = rect->y; uw = rect->w; uh = rect->h;
697 re->cur_rect = re->cur_rect->next;
698 if (!re->cur_rect)
699 {
700 evas_common_tilebuf_free_render_rects(re->rects);
701 re->rects = NULL;
702 re->end = 1;
703 }
704
705 surface =
706 re->outbuf_new_region_for_update(re->ob, ux, uy, uw, uh, cx, cy, cw, ch);
707
708 *x = ux; *y = uy; *w = uw; *h = uh;
709 return surface;
710}
711
712static void
713eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h)
714{
715 Render_Engine *re;
716#ifdef EVAS_FRAME_QUEUING
717 Evas_Surface *e_surface;
718#endif
719
720 re = (Render_Engine *)data;
721#if defined(BUILD_PIPE_RENDER) && !defined(EVAS_FRAME_QUEUING)
722 evas_common_pipe_map_begin(surface);
723#endif /* BUILD_PIPE_RENDER && !EVAS_FRAME_QUEUING*/
724
725#ifdef EVAS_FRAME_QUEUING
726 if (re->render_mode == EVAS_RENDER_MODE_NONBLOCKING)
727 {
728 /* create a new frame if this is the first surface of this frame */
729 evas_common_frameq_prepare_frame();
730 /* add surface into the frame */
731 e_surface = evas_common_frameq_new_surface(surface, x, y, w, h);
732 evas_common_frameq_add_surface(e_surface);
733 return;
734 }
735#endif
736
737 re->outbuf_push_updated_region(re->ob, surface, x, y, w, h);
738 re->outbuf_free_region_for_update(re->ob, surface);
739 evas_common_cpu_end_opt();
740}
741
742#ifdef EVAS_FRAME_QUEUING
743static void *
744eng_image_map_surface_new(void *data , int w, int h, int alpha)
745{
746 void *surface;
747 DATA32 *pixels;
748 Render_Engine *re;
749 Evas_Surface *e_surface;
750
751 re = (Render_Engine *)data;
752
753 surface =
754 evas_cache_image_copied_data(evas_common_image_cache_get(), w, h, NULL,
755 alpha, EVAS_COLORSPACE_ARGB8888);
756 pixels = evas_cache_image_pixels(surface);
757
758 if (re->render_mode == EVAS_RENDER_MODE_NONBLOCKING)
759 {
760 /* create a new frame if this is the first surface of this frame */
761 evas_common_frameq_prepare_frame();
762
763 /* add surface into the frame */
764 e_surface = evas_common_frameq_new_surface(surface, 0, 0, w, h);
765
766 /* this surface is not going to be pushed to screen */
767 e_surface->dontpush = 1;
768 evas_common_frameq_add_surface(e_surface);
769 }
770 return surface;
771}
772
773static void
774eng_output_frameq_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h)
775{
776 Render_Engine *re;
777
778 re = (Render_Engine *)data;
779 re->outbuf_push_updated_region(re->ob, surface, x, y, w, h);
780 re->outbuf_free_region_for_update(re->ob, surface);
781 evas_common_cpu_end_opt();
782}
783
784static void
785eng_output_frameq_flush(void *data)
786{
787 Render_Engine *re;
788
789 re = (Render_Engine *)data;
790 re->outbuf_flush(re->ob);
791}
792
793static void
794eng_output_frameq_set_priv(void *data, void *cur, void *prev)
795{
796 Render_Engine *re;
797
798 re = (Render_Engine *)data;
799 re->outbuf_set_priv(re->ob, cur, prev);
800}
801#endif
802
803static void
804eng_output_flush(void *data)
805{
806 Render_Engine *re;
807
808 re = (Render_Engine *)data;
809#ifdef EVAS_FRAME_QUEUING
810 if (re->render_mode == EVAS_RENDER_MODE_NONBLOCKING)
811 {
812 evas_common_frameq_set_frame_data(data,
813 eng_output_frameq_redraws_next_update_push,
814 eng_output_frameq_flush,
815 eng_output_frameq_set_priv);
816 evas_common_frameq_ready_frame();
817 evas_common_frameq_begin();
818 }
819 else
820#endif
821 re->outbuf_flush(re->ob);
822}
823
824static void
825eng_output_idle_flush(void *data)
826{
827 Render_Engine *re;
828
829 re = (Render_Engine *)data;
830 re->outbuf_idle_flush(re->ob);
831}
832
833static Eina_Bool
834eng_canvas_alpha_get(void *data, void *context __UNUSED__)
835{
836 Render_Engine *re;
837
838 re = (Render_Engine *)data;
839 return (re->ob->priv.destination_alpha) || (re->outbuf_alpha_get(re->ob));
840}
841
842
843/* module advertising code */
844static int
845module_open(Evas_Module *em)
846{
847#ifdef BUILD_ENGINE_SOFTWARE_XLIB
848 static Eina_Bool xrm_inited = EINA_FALSE;
849
850 if (!xrm_inited)
851 {
852 xrm_inited = EINA_TRUE;
853 XrmInitialize();
854 }
855#endif
856
857 if (!em) return 0;
858
859 /* get whatever engine module we inherit from */
860 if (!_evas_module_engine_inherit(&pfunc, "software_generic")) return 0;
861
862 _evas_engine_soft_x11_log_dom =
863 eina_log_domain_register("evas-software_x11", EVAS_DEFAULT_LOG_COLOR);
864
865 if (_evas_engine_soft_x11_log_dom < 0)
866 {
867 EINA_LOG_ERR("Can not create a module log domain.");
868 return 0;
869 }
870
871 /* store it for later use */
872 func = pfunc;
873
874 /* now to override methods */
875#define ORD(f) EVAS_API_OVERRIDE(f, &func, eng_)
876 ORD(info);
877 ORD(info_free);
878 ORD(setup);
879 ORD(canvas_alpha_get);
880 ORD(output_free);
881 ORD(output_resize);
882 ORD(output_tile_size_set);
883 ORD(output_redraws_rect_add);
884 ORD(output_redraws_rect_del);
885 ORD(output_redraws_clear);
886 ORD(output_redraws_next_update_get);
887 ORD(output_redraws_next_update_push);
888 ORD(output_flush);
889 ORD(output_idle_flush);
890#ifdef EVAS_FRAME_QUEUING
891 ORD(image_map_surface_new);
892#endif
893
894 /* now advertise out own api */
895 em->functions = (void *)(&func);
896 return 1;
897}
898
899static void
900module_close(Evas_Module *em __UNUSED__)
901{
902 eina_log_domain_unregister(_evas_engine_soft_x11_log_dom);
903#ifdef BUILD_ENGINE_SOFTWARE_XLIB
904/*
905 if (xrdb_user.db)
906 {
907 XrmDestroyDatabase(xrdb_user.db);
908 xrdb_user.last_stat = 0;
909 xrdb_user.last_mtime = 0;
910 xrdb_user.db = NULL;
911 }
912 */
913#endif
914}
915
916static Evas_Module_Api evas_modapi =
917{
918 EVAS_MODULE_API_VERSION, "software_x11", "none",
919 {
920 module_open,
921 module_close
922 }
923};
924
925EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_ENGINE, engine, software_x11);
926
927#ifndef EVAS_STATIC_BUILD_SOFTWARE_X11
928EVAS_EINA_MODULE_DEFINE(engine, software_x11);
929#endif