summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile_Evas.am14
-rw-r--r--src/modules/evas/engines/software_x11/evas_engine.c390
-rw-r--r--src/modules/evas/engines/software_x11/evas_engine.h9
-rw-r--r--src/modules/evas/engines/software_x11/evas_xcb_outbuf.c2
-rw-r--r--src/modules/evas/engines/software_x11/evas_xlib_outbuf.c13
-rw-r--r--src/modules/evas/engines/software_x11/evas_xlib_swapbuf.c549
-rw-r--r--src/modules/evas/engines/software_x11/evas_xlib_swapbuf.h53
-rw-r--r--src/modules/evas/engines/software_x11/evas_xlib_swapper.c281
-rw-r--r--src/modules/evas/engines/software_x11/evas_xlib_swapper.h15
9 files changed, 1226 insertions, 100 deletions
diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am
index 05a1150112..a7f4702107 100644
--- a/src/Makefile_Evas.am
+++ b/src/Makefile_Evas.am
@@ -1007,6 +1007,7 @@ if BUILD_ENGINE_SOFTWARE_X11
1007dist_installed_evasmainheaders_DATA += modules/evas/engines/software_x11/Evas_Engine_Software_X11.h 1007dist_installed_evasmainheaders_DATA += modules/evas/engines/software_x11/Evas_Engine_Software_X11.h
1008SOFTWARE_X11_SOURCES = \ 1008SOFTWARE_X11_SOURCES = \
1009modules/evas/engines/software_x11/evas_engine.c \ 1009modules/evas/engines/software_x11/evas_engine.c \
1010modules/evas/engines/software_x11/evas_engine.h \
1010modules/evas/engines/software_x11/evas_x_egl.c \ 1011modules/evas/engines/software_x11/evas_x_egl.c \
1011modules/evas/engines/software_x11/evas_x_egl.h 1012modules/evas/engines/software_x11/evas_x_egl.h
1012SOFTWARE_X11_CPPFLAGS = \ 1013SOFTWARE_X11_CPPFLAGS = \
@@ -1025,10 +1026,17 @@ SOFTWARE_X11_CPPFLAGS = \
1025SOFTWARE_X11_LIBADD = 1026SOFTWARE_X11_LIBADD =
1026if BUILD_ENGINE_SOFTWARE_XLIB 1027if BUILD_ENGINE_SOFTWARE_XLIB
1027SOFTWARE_X11_SOURCES += \ 1028SOFTWARE_X11_SOURCES += \
1029modules/evas/engines/software_x11/evas_xlib_swapbuf.c \
1028modules/evas/engines/software_x11/evas_xlib_outbuf.c \ 1030modules/evas/engines/software_x11/evas_xlib_outbuf.c \
1029modules/evas/engines/software_x11/evas_xlib_buffer.c \ 1031modules/evas/engines/software_x11/evas_xlib_buffer.c \
1030modules/evas/engines/software_x11/evas_xlib_color.c \ 1032modules/evas/engines/software_x11/evas_xlib_color.c \
1031modules/evas/engines/software_x11/evas_xlib_main.c 1033modules/evas/engines/software_x11/evas_xlib_main.c \
1034modules/evas/engines/software_x11/evas_xlib_swapper.c \
1035modules/evas/engines/software_x11/evas_xlib_outbuf.h \
1036modules/evas/engines/software_x11/evas_xlib_swapbuf.h \
1037modules/evas/engines/software_x11/evas_xlib_buffer.h \
1038modules/evas/engines/software_x11/evas_xlib_color.h \
1039modules/evas/engines/software_x11/evas_xlib_swapper.h
1032SOFTWARE_X11_CPPFLAGS += @evas_engine_software_xlib_cflags@ 1040SOFTWARE_X11_CPPFLAGS += @evas_engine_software_xlib_cflags@
1033SOFTWARE_X11_LIBADD += @evas_engine_software_xlib_libs@ 1041SOFTWARE_X11_LIBADD += @evas_engine_software_xlib_libs@
1034endif 1042endif
@@ -1039,10 +1047,6 @@ modules/evas/engines/software_x11/evas_xcb_outbuf.c \
1039modules/evas/engines/software_x11/evas_xcb_buffer.c \ 1047modules/evas/engines/software_x11/evas_xcb_buffer.c \
1040modules/evas/engines/software_x11/evas_xcb_color.c \ 1048modules/evas/engines/software_x11/evas_xcb_color.c \
1041modules/evas/engines/software_x11/evas_xcb_main.c \ 1049modules/evas/engines/software_x11/evas_xcb_main.c \
1042modules/evas/engines/software_x11/evas_engine.h \
1043modules/evas/engines/software_x11/evas_xlib_outbuf.h \
1044modules/evas/engines/software_x11/evas_xlib_buffer.h \
1045modules/evas/engines/software_x11/evas_xlib_color.h \
1046modules/evas/engines/software_x11/evas_xcb_outbuf.h \ 1050modules/evas/engines/software_x11/evas_xcb_outbuf.h \
1047modules/evas/engines/software_x11/evas_xcb_buffer.h \ 1051modules/evas/engines/software_x11/evas_xcb_buffer.h \
1048modules/evas/engines/software_x11/evas_xcb_color.h \ 1052modules/evas/engines/software_x11/evas_xcb_color.h \
diff --git a/src/modules/evas/engines/software_x11/evas_engine.c b/src/modules/evas/engines/software_x11/evas_engine.c
index 0ac8bb14ed..accbc25aee 100644
--- a/src/modules/evas/engines/software_x11/evas_engine.c
+++ b/src/modules/evas/engines/software_x11/evas_engine.c
@@ -6,6 +6,7 @@
6 6
7#ifdef BUILD_ENGINE_SOFTWARE_XLIB 7#ifdef BUILD_ENGINE_SOFTWARE_XLIB
8# include "evas_xlib_outbuf.h" 8# include "evas_xlib_outbuf.h"
9# include "evas_xlib_swapbuf.h"
9# include "evas_xlib_color.h" 10# include "evas_xlib_color.h"
10#endif 11#endif
11 12
@@ -30,8 +31,11 @@ struct _Render_Engine
30 Tilebuf *tb; 31 Tilebuf *tb;
31 Outbuf *ob; 32 Outbuf *ob;
32 Tilebuf_Rect *rects; 33 Tilebuf_Rect *rects;
34 Tilebuf_Rect *rects_prev[3];
33 Eina_Inlist *cur_rect; 35 Eina_Inlist *cur_rect;
36 short mode;
34 unsigned char end : 1; 37 unsigned char end : 1;
38 unsigned char lost_back : 1;
35 void (*outbuf_free)(Outbuf *ob); 39 void (*outbuf_free)(Outbuf *ob);
36 void (*outbuf_reconfigure)(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth); 40 void (*outbuf_reconfigure)(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth);
37 int (*outbuf_get_rot)(Outbuf *ob); 41 int (*outbuf_get_rot)(Outbuf *ob);
@@ -40,6 +44,7 @@ struct _Render_Engine
40 void (*outbuf_free_region_for_update)(Outbuf *ob, RGBA_Image *update); 44 void (*outbuf_free_region_for_update)(Outbuf *ob, RGBA_Image *update);
41 void (*outbuf_flush)(Outbuf *ob); 45 void (*outbuf_flush)(Outbuf *ob);
42 void (*outbuf_idle_flush)(Outbuf *ob); 46 void (*outbuf_idle_flush)(Outbuf *ob);
47 int (*outbuf_swap_mode_get)(Outbuf *ob);
43 Eina_Bool (*outbuf_alpha_get)(Outbuf *ob); 48 Eina_Bool (*outbuf_alpha_get)(Outbuf *ob);
44 49
45 struct { 50 struct {
@@ -72,6 +77,7 @@ static void eng_output_idle_flush(void *data);
72 77
73#ifdef BUILD_ENGINE_SOFTWARE_XLIB 78#ifdef BUILD_ENGINE_SOFTWARE_XLIB
74 79
80/*
75static void * 81static void *
76_output_egl_setup(int w, int h, int rot, Display *disp, Drawable draw, 82_output_egl_setup(int w, int h, int rot, Display *disp, Drawable draw,
77 Visual *vis, Colormap cmap, int depth, int debug, 83 Visual *vis, Colormap cmap, int depth, int debug,
@@ -129,12 +135,12 @@ _output_egl_setup(int w, int h, int rot, Display *disp, Drawable draw,
129 return NULL; 135 return NULL;
130 } 136 }
131 137
132 /* in preliminary tests 16x16 gave highest framerates */
133 evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE); 138 evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
134 139
135 return re; 140 return re;
136 debug = 0; 141 debug = 0;
137} 142}
143*/
138 144
139static void 145static void
140_output_egl_shutdown(Render_Engine *re) 146_output_egl_shutdown(Render_Engine *re)
@@ -157,7 +163,7 @@ _output_xlib_setup(int w, int h, int rot, Display *disp, Drawable draw,
157 evas_software_xlib_x_init(); 163 evas_software_xlib_x_init();
158 evas_software_xlib_x_color_init(); 164 evas_software_xlib_x_color_init();
159 evas_software_xlib_outbuf_init(); 165 evas_software_xlib_outbuf_init();
160 166
161 re->ob = 167 re->ob =
162 evas_software_xlib_outbuf_setup_x(w, h, rot, OUTBUF_DEPTH_INHERIT, disp, 168 evas_software_xlib_outbuf_setup_x(w, h, rot, OUTBUF_DEPTH_INHERIT, disp,
163 draw, vis, cmap, depth, grayscale, 169 draw, vis, cmap, depth, grayscale,
@@ -192,6 +198,44 @@ _output_xlib_setup(int w, int h, int rot, Display *disp, Drawable draw,
192 evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE); 198 evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
193 return re; 199 return re;
194} 200}
201
202static void *
203_output_swapbuf_setup(int w, int h, int rot, Display *disp, Drawable draw,
204 Visual *vis, Colormap cmap, int depth,
205 int debug EINA_UNUSED,
206 int grayscale, int max_colors, Pixmap mask,
207 int shape_dither, int destination_alpha)
208{
209 Render_Engine *re;
210
211 if (!(re = calloc(1, sizeof(Render_Engine)))) return NULL;
212
213 evas_software_xlib_x_init();
214 evas_software_xlib_x_color_init();
215 evas_software_xlib_swapbuf_init();
216
217 re->ob =
218 evas_software_xlib_swapbuf_setup_x(w, h, rot, OUTBUF_DEPTH_INHERIT, disp,
219 draw, vis, cmap, depth, grayscale,
220 max_colors, mask, shape_dither,
221 destination_alpha);
222 if (!re->ob)
223 {
224 free(re);
225 return NULL;
226 }
227
228 re->tb = evas_common_tilebuf_new(w, h);
229 if (!re->tb)
230 {
231 evas_software_xlib_swapbuf_free(re->ob);
232 free(re);
233 return NULL;
234 }
235
236 evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
237 return re;
238}
195#endif 239#endif
196 240
197#ifdef BUILD_ENGINE_SOFTWARE_XCB 241#ifdef BUILD_ENGINE_SOFTWARE_XCB
@@ -409,29 +453,34 @@ eng_setup(Evas *eo_e, void *in)
409#ifdef BUILD_ENGINE_SOFTWARE_XLIB 453#ifdef BUILD_ENGINE_SOFTWARE_XLIB
410 if (info->info.backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XLIB) 454 if (info->info.backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XLIB)
411 { 455 {
412 re = _output_egl_setup(e->output.w, e->output.h, 456 // this is disabled for now as we should only use/need the
413 info->info.rotation, info->info.connection, 457 // swapper infra *IF* we can get direct access to the "backbuffer"
414 info->info.drawable, info->info.visual, 458 // of a window in x11.
415 info->info.colormap, 459 if (0)
416 info->info.depth, info->info.debug, 460 re = _output_swapbuf_setup(e->output.w, e->output.h,
417 info->info.alloc_grayscale, 461 info->info.rotation, info->info.connection,
418 info->info.alloc_colors_max, 462 info->info.drawable, info->info.visual,
419 info->info.mask, info->info.shape_dither, 463 info->info.colormap,
420 info->info.destination_alpha); 464 info->info.depth, info->info.debug,
465 info->info.alloc_grayscale,
466 info->info.alloc_colors_max,
467 info->info.mask, info->info.shape_dither,
468 info->info.destination_alpha);
421 if (re) 469 if (re)
422 { 470 {
423 // XXX these need to provide egl functions not xlib 471 re->outbuf_free = evas_software_xlib_swapbuf_free;
424 re->outbuf_free = evas_software_xlib_outbuf_free; 472 re->outbuf_reconfigure = evas_software_xlib_swapbuf_reconfigure;
425 re->outbuf_reconfigure = evas_software_xlib_outbuf_reconfigure; 473 re->outbuf_get_rot = evas_software_xlib_swapbuf_get_rot;
426 re->outbuf_get_rot = evas_software_xlib_outbuf_get_rot; 474 re->outbuf_new_region_for_update = evas_software_xlib_swapbuf_new_region_for_update;
427 re->outbuf_new_region_for_update = evas_software_xlib_outbuf_new_region_for_update; 475 re->outbuf_push_updated_region = evas_software_xlib_swapbuf_push_updated_region;
428 re->outbuf_push_updated_region = evas_software_xlib_outbuf_push_updated_region; 476 re->outbuf_free_region_for_update = evas_software_xlib_swapbuf_free_region_for_update;
429 re->outbuf_free_region_for_update = evas_software_xlib_outbuf_free_region_for_update; 477 re->outbuf_flush = evas_software_xlib_swapbuf_flush;
430 re->outbuf_flush = evas_software_xlib_outbuf_flush; 478 re->outbuf_idle_flush = evas_software_xlib_swapbuf_idle_flush;
431 re->outbuf_idle_flush = evas_software_xlib_outbuf_idle_flush; 479 re->outbuf_alpha_get = evas_software_xlib_swapbuf_alpha_get;
432 re->outbuf_alpha_get = evas_software_xlib_outbuf_alpha_get; 480 re->outbuf_swap_mode_get = evas_software_xlib_swapbuf_buffer_state_get;
433 } 481 }
434 else 482
483 if (!re)
435 { 484 {
436 re = _output_xlib_setup(e->output.w, e->output.h, 485 re = _output_xlib_setup(e->output.w, e->output.h,
437 info->info.rotation, info->info.connection, 486 info->info.rotation, info->info.connection,
@@ -443,15 +492,16 @@ eng_setup(Evas *eo_e, void *in)
443 info->info.mask, info->info.shape_dither, 492 info->info.mask, info->info.shape_dither,
444 info->info.destination_alpha); 493 info->info.destination_alpha);
445 494
446 re->outbuf_free = evas_software_xlib_outbuf_free; 495 re->outbuf_free = evas_software_xlib_outbuf_free;
447 re->outbuf_reconfigure = evas_software_xlib_outbuf_reconfigure; 496 re->outbuf_reconfigure = evas_software_xlib_outbuf_reconfigure;
448 re->outbuf_get_rot = evas_software_xlib_outbuf_get_rot; 497 re->outbuf_get_rot = evas_software_xlib_outbuf_get_rot;
449 re->outbuf_new_region_for_update = evas_software_xlib_outbuf_new_region_for_update; 498 re->outbuf_new_region_for_update = evas_software_xlib_outbuf_new_region_for_update;
450 re->outbuf_push_updated_region = evas_software_xlib_outbuf_push_updated_region; 499 re->outbuf_push_updated_region = evas_software_xlib_outbuf_push_updated_region;
451 re->outbuf_free_region_for_update = evas_software_xlib_outbuf_free_region_for_update; 500 re->outbuf_free_region_for_update = evas_software_xlib_outbuf_free_region_for_update;
452 re->outbuf_flush = evas_software_xlib_outbuf_flush; 501 re->outbuf_flush = evas_software_xlib_outbuf_flush;
453 re->outbuf_idle_flush = evas_software_xlib_outbuf_idle_flush; 502 re->outbuf_idle_flush = evas_software_xlib_outbuf_idle_flush;
454 re->outbuf_alpha_get = evas_software_xlib_outbuf_alpha_get; 503 re->outbuf_alpha_get = evas_software_xlib_outbuf_alpha_get;
504 re->outbuf_swap_mode_get = NULL;
455 } 505 }
456 } 506 }
457#endif 507#endif
@@ -469,18 +519,16 @@ eng_setup(Evas *eo_e, void *in)
469 info->info.mask, info->info.shape_dither, 519 info->info.mask, info->info.shape_dither,
470 info->info.destination_alpha); 520 info->info.destination_alpha);
471 521
472 re->outbuf_free = evas_software_xcb_outbuf_free; 522 re->outbuf_free = evas_software_xcb_outbuf_free;
473 re->outbuf_reconfigure = evas_software_xcb_outbuf_reconfigure; 523 re->outbuf_reconfigure = evas_software_xcb_outbuf_reconfigure;
474 re->outbuf_get_rot = evas_software_xcb_outbuf_rotation_get; 524 re->outbuf_get_rot = evas_software_xcb_outbuf_rotation_get;
475 re->outbuf_new_region_for_update = 525 re->outbuf_new_region_for_update = evas_software_xcb_outbuf_new_region_for_update;
476 evas_software_xcb_outbuf_new_region_for_update; 526 re->outbuf_push_updated_region = evas_software_xcb_outbuf_push_updated_region;
477 re->outbuf_push_updated_region = 527 re->outbuf_free_region_for_update = evas_software_xcb_outbuf_free_region_for_update;
478 evas_software_xcb_outbuf_push_updated_region; 528 re->outbuf_flush = evas_software_xcb_outbuf_flush;
479 re->outbuf_free_region_for_update = 529 re->outbuf_idle_flush = evas_software_xcb_outbuf_idle_flush;
480 evas_software_xcb_outbuf_free_region_for_update; 530 re->outbuf_alpha_get = evas_software_xcb_outbuf_alpha_get;
481 re->outbuf_flush = evas_software_xcb_outbuf_flush; 531 re->outbuf_swap_mode_get = NULL;
482 re->outbuf_idle_flush = evas_software_xcb_outbuf_idle_flush;
483 re->outbuf_alpha_get = evas_software_xcb_outbuf_alpha_get;
484 } 532 }
485#endif 533#endif
486 534
@@ -491,29 +539,49 @@ eng_setup(Evas *eo_e, void *in)
491 int ponebuf = 0; 539 int ponebuf = 0;
492 540
493 re = e->engine.data.output; 541 re = e->engine.data.output;
494 ponebuf = re->ob->onebuf; 542 if ((re) && (re->ob)) ponebuf = re->ob->onebuf;
495 543
496#ifdef BUILD_ENGINE_SOFTWARE_XLIB 544#ifdef BUILD_ENGINE_SOFTWARE_XLIB
497 if (info->info.backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XLIB) 545 if (info->info.backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XLIB)
498 { 546 {
499 // XXXX do egl stuff as above 547 // XXX
500 evas_software_xlib_outbuf_free(re->ob); 548 re->outbuf_free(re->ob);
501 re->ob = 549
502 evas_software_xlib_outbuf_setup_x(e->output.w, e->output.h, 550 if (re->outbuf_free == evas_software_xlib_swapbuf_free)
503 info->info.rotation, 551 {
504 OUTBUF_DEPTH_INHERIT, 552 re->ob =
505 info->info.connection, 553 evas_software_xlib_swapbuf_setup_x(e->output.w, e->output.h,
506 info->info.drawable, 554 info->info.rotation,
507 info->info.visual, 555 OUTBUF_DEPTH_INHERIT,
508 info->info.colormap, 556 info->info.connection,
509 info->info.depth, 557 info->info.drawable,
510 info->info.alloc_grayscale, 558 info->info.visual,
511 info->info.alloc_colors_max, 559 info->info.colormap,
512 info->info.mask, 560 info->info.depth,
513 info->info.shape_dither, 561 info->info.alloc_grayscale,
514 info->info.destination_alpha); 562 info->info.alloc_colors_max,
515 563 info->info.mask,
516 evas_software_xlib_outbuf_debug_set(re->ob, info->info.debug); 564 info->info.shape_dither,
565 info->info.destination_alpha);
566 }
567 else
568 {
569 re->ob =
570 evas_software_xlib_outbuf_setup_x(e->output.w, e->output.h,
571 info->info.rotation,
572 OUTBUF_DEPTH_INHERIT,
573 info->info.connection,
574 info->info.drawable,
575 info->info.visual,
576 info->info.colormap,
577 info->info.depth,
578 info->info.alloc_grayscale,
579 info->info.alloc_colors_max,
580 info->info.mask,
581 info->info.shape_dither,
582 info->info.destination_alpha);
583 evas_software_xlib_outbuf_debug_set(re->ob, info->info.debug);
584 }
517 } 585 }
518#endif 586#endif
519 587
@@ -536,11 +604,10 @@ eng_setup(Evas *eo_e, void *in)
536 info->info.mask, 604 info->info.mask,
537 info->info.shape_dither, 605 info->info.shape_dither,
538 info->info.destination_alpha); 606 info->info.destination_alpha);
539
540 evas_software_xcb_outbuf_debug_set(re->ob, info->info.debug); 607 evas_software_xcb_outbuf_debug_set(re->ob, info->info.debug);
541 } 608 }
542#endif 609#endif
543 re->ob->onebuf = ponebuf; 610 if ((re) && (re->ob)) re->ob->onebuf = ponebuf;
544 } 611 }
545 if (!e->engine.data.output) return 0; 612 if (!e->engine.data.output) return 0;
546 if (!e->engine.data.context) 613 if (!e->engine.data.context)
@@ -564,6 +631,9 @@ eng_output_free(void *data)
564 re->outbuf_free(re->ob); 631 re->outbuf_free(re->ob);
565 evas_common_tilebuf_free(re->tb); 632 evas_common_tilebuf_free(re->tb);
566 if (re->rects) evas_common_tilebuf_free_render_rects(re->rects); 633 if (re->rects) evas_common_tilebuf_free_render_rects(re->rects);
634 if (re->rects_prev[0]) evas_common_tilebuf_free_render_rects(re->rects_prev[0]);
635 if (re->rects_prev[1]) evas_common_tilebuf_free_render_rects(re->rects_prev[1]);
636 if (re->rects_prev[2]) evas_common_tilebuf_free_render_rects(re->rects_prev[2]);
567 _output_egl_shutdown(re); 637 _output_egl_shutdown(re);
568 free(re); 638 free(re);
569 } 639 }
@@ -622,41 +692,189 @@ eng_output_redraws_clear(void *data)
622 evas_common_tilebuf_clear(re->tb); 692 evas_common_tilebuf_clear(re->tb);
623} 693}
624 694
695static Tilebuf_Rect *
696_merge_rects(Tilebuf *tb, Tilebuf_Rect *r1, Tilebuf_Rect *r2, Tilebuf_Rect *r3)
697{
698 Tilebuf_Rect *r, *rects;
699 int x1, y1, x2, y2;
700
701 if (r1)
702 {
703 EINA_INLIST_FOREACH(EINA_INLIST_GET(r1), r)
704 {
705 evas_common_tilebuf_add_redraw(tb, r->x, r->y, r->w, r->h);
706 }
707 }
708 if (r2)
709 {
710 EINA_INLIST_FOREACH(EINA_INLIST_GET(r2), r)
711 {
712 evas_common_tilebuf_add_redraw(tb, r->x, r->y, r->w, r->h);
713 }
714 }
715 if (r2)
716 {
717 EINA_INLIST_FOREACH(EINA_INLIST_GET(r3), r)
718 {
719 evas_common_tilebuf_add_redraw(tb, r->x, r->y, r->w, r->h);
720 }
721 }
722 rects = evas_common_tilebuf_get_render_rects(tb);
723
724/*
725 // bounding box -> make a bounding box single region update of all regions.
726 // yes we could try and be smart and figure out size of regions, how far
727 // apart etc. etc. to try and figure out an optimal "set". this is a tradeoff
728 // between multiple update regions to render and total pixels to render.
729 if (rects)
730 {
731 x1 = rects->x; y1 = rects->y;
732 x2 = rects->x + rects->w; y2 = rects->y + rects->h;
733 EINA_INLIST_FOREACH(EINA_INLIST_GET(rects), r)
734 {
735 if (r->x < x1) x1 = r->x;
736 if (r->y < y1) y1 = r->y;
737 if ((r->x + r->w) > x2) x2 = r->x + r->w;
738 if ((r->y + r->h) > y2) y2 = r->y + r->h;
739 }
740 evas_common_tilebuf_free_render_rects(rects);
741 rects = calloc(1, sizeof(Tilebuf_Rect));
742 if (rects)
743 {
744 rects->x = x1;
745 rects->y = y1;
746 rects->w = x2 - x1;
747 rects->h = y2 - y1;
748 }
749 }
750 */
751 evas_common_tilebuf_clear(tb);
752 return rects;
753}
754
755
625static void * 756static void *
626eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch) 757eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch)
627{ 758{
628 Render_Engine *re; 759 Render_Engine *re;
629 RGBA_Image *surface; 760 RGBA_Image *surface;
630 Tilebuf_Rect *rect; 761 Tilebuf_Rect *rect;
631 int ux, uy, uw, uh; 762 Eina_Bool first_rect = EINA_FALSE;
632 763 int i;
764
765#define CLEAR_PREV_RECTS(x) \
766 do { \
767 if (re->rects_prev[i]) \
768 evas_common_tilebuf_free_render_rects(re->rects_prev[i]); \
769 re->rects_prev[i] = NULL; \
770 } while (0)
771
633 re = (Render_Engine *)data; 772 re = (Render_Engine *)data;
634 if (re->end) 773 if (re->end)
635 { 774 {
636 re->end = 0; 775 re->end = 0;
637 return NULL; 776 return NULL;
638 } 777 }
778
639 if (!re->rects) 779 if (!re->rects)
640 { 780 {
781 int mode = MODE_COPY;
782
783 if (re->outbuf_swap_mode_get) mode = re->outbuf_swap_mode_get(re->ob);
784 re->mode = mode;
641 re->rects = evas_common_tilebuf_get_render_rects(re->tb); 785 re->rects = evas_common_tilebuf_get_render_rects(re->tb);
642 re->cur_rect = EINA_INLIST_GET(re->rects); 786 if (re->rects)
787 {
788 if (re->lost_back)
789 {
790 /* if we lost our backbuffer since the last frame redraw all */
791 re->lost_back = 0;
792 evas_common_tilebuf_add_redraw(re->tb, 0, 0, re->ob->w, re->ob->h);
793 evas_common_tilebuf_free_render_rects(re->rects);
794 re->rects = evas_common_tilebuf_get_render_rects(re->tb);
795 }
796 /* ensure we get rid of previous rect lists we dont need if mode
797 * changed/is appropriate */
798 switch (re->mode)
799 {
800 case MODE_FULL:
801 case MODE_COPY: // no prev rects needed
802 for (i = 0; i < 3; i++) CLEAR_PREV_RECTS(i);
803 break;
804 case MODE_DOUBLE: // double mode - only 1 level of prev rect
805 for (i = 1; i < 3; i++) CLEAR_PREV_RECTS(i);
806 re->rects_prev[1] = re->rects_prev[0];
807 re->rects_prev[0] = re->rects;
808 // merge prev[1] + prev[0] -> rects
809 re->rects = _merge_rects(re->tb, re->rects_prev[0], re->rects_prev[1], NULL);
810 break;
811 case MODE_TRIPLE: // keep all
812 for (i = 2; i < 3; i++) CLEAR_PREV_RECTS(i);
813 re->rects_prev[2] = re->rects_prev[1];
814 re->rects_prev[1] = re->rects_prev[0];
815 re->rects_prev[0] = re->rects;
816 re->rects = NULL;
817 // merge prev[2] + prev[1] + prev[0] -> rects
818 re->rects = _merge_rects(re->tb, re->rects_prev[0], re->rects_prev[1], re->rects_prev[2]);
819 break;
820 default:
821 break;
822 }
823 re->cur_rect = EINA_INLIST_GET(re->rects);
824 first_rect = EINA_TRUE;
825 }
826 evas_common_tilebuf_clear(re->tb);
827 re->cur_rect = EINA_INLIST_GET(re->rects);
643 } 828 }
644 if (!re->cur_rect) return NULL; 829 if (!re->cur_rect) return NULL;
645 rect = (Tilebuf_Rect *)re->cur_rect; 830 rect = (Tilebuf_Rect *)re->cur_rect;
646 ux = rect->x; uy = rect->y; uw = rect->w; uh = rect->h; 831 if (re->rects)
647 re->cur_rect = re->cur_rect->next;
648 if (!re->cur_rect)
649 { 832 {
650 evas_common_tilebuf_free_render_rects(re->rects); 833 switch (re->mode)
651 re->rects = NULL; 834 {
652 re->end = 1; 835 case MODE_COPY:
836 case MODE_DOUBLE:
837 case MODE_TRIPLE:
838 rect = (Tilebuf_Rect *)re->cur_rect;
839 *x = rect->x;
840 *y = rect->y;
841 *w = rect->w;
842 *h = rect->h;
843 *cx = rect->x;
844 *cy = rect->y;
845 *cw = rect->w;
846 *ch = rect->h;
847 re->cur_rect = re->cur_rect->next;
848 break;
849 case MODE_FULL:
850 re->cur_rect = NULL;
851 if (x) *x = 0;
852 if (y) *y = 0;
853 if (w) *w = re->ob->w;
854 if (h) *h = re->ob->h;
855 if (cx) *cx = 0;
856 if (cy) *cy = 0;
857 if (cw) *cw = re->ob->w;
858 if (ch) *ch = re->ob->h;
859 break;
860 default:
861 break;
862 }
863 if (first_rect)
864 {
865 // do anything needed fir the first frame
866 }
867 surface =
868 re->outbuf_new_region_for_update(re->ob,
869 *x, *y, *w, *h,
870 cx, cy, cw, ch);
871 if (!re->cur_rect)
872 {
873 re->end = 1;
874 }
875 return surface;
653 } 876 }
654 877 return NULL;
655 surface =
656 re->outbuf_new_region_for_update(re->ob, ux, uy, uw, uh, cx, cy, cw, ch);
657
658 *x = ux; *y = uy; *w = uw; *h = uh;
659 return surface;
660} 878}
661 879
662static void 880static void
@@ -668,7 +886,6 @@ eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int
668#if defined(BUILD_PIPE_RENDER) 886#if defined(BUILD_PIPE_RENDER)
669 evas_common_pipe_map_begin(surface); 887 evas_common_pipe_map_begin(surface);
670#endif /* BUILD_PIPE_RENDER */ 888#endif /* BUILD_PIPE_RENDER */
671
672 re->outbuf_push_updated_region(re->ob, surface, x, y, w, h); 889 re->outbuf_push_updated_region(re->ob, surface, x, y, w, h);
673 re->outbuf_free_region_for_update(re->ob, surface); 890 re->outbuf_free_region_for_update(re->ob, surface);
674 evas_common_cpu_end_opt(); 891 evas_common_cpu_end_opt();
@@ -681,6 +898,11 @@ eng_output_flush(void *data)
681 898
682 re = (Render_Engine *)data; 899 re = (Render_Engine *)data;
683 re->outbuf_flush(re->ob); 900 re->outbuf_flush(re->ob);
901 if (re->rects)
902 {
903 evas_common_tilebuf_free_render_rects(re->rects);
904 re->rects = NULL;
905 }
684} 906}
685 907
686static void 908static void
@@ -706,16 +928,6 @@ eng_canvas_alpha_get(void *data, void *context EINA_UNUSED)
706static int 928static int
707module_open(Evas_Module *em) 929module_open(Evas_Module *em)
708{ 930{
709#ifdef BUILD_ENGINE_SOFTWARE_XLIB
710 static Eina_Bool xrm_inited = EINA_FALSE;
711
712 if (!xrm_inited)
713 {
714 xrm_inited = EINA_TRUE;
715 XrmInitialize();
716 }
717#endif
718
719 if (!em) return 0; 931 if (!em) return 0;
720 932
721 /* get whatever engine module we inherit from */ 933 /* get whatever engine module we inherit from */
diff --git a/src/modules/evas/engines/software_x11/evas_engine.h b/src/modules/evas/engines/software_x11/evas_engine.h
index 73a62bccdf..82d2d1f57c 100644
--- a/src/modules/evas/engines/software_x11/evas_engine.h
+++ b/src/modules/evas/engines/software_x11/evas_engine.h
@@ -60,6 +60,13 @@ enum _Outbuf_Depth
60 OUTBUF_DEPTH_LAST 60 OUTBUF_DEPTH_LAST
61}; 61};
62 62
63enum {
64 MODE_FULL,
65 MODE_COPY,
66 MODE_DOUBLE,
67 MODE_TRIPLE
68};
69
63typedef struct _Outbuf Outbuf; 70typedef struct _Outbuf Outbuf;
64 71
65struct _Outbuf 72struct _Outbuf
@@ -112,6 +119,8 @@ struct _Outbuf
112 /* 1 big buffer for updates - flush on idle_flush */ 119 /* 1 big buffer for updates - flush on idle_flush */
113 RGBA_Image *onebuf; 120 RGBA_Image *onebuf;
114 Eina_Array onebuf_regions; 121 Eina_Array onebuf_regions;
122
123 void *swapper;
115 124
116 /* a list of pending regions to write to the target */ 125 /* a list of pending regions to write to the target */
117 Eina_List *pending_writes; 126 Eina_List *pending_writes;
diff --git a/src/modules/evas/engines/software_x11/evas_xcb_outbuf.c b/src/modules/evas/engines/software_x11/evas_xcb_outbuf.c
index 9b0079f34f..eb0dcfc2ef 100644
--- a/src/modules/evas/engines/software_x11/evas_xcb_outbuf.c
+++ b/src/modules/evas/engines/software_x11/evas_xcb_outbuf.c
@@ -93,6 +93,8 @@ evas_software_xcb_outbuf_setup(int w, int h, int rot, Outbuf_Depth depth, xcb_co
93 if (!(buf = calloc(1, sizeof(Outbuf)))) 93 if (!(buf = calloc(1, sizeof(Outbuf))))
94 return NULL; 94 return NULL;
95 95
96 if (xdepth < 15) rot = 0;
97
96 setup = xcb_get_setup(conn); 98 setup = xcb_get_setup(conn);
97 99
98 buf->w = w; 100 buf->w = w;
diff --git a/src/modules/evas/engines/software_x11/evas_xlib_outbuf.c b/src/modules/evas/engines/software_x11/evas_xlib_outbuf.c
index 47763c43a1..7cc1cf0e40 100644
--- a/src/modules/evas/engines/software_x11/evas_xlib_outbuf.c
+++ b/src/modules/evas/engines/software_x11/evas_xlib_outbuf.c
@@ -14,7 +14,6 @@
14#include "evas_xlib_buffer.h" 14#include "evas_xlib_buffer.h"
15#include "evas_xlib_color.h" 15#include "evas_xlib_color.h"
16 16
17
18typedef struct _Outbuf_Region Outbuf_Region; 17typedef struct _Outbuf_Region Outbuf_Region;
19 18
20struct _Outbuf_Region 19struct _Outbuf_Region
@@ -188,10 +187,10 @@ evas_software_xlib_outbuf_free(Outbuf *buf)
188 187
189Outbuf * 188Outbuf *
190evas_software_xlib_outbuf_setup_x(int w, int h, int rot, Outbuf_Depth depth, 189evas_software_xlib_outbuf_setup_x(int w, int h, int rot, Outbuf_Depth depth,
191 Display *disp, Drawable draw, Visual *vis, 190 Display *disp, Drawable draw, Visual *vis,
192 Colormap cmap, int x_depth, 191 Colormap cmap, int x_depth,
193 int grayscale, int max_colors, Pixmap mask, 192 int grayscale, int max_colors, Pixmap mask,
194 int shape_dither, int destination_alpha) 193 int shape_dither, int destination_alpha)
195{ 194{
196 Outbuf *buf; 195 Outbuf *buf;
197 196
@@ -199,6 +198,8 @@ evas_software_xlib_outbuf_setup_x(int w, int h, int rot, Outbuf_Depth depth,
199 if (!buf) 198 if (!buf)
200 return NULL; 199 return NULL;
201 200
201 if (x_depth < 15) rot = 0;
202
202 buf->w = w; 203 buf->w = w;
203 buf->h = h; 204 buf->h = h;
204 buf->depth = depth; 205 buf->depth = depth;
@@ -214,7 +215,7 @@ evas_software_xlib_outbuf_setup_x(int w, int h, int rot, Outbuf_Depth depth,
214 215
215 eina_array_step_set(&buf->priv.onebuf_regions, sizeof (Eina_Array), 8); 216 eina_array_step_set(&buf->priv.onebuf_regions, sizeof (Eina_Array), 8);
216 217
217 { 218 {
218 Gfx_Func_Convert conv_func; 219 Gfx_Func_Convert conv_func;
219 X_Output_Buffer *xob; 220 X_Output_Buffer *xob;
220 221
diff --git a/src/modules/evas/engines/software_x11/evas_xlib_swapbuf.c b/src/modules/evas/engines/software_x11/evas_xlib_swapbuf.c
new file mode 100644
index 0000000000..95c1626c5f
--- /dev/null
+++ b/src/modules/evas/engines/software_x11/evas_xlib_swapbuf.c
@@ -0,0 +1,549 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <sys/time.h>
6#include <sys/utsname.h>
7
8#ifdef EVAS_CSERVE2
9#include "evas_cs2_private.h"
10#endif
11#include "evas_common.h"
12#include "evas_macros.h"
13
14#include "evas_xlib_swapbuf.h"
15#include "evas_xlib_color.h"
16#include "evas_xlib_swapper.h"
17
18typedef struct _Outbuf_Region Outbuf_Region;
19
20struct _Outbuf_Region
21{
22 RGBA_Image *im;
23 int x;
24 int y;
25 int w;
26 int h;
27};
28
29void
30evas_software_xlib_swapbuf_init(void)
31{
32}
33
34void
35evas_software_xlib_swapbuf_free(Outbuf *buf)
36{
37 evas_software_xlib_swapbuf_flush(buf);
38 evas_software_xlib_swapbuf_idle_flush(buf);
39 if (buf->priv.pal)
40 evas_software_xlib_x_color_deallocate
41 (buf->priv.x11.xlib.disp, buf->priv.x11.xlib.cmap,
42 buf->priv.x11.xlib.vis, buf->priv.pal);
43 eina_array_flush(&buf->priv.onebuf_regions);
44 free(buf);
45}
46
47Outbuf *
48evas_software_xlib_swapbuf_setup_x(int w, int h, int rot, Outbuf_Depth depth,
49 Display *disp, Drawable draw, Visual *vis,
50 Colormap cmap, int x_depth,
51 int grayscale, int max_colors, Pixmap mask,
52 int shape_dither, int destination_alpha)
53{
54 Outbuf *buf;
55 Gfx_Func_Convert conv_func = NULL;
56 int d;
57
58 buf = calloc(1, sizeof(Outbuf));
59 if (!buf) return NULL;
60
61 if (x_depth < 15) rot = 0;
62
63 buf->onebuf = 1;
64 buf->w = w;
65 buf->h = h;
66 buf->depth = depth;
67 buf->rot = rot;
68 buf->priv.x11.xlib.disp = disp;
69 buf->priv.x11.xlib.win = draw;
70 buf->priv.x11.xlib.vis = vis;
71 buf->priv.x11.xlib.cmap = cmap;
72 buf->priv.x11.xlib.depth = x_depth;
73 buf->priv.mask_dither = shape_dither;
74 buf->priv.destination_alpha = destination_alpha;
75
76 if ((buf->rot == 0) || (buf->rot == 180))
77 buf->priv.swapper = evas_xlib_swapper_new(buf->priv.x11.xlib.disp,
78 buf->priv.x11.xlib.win,
79 buf->priv.x11.xlib.vis,
80 buf->priv.x11.xlib.depth,
81 buf->w, buf->h);
82 else if ((buf->rot == 90) || (buf->rot == 270))
83 buf->priv.swapper = evas_xlib_swapper_new(buf->priv.x11.xlib.disp,
84 buf->priv.x11.xlib.win,
85 buf->priv.x11.xlib.vis,
86 buf->priv.x11.xlib.depth,
87 buf->h, buf->w);
88 if (!buf->priv.swapper)
89 {
90 free(buf);
91 return NULL;
92 }
93
94 eina_array_step_set(&buf->priv.onebuf_regions, sizeof (Eina_Array), 8);
95
96#ifdef WORDS_BIGENDIAN
97 if (evas_xlib_swapper_byte_order_get(buf->priv.swapper) == LSBFirst)
98 buf->priv.x11.xlib.swap = 1;
99 if (evas_xlib_swapper_bit_order_get(buf->priv.swapper) == MSBFirst)
100 buf->priv.x11.xlib.bit_swap = 1;
101#else
102 if (evas_xlib_swapper_byte_order_get(buf->priv.swapper) == MSBFirst)
103 buf->priv.x11.xlib.swap = 1;
104 if (evas_xlib_swapper_bit_order_get(buf->priv.swapper) == MSBFirst)
105 buf->priv.x11.xlib.bit_swap = 1;
106#endif
107 if (((vis->class == TrueColor) || (vis->class == DirectColor)) &&
108 (x_depth > 8))
109 {
110 buf->priv.mask.r = (DATA32) vis->red_mask;
111 buf->priv.mask.g = (DATA32) vis->green_mask;
112 buf->priv.mask.b = (DATA32) vis->blue_mask;
113 if (buf->priv.x11.xlib.swap)
114 {
115 SWAP32(buf->priv.mask.r);
116 SWAP32(buf->priv.mask.g);
117 SWAP32(buf->priv.mask.b);
118 }
119 }
120 else if ((vis->class == PseudoColor) || (vis->class == StaticColor) ||
121 (vis->class == GrayScale) || (vis->class == StaticGray) ||
122 (x_depth <= 8))
123 {
124 Convert_Pal_Mode pm = PAL_MODE_RGB332;
125
126 if ((vis->class == GrayScale) || (vis->class == StaticGray))
127 grayscale = 1;
128 if (grayscale)
129 {
130 if (max_colors >= 256) pm = PAL_MODE_GRAY256;
131 else if (max_colors >= 64) pm = PAL_MODE_GRAY64;
132 else if (max_colors >= 16) pm = PAL_MODE_GRAY16;
133 else if (max_colors >= 4) pm = PAL_MODE_GRAY4;
134 else pm = PAL_MODE_MONO;
135 }
136 else
137 {
138 if (max_colors >= 256) pm = PAL_MODE_RGB332;
139 else if (max_colors >= 216) pm = PAL_MODE_RGB666;
140 else if (max_colors >= 128) pm = PAL_MODE_RGB232;
141 else if (max_colors >= 64) pm = PAL_MODE_RGB222;
142 else if (max_colors >= 32) pm = PAL_MODE_RGB221;
143 else if (max_colors >= 16) pm = PAL_MODE_RGB121;
144 else if (max_colors >= 8) pm = PAL_MODE_RGB111;
145 else if (max_colors >= 4) pm = PAL_MODE_GRAY4;
146 else pm = PAL_MODE_MONO;
147 }
148 /* FIXME: only alloc once per display+cmap */
149 buf->priv.pal = evas_software_xlib_x_color_allocate
150 (disp, cmap, vis, pm);
151 if (!buf->priv.pal)
152 {
153 evas_xlib_swapper_free(buf->priv.swapper);
154 free(buf);
155 return NULL;
156 }
157 }
158 d = evas_xlib_swapper_depth_get(buf->priv.swapper);
159 if (buf->priv.pal)
160 {
161
162 if (buf->rot == 0 || buf->rot == 180)
163 conv_func = evas_common_convert_func_get(0, buf->w, buf->h, d,
164 buf->priv.mask.r,
165 buf->priv.mask.g,
166 buf->priv.mask.b,
167 buf->priv.pal->colors,
168 buf->rot);
169 else if (buf->rot == 90 || buf->rot == 270)
170 conv_func = evas_common_convert_func_get(0, buf->h, buf->w, d,
171 buf->priv.mask.r,
172 buf->priv.mask.g,
173 buf->priv.mask.b,
174 buf->priv.pal->colors,
175 buf->rot);
176 }
177 else
178 {
179 if (buf->rot == 0 || buf->rot == 180)
180 conv_func = evas_common_convert_func_get(0, buf->w, buf->h, d,
181 buf->priv.mask.r,
182 buf->priv.mask.g,
183 buf->priv.mask.b,
184 PAL_MODE_NONE,
185 buf->rot);
186 else if (buf->rot == 90 || buf->rot == 270)
187 conv_func = evas_common_convert_func_get(0, buf->h, buf->w, d,
188 buf->priv.mask.r,
189 buf->priv.mask.g,
190 buf->priv.mask.b,
191 PAL_MODE_NONE,
192 buf->rot);
193 }
194 if (!conv_func)
195 {
196 ERR("At depth: %i, RGB format mask: %08x %08x %08x, "
197 "Palette mode: %i. "
198 "Not supported by compiled in converters!",
199 buf->priv.x11.xlib.depth,
200 buf->priv.mask.r,
201 buf->priv.mask.g,
202 buf->priv.mask.b,
203 buf->priv.pal ? (int)buf->priv.pal->colors : -1);
204 }
205 return buf;
206}
207
208RGBA_Image *
209evas_software_xlib_swapbuf_new_region_for_update(Outbuf *buf, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch)
210{
211 RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, buf->w, buf->h);
212 if ((w <= 0) || (h <= 0)) return NULL;
213 // if rotation is 0, and 32bit argb, we can use the buffer directly
214 if ((buf->rot == 0) &&
215 (buf->priv.mask.r == 0xff0000) &&
216 (buf->priv.mask.g == 0x00ff00) &&
217 (buf->priv.mask.b == 0x0000ff))
218 {
219 RGBA_Image *im;
220 void *data;
221 int bpl = 0;
222 Eina_Rectangle *rect;
223
224 im = buf->priv.onebuf;
225 if (!im)
226 {
227 data = evas_xlib_swapper_buffer_map(buf->priv.swapper, &bpl);
228#ifdef EVAS_CSERVE2
229 if (evas_cserve2_use_get())
230 im = (RGBA_Image *)evas_cache2_image_data(evas_common_image_cache2_get(),
231 buf->w, buf->h, data,
232 buf->priv.destination_alpha,
233 EVAS_COLORSPACE_ARGB8888);
234 else
235#endif
236 im = (RGBA_Image *)evas_cache_image_data(evas_common_image_cache_get(),
237 buf->w, buf->h, data,
238 buf->priv.destination_alpha,
239 EVAS_COLORSPACE_ARGB8888);
240 buf->priv.onebuf = im;
241 if (!im) return NULL;
242 }
243 rect = eina_rectangle_new(x, y, w, h);
244 if (!eina_array_push(&buf->priv.onebuf_regions, rect))
245 {
246#ifdef EVAS_CSERVE2
247 if (evas_cserve2_use_get())
248 evas_cache2_image_close(&im->cache_entry);
249 else
250#endif
251 evas_cache_image_drop(&im->cache_entry);
252 return NULL;
253 }
254
255 // the clip region of the onebuf to render
256 *cx = x;
257 *cy = y;
258 *cw = w;
259 *ch = h;
260 return im;
261 }
262 else
263 {
264 RGBA_Image *im;
265 Eina_Rectangle *rect;
266
267 rect = eina_rectangle_new(x, y, w, h);
268 if (!rect) return NULL;
269#ifdef EVAS_CSERVE2
270 if (evas_cserve2_use_get())
271 im = (RGBA_Image *)evas_cache2_image_empty(evas_common_image_cache2_get());
272 else
273#endif
274 im = (RGBA_Image *)evas_cache_image_empty(evas_common_image_cache_get());
275 if (!im)
276 {
277 free(rect);
278 return NULL;
279 }
280 im->cache_entry.flags.alpha |= buf->priv.destination_alpha ? 1 : 0;
281#ifdef EVAS_CSERVE2
282 if (evas_cserve2_use_get())
283 evas_cache2_image_surface_alloc(&im->cache_entry, w, h);
284 else
285#endif
286 evas_cache_image_surface_alloc(&im->cache_entry, w, h);
287 im->extended_info = rect;
288 buf->priv.pending_writes = eina_list_append(buf->priv.pending_writes, im);
289
290 // the region is the update image
291 *cx = 0;
292 *cy = 0;
293 *cw = w;
294 *ch = h;
295 return im;
296 }
297 return NULL;
298}
299
300void
301evas_software_xlib_swapbuf_free_region_for_update(Outbuf *buf EINA_UNUSED, RGBA_Image *update EINA_UNUSED)
302{
303 /* no need to do anything - they are cleaned up on flush */
304}
305
306void
307evas_software_xlib_swapbuf_flush(Outbuf *buf)
308{
309 if (!buf->priv.pending_writes)
310 {
311 Eina_Rectangle *rects, *rect;
312 Eina_Array_Iterator it;
313 unsigned int n, i;
314 RGBA_Image *im;
315
316 n = eina_array_count_get(&buf->priv.onebuf_regions);
317 if (n == 0) return;
318 rects = alloca(n * sizeof(Eina_Rectangle));
319 EINA_ARRAY_ITER_NEXT(&buf->priv.onebuf_regions, i, rect, it)
320 {
321 rects[i] = *rect;
322 }
323 evas_xlib_swapper_buffer_unmap(buf->priv.swapper);
324 evas_xlib_swapper_swap(buf->priv.swapper, rects, n);
325 eina_array_clean(&buf->priv.onebuf_regions);
326 im = buf->priv.onebuf;
327 buf->priv.onebuf = NULL;
328 if (im)
329 {
330#ifdef EVAS_CSERVE2
331 if (evas_cserve2_use_get())
332 evas_cache2_image_close(&im->cache_entry);
333 else
334#endif
335 evas_cache_image_drop(&im->cache_entry);
336 }
337 }
338 else
339 {
340 RGBA_Image *im;
341 Eina_Rectangle *rects;
342 unsigned int n, i = 0;
343
344 n = eina_list_count(buf->priv.pending_writes);
345 if (n == 0) return;
346 rects = alloca(n * sizeof(Eina_Rectangle));
347 EINA_LIST_FREE(buf->priv.pending_writes, im)
348 {
349 Eina_Rectangle *rect = im->extended_info;
350 int x, y, w, h;
351
352 x = rect->x; y = rect->y; w = rect->w; h = rect->h;
353 rects[i] = *rect;
354 if (buf->rot == 0)
355 {
356 rects[i].x = x;
357 rects[i].y = y;
358 }
359 else if (buf->rot == 90)
360 {
361 rects[i].x = y;
362 rects[i].y = buf->w - x - w;
363 }
364 else if (buf->rot == 180)
365 {
366 rects[i].x = buf->w - x - w;
367 rects[i].y = buf->h - y - h;
368 }
369 else if (buf->rot == 270)
370 {
371 rects[i].x = buf->h - y - h;
372 rects[i].y = x;
373 }
374 if ((buf->rot == 0) || (buf->rot == 180))
375 {
376 rects[i].w = w;
377 rects[i].h = h;
378 }
379 else if ((buf->rot == 90) || (buf->rot == 270))
380 {
381 rects[i].w = h;
382 rects[i].h = w;
383 }
384 free(rect);
385#ifdef EVAS_CSERVE2
386 if (evas_cserve2_use_get())
387 evas_cache2_image_close(&im->cache_entry);
388 else
389#endif
390 evas_cache_image_drop(&im->cache_entry);
391 }
392 evas_xlib_swapper_buffer_unmap(buf->priv.swapper);
393 evas_xlib_swapper_swap(buf->priv.swapper, rects, n);
394// evas_xlib_swapper_swap(buf->priv.swapper, NULL, 0);
395 }
396}
397
398void
399evas_software_xlib_swapbuf_idle_flush(Outbuf *buf)
400{
401 return;
402 buf = NULL;
403}
404
405void
406evas_software_xlib_swapbuf_push_updated_region(Outbuf *buf, RGBA_Image *update, int x, int y, int w, int h)
407{
408 Gfx_Func_Convert conv_func = NULL;
409 Eina_Rectangle r = { 0, 0, 0, 0 };
410 int d, bpl = 0, wid, bpp;
411 DATA32 *src_data;
412 DATA8 *dst_data;
413
414 if (!buf->priv.pending_writes) return;
415 d = evas_xlib_swapper_depth_get(buf->priv.swapper);
416 if (buf->priv.pal)
417 {
418 if ((buf->rot == 0) || (buf->rot == 180))
419 conv_func = evas_common_convert_func_get(0, w, h, d,
420 buf->priv.mask.r,
421 buf->priv.mask.g,
422 buf->priv.mask.b,
423 buf->priv.pal->colors,
424 buf->rot);
425 else if ((buf->rot == 90) || (buf->rot == 270))
426 conv_func = evas_common_convert_func_get(0, h, w, d,
427 buf->priv.mask.r,
428 buf->priv.mask.g,
429 buf->priv.mask.b,
430 buf->priv.pal->colors,
431 buf->rot);
432 }
433 else
434 {
435 if ((buf->rot == 0) || (buf->rot == 180))
436 conv_func = evas_common_convert_func_get(0, w, h, d,
437 buf->priv.mask.r,
438 buf->priv.mask.g,
439 buf->priv.mask.b,
440 PAL_MODE_NONE,
441 buf->rot);
442 else if ((buf->rot == 90) || (buf->rot == 270))
443 conv_func = evas_common_convert_func_get(0, h, w, d,
444 buf->priv.mask.r,
445 buf->priv.mask.g,
446 buf->priv.mask.b,
447 PAL_MODE_NONE,
448 buf->rot);
449 }
450 if (!conv_func) return;
451 if (buf->rot == 0)
452 {
453 r.x = x;
454 r.y = y;
455 }
456 else if (buf->rot == 90)
457 {
458 r.x = y;
459 r.y = buf->w - x - w;
460 }
461 else if (buf->rot == 180)
462 {
463 r.x = buf->w - x - w;
464 r.y = buf->h - y - h;
465 }
466 else if (buf->rot == 270)
467 {
468 r.x = buf->h - y - h;
469 r.y = x;
470 }
471 if ((buf->rot == 0) || (buf->rot == 180))
472 {
473 r.w = w;
474 r.h = h;
475 }
476 else if ((buf->rot == 90) || (buf->rot == 270))
477 {
478 r.w = h;
479 r.h = w;
480 }
481 src_data = update->image.data;
482 if (!src_data) return;
483 dst_data = evas_xlib_swapper_buffer_map(buf->priv.swapper, &bpl);
484 if (!dst_data) return;
485 bpp = d / 8;
486 if (bpp <= 0) return;
487 wid = bpl / bpp;
488 dst_data += (bpl * r.y) + (r.x * bpp);
489 if (buf->priv.pal)
490 conv_func(src_data, dst_data,
491 update->cache_entry.w - w,
492 wid - r.w,
493 r.w, r.h,
494 x, y,
495 buf->priv.pal->lookup);
496 else
497 conv_func(src_data, dst_data,
498 update->cache_entry.w - w,
499 wid - r.w,
500 r.w, r.h,
501 x, y,
502 NULL);
503}
504
505void
506evas_software_xlib_swapbuf_reconfigure(Outbuf *buf, int w, int h, int rot,
507 Outbuf_Depth depth)
508{
509 if ((w == buf->w) && (h == buf->h) && (rot == buf->rot) &&
510 (depth == buf->depth))
511 return;
512 buf->w = w;
513 buf->h = h;
514 buf->rot = rot;
515 evas_xlib_swapper_free(buf->priv.swapper);
516 if ((buf->rot == 0) || (buf->rot == 180))
517 buf->priv.swapper = evas_xlib_swapper_new(buf->priv.x11.xlib.disp,
518 buf->priv.x11.xlib.win,
519 buf->priv.x11.xlib.vis,
520 buf->priv.x11.xlib.depth,
521 buf->w, buf->h);
522 else if ((buf->rot == 90) || (buf->rot == 270))
523 buf->priv.swapper = evas_xlib_swapper_new(buf->priv.x11.xlib.disp,
524 buf->priv.x11.xlib.win,
525 buf->priv.x11.xlib.vis,
526 buf->priv.x11.xlib.depth,
527 buf->h, buf->w);
528}
529
530int
531evas_software_xlib_swapbuf_get_rot(Outbuf * buf)
532{
533 return buf->rot;
534}
535
536Eina_Bool
537evas_software_xlib_swapbuf_alpha_get(Outbuf *buf)
538{
539 return buf->priv.destination_alpha;
540}
541
542int
543evas_software_xlib_swapbuf_buffer_state_get(Outbuf *buf)
544{
545 int mode;
546 if (!buf->priv.swapper) return MODE_FULL;
547 mode = evas_xlib_swapper_buffer_state_get(buf->priv.swapper);
548 return mode;
549}
diff --git a/src/modules/evas/engines/software_x11/evas_xlib_swapbuf.h b/src/modules/evas/engines/software_x11/evas_xlib_swapbuf.h
new file mode 100644
index 0000000000..f8276a01e0
--- /dev/null
+++ b/src/modules/evas/engines/software_x11/evas_xlib_swapbuf.h
@@ -0,0 +1,53 @@
1#ifndef EVAS_XLIB_SWAPBUF_H
2#define EVAS_XLIB_SWAPBUF_H
3
4
5#include "evas_engine.h"
6
7
8void evas_software_xlib_swapbuf_init(void);
9void evas_software_xlib_swapbuf_free(Outbuf *buf);
10Outbuf *evas_software_xlib_swapbuf_setup_x(int w,
11 int h,
12 int rot,
13 Outbuf_Depth depth,
14 Display *disp,
15 Drawable draw,
16 Visual *vis,
17 Colormap cmap,
18 int x_depth,
19 int grayscale,
20 int max_colors,
21 Pixmap mask,
22 int shape_dither,
23 int destination_alpha);
24RGBA_Image *evas_software_xlib_swapbuf_new_region_for_update(Outbuf *buf,
25 int x,
26 int y,
27 int w,
28 int h,
29 int *cx,
30 int *cy,
31 int *cw,
32 int *ch);
33void evas_software_xlib_swapbuf_free_region_for_update(Outbuf *buf,
34 RGBA_Image *update);
35void evas_software_xlib_swapbuf_flush(Outbuf *buf);
36void evas_software_xlib_swapbuf_idle_flush(Outbuf *buf);
37void evas_software_xlib_swapbuf_push_updated_region(Outbuf *buf,
38 RGBA_Image *update,
39 int x,
40 int y,
41 int w,
42 int h);
43void evas_software_xlib_swapbuf_reconfigure(Outbuf *buf,
44 int w,
45 int h,
46 int rot,
47 Outbuf_Depth depth);
48int evas_software_xlib_swapbuf_get_rot(Outbuf *buf);
49void evas_software_xlib_swapbuf_rotation_set(Outbuf *buf,
50 int rot);
51Eina_Bool evas_software_xlib_swapbuf_alpha_get(Outbuf *buf);
52int evas_software_xlib_swapbuf_buffer_state_get(Outbuf *buf);
53#endif
diff --git a/src/modules/evas/engines/software_x11/evas_xlib_swapper.c b/src/modules/evas/engines/software_x11/evas_xlib_swapper.c
new file mode 100644
index 0000000000..f863a75ad7
--- /dev/null
+++ b/src/modules/evas/engines/software_x11/evas_xlib_swapper.c
@@ -0,0 +1,281 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include "evas_common.h"
6#include "evas_macros.h"
7#include "evas_xlib_swapper.h"
8
9typedef struct
10{
11 XImage *xim;
12 XShmSegmentInfo shm_info;
13 void *data;
14 int w, h, bpl;
15 Eina_Bool shm : 1;
16 Eina_Bool valid : 1;
17} Buffer;
18
19struct _X_Swapper
20{
21 Display *disp;
22 Drawable draw;
23 Visual *vis;
24 GC gc;
25 Buffer buf[3];
26 int w, h, depth;
27 int buf_cur, buf_num;
28 Eina_Bool mapped: 1;
29};
30
31static Eina_Bool _x_err = EINA_FALSE;
32
33static void
34_x_err_hand(Display *d EINA_UNUSED, XErrorEvent *ev EINA_UNUSED)
35{
36 _x_err = 1;
37 return;
38}
39
40static Eina_Bool
41_buf_new(X_Swapper *swp, Buffer *buf)
42{
43 buf->w = swp->w;
44 buf->h = swp->h;
45
46 // try shm first
47 buf->xim = XShmCreateImage(swp->disp, swp->vis, swp->depth, ZPixmap,
48 NULL, &(buf->shm_info), buf->w, buf->h);
49 if (buf->xim)
50 {
51 buf->bpl = buf->xim->bytes_per_line;
52
53 buf->shm_info.shmid = shmget(IPC_PRIVATE, buf->bpl * buf->h,
54 IPC_CREAT | 0777);
55 if (buf->shm_info.shmid >= 0)
56 {
57 buf->shm_info.readOnly = False;
58 buf->shm_info.shmaddr = buf->data = buf->xim->data =
59 shmat(buf->shm_info.shmid, 0, 0);
60 if (buf->shm_info.shmaddr != ((void *)-1))
61 {
62 XErrorHandler ph;
63
64 XSync(swp->disp, False);
65 _x_err = EINA_FALSE;
66 ph = XSetErrorHandler((XErrorHandler)_x_err_hand);
67 XShmAttach(swp->disp, &(buf->shm_info));
68 XSync(swp->disp, False);
69 XSetErrorHandler((XErrorHandler)ph);
70 if (!_x_err)
71 {
72 buf->shm = EINA_TRUE;
73 }
74 else
75 {
76 shmdt(buf->shm_info.shmaddr);
77 shmctl(buf->shm_info.shmid, IPC_RMID, 0);
78 XDestroyImage(buf->xim);
79 buf->xim = NULL;
80 }
81 }
82 else
83 {
84 shmdt(buf->shm_info.shmaddr);
85 shmctl(buf->shm_info.shmid, IPC_RMID, 0);
86 XDestroyImage(buf->xim);
87 buf->xim = NULL;
88 }
89 }
90 else
91 {
92 XDestroyImage(buf->xim);
93 buf->xim = NULL;
94 }
95 }
96
97 if (!buf->xim) // shm failed - try normal ximage
98 {
99 buf->xim = XCreateImage(swp->disp, swp->vis, swp->depth, ZPixmap,
100 0, NULL, buf->w, buf->h, 32, 0);
101 if (!buf->xim) return EINA_FALSE;
102 buf->bpl = buf->xim->bytes_per_line;
103 buf->data = buf->xim->data = malloc(buf->bpl * buf->h);
104 if (!buf->data)
105 {
106 XDestroyImage(buf->xim);
107 buf->xim = NULL;
108 return EINA_FALSE;
109 }
110 }
111 return EINA_TRUE;
112}
113
114static void
115_buf_free(X_Swapper *swp, Buffer *buf)
116{
117 if (!buf->xim) return;
118 if (buf->shm)
119 {
120 XShmDetach(swp->disp, &(buf->shm_info));
121 XDestroyImage(buf->xim);
122 shmdt(buf->shm_info.shmaddr);
123 shmctl(buf->shm_info.shmid, IPC_RMID, 0);
124 }
125 else
126 {
127 XDestroyImage(buf->xim);
128 }
129 buf->xim = NULL;
130 buf->shm = EINA_FALSE;
131}
132
133static void
134_buf_put(X_Swapper *swp, Buffer *buf, Eina_Rectangle *rects, int nrects)
135{
136 Region tmpr;
137 int i;
138
139 if (!buf->xim) return;
140 tmpr = XCreateRegion();
141 if (rects)
142 {
143 for (i = 0; i < nrects; i++)
144 {
145 XRectangle xr;
146
147 xr.x = rects[i].x; xr.y = rects[i].y;
148 xr.width = rects[i].w; xr.height = rects[i].h;
149 XUnionRectWithRegion(&xr, tmpr, tmpr);
150 }
151 }
152 else
153 {
154 XRectangle xr;
155
156 xr.x = 0; xr.y = 0;
157 xr.width = buf->w; xr.height = buf->h;
158 XUnionRectWithRegion(&xr, tmpr, tmpr);
159 }
160 XSetRegion(swp->disp, swp->gc, tmpr);
161 XDestroyRegion(tmpr);
162 if (buf->shm)
163 {
164 XShmPutImage(swp->disp, swp->draw, swp->gc, buf->xim, 0, 0, 0, 0,
165 buf->w, buf->h, False);
166 }
167 else
168 {
169 XPutImage(swp->disp, swp->draw, swp->gc, buf->xim, 0, 0, 0, 0,
170 buf->w, buf->h);
171 }
172 XSync(swp->disp, False);
173}
174
175////////////////////////////////////
176
177X_Swapper *
178evas_xlib_swapper_new(Display *disp, Drawable draw, Visual *vis,
179 int depth, int w, int h)
180{
181 X_Swapper *swp;
182 XGCValues gcv;
183 int i;
184
185 int nbuf = 3; // pretend we are triple buffered
186
187 swp = calloc(1, sizeof(X_Swapper));
188 if (!swp) return NULL;
189 swp->disp = disp;
190 swp->draw = draw;
191 swp->vis = vis;
192 swp->depth = depth;
193 swp->w = w;
194 swp->h = h;
195 swp->buf_num = nbuf;
196 swp->gc = XCreateGC(swp->disp, swp->draw, 0, &gcv);
197 for (i = 0; i < swp->buf_num; i++)
198 {
199 if (!_buf_new(swp, &(swp->buf[i])))
200 {
201 evas_xlib_swapper_free(swp);
202 return NULL;
203 }
204 }
205 return swp;
206}
207
208void
209evas_xlib_swapper_free(X_Swapper *swp)
210{
211 int i;
212
213 for (i = 0; i < swp->buf_num; i++)
214 {
215 _buf_free(swp, &(swp->buf[i]));
216 }
217 free(swp);
218}
219
220void *
221evas_xlib_swapper_buffer_map(X_Swapper *swp, int *bpl)
222{
223 swp->mapped = EINA_TRUE;
224 if (bpl) *bpl = swp->buf[swp->buf_cur].bpl;
225 return swp->buf[swp->buf_cur].data;
226}
227
228void
229evas_xlib_swapper_buffer_unmap(X_Swapper *swp)
230{
231 swp->mapped = EINA_FALSE;
232}
233
234void
235evas_xlib_swapper_swap(X_Swapper *swp, Eina_Rectangle *rects, int nrects)
236{
237 int n;
238
239 n = swp->buf_cur;
240 _buf_put(swp, &(swp->buf[n]), rects, nrects);
241 swp->buf[n].valid = 1;
242 swp->buf_cur = (swp->buf_cur + 1) % swp->buf_num;
243}
244
245int
246evas_xlib_swapper_buffer_state_get(X_Swapper *swp)
247{
248 int i, n, count = 0;
249
250 for (i = 0; i < swp->buf_num; i++)
251 {
252 n = (swp->buf_num + swp->buf_cur - (i)) % swp->buf_num;
253 if (swp->buf[n].valid) count++;
254 else break;
255 }
256 if (count == swp->buf_num)
257 {
258 if (count == 1) return MODE_COPY;
259 else if (count == 2) return MODE_DOUBLE;
260 else if (count == 3) return MODE_TRIPLE;
261 }
262 return MODE_FULL;
263}
264
265int
266evas_xlib_swapper_depth_get(X_Swapper *swp)
267{
268 return swp->buf[0].xim->bits_per_pixel;
269}
270
271int
272evas_xlib_swapper_byte_order_get(X_Swapper *swp)
273{
274 return swp->buf[0].xim->byte_order;
275}
276
277int
278evas_xlib_swapper_bit_order_get(X_Swapper *swp)
279{
280 return swp->buf[0].xim->bitmap_bit_order;
281}
diff --git a/src/modules/evas/engines/software_x11/evas_xlib_swapper.h b/src/modules/evas/engines/software_x11/evas_xlib_swapper.h
new file mode 100644
index 0000000000..5399b80fcb
--- /dev/null
+++ b/src/modules/evas/engines/software_x11/evas_xlib_swapper.h
@@ -0,0 +1,15 @@
1#include "evas_engine.h"
2
3typedef struct _X_Swapper X_Swapper;
4
5X_Swapper *evas_xlib_swapper_new(Display *disp, Drawable draw, Visual *vis,
6 int depth, int w, int h);
7void evas_xlib_swapper_free(X_Swapper *swp);
8void *evas_xlib_swapper_buffer_map(X_Swapper *swp, int *bpl);
9void evas_xlib_swapper_buffer_unmap(X_Swapper *swp);
10void evas_xlib_swapper_swap(X_Swapper *swp, Eina_Rectangle *rects, int nrects);
11int evas_xlib_swapper_buffer_state_get(X_Swapper *swp);
12int evas_xlib_swapper_depth_get(X_Swapper *swp);
13int evas_xlib_swapper_byte_order_get(X_Swapper *swp);
14int evas_xlib_swapper_bit_order_get(X_Swapper *swp);
15