1 #include "evas_common.h"
2 #include "evas_private.h"
3 #include "evas_engine.h"
4 #include "Evas_Engine_XRender_X11.h"
6 /* function tables - filled in later (func and parent func) */
7 static Evas_Func func, pfunc;
9 /* engine struct data */
10 typedef struct _Render_Engine Render_Engine;
11 typedef struct _Render_Engine_Update Render_Engine_Update;
13 struct _Render_Engine_Update
16 Xrender_Surface *surface;
25 unsigned char destination_alpha : 1;
28 Xrender_Surface *output;
29 Xrender_Surface *mask_output;
33 Evas_Object_List *cur_rect;
39 /* internal engine routines */
41 /* engine api this module provides */
45 Evas_Engine_Info_XRender_X11 *info;
47 info = calloc(1, sizeof(Evas_Engine_Info_XRender_X11));
48 if (!info) return NULL;
49 info->magic.magic = rand();
55 eng_info_free(Evas *e, void *info)
57 Evas_Engine_Info_XRender_X11 *in;
59 in = (Evas_Engine_Info_XRender_X11 *)info;
64 eng_setup(Evas *e, void *in)
67 Evas_Engine_Info_XRender_X11 *info;
70 info = (Evas_Engine_Info_XRender_X11 *)in;
71 if (!e->engine.data.output)
73 re = calloc(1, sizeof(Render_Engine));
74 evas_common_cpu_init();
75 evas_common_blend_init();
76 evas_common_image_init();
77 evas_common_convert_init();
78 evas_common_scale_init();
79 evas_common_rectangle_init();
80 evas_common_gradient_init();
81 evas_common_polygon_init();
82 evas_common_line_init();
83 evas_common_font_init();
84 evas_common_draw_init();
85 evas_common_tilebuf_init();
86 re->tb = evas_common_tilebuf_new(e->output.w, e->output.h);
88 evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
89 e->engine.data.output = re;
92 re = e->engine.data.output;
95 if (!e->engine.data.context) e->engine.data.context = e->engine.func->context_new(e->engine.data.output);
97 re->disp = info->info.display;
98 re->vis = info->info.visual;
99 re->win = info->info.drawable;
100 re->mask = info->info.mask;
101 re->destination_alpha = info->info.destination_alpha;
103 if (re->xinf) _xr_image_info_free(re->xinf);
104 re->xinf = _xr_image_info_get(re->disp, re->win, re->vis);
106 if (re->output) _xr_render_surface_free(re->output);
107 if (re->mask_output) _xr_render_surface_free(re->mask_output);
109 re->output = _xr_render_surface_adopt(re->xinf, re->win, e->output.w, e->output.h, re->destination_alpha);
111 re->output = _xr_render_surface_adopt(re->xinf, re->win, e->output.w, e->output.h, 0);
113 re->mask_output = _xr_render_surface_format_adopt(re->xinf, re->mask,
114 e->output.w, e->output.h,
117 re->mask_output = NULL;
120 if (re->tb) evas_common_tilebuf_free(re->tb);
121 if ((e->output.w > 0) && (e->output.h > 0))
122 re->tb = evas_common_tilebuf_new(e->output.w, e->output.h);
124 re->tb = evas_common_tilebuf_new(1, 1);
126 evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
131 eng_output_free(void *data)
135 re = (Render_Engine *)data;
136 evas_common_font_shutdown();
137 evas_common_image_shutdown();
140 Render_Engine_Update *reu;
142 reu = re->updates->data;
143 re->updates = evas_list_remove_list(re->updates, re->updates);
144 _xr_render_surface_free(reu->surface);
147 if (re->tb) evas_common_tilebuf_free(re->tb);
148 if (re->output) _xr_render_surface_free(re->output);
149 if (re->mask_output) _xr_render_surface_free(re->mask_output);
150 if (re->rects) evas_common_tilebuf_free_render_rects(re->rects);
151 if (re->xinf) _xr_image_info_free(re->xinf);
156 eng_output_resize(void *data, int w, int h)
160 re = (Render_Engine *)data;
163 if ((re->output->w == w) && (re->output->h ==h)) return;
164 if (re->output) _xr_render_surface_free(re->output);
166 re->output = _xr_render_surface_adopt(re->xinf, re->win, w, h, 0);
169 if (re->mask_output) _xr_render_surface_free(re->mask_output);
170 re->mask_output = _xr_render_surface_format_adopt(re->xinf, re->mask,
174 evas_common_tilebuf_free(re->tb);
175 re->tb = evas_common_tilebuf_new(w, h);
176 if (re->tb) evas_common_tilebuf_set_tile_size(re->tb, TILESIZE, TILESIZE);
180 eng_output_tile_size_set(void *data, int w, int h)
184 re = (Render_Engine *)data;
185 evas_common_tilebuf_set_tile_size(re->tb, w, h);
189 eng_output_redraws_rect_add(void *data, int x, int y, int w, int h)
193 re = (Render_Engine *)data;
194 evas_common_tilebuf_add_redraw(re->tb, x, y, w, h);
198 eng_output_redraws_rect_del(void *data, int x, int y, int w, int h)
202 re = (Render_Engine *)data;
203 evas_common_tilebuf_del_redraw(re->tb, x, y, w, h);
207 eng_output_redraws_clear(void *data)
211 re = (Render_Engine *)data;
212 evas_common_tilebuf_clear(re->tb);
216 eng_output_redraws_next_update_get(void *data, int *x, int *y, int *w, int *h, int *cx, int *cy, int *cw, int *ch)
222 re = (Render_Engine *)data;
230 re->rects = evas_common_tilebuf_get_render_rects(re->tb);
231 re->cur_rect = (Evas_Object_List *)re->rects;
233 if (!re->cur_rect) return NULL;
234 rect = (Tilebuf_Rect *)re->cur_rect;
235 ux = rect->x; uy = rect->y; uw = rect->w; uh = rect->h;
236 re->cur_rect = re->cur_rect->next;
239 evas_common_tilebuf_free_render_rects(re->rects);
244 *x = ux; *y = uy; *w = uw; *h = uh;
245 *cx = 0; *cy = 0; *cw = uw; *ch = uh;
246 if ((re->destination_alpha) || (re->mask))
248 Xrender_Surface *surface;
250 surface = _xr_render_surface_new(re->xinf, uw, uh, re->xinf->fmt32, 1);
251 _xr_render_surface_solid_rectangle_set(surface, 0, 0, 0, 0, 0, 0, uw, uh);
254 return _xr_render_surface_new(re->xinf, uw, uh, re->xinf->fmtdef, 0);
258 eng_output_redraws_next_update_push(void *data, void *surface, int x, int y, int w, int h)
261 Render_Engine_Update *reu;
263 re = (Render_Engine *)data;
264 reu = malloc(sizeof(Render_Engine_Update));
270 reu->surface = (Xrender_Surface *)surface;
271 re->updates = evas_list_append(re->updates, reu);
275 eng_output_flush(void *data)
279 re = (Render_Engine *)data;
282 Render_Engine_Update *reu;
284 reu = re->updates->data;
285 re->updates = evas_list_remove_list(re->updates, re->updates);
288 Xrender_Surface *tsurf;
290 _xr_render_surface_copy(reu->surface, re->output, 0, 0,
291 reu->x, reu->y, reu->w, reu->h);
292 tsurf = _xr_render_surface_new(re->xinf, reu->w, reu->h, re->xinf->fmt1, 1);
295 _xr_render_surface_copy(reu->surface, tsurf, 0, 0,
296 0, 0, reu->w, reu->h);
297 _xr_render_surface_copy(tsurf, re->mask_output, 0, 0,
298 reu->x, reu->y, reu->w, reu->h);
299 _xr_render_surface_free(tsurf);
304 _xr_render_surface_copy(reu->surface, re->output, 0, 0,
305 reu->x, reu->y, reu->w, reu->h);
307 _xr_render_surface_free(reu->surface);
310 XSync(re->disp, False);
311 _xr_image_info_pool_flush(re->xinf, 0, 0);
315 eng_output_idle_flush(void *data)
319 re = (Render_Engine *)data;
323 eng_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w, int h)
325 _xr_render_surface_rectangle_draw((Xrender_Surface *)surface,
326 (RGBA_Draw_Context *)context,
331 eng_line_draw(void *data, void *context, void *surface, int x1, int y1, int x2, int y2)
333 _xr_render_surface_line_draw((Xrender_Surface *)surface, (RGBA_Draw_Context *)context, x1, y1, x2, y2);
337 eng_polygon_draw(void *data, void *context, void *surface, void *polygon)
339 _xre_poly_draw((Xrender_Surface *)surface, (RGBA_Draw_Context *)context, (RGBA_Polygon_Point *)polygon);
343 eng_gradient_new(void *data)
345 Render_Engine *re = (Render_Engine *)data;
347 return _xre_gradient_new(re->xinf);
351 eng_gradient_free(void *data, void *gradient)
353 _xre_gradient_free(gradient);
357 eng_gradient_color_stop_add(void *data, void *gradient, int r, int g, int b, int a, int delta)
359 _xre_gradient_color_stop_add(gradient, r, g, b, a, delta);
363 eng_gradient_alpha_stop_add(void *data, void *gradient, int a, int delta)
365 _xre_gradient_alpha_stop_add(gradient, a, delta);
369 eng_gradient_color_data_set(void *data, void *gradient, void *map, int len, int has_alpha)
371 _xre_gradient_color_data_set(gradient, map, len, has_alpha);
375 eng_gradient_alpha_data_set(void *data, void *gradient, void *alpha_map, int len)
377 _xre_gradient_alpha_data_set(gradient, alpha_map, len);
381 eng_gradient_clear(void *data, void *gradient)
383 _xre_gradient_clear(gradient);
387 eng_gradient_fill_set(void *data, void *gradient, int x, int y, int w, int h)
389 _xre_gradient_fill_set(gradient, x, y, w, h);
393 eng_gradient_fill_angle_set(void *data, void *gradient, double angle)
395 _xre_gradient_fill_angle_set(gradient, angle);
399 eng_gradient_fill_spread_set(void *data, void *gradient, int spread)
401 _xre_gradient_fill_spread_set(gradient, spread);
405 eng_gradient_angle_set(void *data, void *gradient, double angle)
407 _xre_gradient_angle_set(gradient, angle);
411 eng_gradient_offset_set(void *data, void *gradient, float offset)
413 _xre_gradient_offset_set(gradient, offset);
417 eng_gradient_direction_set(void *data, void *gradient, int direction)
419 _xre_gradient_direction_set(gradient, direction);
423 eng_gradient_type_set(void *data, void *gradient, char *name, char *params)
425 _xre_gradient_type_set(gradient, name, params);
429 eng_gradient_is_opaque(void *data, void *context, void *gradient, int x, int y, int w, int h)
432 RGBA_Draw_Context *dc = (RGBA_Draw_Context *)context;
434 if (!dc || !gradient) return 0;
435 grad = ((XR_Gradient *)gradient)->grad;
436 if(!grad || !grad->type.geometer) return 0;
437 return !(grad->type.geometer->has_alpha(grad, dc->render_op) |
438 grad->type.geometer->has_mask(grad, dc->render_op));
442 eng_gradient_is_visible(void *data, void *context, void *gradient, int x, int y, int w, int h)
444 if (!context || !gradient) return 0;
449 eng_gradient_render_pre(void *data, void *context, void *gradient)
454 if (!context || !gradient) return;
455 grad = ((XR_Gradient *)gradient)->grad;
456 if(!grad || !grad->type.geometer) return;
457 grad->type.geometer->geom_set(grad);
458 len = grad->type.geometer->get_map_len(grad);
459 evas_common_gradient_map(context, grad, len);
463 eng_gradient_render_post(void *data, void *gradient)
468 eng_gradient_draw(void *data, void *context, void *surface, void *gradient, int x, int y, int w, int h)
470 _xre_gradient_draw(surface, context, gradient, x, y, w, h);
474 eng_image_alpha_get(void *data, void *image)
476 if (!image) return 0;
477 return _xre_image_alpha_get((XR_Image *)image);
481 eng_image_colorspace_get(void *data, void *image)
483 if (!image) return EVAS_COLORSPACE_ARGB8888;
484 return ((XR_Image *)image)->cs.space;
488 eng_image_alpha_set(void *data, void *image, int has_alpha)
492 im = (XR_Image *)image;
494 if (im->cs.space != EVAS_COLORSPACE_ARGB8888) return im;
495 if (((im->alpha) && (has_alpha)) || ((!im->alpha) && (!has_alpha)))
497 if (im->references > 1)
502 im = _xre_image_copy(old_im);
505 im->alpha = old_im->alpha;
506 _xre_image_free(old_im);
512 _xre_image_dirty(im);
513 _xre_image_alpha_set(im, has_alpha);
518 eng_image_border_set(void *data, void *image, int l, int r, int t, int b)
520 if (!image) return image;
521 _xre_image_border_set((XR_Image *)image, l, r, t, b);
526 eng_image_border_get(void *data, void *image, int *l, int *r, int *t, int *b)
529 _xre_image_border_get((XR_Image *)image, l, r, t, b);
533 eng_image_comment_get(void *data, void *image, char *key)
535 if (!image) return NULL;
536 return strdup(((XR_Image *)image)->comment);
540 eng_image_format_get(void *data, void *image)
542 if (!image) return NULL;
543 return ((XR_Image *)image)->format;
547 eng_image_colorspace_set(void *data, void *image, int cspace)
552 im = (XR_Image *)image;
553 if (im->cs.space == cspace) return;
555 if (im->im) evas_cache_image_drop(&im->im->cache_entry);
560 case EVAS_COLORSPACE_ARGB8888:
563 if (!im->cs.no_free) free(im->cs.data);
568 case EVAS_COLORSPACE_YCBCR422P601_PL:
569 case EVAS_COLORSPACE_YCBCR422P709_PL:
570 if ((im->free_data) && (im->data)) free(im->data);
574 if (!im->cs.no_free) free(im->cs.data);
577 im->cs.data = calloc(1, im->h * sizeof(unsigned char *) * 2);
584 im->cs.space = cspace;
585 _xre_image_dirty(im);
586 _xre_image_region_dirty(im, 0, 0, im->w, im->h);
590 eng_image_native_set(void *data, void *image, void *native)
595 eng_image_native_get(void *data, void *image)
601 eng_image_load(void *data, const char *file, const char *key, int *error, Evas_Image_Load_Opts *lo)
606 re = (Render_Engine *)data;
608 im = _xre_image_load(re->xinf, file, key, lo);
613 eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace)
618 re = (Render_Engine *)data;
619 im = _xre_image_new_from_data(re->xinf, w, h, image_data, alpha, cspace);
624 eng_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data, int alpha, int cspace)
629 re = (Render_Engine *)data;
630 im = _xre_image_new_from_copied_data(re->xinf, w, h, image_data, alpha, cspace);
635 eng_image_free(void *data, void *image)
638 _xre_image_free((XR_Image *)image);
642 eng_image_size_get(void *data, void *image, int *w, int *h)
645 if (w) *w = ((XR_Image *)image)->w;
646 if (h) *h = ((XR_Image *)image)->h;
650 eng_image_size_set(void *data, void *image, int w, int h)
652 XR_Image *im, *im_old;
654 if (!image) return NULL;
656 if ((im_old->cs.space == EVAS_COLORSPACE_YCBCR422P601_PL) ||
657 (im_old->cs.space == EVAS_COLORSPACE_YCBCR422P709_PL))
659 if ((im_old) && (im_old->w == w) && (im_old->h == h))
661 if ((w <= 0) || (h <= 0))
663 _xre_image_free(im_old);
668 im = _xre_image_new_from_copied_data(im_old->xinf, w, h, NULL, im_old->alpha, im_old->cs.space);
669 _xre_image_free(im_old);
676 eng_image_dirty_region(void *data, void *image, int x, int y, int w, int h)
678 if (!image) return image;
679 _xre_image_dirty((XR_Image *)image);
680 _xre_image_region_dirty((XR_Image *)image, x, y, w, h);
685 eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data)
694 im = (XR_Image *)image;
696 evas_cache_image_load_data(&im->im->cache_entry);
697 switch (im->cs.space)
699 case EVAS_COLORSPACE_ARGB8888:
702 if (im->references > 1)
707 im = _xre_image_copy(im_old);
709 _xre_image_free(im_old);
714 _xre_image_dirty(im);
717 case EVAS_COLORSPACE_YCBCR422P601_PL:
718 case EVAS_COLORSPACE_YCBCR422P709_PL:
724 if (image_data) *image_data = _xre_image_data_get(im);
729 eng_image_data_put(void *data, void *image, DATA32 *image_data)
733 if (!image) return image;
734 im = (XR_Image *)image;
736 switch (im->cs.space)
738 case EVAS_COLORSPACE_ARGB8888:
739 if (_xre_image_data_get(im) != image_data)
744 image = _xre_image_data_find(image_data);
749 image = _xre_image_new_from_data(im_old->xinf, im_old->w, im_old->h, image_data, im_old->alpha, EVAS_COLORSPACE_ARGB8888);
752 ((XR_Image *)image)->alpha = im_old->alpha;
753 _xre_image_free(im_old);
760 _xre_image_free(im_old);
765 _xre_image_free(image);
770 case EVAS_COLORSPACE_YCBCR422P601_PL:
771 case EVAS_COLORSPACE_YCBCR422P709_PL:
772 if (_xre_image_data_get(im) != image_data)
776 if (im->free_data) free(im->data);
781 if (!im->cs.no_free) free(im->cs.data);
783 im->cs.data = image_data;
784 _xre_image_dirty(im);
795 eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth)
797 if ((!image) || (!surface)) return;
798 _xre_image_surface_gen((XR_Image *)image);
799 if (((XR_Image *)image)->surface)
800 _xr_render_surface_composite(((XR_Image *)image)->surface,
801 (Xrender_Surface *)surface,
802 (RGBA_Draw_Context *)context,
803 src_x, src_y, src_w, src_h,
804 dst_x, dst_y, dst_w, dst_h,
809 eng_image_cache_flush(void *data)
813 tmp_size = _xre_image_cache_get();
814 pfunc.image_cache_flush(data);
815 _xre_image_cache_set(0);
816 _xre_image_cache_set(tmp_size);
820 eng_image_cache_set(void *data, int bytes)
822 pfunc.image_cache_set(data, bytes);
823 _xre_image_cache_set(bytes);
827 eng_image_cache_get(void *data)
829 return pfunc.image_cache_get(data);
833 eng_font_draw(void *data, void *context, void *surface, void *font, int x, int y, int w, int h, int ow, int oh, const char *text)
838 re = (Render_Engine *)data;
840 _xr_render_surface_clips_set((Xrender_Surface *)surface, (RGBA_Draw_Context *)context, x, y, w, h);
842 im = (RGBA_Image *) evas_cache_image_data(evas_common_image_cache_get(),
843 ((Xrender_Surface *)surface)->w,
844 ((Xrender_Surface *)surface)->h,
846 0, EVAS_COLORSPACE_ARGB8888);
847 evas_common_draw_context_font_ext_set(context,
849 _xre_font_surface_new,
850 _xre_font_surface_free,
851 _xre_font_surface_draw);
852 evas_common_font_draw(im, context, font, x, y, text);
853 evas_common_draw_context_font_ext_set(context,
858 evas_common_cpu_end_opt();
860 evas_cache_image_drop(&im->cache_entry);
863 /* module advertising code */
865 module_open(Evas_Module *em)
868 /* get whatever engine module we inherit from */
869 if (!_evas_module_engine_inherit(&pfunc, "software_generic")) return 0;
870 /* store it for later use */
872 /* now to override methods */
873 #define ORD(f) EVAS_API_OVERRIDE(f, &func, eng_)
879 ORD(output_tile_size_set);
880 ORD(output_redraws_rect_add);
881 ORD(output_redraws_rect_del);
882 ORD(output_redraws_clear);
883 ORD(output_redraws_next_update_get);
884 ORD(output_redraws_next_update_push);
886 ORD(output_idle_flush);
892 ORD(gradient_color_stop_add);
893 ORD(gradient_alpha_stop_add);
894 ORD(gradient_color_data_set);
895 ORD(gradient_alpha_data_set);
897 ORD(gradient_fill_set);
898 ORD(gradient_fill_angle_set);
899 ORD(gradient_fill_spread_set);
900 ORD(gradient_angle_set);
901 ORD(gradient_offset_set);
902 ORD(gradient_direction_set);
903 ORD(gradient_type_set);
904 ORD(gradient_is_opaque);
905 ORD(gradient_is_visible);
906 ORD(gradient_render_pre);
907 ORD(gradient_render_post);
910 ORD(image_new_from_data);
911 ORD(image_new_from_copied_data);
915 ORD(image_dirty_region);
918 ORD(image_alpha_set);
919 ORD(image_alpha_get);
920 ORD(image_border_set);
921 ORD(image_border_get);
923 ORD(image_comment_get);
924 ORD(image_format_get);
925 ORD(image_colorspace_set);
926 ORD(image_colorspace_get);
927 ORD(image_native_set);
928 ORD(image_native_get);
929 ORD(image_cache_flush);
930 ORD(image_cache_set);
931 ORD(image_cache_get);
933 /* now advertise out own api */
934 em->functions = (void *)(&func);
943 EAPI Evas_Module_Api evas_modapi =
945 EVAS_MODULE_API_VERSION,
946 EVAS_MODULE_TYPE_ENGINE,