fix map draw use internal function when native surface set turn on
[framework/uifw/evas.git] / src / modules / engines / software_x11 / evas_engine.c
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_swapbuf.h"
10 # include "evas_xlib_color.h"
11 # include "evas_xlib_image.h"
12 #endif
13
14 #ifdef BUILD_ENGINE_SOFTWARE_XCB
15 # include "evas_xcb_outbuf.h"
16 # include "evas_xcb_color.h"
17 # include "evas_xcb_xdefaults.h"
18 #endif
19
20 #include "evas_x_egl.h"
21
22 int _evas_engine_soft_x11_log_dom = -1;
23
24 /* function tables - filled in later (func and parent func) */
25 static Evas_Func func, pfunc;
26
27 /* engine struct data */
28 typedef struct _Render_Engine Render_Engine;
29
30 struct _Render_Engine
31 {
32    Tilebuf *tb;
33    Outbuf *ob;
34    Tilebuf_Rect *rects;
35    Tilebuf_Rect *rects_prev[3];
36    Eina_Inlist *cur_rect;
37    short mode;
38    unsigned char end : 1;
39    unsigned char lost_back : 1;
40    void (*outbuf_free)(Outbuf *ob);
41    void (*outbuf_reconfigure)(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth);
42    int (*outbuf_get_rot)(Outbuf *ob);
43    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);
44    void (*outbuf_push_updated_region)(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h);
45    void (*outbuf_free_region_for_update)(Outbuf *ob, RGBA_Image *update);
46    void (*outbuf_flush)(Outbuf *ob);
47    void (*outbuf_idle_flush)(Outbuf *ob);
48    int (*outbuf_swap_mode_get)(Outbuf *ob);
49    Eina_Bool (*outbuf_alpha_get)(Outbuf *ob);
50    
51    struct {
52       void *disp;
53       void *config;
54       void *surface;
55    } egl;
56 };
57
58 /* prototypes we will use here */
59 static void *_best_visual_get(int backend, void *connection, int screen);
60 static unsigned int _best_colormap_get(int backend, void *connection, int screen);
61 static int _best_depth_get(int backend, void *connection, int screen);
62
63 static void *eng_info(Evas *e);
64 static void eng_info_free(Evas *e, void *info);
65 static int eng_setup(Evas *e, void *info);
66 static void eng_output_free(void *data);
67 static void eng_output_resize(void *data, int w, int h);
68 static void eng_output_tile_size_set(void *data, int w, int h);
69 static void eng_output_redraws_rect_add(void *data, int x, int y, int w, int h);
70 static void eng_output_redraws_rect_del(void *data, int x, int y, int w, int h);
71 static void eng_output_redraws_clear(void *data);
72 static 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);
73 static void eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h);
74 static void eng_output_flush(void *data);
75 static void eng_output_idle_flush(void *data);
76 static void *eng_image_native_set(void *data, void *image, void *native);
77 static void *eng_image_native_get(void *data __UNUSED__, void *image);
78 static Eina_Bool eng_image_draw(void *data __UNUSED__, void *context, void *surface, void *image,
79                                 int src_x, int src_y, int src_w, int src_h,
80                                 int dst_x, int dst_y, int dst_w, int dst_h,
81                                 int smooth);
82
83 /* internal engine routines */
84
85 #ifdef BUILD_ENGINE_SOFTWARE_XLIB
86
87 /*
88 static void *
89 _output_egl_setup(int w, int h, int rot, Display *disp, Drawable draw,
90                   Visual *vis, Colormap cmap, int depth, int debug,
91                   int grayscale, int max_colors, Pixmap mask,
92                   int shape_dither, int destination_alpha)
93 {
94    Render_Engine *re;
95    void *ptr;
96    int stride = 0;
97    
98    if (depth != 32) return NULL;
99    if (mask) return NULL;
100    if (!(re = calloc(1, sizeof(Render_Engine)))) return NULL;
101    re->egl.disp = _egl_x_disp_get(disp);
102    if (!re->egl.disp)
103      {
104         free(re);
105         return NULL;
106      }
107    re->egl.config = _egl_x_disp_choose_config(re->egl.disp);
108    if (!re->egl.config)
109      {
110         _egl_x_disp_terminate(re->egl.disp);
111         free(re);
112         return NULL;
113      }
114    re->egl.surface = _egl_x_win_surf_new(re->egl.disp, draw, re->egl.config);
115    if (!re->egl.surface)
116      {
117         _egl_x_disp_terminate(re->egl.disp);
118         free(re);
119         return NULL;
120      }
121    ptr = _egl_x_surf_map(re->egl.disp, re->egl.surface, &stride);
122    if (!ptr)
123      {
124         _egl_x_win_surf_free(re->egl.disp, re->egl.surface);
125         _egl_x_disp_terminate(re->egl.disp);
126         free(re);
127         return NULL;
128      }
129    _egl_x_surf_unmap(re->egl.disp, re->egl.surface);
130    
131    re->ob = 
132      evas_software_egl_outbuf_setup_x(w, h, rot, OUTBUF_DEPTH_INHERIT, disp, 
133                                        draw, vis, cmap, depth, grayscale,
134                                        max_colors, mask, shape_dither,
135                                        destination_alpha);
136    
137    re->tb = evas_common_tilebuf_new(w, h);
138    if (!re->tb)
139      {
140         evas_software_xlib_outbuf_free(re->ob);
141         free(re);
142         return NULL;
143      }
144    evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
145    
146    return re;
147 }
148 */
149    
150 static void
151 _output_egl_shutdown(Render_Engine *re)
152 {
153    if (!re->egl.disp) return;
154    _egl_x_win_surf_free(re->egl.disp, re->egl.surface);
155    _egl_x_disp_terminate(re->egl.disp);
156 }
157
158 static void *
159 _output_xlib_setup(int w, int h, int rot, Display *disp, Drawable draw,
160                    Visual *vis, Colormap cmap, int depth, int debug,
161                    int grayscale, int max_colors, Pixmap mask,
162                    int shape_dither, int destination_alpha)
163 {
164    Render_Engine *re;
165
166    if (!(re = calloc(1, sizeof(Render_Engine)))) return NULL;
167
168    evas_software_xlib_x_init();
169    evas_software_xlib_x_color_init();
170    evas_software_xlib_outbuf_init();
171
172    re->ob = 
173      evas_software_xlib_outbuf_setup_x(w, h, rot, OUTBUF_DEPTH_INHERIT, disp, 
174                                        draw, vis, cmap, depth, grayscale,
175                                        max_colors, mask, shape_dither,
176                                        destination_alpha);
177    if (!re->ob)
178      {
179         free(re);
180         return NULL;
181      }
182
183    /* for updates return 1 big buffer, but only use portions of it, also cache
184     * it and keepit around until an idle_flush */
185
186    /* disable for now - i am hunting down why some expedite tests are slower,
187     * as well as shaped stuff is broken and probable non-32bpp is broken as
188     * convert funcs dont do the right thing
189     *
190     */
191 //   re->ob->onebuf = 1;
192
193    evas_software_xlib_outbuf_debug_set(re->ob, debug);
194    re->tb = evas_common_tilebuf_new(w, h);
195    if (!re->tb)
196      {
197         evas_software_xlib_outbuf_free(re->ob);
198         free(re);
199         return NULL;
200      }
201
202    /* in preliminary tests 16x16 gave highest framerates */
203    evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
204    return re;
205 }
206
207 static void *
208 _output_swapbuf_setup(int w, int h, int rot, Display *disp, Drawable draw,
209                       Visual *vis, Colormap cmap, int depth,
210                       int debug EINA_UNUSED,
211                       int grayscale, int max_colors, Pixmap mask,
212                       int shape_dither, int destination_alpha)
213 {
214    Render_Engine *re;
215
216    if (!(re = calloc(1, sizeof(Render_Engine)))) return NULL;
217
218    evas_software_xlib_x_init();
219    evas_software_xlib_x_color_init();
220    evas_software_xlib_swapbuf_init();
221    
222    re->ob = 
223      evas_software_xlib_swapbuf_setup_x(w, h, rot, OUTBUF_DEPTH_INHERIT, disp, 
224                                         draw, vis, cmap, depth, grayscale,
225                                         max_colors, mask, shape_dither,
226                                         destination_alpha);
227    if (!re->ob)
228      {
229         free(re);
230         return NULL;
231      }
232
233    re->tb = evas_common_tilebuf_new(w, h);
234    if (!re->tb)
235      {
236         evas_software_xlib_swapbuf_free(re->ob);
237         free(re);
238         return NULL;
239      }
240
241    evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
242    return re;
243 }
244 #endif
245
246 #ifdef BUILD_ENGINE_SOFTWARE_XCB
247 static void *
248 _output_xcb_setup(int w, int h, int rot, xcb_connection_t *conn, 
249                   xcb_screen_t *screen, xcb_drawable_t draw, 
250                   xcb_visualtype_t *vis, xcb_colormap_t cmap, int depth,
251                   int debug, int grayscale, int max_colors, xcb_drawable_t mask,
252                   int shape_dither, int destination_alpha)
253 {
254    Render_Engine *re;
255
256    if (!(re = calloc(1, sizeof(Render_Engine)))) return NULL;
257
258    evas_software_xcb_init();
259    evas_software_xcb_color_init();
260    evas_software_xcb_outbuf_init();
261    re->ob = 
262      evas_software_xcb_outbuf_setup(w, h, rot, OUTBUF_DEPTH_INHERIT, conn, 
263                                     screen, draw, vis, cmap, depth,
264                                     grayscale, max_colors, mask, 
265                                     shape_dither, destination_alpha);
266    if (!re->ob)
267      {
268         free(re);
269         return NULL;
270      }
271
272    /* for updates return 1 big buffer, but only use portions of it, also cache 
273     * it and keepit around until an idle_flush */
274
275    /* disable for now - i am hunting down why some expedite tests are slower,
276     * as well as shaped stuff is broken and probable non-32bpp is broken as
277     * convert funcs dont do the right thing
278     *
279     */
280 //   re->ob->onebuf = 1;
281
282    evas_software_xcb_outbuf_debug_set(re->ob, debug);
283
284    re->tb = evas_common_tilebuf_new(w, h);
285    if (!re->tb)
286      {
287         evas_software_xcb_outbuf_free(re->ob);
288         free(re);
289         return NULL;
290      }
291
292    /* in preliminary tests 16x16 gave highest framerates */
293    evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
294    return re;
295 }
296 #endif
297
298 static void *
299 _best_visual_get(int backend, void *connection, int screen)
300 {
301    if (!connection) return NULL;
302
303 #ifdef BUILD_ENGINE_SOFTWARE_XLIB
304    if (backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XLIB)
305      return DefaultVisual((Display *)connection, screen);
306 #endif
307
308 #ifdef BUILD_ENGINE_SOFTWARE_XCB
309    if (backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XCB)
310      {
311         xcb_screen_iterator_t iter_screen;
312         xcb_depth_iterator_t iter_depth;
313         xcb_screen_t *s = NULL;
314
315         iter_screen = 
316           xcb_setup_roots_iterator(xcb_get_setup((xcb_connection_t *)connection));
317         for (; iter_screen.rem; --screen, xcb_screen_next(&iter_screen))
318           if (screen == 0)
319             {
320                s = iter_screen.data;
321                break;
322             }
323
324         iter_depth = xcb_screen_allowed_depths_iterator(s);
325         for (; iter_depth.rem; xcb_depth_next(&iter_depth))
326           {
327              xcb_visualtype_iterator_t iter_vis;
328
329              iter_vis = xcb_depth_visuals_iterator(iter_depth.data);
330              for (; iter_vis.rem; xcb_visualtype_next(&iter_vis))
331                {
332                   if (s->root_visual == iter_vis.data->visual_id)
333                     return iter_vis.data;
334                }
335           }
336      }
337 #endif
338
339    return NULL;
340 }
341
342 static unsigned int
343 _best_colormap_get(int backend, void *connection, int screen)
344 {
345    if (!connection) return 0;
346
347 #ifdef BUILD_ENGINE_SOFTWARE_XLIB
348    if (backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XLIB)
349      return DefaultColormap((Display *)connection, screen);
350 #endif
351
352 #ifdef BUILD_ENGINE_SOFTWARE_XCB
353    if (backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XCB)
354      {
355         xcb_screen_iterator_t iter_screen;
356         xcb_screen_t *s = NULL;
357
358         iter_screen = 
359           xcb_setup_roots_iterator(xcb_get_setup((xcb_connection_t *)connection));
360         for (; iter_screen.rem; --screen, xcb_screen_next(&iter_screen))
361           if (screen == 0)
362             {
363                s = iter_screen.data;
364                break;
365             }
366
367         return s->default_colormap;
368      }
369 #endif
370
371    return 0;
372 }
373
374 static int
375 _best_depth_get(int backend, void *connection, int screen)
376 {
377    if (!connection) return 0;
378
379 #ifdef BUILD_ENGINE_SOFTWARE_XLIB
380    if (backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XLIB)
381      return DefaultDepth((Display *)connection, screen);
382 #endif
383
384 #ifdef BUILD_ENGINE_SOFTWARE_XCB
385    if (backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XCB)
386      {
387         xcb_screen_iterator_t iter_screen;
388         xcb_screen_t *s = NULL;
389
390         iter_screen = 
391           xcb_setup_roots_iterator(xcb_get_setup((xcb_connection_t *)connection));
392         for (; iter_screen.rem; --screen, xcb_screen_next(&iter_screen))
393           if (screen == 0)
394             {
395                s = iter_screen.data;
396                break;
397             }
398
399         return s->root_depth;
400      }
401 #endif
402
403    return 0;
404 }
405
406 /* engine api this module provides */
407 static void *
408 eng_info(Evas *e __UNUSED__)
409 {
410    Evas_Engine_Info_Software_X11 *info;
411
412    if (!(info = calloc(1, sizeof(Evas_Engine_Info_Software_X11))))
413      return NULL;
414
415    info->magic.magic = rand();
416    info->info.debug = 0;
417    info->info.alloc_grayscale = 0;
418    info->info.alloc_colors_max = 216;
419    info->func.best_visual_get = _best_visual_get;
420    info->func.best_colormap_get = _best_colormap_get;
421    info->func.best_depth_get = _best_depth_get;
422    info->render_mode = EVAS_RENDER_MODE_BLOCKING;
423    return info;
424 }
425
426 static void
427 eng_info_free(Evas *e __UNUSED__, void *info)
428 {
429    Evas_Engine_Info_Software_X11 *in;
430
431    in = (Evas_Engine_Info_Software_X11 *)info;
432    free(in);
433 }
434
435 static int
436 eng_setup(Evas *e, void *in)
437 {
438    Evas_Engine_Info_Software_X11 *info;
439    Render_Engine *re = NULL;
440
441    info = (Evas_Engine_Info_Software_X11 *)in;
442    if (!e->engine.data.output)
443      {
444         /* if we haven't initialized - init (automatic abort if already done) */
445         evas_common_cpu_init();
446         evas_common_blend_init();
447         evas_common_image_init();
448         evas_common_convert_init();
449         evas_common_scale_init();
450         evas_common_rectangle_init();
451         evas_common_polygon_init();
452         evas_common_line_init();
453         evas_common_font_init();
454         evas_common_draw_init();
455         evas_common_tilebuf_init();
456
457 #ifdef BUILD_ENGINE_SOFTWARE_XLIB
458         if (info->info.backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XLIB)
459           {
460              static int try_swapbuf = -1;
461              
462              if (try_swapbuf == -1)
463                {
464                   if (getenv("EVAS_DRI_SWAPBUF")) try_swapbuf = 1;
465                   else try_swapbuf = 0;
466                }
467              if (try_swapbuf)
468                re = _output_swapbuf_setup(e->output.w, e->output.h,
469                                           info->info.rotation, info->info.connection,
470                                           info->info.drawable, info->info.visual,
471                                           info->info.colormap,
472                                           info->info.depth, info->info.debug,
473                                           info->info.alloc_grayscale,
474                                           info->info.alloc_colors_max,
475                                           info->info.mask, info->info.shape_dither,
476                                           info->info.destination_alpha);
477              if (re)
478                {
479                   re->outbuf_free                   = evas_software_xlib_swapbuf_free;
480                   re->outbuf_reconfigure            = evas_software_xlib_swapbuf_reconfigure;
481                   re->outbuf_get_rot                = evas_software_xlib_swapbuf_get_rot;
482                   re->outbuf_new_region_for_update  = evas_software_xlib_swapbuf_new_region_for_update;
483                   re->outbuf_push_updated_region    = evas_software_xlib_swapbuf_push_updated_region;
484                   re->outbuf_free_region_for_update = evas_software_xlib_swapbuf_free_region_for_update;
485                   re->outbuf_flush                  = evas_software_xlib_swapbuf_flush;
486                   re->outbuf_idle_flush             = evas_software_xlib_swapbuf_idle_flush;
487                   re->outbuf_alpha_get              = evas_software_xlib_swapbuf_alpha_get;
488                   re->outbuf_swap_mode_get          = evas_software_xlib_swapbuf_buffer_state_get;
489                }
490
491              if (!re)
492                {
493                   re = _output_xlib_setup(e->output.w, e->output.h,
494                                           info->info.rotation, info->info.connection,
495                                           info->info.drawable, info->info.visual,
496                                           info->info.colormap,
497                                           info->info.depth, info->info.debug,
498                                           info->info.alloc_grayscale,
499                                           info->info.alloc_colors_max,
500                                           info->info.mask, info->info.shape_dither,
501                                           info->info.destination_alpha);
502                   
503                   re->outbuf_free                   = evas_software_xlib_outbuf_free;
504                   re->outbuf_reconfigure            = evas_software_xlib_outbuf_reconfigure;
505                   re->outbuf_get_rot                = evas_software_xlib_outbuf_get_rot;
506                   re->outbuf_new_region_for_update  = evas_software_xlib_outbuf_new_region_for_update;
507                   re->outbuf_push_updated_region    = evas_software_xlib_outbuf_push_updated_region;
508                   re->outbuf_free_region_for_update = evas_software_xlib_outbuf_free_region_for_update;
509                   re->outbuf_flush                  = evas_software_xlib_outbuf_flush;
510                   re->outbuf_idle_flush             = evas_software_xlib_outbuf_idle_flush;
511                   re->outbuf_alpha_get              = evas_software_xlib_outbuf_alpha_get;
512                   re->outbuf_swap_mode_get          = NULL;
513                }
514           }
515 #endif
516
517 #ifdef BUILD_ENGINE_SOFTWARE_XCB
518         if (info->info.backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XCB)
519           {
520              re = _output_xcb_setup(e->output.w, e->output.h,
521                                     info->info.rotation, info->info.connection, 
522                                     info->info.screen, info->info.drawable, 
523                                     info->info.visual, info->info.colormap, 
524                                     info->info.depth, info->info.debug, 
525                                     info->info.alloc_grayscale,
526                                     info->info.alloc_colors_max,
527                                     info->info.mask, info->info.shape_dither,
528                                     info->info.destination_alpha);
529
530              re->outbuf_free                   = evas_software_xcb_outbuf_free;
531              re->outbuf_reconfigure            = evas_software_xcb_outbuf_reconfigure;
532              re->outbuf_get_rot                = evas_software_xcb_outbuf_rotation_get;
533              re->outbuf_new_region_for_update  = evas_software_xcb_outbuf_new_region_for_update;
534              re->outbuf_push_updated_region    = evas_software_xcb_outbuf_push_updated_region;
535              re->outbuf_free_region_for_update = evas_software_xcb_outbuf_free_region_for_update;
536              re->outbuf_flush                  = evas_software_xcb_outbuf_flush;
537              re->outbuf_idle_flush             = evas_software_xcb_outbuf_idle_flush;
538              re->outbuf_alpha_get              = evas_software_xcb_outbuf_alpha_get;
539              re->outbuf_swap_mode_get          = NULL;
540           }
541 #endif
542
543         e->engine.data.output = re;
544      }
545    else
546      {
547         int ponebuf = 0;
548
549         re = e->engine.data.output;
550         if ((re) && (re->ob)) ponebuf = re->ob->onebuf;
551
552 #ifdef BUILD_ENGINE_SOFTWARE_XLIB
553         if (info->info.backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XLIB)
554           {
555              // XXX
556              re->outbuf_free(re->ob);
557
558              if (re->outbuf_free == evas_software_xlib_swapbuf_free)
559                {
560                   re->ob = 
561                     evas_software_xlib_swapbuf_setup_x(e->output.w, e->output.h,
562                                                        info->info.rotation,
563                                                        OUTBUF_DEPTH_INHERIT,
564                                                        info->info.connection,
565                                                        info->info.drawable,
566                                                        info->info.visual,
567                                                        info->info.colormap,
568                                                        info->info.depth,
569                                                        info->info.alloc_grayscale,
570                                                        info->info.alloc_colors_max,
571                                                        info->info.mask,
572                                                        info->info.shape_dither,
573                                                        info->info.destination_alpha);
574                }
575              else
576                {
577                   re->ob = 
578                     evas_software_xlib_outbuf_setup_x(e->output.w, e->output.h,
579                                                       info->info.rotation,
580                                                       OUTBUF_DEPTH_INHERIT,
581                                                       info->info.connection,
582                                                       info->info.drawable,
583                                                       info->info.visual,
584                                                       info->info.colormap,
585                                                       info->info.depth,
586                                                       info->info.alloc_grayscale,
587                                                       info->info.alloc_colors_max,
588                                                       info->info.mask,
589                                                       info->info.shape_dither,
590                                                       info->info.destination_alpha);
591                   evas_software_xlib_outbuf_debug_set(re->ob, info->info.debug);
592                }
593           }
594 #endif
595
596 #ifdef BUILD_ENGINE_SOFTWARE_XCB
597         if (info->info.backend == EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XCB)
598           {
599              evas_software_xcb_outbuf_free(re->ob);
600              re->ob = 
601                evas_software_xcb_outbuf_setup(e->output.w, e->output.h,
602                                               info->info.rotation,
603                                               OUTBUF_DEPTH_INHERIT,
604                                               info->info.connection,
605                                               info->info.screen,
606                                               info->info.drawable,
607                                               info->info.visual,
608                                               info->info.colormap,
609                                               info->info.depth,
610                                               info->info.alloc_grayscale,
611                                               info->info.alloc_colors_max,
612                                               info->info.mask,
613                                               info->info.shape_dither,
614                                               info->info.destination_alpha);
615              evas_software_xcb_outbuf_debug_set(re->ob, info->info.debug);
616           }
617 #endif
618         if ((re) && (re->ob)) re->ob->onebuf = ponebuf;
619      }
620    if (!e->engine.data.output) return 0;
621    if (!e->engine.data.context) 
622      {
623         e->engine.data.context = 
624           e->engine.func->context_new(e->engine.data.output);
625      }
626
627    re = e->engine.data.output;
628
629    return 1;
630 }
631
632 static void
633 eng_output_free(void *data)
634 {
635    Render_Engine *re;
636
637    if ((re = (Render_Engine *)data))
638      {
639         re->outbuf_free(re->ob);
640         evas_common_tilebuf_free(re->tb);
641         if (re->rects) evas_common_tilebuf_free_render_rects(re->rects);
642         if (re->rects_prev[0]) evas_common_tilebuf_free_render_rects(re->rects_prev[0]);
643         if (re->rects_prev[1]) evas_common_tilebuf_free_render_rects(re->rects_prev[1]);
644         if (re->rects_prev[2]) evas_common_tilebuf_free_render_rects(re->rects_prev[2]);
645         _output_egl_shutdown(re);
646         free(re);
647      }
648
649    evas_common_font_shutdown();
650    evas_common_image_shutdown();
651 }
652
653 static void
654 eng_output_resize(void *data, int w, int h)
655 {
656    Render_Engine *re;
657
658    re = (Render_Engine *)data;
659    re->outbuf_reconfigure(re->ob, w, h, re->outbuf_get_rot(re->ob),
660                           OUTBUF_DEPTH_INHERIT);
661    evas_common_tilebuf_free(re->tb);
662    re->tb = evas_common_tilebuf_new(w, h);
663    if (re->tb)
664      evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
665 }
666
667 static void
668 eng_output_tile_size_set(void *data, int w, int h)
669 {
670    Render_Engine *re;
671
672    re = (Render_Engine *)data;
673    evas_common_tilebuf_set_tile_size(re->tb, w, h);
674 }
675
676 static void
677 eng_output_redraws_rect_add(void *data, int x, int y, int w, int h)
678 {
679    Render_Engine *re;
680
681    re = (Render_Engine *)data;
682    evas_common_tilebuf_add_redraw(re->tb, x, y, w, h);
683 }
684
685 static void
686 eng_output_redraws_rect_del(void *data, int x, int y, int w, int h)
687 {
688    Render_Engine *re;
689
690    re = (Render_Engine *)data;
691    evas_common_tilebuf_del_redraw(re->tb, x, y, w, h);
692 }
693
694 static void
695 eng_output_redraws_clear(void *data)
696 {
697    Render_Engine *re;
698
699    re = (Render_Engine *)data;
700    evas_common_tilebuf_clear(re->tb);
701 }
702
703 static Tilebuf_Rect *
704 _merge_rects(Tilebuf *tb, Tilebuf_Rect *r1, Tilebuf_Rect *r2, Tilebuf_Rect *r3)
705 {
706    Tilebuf_Rect *r, *rects;
707 //   int px1, py1, px2, py2;
708    
709    if (r1)
710      {
711         EINA_INLIST_FOREACH(EINA_INLIST_GET(r1), r)
712           {
713              evas_common_tilebuf_add_redraw(tb, r->x, r->y, r->w, r->h);
714           }
715      }
716    if (r2)
717      {
718         EINA_INLIST_FOREACH(EINA_INLIST_GET(r2), r)
719           {
720              evas_common_tilebuf_add_redraw(tb, r->x, r->y, r->w, r->h);
721           }
722      }
723    if (r2)
724      {
725         EINA_INLIST_FOREACH(EINA_INLIST_GET(r3), r)
726           {
727              evas_common_tilebuf_add_redraw(tb, r->x, r->y, r->w, r->h);
728           }
729      }
730    rects = evas_common_tilebuf_get_render_rects(tb);
731
732 /*   
733    // bounding box -> make a bounding box single region update of all regions.
734    // yes we could try and be smart and figure out size of regions, how far
735    // apart etc. etc. to try and figure out an optimal "set". this is a tradeoff
736    // between multiple update regions to render and total pixels to render.
737    if (rects)
738      {
739         px1 = rects->x; py1 = rects->y;
740         px2 = rects->x + rects->w; py2 = rects->y + rects->h;
741         EINA_INLIST_FOREACH(EINA_INLIST_GET(rects), r)
742           {
743              if (r->x < x1) px1 = r->x;
744              if (r->y < y1) py1 = r->y;
745              if ((r->x + r->w) > x2) px2 = r->x + r->w;
746              if ((r->y + r->h) > y2) py2 = r->y + r->h;
747           }
748         evas_common_tilebuf_free_render_rects(rects);
749         rects = calloc(1, sizeof(Tilebuf_Rect));
750         if (rects)
751           {
752              rects->x = px1;
753              rects->y = py1;
754              rects->w = px2 - px1;
755              rects->h = py2 - py1;
756           }
757      }
758  */
759    evas_common_tilebuf_clear(tb);
760    return rects;
761 }
762
763
764 static void *
765 eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch)
766 {
767    Render_Engine *re;
768    RGBA_Image *surface;
769    Tilebuf_Rect *rect;
770    Eina_Bool first_rect = EINA_FALSE;
771
772 #define CLEAR_PREV_RECTS(x) \
773    do { \
774       if (re->rects_prev[x]) \
775         evas_common_tilebuf_free_render_rects(re->rects_prev[x]); \
776       re->rects_prev[x] = NULL; \
777    } while (0)
778    
779    re = (Render_Engine *)data;
780    if (re->end)
781      {
782         re->end = 0;
783         return NULL;
784      }
785    
786    if (!re->rects)
787      {
788         int mode = MODE_COPY;
789
790         if (re->outbuf_swap_mode_get) mode = re->outbuf_swap_mode_get(re->ob);
791         re->mode = mode;
792         re->rects = evas_common_tilebuf_get_render_rects(re->tb);
793         if (re->rects)
794           {
795              if (re->lost_back)
796                {
797                   /* if we lost our backbuffer since the last frame redraw all */
798                   re->lost_back = 0;
799                   evas_common_tilebuf_add_redraw(re->tb, 0, 0, re->ob->w, re->ob->h);
800                   evas_common_tilebuf_free_render_rects(re->rects);
801                   re->rects = evas_common_tilebuf_get_render_rects(re->tb);
802                }
803              /* ensure we get rid of previous rect lists we dont need if mode
804               * changed/is appropriate */
805              evas_common_tilebuf_clear(re->tb);
806              CLEAR_PREV_RECTS(2);
807              re->rects_prev[2] = re->rects_prev[1];
808              re->rects_prev[1] = re->rects_prev[0];
809              re->rects_prev[0] = re->rects;
810              re->rects = NULL;
811              switch (re->mode)
812                {
813                 case MODE_FULL:
814                 case MODE_COPY: // no prev rects needed
815                   re->rects = _merge_rects(re->tb, re->rects_prev[0], NULL, NULL);
816                   break;
817                 case MODE_DOUBLE: // double mode - only 1 level of prev rect
818                   re->rects = _merge_rects(re->tb, re->rects_prev[0], re->rects_prev[1], NULL);
819                   break;
820                 case MODE_TRIPLE: // keep all
821                   re->rects = _merge_rects(re->tb, re->rects_prev[0], re->rects_prev[1], re->rects_prev[2]);
822                   break;
823                 default:
824                   break;
825                }
826              first_rect = EINA_TRUE;
827           }
828         evas_common_tilebuf_clear(re->tb);
829         re->cur_rect = EINA_INLIST_GET(re->rects);
830      }
831    if (!re->cur_rect) return NULL;
832    rect = (Tilebuf_Rect *)re->cur_rect;
833    if (re->rects)
834      {
835         switch (re->mode)
836           {
837            case MODE_COPY:
838            case MODE_DOUBLE:
839            case MODE_TRIPLE:
840              rect = (Tilebuf_Rect *)re->cur_rect;
841              *x = rect->x;
842              *y = rect->y;
843              *w = rect->w;
844              *h = rect->h;
845              *cx = rect->x;
846              *cy = rect->y;
847              *cw = rect->w;
848              *ch = rect->h;
849              re->cur_rect = re->cur_rect->next;
850              break;
851            case MODE_FULL:
852              re->cur_rect = NULL;
853              if (x) *x = 0;
854              if (y) *y = 0;
855              if (w) *w = re->ob->w;
856              if (h) *h = re->ob->h;
857              if (cx) *cx = 0;
858              if (cy) *cy = 0;
859              if (cw) *cw = re->ob->w;
860              if (ch) *ch = re->ob->h;
861              break;
862            default:
863              break;
864           }
865         if (first_rect)
866           {
867              // do anything needed fir the first frame
868           }
869         surface = 
870           re->outbuf_new_region_for_update(re->ob,
871                                            *x, *y, *w, *h,
872                                            cx, cy, cw, ch);
873         if (!re->cur_rect)
874           {
875              re->end = 1;
876           }
877         return surface;
878      }
879    return NULL;
880 }
881
882 static void
883 eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h)
884 {
885    Render_Engine *re;
886
887    re = (Render_Engine *)data;
888 #if defined(BUILD_PIPE_RENDER)
889    evas_common_pipe_map_begin(surface);
890 #endif /* BUILD_PIPE_RENDER */
891    re->outbuf_push_updated_region(re->ob, surface, x, y, w, h);
892    re->outbuf_free_region_for_update(re->ob, surface);
893    evas_common_cpu_end_opt();
894 }
895
896 static void
897 eng_output_flush(void *data)
898 {
899    Render_Engine *re;
900
901    re = (Render_Engine *)data;
902    re->outbuf_flush(re->ob);
903    if (re->rects)
904      {
905         evas_common_tilebuf_free_render_rects(re->rects);
906         re->rects = NULL;
907      }
908 }
909
910 static void
911 eng_output_idle_flush(void *data)
912 {
913    Render_Engine *re;
914
915    re = (Render_Engine *)data;
916    re->outbuf_idle_flush(re->ob);
917 }
918
919 static Eina_Bool
920 eng_canvas_alpha_get(void *data, void *context __UNUSED__)
921 {
922    Render_Engine *re;
923
924    re = (Render_Engine *)data;
925    return (re->ob->priv.destination_alpha) || (re->outbuf_alpha_get(re->ob));
926 }
927
928 static void
929 evas_software_image_map_draw(void *data, void *context, RGBA_Image *surface, RGBA_Image *im, RGBA_Map *m, int smooth, int level, int offset)
930 {
931    if (m->count - offset < 3) return;
932
933    if ((m->pts[0 + offset].x == m->pts[3 + offset].x) &&
934        (m->pts[1 + offset].x == m->pts[2 + offset].x) &&
935        (m->pts[0 + offset].y == m->pts[1 + offset].y) &&
936        (m->pts[3 + offset].y == m->pts[2 + offset].y) &&
937        (m->pts[0 + offset].x <= m->pts[1 + offset].x) &&
938        (m->pts[0 + offset].y <= m->pts[2 + offset].y) &&
939        (m->pts[0 + offset].u == 0) &&
940        (m->pts[0 + offset].v == 0) &&
941        (m->pts[1 + offset].u == (int)(im->cache_entry.w << FP)) &&
942        (m->pts[1 + offset].v == 0) &&
943        (m->pts[2 + offset].u == (int)(im->cache_entry.w << FP)) &&
944        (m->pts[2 + offset].v == (int)(im->cache_entry.h << FP)) &&
945        (m->pts[3 + offset].u == 0) &&
946        (m->pts[3 + offset].v == (int)(im->cache_entry.h << FP)) &&
947        (m->pts[0 + offset].col == 0xffffffff) &&
948        (m->pts[1 + offset].col == 0xffffffff) &&
949        (m->pts[2 + offset].col == 0xffffffff) &&
950        (m->pts[3 + offset].col == 0xffffffff))
951      {
952         int dx, dy, dw, dh;
953
954         dx = m->pts[0 + offset].x >> FP;
955         dy = m->pts[0 + offset].y >> FP;
956         dw = (m->pts[2 + offset].x >> FP) - dx;
957         dh = (m->pts[2 + offset].y >> FP) - dy;
958         eng_image_draw
959           (data, context, surface, im,
960            0, 0, im->cache_entry.w, im->cache_entry.h,
961            dx, dy, dw, dh, smooth);
962      }
963    else
964      {
965 #ifdef BUILD_PIPE_RENDER
966         if ((cpunum > 1))
967           {
968              evas_common_pipe_map_draw(im, surface, context, m, smooth, level);
969              return ;
970           }
971         else
972 #endif
973           {
974              evas_common_map_rgba(im, surface, context, m->count - offset, &m->pts[offset], smooth, level);
975           }
976      }
977    evas_common_cpu_end_opt();
978
979    if (m->count > 4)
980      {
981         evas_software_image_map_draw(data, context, surface, im, m, smooth, level, offset + 2);
982      }
983 }
984
985 static void
986 eng_image_map_draw(void *data, void *context, void *surface, void *image, RGBA_Map *m, int smooth, int level)
987 {
988    if (!image) return;
989    if (m->count < 3) return;
990
991    evas_software_image_map_draw(data, context, surface, image, m, smooth, level, 0);
992 }
993
994 static void *
995 eng_image_native_set(void *data, void *image, void *native)
996 {
997    //return image;
998    Evas_Native_Surface *ns = native;
999    RGBA_Image *im = image;
1000    Render_Engine *re = (Render_Engine *)data;
1001
1002    if (!im || !ns) return NULL;
1003    if (ns->type != EVAS_NATIVE_SURFACE_X11) return NULL;
1004 #ifdef BUILD_ENGINE_SOFTWARE_XLIB
1005    return evas_xlib_image_native_set(re->ob, image, ns);
1006 #endif
1007    return im;
1008 }
1009
1010 static void *
1011 eng_image_native_get(void *data __UNUSED__, void *image)
1012 {
1013 #ifdef BUILD_ENGINE_SOFTWARE_XLIB
1014    RGBA_Image *im = image;
1015    Native *n;
1016    if (!im) return NULL;
1017    n = im->native.data;
1018    if (!n) return NULL;
1019    return &(n->ns);
1020 #endif
1021    return NULL;
1022 }
1023
1024 static Eina_Bool
1025 eng_image_draw(void *data __UNUSED__, void *context, void *surface, void *image,
1026                int src_x, int src_y, int src_w, int src_h,
1027                int dst_x, int dst_y, int dst_w, int dst_h,
1028                int smooth)
1029 {
1030    RGBA_Image *im;
1031    Native *n = NULL;
1032
1033    if (!image) return EINA_FALSE;
1034    im = image;
1035    if (im->native.data)
1036      n = im->native.data;
1037    if ((n) && (n->ns.type == EVAS_NATIVE_SURFACE_X11))
1038      {
1039 #ifdef BUILD_ENGINE_SOFTWARE_XLIB
1040         if(evas_xlib_image_shm_copy(im))
1041           {
1042              evas_common_image_colorspace_dirty(im);
1043           }
1044 #endif
1045      }
1046    evas_common_rgba_image_scalecache_prepare(&im->cache_entry, surface, context, smooth,
1047            src_x, src_y, src_w, src_h,
1048            dst_x, dst_y, dst_w, dst_h);
1049    evas_common_rgba_image_scalecache_do(&im->cache_entry, surface, context, smooth,
1050            src_x, src_y, src_w, src_h,
1051            dst_x, dst_y, dst_w, dst_h);
1052    evas_common_cpu_end_opt();
1053    return EINA_TRUE;
1054 }
1055
1056 /* module advertising code */
1057 static int
1058 module_open(Evas_Module *em)
1059 {
1060    if (!em) return 0;
1061
1062    /* get whatever engine module we inherit from */
1063    if (!_evas_module_engine_inherit(&pfunc, "software_generic")) return 0;
1064
1065    _evas_engine_soft_x11_log_dom = 
1066      eina_log_domain_register("evas-software_x11", EVAS_DEFAULT_LOG_COLOR);
1067
1068    if (_evas_engine_soft_x11_log_dom < 0)
1069      {
1070         EINA_LOG_ERR("Can not create a module log domain.");
1071         return 0;
1072      }
1073
1074    /* store it for later use */
1075    func = pfunc;
1076
1077    /* now to override methods */
1078 #define ORD(f) EVAS_API_OVERRIDE(f, &func, eng_)
1079    ORD(info);
1080    ORD(info_free);
1081    ORD(setup);
1082    ORD(canvas_alpha_get);
1083    ORD(output_free);
1084    ORD(output_resize);
1085    ORD(output_tile_size_set);
1086    ORD(output_redraws_rect_add);
1087    ORD(output_redraws_rect_del);
1088    ORD(output_redraws_clear);
1089    ORD(output_redraws_next_update_get);
1090    ORD(output_redraws_next_update_push);
1091    ORD(output_flush);
1092    ORD(output_idle_flush);
1093
1094    ORD(image_map_draw);
1095    ORD(image_draw);
1096    ORD(image_native_set);
1097    ORD(image_native_get);
1098    /* now advertise out own api */
1099    em->functions = (void *)(&func);
1100    return 1;
1101 }
1102
1103 static void
1104 module_close(Evas_Module *em __UNUSED__)
1105 {
1106   eina_log_domain_unregister(_evas_engine_soft_x11_log_dom);
1107 }
1108
1109 static Evas_Module_Api evas_modapi =
1110 {
1111    EVAS_MODULE_API_VERSION, "software_x11", "none",
1112    {
1113      module_open,
1114      module_close
1115    }
1116 };
1117
1118 EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_ENGINE, engine, software_x11);
1119
1120 #ifndef EVAS_STATIC_BUILD_SOFTWARE_X11
1121 EVAS_EINA_MODULE_DEFINE(engine, software_x11);
1122 #endif