diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am index faff651382..9e8d0404bd 100644 --- a/src/Makefile_Evas.am +++ b/src/Makefile_Evas.am @@ -984,6 +984,7 @@ modules/evas/engines/software_x11/evas_x_egl.h SOFTWARE_X11_CPPFLAGS = -I$(top_builddir)/src/lib/efl \ -I$(top_srcdir)/src/lib/evas/include \ -I$(top_srcdir)/src/lib/evas/cserve2 \ +@ECORE_X_CFLAGS@ \ @EVAS_CFLAGS@ SOFTWARE_X11_LIBADD = if BUILD_ENGINE_SOFTWARE_XLIB @@ -994,11 +995,13 @@ modules/evas/engines/software_x11/evas_xlib_buffer.c \ modules/evas/engines/software_x11/evas_xlib_color.c \ modules/evas/engines/software_x11/evas_xlib_main.c \ modules/evas/engines/software_x11/evas_xlib_swapper.c \ +modules/evas/engines/software_x11/evas_xlib_image.c \ modules/evas/engines/software_x11/evas_xlib_outbuf.h \ modules/evas/engines/software_x11/evas_xlib_swapbuf.h \ modules/evas/engines/software_x11/evas_xlib_buffer.h \ modules/evas/engines/software_x11/evas_xlib_color.h \ -modules/evas/engines/software_x11/evas_xlib_swapper.h +modules/evas/engines/software_x11/evas_xlib_swapper.h \ +modules/evas/engines/software_x11/evas_xlib_image.h SOFTWARE_X11_CPPFLAGS += @evas_engine_software_xlib_cflags@ SOFTWARE_X11_LIBADD += @evas_engine_software_xlib_libs@ endif @@ -1025,8 +1028,8 @@ enginesoftwarex11pkgdir = $(libdir)/evas/modules/engines/software_x11/$(MODULE_A enginesoftwarex11pkg_LTLIBRARIES = modules/evas/engines/software_x11/module.la modules_evas_engines_software_x11_module_la_SOURCES = $(SOFTWARE_X11_SOURCES) modules_evas_engines_software_x11_module_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl $(SOFTWARE_X11_CPPFLAGS) -modules_evas_engines_software_x11_module_la_LIBADD = @USE_EVAS_LIBS@ $(SOFTWARE_X11_LIBADD) -modules_evas_engines_software_x11_module_la_DEPENDENCIES = @USE_EVAS_INTERNAL_LIBS@ +modules_evas_engines_software_x11_module_la_LIBADD = @USE_ECORE_X_LIBS@ @USE_EVAS_LIBS@ $(SOFTWARE_X11_LIBADD) +modules_evas_engines_software_x11_module_la_DEPENDENCIES = @USE_ECORE_X_INTERNAL_LIBS@ @USE_EVAS_INTERNAL_LIBS@ modules_evas_engines_software_x11_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@ modules_evas_engines_software_x11_module_la_LIBTOOLFLAGS = --tag=disable-static endif diff --git a/src/lib/evas/include/evas_common_private.h b/src/lib/evas/include/evas_common_private.h index 8f01bf0536..d41f24b399 100644 --- a/src/lib/evas/include/evas_common_private.h +++ b/src/lib/evas/include/evas_common_private.h @@ -835,6 +835,14 @@ struct _RGBA_Image pixman_image_t *im; } pixman; #endif + struct { + void *data; //Evas_Native_Surface ns; + struct { + void (*bind) (void *data, void *image, int x, int y, int w, int h); + void (*free) (void *data, void *image); + void *data; + } func; + } native; }; struct _RGBA_Polygon_Point diff --git a/src/modules/evas/engines/software_generic/evas_engine.c b/src/modules/evas/engines/software_generic/evas_engine.c index 50b3e98729..3c13f80cd2 100644 --- a/src/modules/evas/engines/software_generic/evas_engine.c +++ b/src/modules/evas/engines/software_generic/evas_engine.c @@ -1449,6 +1449,8 @@ eng_image_draw(void *data EINA_UNUSED, void *context, void *surface, void *image if (!image) return EINA_FALSE; im = image; + if (im->native.func.bind) + im->native.func.bind(data, image, src_x, src_y, src_w, src_h); if (do_async) { diff --git a/src/modules/evas/engines/software_x11/evas_engine.c b/src/modules/evas/engines/software_x11/evas_engine.c index 43601ef07a..fa74a38a40 100644 --- a/src/modules/evas/engines/software_x11/evas_engine.c +++ b/src/modules/evas/engines/software_x11/evas_engine.c @@ -1,5 +1,8 @@ #include "evas_common_private.h" #include "evas_private.h" +#ifdef EVAS_CSERVE2 +#include "evas_cs2_private.h" +#endif #include "Evas_Engine_Software_X11.h" #include "evas_engine.h" @@ -8,6 +11,7 @@ # include "evas_xlib_outbuf.h" # include "evas_xlib_swapbuf.h" # include "evas_xlib_color.h" +# include "evas_xlib_image.h" #endif #ifdef BUILD_ENGINE_SOFTWARE_XCB @@ -616,6 +620,83 @@ eng_canvas_alpha_get(void *data, void *context EINA_UNUSED) (re->outbuf_alpha_get(re->generic.ob)); } +static void * +eng_image_native_set(void *data EINA_UNUSED, void *image, void *native) +{ + Render_Engine *re = (Render_Engine *)data; + Evas_Native_Surface *ns = native; + RGBA_Image *im = image, *im2 = NULL; + Image_Entry *ie = image; + + if (!im || !ns) return im; + + if (ns) + { + if (ns->type == EVAS_NATIVE_SURFACE_X11) + { + if (im->native.data) + { + //image have native surface already + Evas_Native_Surface *ens = im->native.data; + + if ((ens->type == ns->type) && + (ens->data.x11.visual == ns->data.x11.visual) && + (ens->data.x11.pixmap == ns->data.x11.pixmap)) + return im; + } + } + } + else + { + return im; + } + + if ((!ns) && (!im->native.data)) return im; + + //create new im and clean already existed im even though ns = NULL + im2 = (RGBA_Image *)evas_cache_image_data(evas_common_image_cache_get(), + ie->w, ie->h, NULL, ie->flags.alpha, + EVAS_COLORSPACE_ARGB8888); + if (im->native.data) + { + if (im->native.func.free) + im->native.func.free(im->native.func.data, im); + } + +#ifdef EVAS_CSERVE2 + if (evas_cserve2_use_get() && evas_cache2_image_cached(&im->cache_entry)) + evas_cache2_image_close(&im->cache_entry); + else +#endif + evas_cache_image_drop(&im->cache_entry); + im = im2; + + if (!ns) return im; + +#ifdef BUILD_ENGINE_SOFTWARE_XLIB + if (ns->type == EVAS_NATIVE_SURFACE_X11) + { + return evas_xlib_image_native_set(re->generic.ob, im, ns); + } +#endif + + return im; +} + +static void * +eng_image_native_get(void *data EINA_UNUSED, void *image) +{ +#ifdef BUILD_ENGINE_SOFTWARE_XLIB + RGBA_Image *im = image; + Native *n; + if (!im) return NULL; + n = im->native.data; + if (!n) return NULL; + return &(n->ns); +#endif + return NULL; +} + /* module advertising code */ static int @@ -645,6 +726,8 @@ module_open(Evas_Module *em) ORD(setup); ORD(canvas_alpha_get); ORD(output_free); + ORD(image_native_set); + ORD(image_native_get); /* now advertise out own api */ em->functions = (void *)(&func); diff --git a/src/modules/evas/engines/software_x11/evas_xlib_image.c b/src/modules/evas/engines/software_x11/evas_xlib_image.c new file mode 100644 index 0000000000..9514df450e --- /dev/null +++ b/src/modules/evas/engines/software_x11/evas_xlib_image.c @@ -0,0 +1,111 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "evas_common_private.h" +#include "evas_xlib_image.h" + +static void +evas_xlib_image_update(void *data EINA_UNUSED, void *image, int x, int y, int w, int h) +{ + RGBA_Image *im = image; + Native *n = im->native.data; + char *pix; + int bpl, rows, bpp; + + if (ecore_x_image_get(n->exim, n->pixmap, 0, 0, x, y, w, h)) + { + pix = ecore_x_image_data_get(n->exim, &bpl, &rows, &bpp); + if (!ecore_x_image_is_argb32_get(n->exim)) + { + if (!im->image.data) + im->image.data = (DATA32 *)malloc(im->cache_entry.w * im->cache_entry.h * sizeof(DATA32)); + Ecore_X_Colormap colormap = ecore_x_default_colormap_get(ecore_x_display_get(), ecore_x_default_screen_get()); + ecore_x_image_to_argb_convert(pix, bpp, bpl, colormap, n->visual, + x, y, w, h, + im->image.data, (w * sizeof(int)), 0, 0); + } + else + { + im->image.data = (DATA32 *)pix; + } + } +} + +static void +_native_bind_cb(void *data EINA_UNUSED, void *image, int x, int y, int w, int h) +{ + RGBA_Image *im = image; + Native *n = im->native.data; + + if ((n) && (n->ns.type == EVAS_NATIVE_SURFACE_X11)) + { + evas_xlib_image_update(data, image, x, y, w, h); + } +} + +static void +_native_free_cb(void *data EINA_UNUSED, void *image) +{ + RGBA_Image *im = image; + Native *n = im->native.data; + + if (n->exim) + { + ecore_x_image_free(n->exim); + n->exim = NULL; + } + n->visual = NULL; + + im->native.data = NULL; + im->native.func.data = NULL; + im->native.func.bind = NULL; + im->native.func.free = NULL; + im->image.data = NULL; + free(n); +} + +void * +evas_xlib_image_native_set(void *data, void *image, void *native) +{ + RGBA_Image *im = image; + Evas_Native_Surface *ns = native; + Native *n = NULL; + Ecore_X_Image *exim = NULL; + Visual *vis = NULL; + Pixmap pm = 0; + int w, h, depth; + + if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_X11)) + { + vis = ns->data.x11.visual; + pm = ns->data.x11.pixmap; + + depth = ecore_x_drawable_depth_get(pm); + + w = im->cache_entry.w; + h = im->cache_entry.h; + + exim = ecore_x_image_new(w, h, vis, depth); + if (!exim) + { + ERR("ecore_x_image_new failed."); + return NULL; + } + + n = calloc(1, sizeof(Native)); + if (!n) return NULL; + + memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface)); + n->pixmap = pm; + n->visual = vis; + n->exim = exim; + im->native.data = n; + im->native.func.data = NULL; + im->native.func.bind = _native_bind_cb; + im->native.func.free = _native_free_cb; + + evas_xlib_image_update(data, image, 0, 0, w, h); + } + return im; +} diff --git a/src/modules/evas/engines/software_x11/evas_xlib_image.h b/src/modules/evas/engines/software_x11/evas_xlib_image.h new file mode 100644 index 0000000000..36a62258c4 --- /dev/null +++ b/src/modules/evas/engines/software_x11/evas_xlib_image.h @@ -0,0 +1,15 @@ +#include "evas_engine.h" +#include + +typedef struct _Native Native; + +struct _Native +{ + Evas_Native_Surface ns; + Pixmap pixmap; + Visual *visual; + + Ecore_X_Image *exim; +}; + +void *evas_xlib_image_native_set(void *data, void *image, void *native);