evas: and now, the last one to die today, Evas Xrender backend.

SVN revision: 58364
This commit is contained in:
Cedric BAIL 2011-04-05 14:16:18 +00:00
parent 38771d0adb
commit b0e45e04bc
24 changed files with 2 additions and 6034 deletions

View File

@ -214,3 +214,5 @@
* Remove Evas Quartz backend.
* Remove Evas Cairo backend.
* Remove Evas Qtopia backend.
* Remove Evas Xrender backend.

View File

@ -40,8 +40,6 @@ evas-software-buffer.pc.in \
evas-software-x11.pc.in \
evas-software-16-x11.pc.in \
evas-software-8-x11.pc.in \
evas-xrender-x11.pc.in \
evas-xrender-xcb.pc.in \
evas-software-gdi.pc.in \
evas-software-ddraw.pc.in \
evas-software-16-ddraw.pc.in \
@ -86,14 +84,6 @@ if BUILD_ENGINE_GL_SDL
pkgconfig_DATA += evas-opengl-sdl.pc
endif
if BUILD_ENGINE_XRENDER_X11
pkgconfig_DATA += evas-xrender-x11.pc
endif
if BUILD_ENGINE_XRENDER_XCB
pkgconfig_DATA += evas-xrender-xcb.pc
endif
if BUILD_ENGINE_SOFTWARE_GDI
pkgconfig_DATA += evas-software-gdi.pc
endif

View File

@ -19,7 +19,6 @@ Must:
Recommended:
libX11
libXext
libXrender
fontconfig
libpng
libjpeg
@ -192,22 +191,6 @@ pixels, allowing the results of rendering to be directly read out or
used again for other purposes.
--enable-xrender-x11[=static]
this engine uses the xrender api to do drawing via (possibly)
accelerated 2d or 3d hardware means. as such xrender has never lived
up to its possible performance levels and has fallen into disrepair.
use this engine at your own risk. it is considered to be "bitrotting"
and be unmaintained.
--enable-xrender-xcb[=static]
this is the same as xrender-x11 but uses/exposes an xcb api. It is not
recommended to use this as it's experimental and will create problems
with both ecore_evas and enlightenment itself.
--enable-gl-x11[=static]
this is the opengl engine. it is intended for an x11 target (via xlib)

View File

@ -94,11 +94,9 @@ want_evas_cserve="yes"
want_evas_engine_buffer="yes"
want_evas_engine_software_xlib="no"
want_evas_engine_xrender_x11="no"
want_evas_engine_gl_x11="no"
want_evas_engine_gl_sdl="no"
want_evas_engine_software_xcb="no"
want_evas_engine_xrender_xcb="no"
want_evas_engine_software_gdi="no"
want_evas_engine_software_ddraw="no"
want_evas_engine_direct3d="no"
@ -152,7 +150,6 @@ case "$host_os" in
want_evas_engine_fb="auto"
### no - not ready/usable/complete
# want_evas_engine_software_8_x11="auto"
# want_evas_engine_xrender_x11="auto"
# want_evas_engine_software_16_x11="auto"
;;
esac
@ -578,14 +575,10 @@ EVAS_CHECK_ENGINE([buffer], [${want_evas_engine_buffer}], [yes], [Buffer])
EVAS_CHECK_ENGINE([software-xlib], [${want_evas_engine_software_xlib}], [yes], [Software Xlib])
EVAS_CHECK_ENGINE([xrender-x11], [${want_evas_engine_xrender_x11}], [yes], [XRender X11])
EVAS_CHECK_ENGINE([gl-x11], [${want_evas_engine_gl_x11}], [yes], [OpenGL X11])
EVAS_CHECK_ENGINE([software-xcb], [${want_evas_engine_software_xcb}], [no], [Software XCB])
EVAS_CHECK_ENGINE([xrender-xcb], [${want_evas_engine_xrender_xcb}], [no], [XRender XCB])
EVAS_CHECK_ENGINE([software-gdi], [${want_evas_engine_software_gdi}], [no], [Software GDI])
EVAS_CHECK_ENGINE([software-ddraw], [${want_evas_engine_software_ddraw}], [no], [Software DirectDraw])
@ -1523,8 +1516,6 @@ evas-software-buffer.pc
evas-software-x11.pc
evas-software-8-x11.pc
evas-software-16-x11.pc
evas-xrender-x11.pc
evas-xrender-xcb.pc
evas-software-gdi.pc
evas-software-ddraw.pc
evas-software-16-ddraw.pc
@ -1565,7 +1556,6 @@ src/modules/engines/directfb/Makefile
src/modules/engines/gl_common/Makefile
src/modules/engines/gl_x11/Makefile
src/modules/engines/gl_sdl/Makefile
src/modules/engines/xrender_x11/Makefile
src/modules/engines/software_sdl/Makefile
src/modules/engines/software_8/Makefile
src/modules/engines/software_8_x11/Makefile
@ -1638,7 +1628,6 @@ echo
echo "Engines:"
echo " Software Memory Buffer.....: $have_evas_engine_buffer"
echo " Software X11...............: $have_evas_engine_software_x11 (Xlib: $have_evas_engine_software_xlib) (XCB: $have_evas_engine_software_xcb)"
echo " XRender X11................: $have_evas_engine_xrender_x11 (XCB: $have_evas_engine_xrender_xcb)"
echo $ECHO_N " OpenGL X11.................: $have_evas_engine_gl_x11 $ECHO_C"
if test "x$have_evas_engine_gl_x11" = "xyes"; then
echo "(GLES: $gl_flavor_gles) (SGX: $gles_variety_sgx) (s3c6410: $gles_variety_s3c6410)"

View File

@ -1,3 +0,0 @@
Name: evas-xrender-x11
Description: Evas XRender X11 engine
Version: @VERSION@

View File

@ -1,3 +0,0 @@
Name: evas-xrender-xcb
Description: Evas XRender XCB engine
Version: @VERSION@

View File

@ -22,8 +22,6 @@
%bcond_with module_engine_software_16_x11
%bcond_with module_engine_software_sdl
%bcond_with module_engine_software_xcb
%bcond_with module_engine_xrender_x11
%bcond_with module_engine_xrender_xcb
%bcond_with module_loader_gif
%bcond_with module_loader_svg
@ -71,13 +69,11 @@
%define ac_with_module_engine_software-x11 --%{?with_module_engine_software_x11:en}%{!?with_module_engine_software_x11:dis}able-software-x11
%define ac_with_module_engine_buffer --%{?with_module_engine_buffer:en}%{!?with_module_engine_buffer:dis}able-buffer
%define ac_with_module_engine_fb --%{?with_module_engine_fb:en}%{!?with_module_engine_fb:dis}able-fb
%define ac_with_module_engine_xrender_x11 --%{?with_module_engine_xrender_x11:en}%{!?with_module_engine_xrender_x11:dis}able-xrender-x11
%define ac_with_module_engine_gl_x11 --%{?with_module_engine_gl_x11:en}%{!?with_module_engine_gl_x11:dis}able-gl-x11
%define ac_with_module_engine_directfb --%{?with_module_engine_directfb:en}%{!?with_module_engine_directfb:dis}able-directfb
%define ac_with_module_engine_software_16_x11 --%{?with_module_engine_software_16_x11:en}%{!?with_module_engine_software_16_x11:dis}able-software-16-x11
%define ac_with_module_engine_software_sdl --%{?with_module_engine_software_sdl:en}%{!?with_module_engine_software_sdl:dis}able-sdl
%define ac_with_module_engine_software_xcb --%{?with_module_engine_software_xcb:en}%{!?with_module_engine_software_xcb:dis}able-software-xcb
%define ac_with_module_engine_xrender_xcb --%{?with_module_engine_xrender_xcb:en}%{!?with_module_engine_xrender_xcb:dis}able-xrender-xcb
%{!?_rel:%{expand:%%global _rel 0.r%(svnversion | sed 's/[^0-9].*$//' || echo 0000)}}
@ -301,18 +297,6 @@ Requires: evas
Framebuffer rendering engine module for Evas
%endif
%if %{with module_engine_xrender_x11}
%package module_engine_xrender_x11
Summary: XRender rendering engine module for Evas
Group: System Environment/Libraries
#BuildSuggests: xorg-x11-devel, XFree86-devel, xrender-devel
BuildRequires: libXrender-devel
Requires: evas-module_engine_software_generic
Requires: evas
%description module_engine_xrender_x11
XRender rendering engine module for Evas
%endif
%if %{with module_engine_gl_x11}
%package module_engine_gl_x11
Summary: OpenGL under X11 rendering engine module for Evas
@ -366,17 +350,6 @@ Requires: evas
Software XCB X11 rendering engine module for Evas
%endif
%if %{with module_engine_xrender_xcb}
%package module_engine_xrender_xcb
Summary: Xrender XCB X11 rendering engine module for Evas
Group: System Environment/Libraries
BuildRequires: libxcb-devel
Requires: evas-module_engine_xrender_x11
Requires: evas
%description module_engine_xrender_xcb
Xrender XCB X11 rendering engine module for Evas
%endif
%prep
%setup -q
@ -399,13 +372,11 @@ Xrender XCB X11 rendering engine module for Evas
%{?ac_with_module_engine_software_x11} \
%{?ac_with_module_engine_buffer} \
%{?ac_with_module_engine_fb} \
%{?ac_with_module_engine_xrender_x11} \
%{?ac_with_module_engine_gl_x11} \
%{?ac_with_module_engine_directfb} \
%{?ac_with_module_engine_software_16_x11} \
%{?ac_with_module_engine_software_sdl} \
%{?ac_with_module_engine_software_xcb} \
%{?ac_with_module_engine_xrender_xcb} \
$RPM_CONFIGURE_OPTS
%{__make} %{?_smp_mflags} %{?mflags}
test -x `which doxygen` && /bin/sh gendoc || :
@ -561,12 +532,6 @@ test "x$RPM_BUILD_ROOT" != "x/" && rm -rf $RPM_BUILD_ROOT
%{_libdir}/evas/modules/engines/fb/*/module.so
%endif
%if %{with module_engine_xrender_x11}
%files module_engine_xrender_x11
%defattr(-, root, root)
%{_libdir}/evas/modules/engines/xrender_x11/*/module.so
%endif
%if %{with module_engine_gl_x11}
%files module_engine_gl_x11
%defattr(-, root, root)
@ -598,10 +563,4 @@ test "x$RPM_BUILD_ROOT" != "x/" && rm -rf $RPM_BUILD_ROOT
%{_libdir}/evas/modules/engines/software_xcb/*/module.so
%endif
%if %{with module_engine_xrender_xcb}
%files module_engine_xrender_xcb
%defattr(-, root, root)
%{_libdir}/evas/modules/engines/xrender_xcb/*/module.so
%endif
%changelog

View File

@ -95,11 +95,6 @@ SUBDIRS += ../modules/engines/software_x11/
EVAS_STATIC_MODULE += ../modules/engines/software_x11/libevas_engine_software_x11.la
EVAS_STATIC_LIBADD += @evas_engine_software_xlib_libs@ @evas_engine_software_xcb_libs@
endif
if EVAS_STATIC_BUILD_XRENDER_X11
SUBDIRS += ../modules/engines/xrender_x11/
EVAS_STATIC_MODULE += ../modules/engines/xrender_x11/libevas_engine_xrender_x11.la
EVAS_STATIC_LIBADD += @evas_engine_xrender_x11_libs@ @evas_engine_xrender_xcb_libs@
endif
if EVAS_STATIC_BUILD_BMP
SUBDIRS += ../modules/loaders/bmp
EVAS_STATIC_MODULE += ../modules/loaders/bmp/libevas_loader_bmp.la

View File

@ -825,12 +825,6 @@ evas_render_method_list(void)
#ifdef BUILD_ENGINE_SOFTWARE_X11
methods = eina_list_append(methods, "software_x11");
#endif
#ifdef BUILD_ENGINE_XRENDER_X11
methods = eina_list_append(methods, "xrender_x11");
#endif
#ifdef BUILD_ENGINE_XRENDER_XCB
methods = eina_list_append(methods, "xrender_xcb");
#endif
#ifdef BUILD_ENGINE_SOFTWARE_16_X11
methods = eina_list_append(methods, "software_16_x11");
#endif

View File

@ -108,7 +108,6 @@ EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_gdi);
EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_generic);
EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_sdl);
EVAS_EINA_STATIC_MODULE_DEFINE(engine, software_x11);
EVAS_EINA_STATIC_MODULE_DEFINE(engine, xrender_x11);
EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, xpm);
EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, bmp);
EVAS_EINA_STATIC_MODULE_DEFINE(image_loader, tiff);
@ -186,9 +185,6 @@ static const struct {
#ifdef EVAS_STATIC_BUILD_SOFTWARE_X11
EVAS_EINA_STATIC_MODULE_USE(engine, software_x11),
#endif
#ifdef EVAS_STATIC_BUILD_XRENDER_X11
EVAS_EINA_STATIC_MODULE_USE(engine, xrender_x11),
#endif
#ifdef EVAS_STATIC_BUILD_XPM
EVAS_EINA_STATIC_MODULE_USE(image_loader, xpm),
#endif

View File

@ -58,7 +58,4 @@ endif
if !EVAS_STATIC_BUILD_SOFTWARE_X11
SUBDIRS += software_x11
endif
if !EVAS_STATIC_BUILD_XRENDER_X11
SUBDIRS += xrender_x11
endif

View File

@ -1,6 +0,0 @@
.deps
.libs
Makefile
Makefile.in
*.lo
*.la

View File

@ -1,44 +0,0 @@
#ifndef _EVAS_ENGINE_XRENDER_X11_H
#define _EVAS_ENGINE_XRENDER_X11_H
#include <X11/Xlib.h>
typedef enum
{
EVAS_ENGINE_INFO_XRENDER_BACKEND_XLIB,
EVAS_ENGINE_INFO_XRENDER_BACKEND_XCB
} Evas_Engine_Info_XRender_Backend;
typedef struct _Evas_Engine_Info_XRender_X11 Evas_Engine_Info_XRender_X11;
/*
* Xlib | XCB
* connection | Display * | xcb_connection_t *
* screen | NULL | xcb_screen_t *
* drawable | Drawable | xcb_drawable_t
* mask | Pixmap | xcb_pixmap_t
* visual | Visual * | xcb_visualtype_t *
* colormap | Colormap | xcb_colormap_t
*/
struct _Evas_Engine_Info_XRender_X11
{
/* PRIVATE - don't mess with this baby or evas will poke its tongue out */
/* at you and make nasty noises */
Evas_Engine_Info magic;
/* engine specific data & parameters it needs to set up */
struct {
Evas_Engine_Info_XRender_Backend backend;
void *connection;
void *screen;
unsigned int drawable;
unsigned int mask;
void *visual;
unsigned char destination_alpha : 1;
} info;
/* non-blocking or blocking mode */
Evas_Engine_Render_Mode render_mode;
};
#endif

View File

@ -1,59 +0,0 @@
MAINTAINERCLEANFILES = Makefile.in
AM_CPPFLAGS = \
-I. \
-I$(top_srcdir)/src/lib \
-I$(top_srcdir)/src/lib/include \
-I$(top_srcdir)/src/modules/engines \
@FREETYPE_CFLAGS@ \
@EINA_CFLAGS@ \
@evas_engine_xrender_x11_cflags@ \
@evas_engine_xrender_xcb_cflags@
if BUILD_ENGINE_XRENDER_X11
XRENDER_X11_SOURCES = \
evas_engine_xlib_font.c \
evas_engine_xlib_image.c \
evas_engine_xlib_render.c \
evas_engine_xlib_ximage.c \
evas_engine.c
if BUILD_ENGINE_XRENDER_XCB
XRENDER_X11_SOURCES += \
evas_engine_xcb_font.c \
evas_engine_xcb_image.c \
evas_engine_xcb_render.c \
evas_engine_xcb_ximage.c
endif
XRENDER_X11_LIBADD = @evas_engine_xrender_xcb_libs@ @evas_engine_xrender_x11_libs@
includes_HEADERS = Evas_Engine_XRender_X11.h
includesdir = $(includedir)/evas-@VMAJ@
if !EVAS_STATIC_BUILD_XRENDER_X11
pkgdir = $(libdir)/evas/modules/engines/xrender_x11/$(MODULE_ARCH)
pkg_LTLIBRARIES = module.la
module_la_SOURCES = $(XRENDER_X11_SOURCES)
module_la_LIBADD = $(top_builddir)/src/lib/libevas.la @EINA_LIBS@ $(XRENDER_X11_LIBADD)
module_la_LDFLAGS = -no-undefined -module -avoid-version
module_la_LIBTOOLFLAGS = --tag=disable-static
else
noinst_LTLIBRARIES = libevas_engine_xrender_x11.la
libevas_engine_xrender_x11_la_SOURCES = $(XRENDER_X11_SOURCES)
libevas_engine_xrender_x11_la_LIBADD = $(XRENDER_X11_LIBADD)
endif
endif
EXTRA_DIST = evas_engine.h

File diff suppressed because it is too large Load Diff

View File

@ -1,264 +0,0 @@
#ifndef EVAS_ENGINE_H
#define EVAS_ENGINE_H
#include <sys/ipc.h>
#include <sys/shm.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/extensions/XShm.h>
#include <X11/extensions/Xrender.h>
#include <X11/Xresource.h> // xres - dpi
#ifdef BUILD_ENGINE_XRENDER_XCB
# include <xcb/xcb.h>
# include <xcb/render.h>
# include <xcb/xcb_image.h>
#endif
extern int _evas_xrender_xcb_log_dom ;
#ifdef ERR
# undef ERR
#endif
#define ERR(...) EINA_LOG_DOM_ERR(_evas_xrender_xcb_log_dom, __VA_ARGS__)
#ifdef DBG
# undef DBG
#endif
#define DBG(...) EINA_LOG_DOM_DBG(_evas_xrender_xcb_log_dom, __VA_ARGS__)
#ifdef INF
# undef INF
#endif
#define INF(...) EINA_LOG_DOM_INFO(_evas_xrender_xcb_log_dom, __VA_ARGS__)
#ifdef WRN
# undef WRN
#endif
#define WRN(...) EINA_LOG_DOM_WARN(_evas_xrender_xcb_log_dom, __VA_ARGS__)
#ifdef CRIT
# undef CRIT
#endif
#define CRIT(...) EINA_LOG_DOM_CRIT(_evas_xrender_xcb_log_dom, __VA_ARGS__)
typedef struct _Ximage_Info Ximage_Info;
typedef struct _Ximage_Image Ximage_Image;
typedef struct _Xrender_Surface Xrender_Surface;
struct _Ximage_Info
{
struct {
void *connection;
void *screen;
unsigned int root;
unsigned int draw;
void *visual;
void *fmt32;
void *fmt24;
void *fmt8;
void *fmt4;
void *fmt1;
void *fmtdef;
} x11;
unsigned int depth;
unsigned int pool_mem;
Eina_List *pool;
unsigned char can_do_shm;
Xrender_Surface *mul;
unsigned char mul_r, mul_g, mul_b, mul_a;
int references;
};
struct _Ximage_Image
{
union {
struct {
XImage *xim;
XShmSegmentInfo *shm_info;
} xlib;
#ifdef BUILD_ENGINE_XRENDER_XCB
struct {
xcb_image_t *xim;
xcb_shm_segment_info_t *shm_info;
} xcb;
#endif
} x11;
Ximage_Info *xinf;
int width;
int height;
int depth;
int line_bytes;
unsigned char *data;
unsigned char available : 1;
};
struct _Xrender_Surface
{
union {
struct {
XRenderPictFormat *fmt;
Drawable draw;
Picture pic;
} xlib;
#ifdef BUILD_ENGINE_XRENDER_XCB
struct {
xcb_render_pictforminfo_t *fmt;
xcb_drawable_t draw;
xcb_render_picture_t pic;
} xcb;
#endif
} x11;
Ximage_Info *xinf;
int width;
int height;
int depth;
unsigned char alpha : 1;
unsigned char allocated : 1;
unsigned char bordered : 1;
};
/* ximage support calls (ximage vs xshmimage, cache etc.) */
Ximage_Info *_xr_xlib_image_info_get(Display *disp, Drawable draw, Visual *vis);
void _xr_xlib_image_info_free(Ximage_Info *xinf);
void _xr_xlib_image_info_pool_flush(Ximage_Info *xinf, unsigned int max_num, unsigned int max_mem);
Ximage_Image *_xr_xlib_image_new(Ximage_Info *xinf, int w, int h, int depth);
void _xr_xlib_image_free(Ximage_Image *xim);
void _xr_xlib_image_put(Ximage_Image *xim, Drawable draw, int x, int y, int w, int h);
#ifdef BUILD_ENGINE_XRENDER_XCB
Ximage_Info *_xr_xcb_image_info_get(xcb_connection_t *conn, xcb_screen_t *screen, xcb_drawable_t draw, xcb_visualtype_t *visual);
void _xr_xcb_image_info_free(Ximage_Info *xinf);
void _xr_xcb_image_info_pool_flush(Ximage_Info *xinf, unsigned int max_num, unsigned int max_mem);
Ximage_Image *_xr_xcb_image_new(Ximage_Info *xinf, int w, int h, int depth);
void _xr_xcb_image_free(Ximage_Image *xim);
void _xr_xcb_image_put(Ximage_Image *xim, xcb_drawable_t draw, int x, int y, int w, int h);
#endif
/* xrender support calls */
Xrender_Surface *_xr_xlib_render_surface_new(Ximage_Info *xinf, int w, int h, XRenderPictFormat *fmt, int alpha);
Xrender_Surface *_xr_xlib_render_surface_adopt(Ximage_Info *xinf, Drawable draw, int w, int h, int alpha);
Xrender_Surface *_xr_xlib_render_surface_format_adopt(Ximage_Info *xinf, Drawable draw, int w, int h, XRenderPictFormat *fmt, int alpha);
void _xr_xlib_render_surface_free(Xrender_Surface *rs);
void _xr_xlib_render_surface_repeat_set(Xrender_Surface *rs, int repeat);
void _xr_xlib_render_surface_solid_rectangle_set(Xrender_Surface *rs, int r, int g, int b, int a, int x, int y, int w, int h);
void _xr_xlib_render_surface_argb_pixels_fill(Xrender_Surface *rs, int sw, int sh, void *pixels, int x, int y, int w, int h, int ox, int oy);
void _xr_xlib_render_surface_rgb_pixels_fill(Xrender_Surface *rs, int sw, int sh, void *pixels, int x, int y, int w, int h, int ox, int oy);
void _xr_xlib_render_surface_clips_set(Xrender_Surface *rs, RGBA_Draw_Context *dc, int rx, int ry, int rw, int rh);
void _xr_xlib_render_surface_composite(Xrender_Surface *srs, Xrender_Surface *drs, RGBA_Draw_Context *dc, int sx, int sy, int sw, int sh, int x, int y, int w, int h, int smooth);
void _xr_xlib_render_surface_copy(Xrender_Surface *srs, Xrender_Surface *drs, int sx, int sy, int x, int y, int w, int h);
void _xr_xlib_render_surface_rectangle_draw(Xrender_Surface *rs, RGBA_Draw_Context *dc, int x, int y, int w, int h);
void _xr_xlib_render_surface_line_draw(Xrender_Surface *rs, RGBA_Draw_Context *dc, int x1, int y1, int x2, int y2);
void _xr_xlib_render_surface_polygon_draw(Xrender_Surface *rs, RGBA_Draw_Context *dc, RGBA_Polygon_Point *points, int x, int y);
#ifdef BUILD_ENGINE_XRENDER_XCB
Xrender_Surface *_xr_xcb_render_surface_new(Ximage_Info *xinf, int w, int h, xcb_render_pictforminfo_t *fmt, int alpha);
Xrender_Surface *_xr_xcb_render_surface_adopt(Ximage_Info *xinf, xcb_drawable_t draw, int w, int h, int alpha);
Xrender_Surface *_xr_xcb_render_surface_format_adopt(Ximage_Info *xinf, xcb_drawable_t draw, int w, int h, xcb_render_pictforminfo_t *fmt, int alpha);
void _xr_xcb_render_surface_free(Xrender_Surface *rs);
void _xr_xcb_render_surface_repeat_set(Xrender_Surface *rs, int repeat);
void _xr_xcb_render_surface_solid_rectangle_set(Xrender_Surface *rs, int r, int g, int b, int a, int x, int y, int w, int h);
void _xr_xcb_render_surface_argb_pixels_fill(Xrender_Surface *rs, int sw, int sh, void *pixels, int x, int y, int w, int h, int ox, int oy);
void _xr_xcb_render_surface_rgb_pixels_fill(Xrender_Surface *rs, int sw, int sh, void *pixels, int x, int y, int w, int h, int ox, int oy);
void _xr_xcb_render_surface_clips_set(Xrender_Surface *rs, RGBA_Draw_Context *dc, int rx, int ry, int rw, int rh);
void _xr_xcb_render_surface_composite(Xrender_Surface *srs, Xrender_Surface *drs, RGBA_Draw_Context *dc, int sx, int sy, int sw, int sh, int x, int y, int w, int h, int smooth);
void _xr_xcb_render_surface_copy(Xrender_Surface *srs, Xrender_Surface *drs, int sx, int sy, int x, int y, int w, int h);
void _xr_xcb_render_surface_rectangle_draw(Xrender_Surface *rs, RGBA_Draw_Context *dc, int x, int y, int w, int h);
void _xr_xcb_render_surface_line_draw(Xrender_Surface *rs, RGBA_Draw_Context *dc, int x1, int y1, int x2, int y2);
void _xr_xcb_render_surface_polygon_draw(Xrender_Surface *rs, RGBA_Draw_Context *dc, RGBA_Polygon_Point *points, int x, int y);
#endif
typedef struct _XR_Image XR_Image;
struct _XR_Image
{
Ximage_Info *xinf;
const char *file;
const char *key;
char *fkey;
RGBA_Image *im;
void *data;
int w, h;
Xrender_Surface *surface;
int references;
char *format;
const char *comment;
Tilebuf *updates;
RGBA_Image_Loadopts load_opts;
int *load_error; /* points to Evas_Object's load_error field */
struct {
int space;
void *data;
unsigned char no_free : 1;
} cs;
unsigned char alpha : 1;
unsigned char dirty : 1;
unsigned char free_data : 1;
};
XR_Image *_xre_xlib_image_load(Ximage_Info *xinf, const char *file, const char *key, Evas_Image_Load_Opts *lo, int *error);
XR_Image *_xre_xlib_image_new_from_data(Ximage_Info *xinf, int w, int h, void *data, int alpha, int cspace);
XR_Image *_xre_xlib_image_new_from_copied_data(Ximage_Info *xinf, int w, int h, void *data, int alpha, int cspace);
XR_Image *_xre_xlib_image_new(Ximage_Info *xinf, int w, int h);
void _xre_xlib_image_resize(XR_Image *im, int w, int h);
void _xre_xlib_image_free(XR_Image *im);
void _xre_xlib_image_region_dirty(XR_Image *im, int x, int y, int w, int h);
void _xre_xlib_image_dirty(XR_Image *im);
XR_Image *_xre_xlib_image_copy(XR_Image *im);
void *_xre_xlib_image_data_get(XR_Image *im);
XR_Image *_xre_xlib_image_data_find(void *data);
void _xre_xlib_image_data_put(XR_Image *im, void *data);
void _xre_xlib_image_alpha_set(XR_Image *im, int alpha);
int _xre_xlib_image_alpha_get(XR_Image *im);
void _xre_xlib_image_border_set(XR_Image *im, int l, int r, int t, int b);
void _xre_xlib_image_border_get(XR_Image *im, int *l, int *r, int *t, int *b);
void _xre_xlib_image_surface_gen(XR_Image *im);
void _xre_xlib_image_cache_set(int size);
int _xre_xlib_image_cache_get(void);
#ifdef BUILD_ENGINE_XRENDER_XCB
XR_Image *_xre_xcb_image_load(Ximage_Info *xinf, const char *file, const char *key, Evas_Image_Load_Opts *lo, int *error);
XR_Image *_xre_xcb_image_new_from_data(Ximage_Info *xinf, int w, int h, void *data, int alpha, int cspace);
XR_Image *_xre_xcb_image_new_from_copied_data(Ximage_Info *xinf, int w, int h, void *data, int alpha, int cspace);
XR_Image *_xre_xcb_image_new(Ximage_Info *xinf, int w, int h);
void _xre_xcb_image_resize(XR_Image *im, int w, int h);
void _xre_xcb_image_free(XR_Image *im);
void _xre_xcb_image_region_dirty(XR_Image *im, int x, int y, int w, int h);
void _xre_xcb_image_dirty(XR_Image *im);
XR_Image *_xre_xcb_image_copy(XR_Image *im);
void *_xre_xcb_image_data_get(XR_Image *im);
XR_Image *_xre_xcb_image_data_find(void *data);
void _xre_xcb_image_data_put(XR_Image *im, void *data);
void _xre_xcb_image_alpha_set(XR_Image *im, int alpha);
int _xre_xcb_image_alpha_get(XR_Image *im);
void _xre_xcb_image_border_set(XR_Image *im, int l, int r, int t, int b);
void _xre_xcb_image_border_get(XR_Image *im, int *l, int *r, int *t, int *b);
void _xre_xcb_image_surface_gen(XR_Image *im);
void _xre_xcb_image_cache_set(int size);
int _xre_xcb_image_cache_get(void);
#endif
typedef struct _XR_Font_Surface XR_Font_Surface;
struct _XR_Font_Surface
{
Ximage_Info *xinf;
RGBA_Font_Glyph *fg;
int w, h;
Drawable draw;
Picture pic;
};
XR_Font_Surface *_xre_xlib_font_surface_new(Ximage_Info *xinf, RGBA_Font_Glyph *fg);
void _xre_xlib_font_surface_free(XR_Font_Surface *fs);
void _xre_xlib_font_surface_draw(Ximage_Info *xinf, RGBA_Image *surface, RGBA_Draw_Context *dc, RGBA_Font_Glyph *fg, int x, int y);
#ifdef BUILD_ENGINE_XRENDER_XCB
XR_Font_Surface *_xre_xcb_font_surface_new(Ximage_Info *xinf, RGBA_Font_Glyph *fg);
void _xre_xcb_font_surface_free(XR_Font_Surface *fs);
void _xre_xcb_font_surface_draw(Ximage_Info *xinf, RGBA_Image *surface, RGBA_Draw_Context *dc, RGBA_Font_Glyph *fg, int x, int y);
#endif
#endif

View File

@ -1,208 +0,0 @@
#include "evas_common.h"
#include "evas_private.h"
#include "evas_engine.h"
#include "Evas_Engine_XRender_X11.h"
static Eina_Hash *_xr_fg_pool = NULL;
XR_Font_Surface *
_xre_xcb_font_surface_new(Ximage_Info *xinf, RGBA_Font_Glyph *fg)
{
char buf[256];
char buf2[256];
uint32_t values[3];
XR_Font_Surface *fs;
DATA8 *data;
Ximage_Image *xim;
Eina_Hash *pool;
uint32_t mask;
int w;
int h;
int pitch;
data = fg->glyph_out->bitmap.buffer;
w = fg->glyph_out->bitmap.width;
h = fg->glyph_out->bitmap.rows;
pitch = fg->glyph_out->bitmap.pitch;
if (pitch < w) pitch = w;
if ((w <= 0) || (h <= 0)) return NULL;
if (fg->ext_dat)
{
fs = fg->ext_dat;
if ((fs->xinf->x11.connection == xinf->x11.connection) &&
(fs->xinf->x11.root == xinf->x11.root))
return fs;
snprintf(buf, sizeof(buf), "@%p@/@%x@", fs->xinf->x11.connection, fs->xinf->x11.root);
pool = eina_hash_find(_xr_fg_pool, buf);
if (pool)
{
snprintf(buf, sizeof(buf), "%p", fg);
fs = eina_hash_find(pool, buf);
if (fs) return fs;
}
}
fs = calloc(1, sizeof(XR_Font_Surface));
if (!fs) return NULL;
fs->xinf = xinf;
fs->fg = fg;
fs->xinf->references++;
fs->w = w;
fs->h = h;
snprintf(buf, sizeof(buf), "@%p@/@%x@", fs->xinf->x11.connection, fs->xinf->x11.root);
pool = eina_hash_find(_xr_fg_pool, buf);
if (!pool) pool = eina_hash_string_superfast_new(NULL);
snprintf(buf2, sizeof(buf2), "%p", fg);
eina_hash_add(pool, buf2, fs);
if (!_xr_fg_pool) _xr_fg_pool = eina_hash_string_superfast_new(NULL);
eina_hash_add(_xr_fg_pool, buf, pool);
fs->draw = xcb_generate_id(xinf->x11.connection);
xcb_create_pixmap(xinf->x11.connection, ((xcb_render_pictforminfo_t *)xinf->x11.fmt8)->depth, fs->draw, xinf->x11.root, w, h);
mask = XCB_RENDER_CP_REPEAT | XCB_RENDER_CP_DITHER | XCB_RENDER_CP_COMPONENT_ALPHA;
values[0] = 0;
values[1] = 0;
values[2] = 0;
fs->pic = xcb_generate_id(xinf->x11.connection);
xcb_render_create_picture(xinf->x11.connection, fs->pic, fs->draw, ((xcb_render_pictforminfo_t *)xinf->x11.fmt8)->id, mask, values);
xim = _xr_xcb_image_new(fs->xinf, w, h, ((xcb_render_pictforminfo_t *)xinf->x11.fmt8)->depth);
if ((fg->glyph_out->bitmap.num_grays == 256) &&
(fg->glyph_out->bitmap.pixel_mode == ft_pixel_mode_grays))
{
int x, y;
DATA8 *p1, *p2;
for (y = 0; y < h; y++)
{
p1 = data + (pitch * y);
p2 = ((DATA8 *)xim->data) + (xim->line_bytes * y);
for (x = 0; x < w; x++)
{
*p2 = *p1;
p1++;
p2++;
}
}
}
else
{
DATA8 *tmpbuf = NULL, *dp, *tp, bits;
int bi, bj, end;
const DATA8 bitrepl[2] = {0x0, 0xff};
tmpbuf = alloca(w);
{
int x, y;
DATA8 *p1, *p2;
for (y = 0; y < h; y++)
{
p1 = tmpbuf;
p2 = ((DATA8 *)xim->data) + (xim->line_bytes * y);
tp = tmpbuf;
dp = data + (y * fg->glyph_out->bitmap.pitch);
for (bi = 0; bi < w; bi += 8)
{
bits = *dp;
if ((w - bi) < 8) end = w - bi;
else end = 8;
for (bj = 0; bj < end; bj++)
{
*tp = bitrepl[(bits >> (7 - bj)) & 0x1];
tp++;
}
dp++;
}
for (x = 0; x < w; x++)
{
*p2 = *p1;
p1++;
p2++;
}
}
}
}
_xr_xcb_image_put(xim, fs->draw, 0, 0, w, h);
return fs;
}
static Eina_Bool
_xre_xcb_font_pool_cb(const Eina_Hash *hash, const void *key, void *data, void *fdata)
{
char buf[256];
Eina_Hash *pool;
XR_Font_Surface *fs;
fs = fdata;
pool = data;
snprintf(buf, sizeof(buf), "@%p@/@%x@", fs->xinf->x11.connection, fs->xinf->x11.root);
eina_hash_del(pool, buf, fs);
if (!hash) hash = eina_hash_string_superfast_new(NULL);
eina_hash_modify(hash, key, pool);
return 1;
}
void
_xre_xcb_font_surface_free(XR_Font_Surface *fs)
{
if (!fs) return;
eina_hash_foreach(_xr_fg_pool, _xre_xcb_font_pool_cb, fs);
xcb_free_pixmap(fs->xinf->x11.connection, fs->draw);
xcb_render_free_picture(fs->xinf->x11.connection, fs->pic);
_xr_xcb_image_info_free(fs->xinf);
free(fs);
}
void
_xre_xcb_font_surface_draw(Ximage_Info *xinf __UNUSED__, RGBA_Image *surface, RGBA_Draw_Context *dc, RGBA_Font_Glyph *fg, int x, int y)
{
XR_Font_Surface *fs;
Xrender_Surface *target_surface;
xcb_rectangle_t rect;
int r;
int g;
int b;
int a;
fs = fg->ext_dat;
if (!fs || !fs->xinf || !dc || !dc->col.col) return;
target_surface = (Xrender_Surface *)(surface->image.data);
a = (dc->col.col >> 24) & 0xff;
r = (dc->col.col >> 16) & 0xff;
g = (dc->col.col >> 8 ) & 0xff;
b = (dc->col.col ) & 0xff;
if ((fs->xinf->mul_r != r) || (fs->xinf->mul_g != g) ||
(fs->xinf->mul_b != b) || (fs->xinf->mul_a != a))
{
fs->xinf->mul_r = r;
fs->xinf->mul_g = g;
fs->xinf->mul_b = b;
fs->xinf->mul_a = a;
_xr_xcb_render_surface_solid_rectangle_set(fs->xinf->mul, r, g, b, a, 0, 0, 1, 1);
}
rect.x = x;
rect.y = y;
rect.width = fs->w;
rect.height = fs->h;
if (dc->clip.use)
{
RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.width, rect.height,
dc->clip.x, dc->clip.y, dc->clip.w, dc->clip.h);
}
xcb_render_set_picture_clip_rectangles(target_surface->xinf->x11.connection,
target_surface->x11.xcb.pic, 0, 0, 1, &rect);
xcb_render_composite(fs->xinf->x11.connection, XCB_RENDER_PICT_OP_OVER,
fs->xinf->mul->x11.xcb.pic,
fs->pic,
target_surface->x11.xcb.pic,
0, 0,
0, 0,
x, y,
fs->w, fs->h);
}

View File

@ -1,704 +0,0 @@
#include "evas_common.h"
#include "evas_private.h"
#include "evas_engine.h"
#include "Evas_Engine_XRender_X11.h"
static Eina_Hash *_xr_image_hash = NULL;
static int _xr_image_cache_size = 0;
static int _xr_image_cache_usage = 0;
static Eina_List *_xr_image_cache = NULL;
static Eina_Hash *_xr_image_dirty_hash = NULL;
static void
__xre_xcb_image_dirty_hash_add(XR_Image *im)
{
char buf[64];
if (!im->data) return;
snprintf(buf, sizeof(buf), "%p", im->data);
if (!_xr_image_dirty_hash) _xr_image_dirty_hash = eina_hash_string_superfast_new(NULL);
eina_hash_add(_xr_image_dirty_hash, buf, im);
}
static void
__xre_xcb_image_dirty_hash_del(XR_Image *im)
{
char buf[64];
if (!im->data) return;
snprintf(buf, sizeof(buf), "%p", im->data);
eina_hash_del(_xr_image_dirty_hash, buf, im);
}
static XR_Image *
__xre_xcb_image_dirty_hash_find(void *data)
{
char buf[64];
snprintf(buf, sizeof(buf), "%p", data);
return eina_hash_find(_xr_image_dirty_hash, buf);
}
static XR_Image *
__xre_xcb_image_find(char *fkey)
{
XR_Image *im;
im = eina_hash_find(_xr_image_hash, fkey);
if (!im)
{
Eina_List *l;
EINA_LIST_FOREACH(_xr_image_cache, l, im)
{
if (!strcmp(im->fkey, fkey))
{
_xr_image_cache = eina_list_remove_list(_xr_image_cache, l);
if (!_xr_image_hash) _xr_image_hash = eina_hash_string_superfast_new(NULL);
eina_hash_add(_xr_image_hash, im->fkey, im);
_xr_image_cache_usage -= (im->w * im->h * 4);
break;
}
im = NULL;
}
}
if (im) im->references++;
return im;
}
XR_Image *
_xre_xcb_image_load(Ximage_Info *xinf, const char *file, const char *key, Evas_Image_Load_Opts *lo, int *error)
{
char buf[4096];
XR_Image *im;
if (!file)
{
*error = EVAS_LOAD_ERROR_GENERIC;
return NULL;
}
if (!lo)
{
if (key)
snprintf(buf, sizeof(buf), "/@%p@%x@/%s//://%s", xinf->x11.connection, xinf->x11.root, file, key);
else
snprintf(buf, sizeof(buf), "/@%p@%x@/%s", xinf->x11.connection, xinf->x11.root, file);
}
else
{
if (key)
snprintf(buf, sizeof(buf), "//@/%i/%1.5f/%ix%i//@%p@%x@/%s//://%s", lo->scale_down_by, lo->dpi, lo->w, lo->h, xinf->x11.connection, xinf->x11.root, file, key);
else
snprintf(buf, sizeof(buf), "//@/%i/%1.5f/%ix%i//@%p@%x@/%s", lo->scale_down_by, lo->dpi, lo->w, lo->h, xinf->x11.connection, xinf->x11.root, file);
}
im = __xre_xcb_image_find(buf);
if (im)
{
*error = EVAS_LOAD_ERROR_NONE;
return im;
}
im = calloc(1, sizeof(XR_Image));
if (!im)
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
return NULL;
}
im->im = evas_common_load_image_from_file(file, key, lo, error);
if (!im->im)
{
free(im);
return NULL;
}
im->xinf = xinf;
im->xinf->references++;
im->cs.space = EVAS_COLORSPACE_ARGB8888;
im->fkey = strdup(buf);
im->file = (char *)eina_stringshare_add(file);
if (key) im->key = (char *)eina_stringshare_add(key);
im->w = im->im->cache_entry.w;
im->h = im->im->cache_entry.h;
im->references = 1;
if (lo) im->load_opts = *lo;
im->load_error = error; /* points to object's load_error */
if (im->im->info.comment) im->comment = (char *)eina_stringshare_add(im->im->info.comment);
/* if (im->im->info.format == 1) im->format = eina_stringshare_add("png"); */
if (im->im->cache_entry.flags.alpha) im->alpha = 1;
if (!_xr_image_hash) _xr_image_hash = eina_hash_string_superfast_new(NULL);
eina_hash_direct_add(_xr_image_hash, im->fkey, im);
return im;
}
XR_Image *
_xre_xcb_image_new_from_data(Ximage_Info *xinf, int w, int h, void *data, int alpha, int cspace)
{
XR_Image *im;
im = calloc(1, sizeof(XR_Image));
if (!im) return NULL;
im->xinf = xinf;
im->xinf->references++;
im->cs.space = cspace;
im->w = w;
im->h = h;
im->references = 1;
switch (im->cs.space)
{
case EVAS_COLORSPACE_ARGB8888:
im->data = data;
im->alpha = alpha;
break;
case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL:
im->cs.data = data;
im->cs.no_free = 1;
break;
default:
abort();
break;
}
im->dirty = 1;
__xre_xcb_image_dirty_hash_add(im);
return im;
}
XR_Image *
_xre_xcb_image_new_from_copied_data(Ximage_Info *xinf, int w, int h, void *data, int alpha, int cspace)
{
XR_Image *im;
im = calloc(1, sizeof(XR_Image));
if (!im) return NULL;
im->cs.space = cspace;
switch (im->cs.space)
{
case EVAS_COLORSPACE_ARGB8888:
im->data = malloc(w * h * 4);
if (!im->data)
{
free(im);
return NULL;
}
if (data)
{
Gfx_Func_Copy func;
func = evas_common_draw_func_copy_get(w * h, 0);
if (func) func(data, im->data, w * h);
evas_common_cpu_end_opt();
}
im->alpha = alpha;
im->free_data = 1;
break;
case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL:
im->cs.no_free = 0;
im->cs.data = calloc(1, h * sizeof(unsigned char *) * 2);
if ((data) && (im->cs.data))
memcpy(im->cs.data, data, h * sizeof(unsigned char *) * 2);
break;
default:
abort();
break;
}
im->w = w;
im->h = h;
im->references = 1;
im->xinf = xinf;
im->xinf->references++;
im->dirty = 1;
__xre_xcb_image_dirty_hash_add(im);
return im;
}
XR_Image *
_xre_xcb_image_new(Ximage_Info *xinf, int w, int h)
{
XR_Image *im;
im = calloc(1, sizeof(XR_Image));
if (!im) return NULL;
im->data = malloc(w * h * 4);
if (!im->data)
{
free(im);
return NULL;
}
im->w = w;
im->h = h;
im->references = 1;
im->cs.space = EVAS_COLORSPACE_ARGB8888;
im->xinf = xinf;
im->xinf->references++;
im->free_data = 1;
im->alpha = 1;
im->dirty = 1;
__xre_xcb_image_dirty_hash_add(im);
return im;
}
static void
__xre_xcb_image_real_free(XR_Image *im)
{
if (im->cs.data)
{
if (!im->cs.no_free) free(im->cs.data);
}
if (im->file) eina_stringshare_del(im->file);
if (im->key) eina_stringshare_del(im->key);
if (im->fkey) free(im->fkey);
if (im->im) evas_cache_image_drop(&im->im->cache_entry);
if ((im->data) && (im->dirty)) __xre_xcb_image_dirty_hash_del(im);
if ((im->free_data) && (im->data)) free(im->data);
if (im->surface) _xr_xcb_render_surface_free(im->surface);
if (im->format) eina_stringshare_del(im->format);
if (im->comment) eina_stringshare_del(im->comment);
if (im->updates) evas_common_tilebuf_free(im->updates);
_xr_xcb_image_info_free(im->xinf);
free(im);
}
void
_xre_xcb_image_free(XR_Image *im)
{
im->references--;
if (im->references != 0) return;
if (!im->dirty)
{
if (im->fkey)
eina_hash_del(_xr_image_hash, im->fkey, im);
_xr_image_cache = eina_list_prepend(_xr_image_cache, im);
_xr_image_cache_usage += (im->w * im->h * 4);
_xre_xcb_image_cache_set(_xr_image_cache_size);
}
else
{
__xre_xcb_image_real_free(im);
}
}
void
_xre_xcb_image_region_dirty(XR_Image *im, int x, int y, int w, int h)
{
if (!im->updates)
{
im->updates = evas_common_tilebuf_new(im->w, im->h);
if (im->updates) evas_common_tilebuf_set_tile_size(im->updates, 8, 8);
}
if (im->updates)
evas_common_tilebuf_add_redraw(im->updates, x, y, w, h);
}
void
_xre_xcb_image_dirty(XR_Image *im)
{
if (im->dirty) return;
if (im->fkey)
eina_hash_del(_xr_image_hash, im->fkey, im);
im->dirty = 1;
__xre_xcb_image_dirty_hash_add(im);
}
XR_Image *
_xre_xcb_image_copy(XR_Image *im)
{
XR_Image *im2;
void *data = NULL;
if (im->data) data = im->data;
else if (im->cs.data) data = im->cs.data;
else
{
if (!im->im)
im->im = evas_common_load_image_from_file(im->file, im->key, &(im->load_opts), im->load_error);
if (im->im)
{
evas_cache_image_load_data(&im->im->cache_entry);
data = im->im->image.data;
}
}
if (!data) return NULL;
im2 = _xre_xcb_image_new_from_copied_data(im->xinf, im->w, im->h, data, im->alpha, im->cs.space);
return im2;
}
void
_xre_xcb_image_resize(XR_Image *im, int w, int h)
{
if ((w == im->w) && (h == im->h)) return;
if (im->surface)
{
Xrender_Surface *old_surface;
old_surface = im->surface;
im->surface = _xr_xcb_render_surface_new(old_surface->xinf, w + 2, h + 2, old_surface->x11.xcb.fmt, old_surface->alpha);
_xr_xcb_render_surface_free(old_surface);
}
switch (im->cs.space)
{
case EVAS_COLORSPACE_ARGB8888:
if (im->data)
{
if (im->free_data)
{
if (im->data) free(im->data);
im->data = malloc(w * h * 4);
}
}
else if (im->im)
{
evas_cache_image_drop(&im->im->cache_entry);
im->im = NULL;
if (im->free_data)
{
if (im->data) free(im->data);
im->data = malloc(w * h * 4);
}
}
else
{
im->data = malloc(w * h * 4);
im->free_data = 1;
}
break;
case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL:
if (im->data)
{
if (im->free_data)
{
if (im->data) free(im->data);
}
im->data = NULL;
}
if (im->im)
{
evas_cache_image_drop(&im->im->cache_entry);
im->im = NULL;
}
if (!im->cs.no_free)
{
if (im->cs.data) free(im->cs.data);
im->cs.data = calloc(1, h * sizeof(unsigned char *) * 2);
}
break;
default:
abort();
break;
}
__xre_xcb_image_dirty_hash_del(im);
__xre_xcb_image_dirty_hash_add(im);
im->w = w;
im->h = h;
}
void *
_xre_xcb_image_data_get(XR_Image *im)
{
void *data = NULL;
if (im->data) data = im->data;
else if (im->cs.data) data = im->cs.data;
else
{
if (!im->im) im->im = evas_common_load_image_from_file(im->file, im->key, &(im->load_opts), im->load_error);
if (im->im)
{
evas_cache_image_load_data(&im->im->cache_entry);
data = im->im->image.data;
}
}
return data;
}
XR_Image *
_xre_xcb_image_data_find(void *data)
{
XR_Image *im;
im = __xre_xcb_image_dirty_hash_find(data);
if (im)
{
im->references++;
}
return im;
}
void
_xre_xcb_image_data_put(XR_Image *im, void *data)
{
if (!data) return;
switch (im->cs.space)
{
case EVAS_COLORSPACE_ARGB8888:
if (im->im)
{
if (data == im->im->image.data) return;
evas_cache_image_drop(&im->im->cache_entry);
im->im = NULL;
}
if (im->cs.data == data) return;
if (im->data)
{
if (im->data == data) return;
if (im->free_data) free(im->data);
im->free_data = 0;
}
im->data = data;
im->free_data = 0;
break;
case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL:
if (im->data)
{
if (im->free_data) free(im->data);
im->data = NULL;
}
im->free_data = 0;
if (data == im->cs.data) return;
if (!im->cs.no_free)
{
if (im->cs.data) free(im->cs.data);
}
im->cs.data = data;
break;
default:
abort();
break;
}
__xre_xcb_image_dirty_hash_del(im);
__xre_xcb_image_dirty_hash_add(im);
if (im->surface)
{
_xr_xcb_render_surface_free(im->surface);
im->surface = NULL;
}
if (!im->dirty)
{
if (im->fkey)
eina_hash_del(_xr_image_hash, im->fkey, im);
im->dirty = 1;
}
if (im->updates)
{
evas_common_tilebuf_free(im->updates);
im->updates = NULL;
}
}
void
_xre_xcb_image_alpha_set(XR_Image *im, int alpha)
{
if (im->alpha == alpha) return;
switch (im->cs.space)
{
case EVAS_COLORSPACE_ARGB8888:
im->alpha = alpha;
if (im->surface)
{
Xrender_Surface *old_surface;
old_surface = im->surface;
im->surface = NULL;
if (im->alpha)
im->surface = _xr_xcb_render_surface_new(im->xinf, im->w + 2, im->h + 2, im->xinf->x11.fmt32, 1);
else
{
/* FIXME: if im->depth == 16, use xinf->fmtdef */
if ((im->xinf->depth == 16) &&
(((xcb_visualtype_t *)im->xinf->x11.visual)->red_mask == 0xf800) &&
(((xcb_visualtype_t *)im->xinf->x11.visual)->green_mask == 0x07e0) &&
(((xcb_visualtype_t *)im->xinf->x11.visual)->blue_mask == 0x001f))
im->surface = _xr_xcb_render_surface_new(im->xinf, im->w + 2, im->h + 2, im->xinf->x11.fmtdef, 0);
else
im->surface = _xr_xcb_render_surface_new(im->xinf, im->w + 2, im->h + 2, im->xinf->x11.fmt24, 0);
}
if (im->surface)
_xr_xcb_render_surface_copy(old_surface, im->surface, 0, 0, 0, 0, im->w + 2, im->h + 2);
_xr_xcb_render_surface_free(old_surface);
}
if (im->updates)
{
evas_common_tilebuf_free(im->updates);
im->updates = NULL;
}
default:
break;
}
}
int
_xre_xcb_image_alpha_get(XR_Image *im)
{
if (im->im)
{
if (im->im->cache_entry.space != EVAS_COLORSPACE_ARGB8888) return 0;
}
return im->alpha;
}
void
_xre_xcb_image_border_set(XR_Image *im, int l, int r, int t, int b)
{
if (!im) return;
_xre_xcb_image_surface_gen(im);
if (l < 1) l = 0;
if (r < 1) r = 0;
if (t < 1) t = 0;
if (b < 1) b = 0;
if (im->surface)
{
if (l | r | t | b)
im->surface->bordered = 1;
else
im->surface->bordered = 0;
}
}
void
_xre_xcb_image_border_get(XR_Image *im __UNUSED__, int *l __UNUSED__, int *r __UNUSED__, int *t __UNUSED__, int *b __UNUSED__)
{
}
void
_xre_xcb_image_surface_gen(XR_Image *im)
{
void *data = NULL;
void *tdata = NULL;
if ((im->surface) && (!im->updates)) return;
if (im->data) data = im->data;
else
{
if (!im->im) im->im = evas_common_load_image_from_file(im->file, im->key, &(im->load_opts), im->load_error);
if (im->im)
{
evas_cache_image_load_data(&im->im->cache_entry);
data = im->im->image.data;
}
}
if (!data)
{
switch (im->cs.space)
{
case EVAS_COLORSPACE_ARGB8888:
return;
break;
case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL:
if ((im->cs.data) && (*((unsigned char **)im->cs.data)))
{
tdata = malloc(im->w * im->h * sizeof(DATA32));
if (tdata)
evas_common_convert_yuv_420p_601_rgba(im->cs.data,
tdata,
im->w, im->h);
data = tdata;
}
break;
default:
abort();
break;
}
if (!data) return;
}
if (im->surface)
{
if (im->updates)
{
Tilebuf_Rect *rects, *r;
rects = evas_common_tilebuf_get_render_rects(im->updates);
if (rects)
{
EINA_INLIST_FOREACH(rects, r)
{
int rx, ry, rw, rh;
rx = r->x; ry = r->y; rw = r->w, rh = r->h;
RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, im->w, im->h);
if (im->alpha)
_xr_xcb_render_surface_argb_pixels_fill(im->surface, im->w, im->h, data, rx, ry, rw, rh, 1, 1);
else
/* FIXME: if im->depth == 16 - convert to 16bpp then
* upload */
_xr_xcb_render_surface_rgb_pixels_fill(im->surface, im->w, im->h, data, rx, ry, rw, rh, 1, 1);
}
evas_common_tilebuf_free_render_rects(rects);
}
evas_common_tilebuf_free(im->updates);
im->updates = NULL;
}
if (tdata) free(tdata);
return;
}
if (im->alpha)
{
im->surface = _xr_xcb_render_surface_new(im->xinf, im->w + 2, im->h + 2, im->xinf->x11.fmt32, 1);
_xr_xcb_render_surface_argb_pixels_fill(im->surface, im->w, im->h, data, 0, 0, im->w, im->h, 1, 1);
}
else
{
/* FIXME: if im->xinf->depth == 16, use xinf->fmtdef */
if ((im->xinf->depth == 16) &&
(((xcb_visualtype_t *)im->xinf->x11.visual)->red_mask == 0xf800) &&
(((xcb_visualtype_t *)im->xinf->x11.visual)->green_mask == 0x07e0) &&
(((xcb_visualtype_t *)im->xinf->x11.visual)->blue_mask == 0x001f))
im->surface = _xr_xcb_render_surface_new(im->xinf, im->w + 2, im->h + 2, im->xinf->x11.fmtdef, 0);
else
im->surface = _xr_xcb_render_surface_new(im->xinf, im->w + 2, im->h + 2, im->xinf->x11.fmt24, 0);
/* FIXME: if im->depth == 16 - convert to 16bpp then
* upload */
_xr_xcb_render_surface_rgb_pixels_fill(im->surface, im->w, im->h, data, 0, 0, im->w, im->h, 1, 1);
}
/* fill borders */
_xr_xcb_render_surface_copy(im->surface, im->surface,
1, 1,
0, 1,
1, im->h);
_xr_xcb_render_surface_copy(im->surface, im->surface,
0, 1,
0, 0,
im->w + 2, 1);
_xr_xcb_render_surface_copy(im->surface, im->surface,
im->w, 1,
im->w + 1, 1,
1, im->h);
_xr_xcb_render_surface_copy(im->surface, im->surface,
0, im->h,
0, im->h + 1,
im->w + 2, 1);
if ((im->im) && (!im->dirty))
{
evas_cache_image_drop(&im->im->cache_entry);
im->im = NULL;
}
if (tdata) free(tdata);
}
void
_xre_xcb_image_cache_set(int size)
{
_xr_image_cache_size = size;
while (_xr_image_cache_usage > _xr_image_cache_size)
{
Eina_List *l;
l = eina_list_last(_xr_image_cache);
if (l)
{
XR_Image *im;
im = l->data;
_xr_image_cache = eina_list_remove_list(_xr_image_cache, l);
_xr_image_cache_usage -= (im->w * im->h * 4);
__xre_xcb_image_real_free(im);
}
}
}
int
_xre_xcb_image_cache_get(void)
{
return _xr_image_cache_size;
}

View File

@ -1,841 +0,0 @@
#include "evas_common.h"
/* #include "evas_macros.h" */
#include "evas_private.h"
#include "evas_engine.h"
#include "Evas_Engine_XRender_X11.h"
#include <math.h>
/* As opposed to libXRender, we don't have
* XDoubleToFixed in XCB :/
*/
#define DOUBLE_TO_FIXED(d) ((xcb_render_fixed_t) ((d) * 65536))
/* this is a work around broken xrender - when/if this ever gets fixed in xorg
* we can comment this out and one day remove it - for now keep it until such
* a fix is spotted in the wild
*/
#define BROKEN_XORG_XRENDER 1
static inline void
set_filter(Xrender_Surface *s, int smooth)
{
const char *f = smooth ? "best": "nearest";
xcb_render_set_picture_filter (s->xinf->x11.connection, s->x11.xcb.pic, strlen (f), f, 0, NULL);
}
xcb_render_pictforminfo_t *
xcb_render_find_visual_format (xcb_connection_t *c, xcb_visualtype_t *visual)
{
xcb_render_query_pict_formats_cookie_t cookie;
xcb_render_query_pict_formats_reply_t *rep;
xcb_render_pictscreen_iterator_t screen_iter;
xcb_render_pictformat_t format = { 0 };
cookie = xcb_render_query_pict_formats (c);
rep = xcb_render_query_pict_formats_reply (c, cookie, NULL);
if (!rep)
return NULL;
screen_iter = xcb_render_query_pict_formats_screens_iterator (rep);
for (; screen_iter.rem; xcb_render_pictscreen_next (&screen_iter)) {
xcb_render_pictdepth_iterator_t depth_iter;
depth_iter = xcb_render_pictscreen_depths_iterator (screen_iter.data);
for (; depth_iter.rem; xcb_render_pictdepth_next (&depth_iter)) {
xcb_render_pictvisual_iterator_t visual_iter;
visual_iter = xcb_render_pictdepth_visuals_iterator (depth_iter.data);
for (; visual_iter.rem; xcb_render_pictvisual_next (&visual_iter)) {
if (visual->visual_id == visual_iter.data->visual) {
format = visual_iter.data->format;
}
}
}
}
if (format != 0)
{
xcb_render_pictforminfo_iterator_t forminfo_iter;
forminfo_iter = xcb_render_query_pict_formats_formats_iterator (rep);
for (; forminfo_iter.rem; xcb_render_pictforminfo_next (&forminfo_iter)) {
if (forminfo_iter.data->id == format) {
xcb_render_pictforminfo_t *forminfo;
forminfo = (xcb_render_pictforminfo_t *)malloc (sizeof (xcb_render_pictforminfo_t));
memcpy (forminfo, forminfo_iter.data, sizeof (xcb_render_pictforminfo_t));
free (rep);
return forminfo;
}
}
}
return NULL;
}
Xrender_Surface *
_xr_xcb_render_surface_new(Ximage_Info *xinf, int w, int h, xcb_render_pictforminfo_t *fmt, int alpha)
{
Xrender_Surface *rs;
uint32_t mask;
uint32_t values[3];
if ((!xinf) || (!fmt) || (w < 1) || (h < 1)) return NULL;
rs = calloc(1, sizeof(Xrender_Surface));
if (!rs) return NULL;
rs->xinf = xinf;
rs->width = w;
rs->height = h;
rs->x11.xcb.fmt = (xcb_render_pictforminfo_t *)malloc (sizeof (xcb_render_pictforminfo_t));
if (!rs->x11.xcb.fmt)
{
free(rs);
return NULL;
}
memcpy (rs->x11.xcb.fmt, fmt, sizeof (xcb_render_pictforminfo_t));
rs->alpha = alpha;
rs->depth = fmt->depth;
rs->allocated = 1;
rs->x11.xcb.draw = xcb_generate_id(xinf->x11.connection);
xcb_create_pixmap(xinf->x11.connection, fmt->depth, rs->x11.xcb.draw, xinf->x11.root, w, h);
if (rs->x11.xcb.draw == XCB_NONE)
{
free(rs->x11.xcb.fmt);
free(rs);
return NULL;
}
rs->xinf->references++;
mask = XCB_RENDER_CP_REPEAT | XCB_RENDER_CP_DITHER | XCB_RENDER_CP_COMPONENT_ALPHA;
values[0] = 0;
values[1] = 1;
values[2] = 0;
rs->x11.xcb.pic = xcb_generate_id(xinf->x11.connection);
xcb_render_create_picture(xinf->x11.connection, rs->x11.xcb.pic, rs->x11.xcb.draw, fmt->id, mask, values);
if (rs->x11.xcb.pic == XCB_NONE)
{
xcb_free_pixmap(rs->xinf->x11.connection, rs->x11.xcb.draw);
rs->xinf->references--;
free(rs->x11.xcb.fmt);
free(rs);
return NULL;
}
return rs;
}
Xrender_Surface *
_xr_xcb_render_surface_adopt(Ximage_Info *xinf, xcb_drawable_t draw, int w, int h, int alpha)
{
Xrender_Surface *rs;
uint32_t mask;
uint32_t values[3];
if ((!xinf) || (draw == 0) || (w < 1) || (h < 1)) return NULL;
rs = calloc(1, sizeof(Xrender_Surface));
if (!rs) return NULL;
rs->xinf = xinf;
rs->width = w;
rs->height = h;
/* if (fmt->depth == xinf->fmt32->depth) */
/* rs->x11.xcb.fmt = xinf->fmt32; */
/* else if (fmt->depth == xinf->fmt24->depth) */
/* rs->x11.xcb.fmt = xinf->fmt24; */
/* else if (fmt->depth == xinf->fmt8->depth) */
/* rs->x11.xcb.fmt = xinf->fmt8; */
/* else if (fmt->depth == xinf->fmt4->depth) */
/* rs->x11.xcb.fmt = xinf->fmt4; */
/* else */
/* rs->x11.xcb.fmt = xinf->fmt1; */
/* free(fmt); */
rs->x11.xcb.fmt = xcb_render_find_visual_format(xinf->x11.connection, xinf->x11.visual);
if (!rs->x11.xcb.fmt)
{
free(rs);
return NULL;
}
rs->alpha = alpha;
rs->depth = rs->x11.xcb.fmt->depth;
if (rs->x11.xcb.fmt->depth == 32) rs->alpha = 1;
rs->allocated = 0;
rs->x11.xcb.draw = draw;
rs->xinf->references++;
mask = XCB_RENDER_CP_REPEAT | XCB_RENDER_CP_DITHER | XCB_RENDER_CP_COMPONENT_ALPHA;
values[0] = 0;
values[1] = 1;
values[2] = 0;
rs->x11.xcb.pic = xcb_generate_id(xinf->x11.connection);
xcb_render_create_picture(xinf->x11.connection, rs->x11.xcb.pic, rs->x11.xcb.draw, rs->x11.xcb.fmt->id, mask, values);
if (rs->x11.xcb.pic == XCB_NONE)
{
rs->xinf->references--;
free(rs->x11.xcb.fmt);
free(rs);
return NULL;
}
return rs;
}
Xrender_Surface *
_xr_xcb_render_surface_format_adopt(Ximage_Info *xinf, xcb_drawable_t draw, int w, int h, xcb_render_pictforminfo_t *fmt, int alpha)
{
Xrender_Surface *rs;
uint32_t mask;
uint32_t values[3];
if ((!xinf) || (!fmt) || (draw == XCB_NONE) || (w < 1) || (h < 1)) return NULL;
rs = calloc(1, sizeof(Xrender_Surface));
if (!rs) return NULL;
rs->xinf = xinf;
rs->width = w;
rs->height = h;
rs->x11.xcb.fmt = (xcb_render_pictforminfo_t *)malloc (sizeof (xcb_render_pictforminfo_t));
memcpy (rs->x11.xcb.fmt, fmt, sizeof (xcb_render_pictforminfo_t));
rs->alpha = alpha;
rs->depth = fmt->depth;
if (fmt->depth == 32) rs->alpha = 1;
rs->xinf->references++;
rs->allocated = 0;
rs->x11.xcb.draw = draw;
mask = XCB_RENDER_CP_REPEAT | XCB_RENDER_CP_DITHER | XCB_RENDER_CP_COMPONENT_ALPHA;
values[0] = 0;
values[1] = 1;
values[2] = 0;
rs->x11.xcb.pic = xcb_generate_id(xinf->x11.connection);
xcb_render_create_picture(xinf->x11.connection, rs->x11.xcb.pic, rs->x11.xcb.draw, fmt->id, mask, values);
if (rs->x11.xcb.pic == XCB_NONE)
{
rs->xinf->references--;
free(rs->x11.xcb.fmt);
free(rs);
return NULL;
}
return rs;
}
void
_xr_xcb_render_surface_free(Xrender_Surface *rs)
{
if (!rs) return;
if (rs->xinf)
{
if ((rs->allocated) && (rs->x11.xcb.draw != XCB_NONE))
xcb_free_pixmap(rs->xinf->x11.connection, rs->x11.xcb.draw);
if (rs->x11.xcb.pic != XCB_NONE)
xcb_render_free_picture(rs->xinf->x11.connection, rs->x11.xcb.pic);
_xr_xcb_image_info_free(rs->xinf);
rs->xinf = NULL;
}
free(rs->x11.xcb.fmt);
free(rs);
}
void
_xr_xcb_render_surface_repeat_set(Xrender_Surface *rs, int repeat)
{
uint32_t mask;
uint32_t value[1];
mask = XCB_RENDER_CP_REPEAT;
value[0] = repeat;
xcb_render_change_picture(rs->xinf->x11.connection, rs->x11.xcb.pic, mask, value);
}
void
_xr_xcb_render_surface_solid_rectangle_set(Xrender_Surface *rs, int r, int g, int b, int a, int x, int y, int w, int h)
{
xcb_render_color_t col;
xcb_rectangle_t rect;
col.red = (r << 8) | r;
col.green = (g << 8) | g;
col.blue = (b << 8) | b;
col.alpha = (a << 8) | a;
rect.x = x;
rect.y = y;
rect.width = w;
rect.height = h;
xcb_render_fill_rectangles(rs->xinf->x11.connection, XCB_RENDER_PICT_OP_SRC, rs->x11.xcb.pic, col, 1, &rect);
}
void
_xr_xcb_render_surface_argb_pixels_fill(Xrender_Surface *rs, int sw, int sh __UNUSED__, void *pixels, int x, int y, int w, int h, int ox, int oy)
{
Ximage_Image *xim;
unsigned int *p, *sp, *sple, *spe;
unsigned int jump, sjump;
xim = _xr_xcb_image_new(rs->xinf, w, h, rs->depth);
if (!xim) return;
p = (unsigned int *)xim->data;
sp = ((unsigned int *)pixels) + (y * sw) + x;
jump = ((xim->line_bytes / 4) - w);
sjump = sw - w;
spe = sp + ((h - 1) * sw) + w;
if
#ifdef WORDS_BIGENDIAN
(xim->x11.xcb.xim->byte_order == XCB_IMAGE_ORDER_LSB_FIRST)
#else
(xim->x11.xcb.xim->byte_order == XCB_IMAGE_ORDER_MSB_FIRST)
#endif
{
while (sp < spe)
{
sple = sp + w;
while (sp < sple)
{
*p++ = (*sp << 24) + ((*sp << 8) & 0xff0000) + ((*sp >> 8) & 0xff00) + (*sp >> 24);
// *p++ = (B_VAL(sp) << 24) | (G_VAL(sp) << 16) | (R_VAL(sp) << 8) | A_VAL(sp);
sp++;
}
p += jump;
sp += sjump;
}
}
else
{
while (sp < spe)
{
sple = sp + w;
while (sp < sple)
*p++ = *sp++;
p += jump;
sp += sjump;
}
}
_xr_xcb_image_put(xim, rs->x11.xcb.draw, x + ox, y + oy, w, h);
}
void
_xr_xcb_render_surface_rgb_pixels_fill(Xrender_Surface *rs, int sw, int sh __UNUSED__, void *pixels, int x, int y, int w, int h, int ox, int oy)
{
Ximage_Image *xim;
unsigned int *p, *sp, *sple, *spe;
unsigned int jump, sjump;
xim = _xr_xcb_image_new(rs->xinf, w, h, rs->depth);
if (!xim) return;
p = (unsigned int *)xim->data;
sp = ((unsigned int *)pixels) + (y * sw) + x;
sjump = sw - w;
spe = sp + ((h - 1) * sw) + w;
if (rs->depth == 16)
{
/* FIXME: if rs->depth == 16 - convert */
Gfx_Func_Convert conv_func;
int swap;
jump = ((xim->line_bytes / 2) - w);
#ifdef WORDS_BIGENDIAN
swap = (int)(xim->x11.xcb.xim->byte_order == XCB_IMAGE_ORDER_LSB_FIRST);
#else
swap = (int)(xim->x11.xcb.xim->byte_order == XCB_IMAGE_ORDER_MSB_FIRST);
#endif
/* FIXME: swap not handled */
conv_func = evas_common_convert_func_get((DATA8 *)sp, w, h, rs->depth,
((xcb_visualtype_t *)rs->xinf->x11.visual)->red_mask,
((xcb_visualtype_t *)rs->xinf->x11.visual)->green_mask,
((xcb_visualtype_t *)rs->xinf->x11.visual)->blue_mask,
PAL_MODE_NONE, 0);
if (conv_func)
conv_func(sp, (DATA8 *)p, sjump, jump, w, h, x, y, NULL);
}
else
{
jump = ((xim->line_bytes / 4) - w);
if
#ifdef WORDS_BIGENDIAN
(xim->x11.xcb.xim->byte_order == XCB_IMAGE_ORDER_LSB_FIRST)
#else
(xim->x11.xcb.xim->byte_order == XCB_IMAGE_ORDER_MSB_FIRST)
#endif
{
while (sp < spe)
{
sple = sp + w;
while (sp < sple)
{
*p++ = (*sp << 24) + ((*sp << 8) & 0xff0000) + ((*sp >> 8) & 0xff00) + 0xff;
// *p++ = ((B_VAL(sp)) << 24) | ((G_VAL(sp)) << 16) | ((R_VAL(sp)) << 8) | 0x000000ff;
sp++;
}
p += jump;
sp += sjump;
}
}
else
{
while (sp < spe)
{
sple = sp + w;
while (sp < sple)
*p++ = 0xff000000 | *sp++;
p += jump;
sp += sjump;
}
}
}
_xr_xcb_image_put(xim, rs->x11.xcb.draw, x + ox, y + oy, w, h);
}
void
_xr_xcb_render_surface_clips_set(Xrender_Surface *rs, RGBA_Draw_Context *dc, int rx, int ry, int rw, int rh)
{
int num = 0;
xcb_rectangle_t *rect = NULL;
if ((dc) && (dc->clip.use))
{
RECTS_CLIP_TO_RECT(rx, ry, rw, rh,
dc->clip.x, dc->clip.y, dc->clip.w, dc->clip.h);
}
if ((!dc) || (!dc->cutout.rects))
{
rect = malloc(sizeof(xcb_rectangle_t));
if (!rect) return;
rect->x = rx;
rect->y = ry;
rect->width = rw;
rect->height = rh;
num = 1;
}
else
{
Cutout_Rects *rects;
Cutout_Rect *r;
int i;
rects = evas_common_draw_context_apply_cutouts(dc);
num = rects->active;
rect = malloc(num * sizeof(xcb_rectangle_t));
if (!rect) return;
for (i = 0; i < num; i++)
{
r = rects->rects + i;
rect[i].x = r->x;
rect[i].y = r->y;
rect[i].width = r->w;
rect[i].height = r->h;
}
evas_common_draw_context_apply_clear_cutouts(rects);
}
if (!rect) return;
xcb_render_set_picture_clip_rectangles(rs->xinf->x11.connection, rs->x11.xcb.pic, 0, 0, num, rect);
free(rect);
}
/* initialized the transform to the identity */
static void
init_transform (xcb_render_transform_t *t)
{
t->matrix11 = t->matrix22 = t->matrix33 = DOUBLE_TO_FIXED(1);
t->matrix12 = t->matrix13 = t->matrix21 = t->matrix23 =
t->matrix31 = t->matrix32 = 0;
}
static void
set_transform_scale(xcb_render_transform_t *t,
int sw,
int sh,
int w,
int h,
int tx,
int ty)
{
/* if ((sw > 1) && (w > 1)) */
/* { sw--; w--; } */
/* if ((sh > 1) && (h > 1)) */
/* { sh--; h--; } */
t->matrix11 = DOUBLE_TO_FIXED((double)sw / (double)w);
t->matrix22 = DOUBLE_TO_FIXED((double)sh / (double)h);
t->matrix31 = (tx * sw) / w;
t->matrix32 = (ty * sh) / h;
}
// when color multiplier is used want: instead
// CA src IN mask SRC temp; non-CA temp OVER dst. - i think. need to check.
void
_xr_xcb_render_surface_composite(Xrender_Surface *srs,
Xrender_Surface *drs,
RGBA_Draw_Context *dc,
int sx,
int sy,
int sw,
int sh,
int x,
int y,
int w,
int h,
int smooth)
{
Xrender_Surface *trs = NULL;
xcb_render_transform_t xf;
xcb_render_picture_t mask = XCB_NONE;
uint32_t value_mask;
uint32_t value_list[1];
int e, is_scaling;
xcb_render_pict_op_t op;
if ((sw <= 0) || (sh <= 0) || (w <= 0) || (h <= 0)) return;
is_scaling = e = (sw != w) || (sh != h);
value_mask = XCB_RENDER_CP_CLIP_MASK;
value_list[0] = 0;
xcb_render_change_picture(srs->xinf->x11.connection, srs->x11.xcb.pic, value_mask, value_list);
xcb_render_change_picture(drs->xinf->x11.connection, drs->x11.xcb.pic, value_mask, value_list);
init_transform(&xf);
op = XCB_RENDER_PICT_OP_OVER;
if (dc->render_op == _EVAS_RENDER_BLEND)
{
if (!srs->alpha) op = XCB_RENDER_PICT_OP_SRC;
}
else if (dc->render_op == _EVAS_RENDER_BLEND_REL)
op = XCB_RENDER_PICT_OP_ATOP;
else if (dc->render_op == _EVAS_RENDER_MUL)
op = XCB_RENDER_PICT_OP_IN;
else if (dc->render_op == _EVAS_RENDER_COPY)
op = XCB_RENDER_PICT_OP_SRC;
else if (dc->render_op == _EVAS_RENDER_COPY_REL)
op = XCB_RENDER_PICT_OP_IN;
else if (dc->render_op == _EVAS_RENDER_MASK)
op = XCB_RENDER_PICT_OP_IN_REVERSE;
if ((dc) && (dc->mul.use))
{
int r, g, b, a;
if ((op == XCB_RENDER_PICT_OP_OVER) && (!dc->mul.col)) return;
a = dc->mul.col >> 24;
r = (dc->mul.col >> 16) & 0xff;
g = (dc->mul.col >> 8) & 0xff;
b = dc->mul.col & 0xff;
if (dc->mul.col != 0xffffffff)
{
if ((srs->xinf->mul_r != r) || (srs->xinf->mul_g != g) ||
(srs->xinf->mul_b != b) || (srs->xinf->mul_a != a))
{
srs->xinf->mul_r = r;
srs->xinf->mul_g = g;
srs->xinf->mul_b = b;
srs->xinf->mul_a = a;
_xr_xcb_render_surface_solid_rectangle_set(srs->xinf->mul,
r,
g,
b,
a,
0, 0, 1, 1);
}
mask = srs->xinf->mul->x11.xcb.pic;
if (dc->mul.col == (a * 0x01010101))
{
value_mask = XCB_RENDER_CP_COMPONENT_ALPHA;
value_list[0] = 0;
xcb_render_change_picture(srs->xinf->x11.connection, mask, value_mask, value_list);
}
else
{
if ((srs->alpha) || (a != 0xff))
trs = _xr_xcb_render_surface_new(srs->xinf, sw + 2, sh + 2,
srs->xinf->x11.fmt32, 1);
else
trs = _xr_xcb_render_surface_new(srs->xinf, sw + 2, sh + 2,
srs->x11.xcb.fmt, srs->alpha);
if (!trs) return;
value_mask = XCB_RENDER_CP_COMPONENT_ALPHA;
value_list[0] = 1;
xcb_render_change_picture(srs->xinf->x11.connection, mask, value_mask, value_list);
xcb_render_set_picture_transform(trs->xinf->x11.connection, srs->x11.xcb.pic, xf);
xcb_render_composite(srs->xinf->x11.connection, XCB_RENDER_PICT_OP_SRC, srs->x11.xcb.pic, mask, trs->x11.xcb.pic,
sx, sy, sx, sy, 0, 0, sw + 2, sh + 2);
mask = XCB_NONE;
}
}
}
//#define HFW + (sw / 2)
//#define HFH + (sh / 2)
#define HFW
#define HFH
_xr_xcb_render_surface_clips_set(drs, dc, x, y, w, h);
if (trs)
{
set_filter(trs, smooth);
set_transform_scale(&xf, sw, sh, w, h, -1, -1);
xcb_render_set_picture_transform(trs->xinf->x11.connection, trs->x11.xcb.pic, xf);
value_mask = XCB_RENDER_CP_COMPONENT_ALPHA;
value_list[0] = 0;
if (dc->render_op == _EVAS_RENDER_MUL)
value_list[0] = 1;
xcb_render_change_picture(trs->xinf->x11.connection, trs->x11.xcb.pic, value_mask, value_list);
xcb_render_composite(trs->xinf->x11.connection, op, trs->x11.xcb.pic, mask, drs->x11.xcb.pic,
(w HFW) / sw, (h HFH) / sh,
(w HFW) / sw, (h HFH) / sh,
x, y, w, h);
_xr_xcb_render_surface_free(trs);
}
else
{
if (srs->bordered && is_scaling)
{
trs = _xr_xcb_render_surface_new(srs->xinf, sw + 2, sh + 2,
srs->x11.xcb.fmt, srs->alpha);
if (!trs) return;
value_mask = XCB_RENDER_CP_COMPONENT_ALPHA;
value_list[0] = 0;
xcb_render_change_picture(srs->xinf->x11.connection, srs->x11.xcb.pic, value_mask, value_list);
xcb_render_set_picture_transform(srs->xinf->x11.connection, srs->x11.xcb.pic, xf);
xcb_render_composite(srs->xinf->x11.connection, XCB_RENDER_PICT_OP_SRC, srs->x11.xcb.pic, XCB_NONE, trs->x11.xcb.pic,
sx, sy, sx, sx, 0, 0, sw + 2, sh + 2);
set_filter(trs, smooth);
set_transform_scale(&xf, sw, sh, w, h, -1, -1);
xcb_render_set_picture_transform(trs->xinf->x11.connection, trs->x11.xcb.pic, xf);
if (dc->render_op == _EVAS_RENDER_MUL)
{
value_mask = XCB_RENDER_CP_COMPONENT_ALPHA;
value_list[0] = 1;
xcb_render_change_picture(trs->xinf->x11.connection, trs->x11.xcb.pic, value_mask, value_list);
}
xcb_render_composite(trs->xinf->x11.connection, op, trs->x11.xcb.pic, mask, drs->x11.xcb.pic,
(w HFW) / sw, (h HFH) / sh,
(w HFW) / sw, (h HFH) / sh,
x, y, w, h);
_xr_xcb_render_surface_free(trs);
}
else
{
set_filter(srs, smooth);
set_transform_scale(&xf, sw, sh, w, h, 0, 0);
xcb_render_set_picture_transform(srs->xinf->x11.connection, srs->x11.xcb.pic, xf);
value_mask = XCB_RENDER_CP_COMPONENT_ALPHA;
value_list[0] = 0;
if (dc->render_op == _EVAS_RENDER_MUL)
value_list[0] = 1;
xcb_render_change_picture(srs->xinf->x11.connection, srs->x11.xcb.pic, value_mask, value_list);
xcb_render_composite(srs->xinf->x11.connection, op, srs->x11.xcb.pic, mask, drs->x11.xcb.pic,
((((sx + 1) * w) HFW) / sw),
((((sy + 1) * h) HFH) / sh),
((((sx + 1) * w) HFW) / sw),
((((sy + 1) * h) HFH) / sh),
x, y, w, h);
}
}
}
void
_xr_xcb_render_surface_copy(Xrender_Surface *srs, Xrender_Surface *drs, int sx, int sy, int x, int y, int w, int h)
{
xcb_render_transform_t xf;
uint32_t value_mask;
uint32_t value_list[1];
if ((w <= 0) || (h <= 0) || (!srs) || (!drs)) return;
init_transform(&xf);
#ifdef BROKEN_XORG_XRENDER
/* FIXME: why do we need to change the identity matrix if the src surface
* is 1 bit deep?
*/
if (srs->depth == 1)
{
xf.matrix11 = xf.matrix22 = xf.matrix33 = 1;
}
#endif
xcb_render_set_picture_transform(srs->xinf->x11.connection, srs->x11.xcb.pic, xf);
/* set_filter(srs, 0); */
value_mask = XCB_RENDER_CP_CLIP_MASK;
value_list[0] = 0;
xcb_render_change_picture(srs->xinf->x11.connection, srs->x11.xcb.pic, value_mask, value_list);
xcb_render_change_picture(drs->xinf->x11.connection, drs->x11.xcb.pic, value_mask, value_list);
xcb_render_composite(srs->xinf->x11.connection, XCB_RENDER_PICT_OP_SRC, srs->x11.xcb.pic, XCB_NONE, drs->x11.xcb.pic,
sx, sy, 0, 0, x, y, w, h);
}
void
_xr_xcb_render_surface_rectangle_draw(Xrender_Surface *rs, RGBA_Draw_Context *dc, int x, int y, int w, int h)
{
xcb_render_color_t col;
xcb_rectangle_t rect;
uint32_t value_mask;
uint32_t value_list;
int r, g, b, a;
xcb_render_pict_op_t op;
if ((!rs) || (!dc)) return;
if ((w <= 0) || (h <= 0)) return;
a = dc->col.col >> 24;
r = (dc->col.col >> 16) & 0xff;
g = (dc->col.col >> 8 ) & 0xff;
b = (dc->col.col ) & 0xff;
col.red = (r << 8) | r;
col.green = (g << 8) | g;
col.blue = (b << 8) | b;
col.alpha = (a << 8) | a;
op = XCB_RENDER_PICT_OP_SRC;
if (dc->render_op == _EVAS_RENDER_BLEND)
{
if (!dc->col.col) return;
if (a == 0xff) op = XCB_RENDER_PICT_OP_SRC;
}
else if (dc->render_op == _EVAS_RENDER_BLEND_REL)
{
if (!dc->col.col) return;
op = XCB_RENDER_PICT_OP_ATOP;
}
else if (dc->render_op == _EVAS_RENDER_MUL)
{
if (dc->col.col == 0xffffffff) return;
op = XCB_RENDER_PICT_OP_IN;
}
else if (dc->render_op == _EVAS_RENDER_COPY)
op = XCB_RENDER_PICT_OP_SRC;
else if (dc->render_op == _EVAS_RENDER_COPY_REL)
op = XCB_RENDER_PICT_OP_IN;
else if (dc->render_op == _EVAS_RENDER_MASK)
op = XCB_RENDER_PICT_OP_IN_REVERSE;
value_mask = XCB_RENDER_CP_CLIP_MASK;
value_list = 0;
xcb_render_change_picture(rs->xinf->x11.connection, rs->x11.xcb.pic, value_mask, &value_list);
_xr_xcb_render_surface_clips_set(rs, dc, x, y, w, h);
rect.x = x;
rect.y = y;
rect.width = w;
rect.height = h;
xcb_render_fill_rectangles(rs->xinf->x11.connection, op, rs->x11.xcb.pic, col, 1, &rect);
}
void
_xr_xcb_render_surface_line_draw(Xrender_Surface *rs __UNUSED__, RGBA_Draw_Context *dc __UNUSED__, int x1 __UNUSED__, int y1 __UNUSED__, int x2 __UNUSED__, int y2 __UNUSED__)
{
/* uint32_t value_mask; */
/* uint32_t value_list[1]; */
/* int op; */
/* if ((!rs) || (!dc)) return; */
/* op = XCB_RENDER_PICT_OP_SRC; */
/* value_mask = XCB_RENDER_CP_CLIP_MASK; */
/* value_list[0] = 0; */
/* xcb_render_change_picture(rs->xinf->x11.connection, rs->x11.xcb.pic, value_mask, value_list); */
/* _xr_xcb_render_surface_clips_set(rs, dc, 0, 0, rs->width, rs->height); */
/* { */
/* int r, g, b, a; */
/* XPointDouble poly[4]; */
/* int dx, dy; */
/* double len, ddx, ddy; */
/* dx = x2 - x1; */
/* dy = y2 - y1; */
/* len = sqrt((double)(dx * dx) + (double)(dy * dy)); */
/* ddx = (0.5 * dx) / len; */
/* ddy = (0.5 * dy) / len; */
/* poly[0].x = (x1 + ddx); */
/* poly[0].y = (y1 - ddy); */
/* poly[1].x = (x2 + ddx); */
/* poly[1].y = (y2 - ddy); */
/* poly[2].x = (x2 - ddx); */
/* poly[2].y = (y2 + ddy); */
/* poly[3].x = (x1 - ddx); */
/* poly[3].y = (y1 + ddy); */
/* a = (dc->col.col >> 24) & 0xff; */
/* if (a == 0) return; */
/* if (a < 0xff) op = XCB_RENDER_PICT_OP_OVER; */
/* r = (dc->col.col >> 16) & 0xff; */
/* g = (dc->col.col >> 8 ) & 0xff; */
/* b = (dc->col.col ) & 0xff; */
/* if ((rs->xinf->mul_r != r) || (rs->xinf->mul_g != g) || */
/* (rs->xinf->mul_b != b) || (rs->xinf->mul_a != a)) */
/* { */
/* rs->xinf->mul_r = r; */
/* rs->xinf->mul_g = g; */
/* rs->xinf->mul_b = b; */
/* rs->xinf->mul_a = a; */
/* _xr_xcb_render_surface_solid_rectangle_set(rs->xinf->mul, r, g, b, a, 0, 0, 1, 1); */
/* } */
/* XRenderCompositeDoublePoly(rs->xinf->x11.connection, op, */
/* rs->xinf->mul->pic, rs->x11.xcb.pic, */
/* rs->xinf->fmt8, 0, 0, 0, 0, */
/* poly, 4, EvenOddRule); */
/* } */
}
void
_xr_xcb_render_surface_polygon_draw(Xrender_Surface *rs __UNUSED__, RGBA_Draw_Context *dc __UNUSED__, RGBA_Polygon_Point *points __UNUSED__, int x, int y)
{
/* RGBA_Polygon_Point *pt; */
/* int i, num; */
/* XPointDouble *pts; */
/* int r, g, b, a; */
/* uint32_t value_mask; */
/* uint32_t value_list[1]; */
/* int op; */
/* if ((!rs) || (!dc)) return; */
/* num = 0; EINA_INLIST_FOREACH(points, pt) num++; */
/* if (num < 3) return; */
/* a = (dc->col.col >> 24) & 0xff; */
/* if (a == 0) return; */
/* op = XCB_RENDER_PICT_OP_OVER; */
/* r = (dc->col.col >> 16) & 0xff; */
/* g = (dc->col.col >> 8 ) & 0xff; */
/* b = (dc->col.col ) & 0xff; */
/* if ((rs->xinf->mul_r != r) || (rs->xinf->mul_g != g) || */
/* (rs->xinf->mul_b != b) || (rs->xinf->mul_a != a)) */
/* { */
/* rs->xinf->mul_r = r; */
/* rs->xinf->mul_g = g; */
/* rs->xinf->mul_b = b; */
/* rs->xinf->mul_a = a; */
/* _xr_xcb_render_surface_solid_rectangle_set(rs->xinf->mul, r, g, b, a, 0, 0, 1, 1); */
/* } */
/* pts = malloc(num * sizeof(XPointDouble)); */
/* if (!pts) return; */
/* i = 0; */
/* EINA_INLIST_FOREACH(points, pt) */
/* { */
/* if (i < num) */
/* { */
/* pts[i].x = pt->x; */
/* pts[i].y = pt->y; */
/* i++; */
/* } */
/* } */
/* value_mask = XCB_RENDER_CP_CLIP_MASK; */
/* value_list[0] = 0; */
/* xcb_render_change_picture(rs->xinf->x11.connection, rs->x11.xcb.pic, value_mask, value_list); */
/* _xr_xcb_render_surface_clips_set(rs, dc, 0, 0, rs->width, rs->height); */
/* XRenderCompositeDoublePoly(rs->xinf->x11.connection, op, */
/* rs->xinf->mul->pic, rs->x11.xcb.pic, */
/* rs->xinf->fmt8, 0, 0, 0, 0, */
/* pts, num, Complex); */
/* free(pts); */
}

View File

@ -1,574 +0,0 @@
#include "evas_common.h"
#include "evas_private.h"
#include "evas_engine.h"
#include "Evas_Engine_XRender_X11.h"
static Eina_List *_image_info_list = NULL;
static int _xcb_err = 0;
enum
{
xcb_render_pictforminfo_id = 1 << 0,
xcb_render_pictforminfo_type_t = 1 << 1,
xcb_render_pictforminfo_depth_t = 1 << 2,
xcb_render_pictforminfo_red_shift_t = 1 << 3,
xcb_render_pictforminfo_red_mask_t = 1 << 4,
xcb_render_pictforminfo_green_shift_t = 1 << 5,
xcb_render_pictforminfo_green_mask_t = 1 << 6,
xcb_render_pictforminfo_blue_shift_t = 1 << 7,
xcb_render_pictforminfo_blue_mask_t = 1 << 8,
xcb_render_pictforminfo_alpha_shift_t = 1 << 9,
xcb_render_pictforminfo_alpha_mask_t = 1 << 10,
xcb_render_pictforminfo_colormap_t = 1 << 11,
};
enum
{
xcb_render_standard_pictforminfoargb_32_t,
xcb_render_standard_pictforminforgb_24_t,
xcb_render_standard_pictforminfoa_8_t,
xcb_render_standard_pictforminfoa_4_t,
xcb_render_standard_pictforminfoa_1_t,
xcb_render_standard_pictforminfo_count_t
};
static xcb_render_pictforminfo_t *
xcb_render_find_pictforminfo (xcb_connection_t *conn, uint32_t mask, const xcb_render_pictforminfo_t *template, int count)
{
xcb_render_query_pict_formats_cookie_t cookie;
xcb_render_query_pict_formats_reply_t *rep;
xcb_render_pictforminfo_iterator_t iter_forminfo;
cookie = xcb_render_query_pict_formats_unchecked (conn);
rep = xcb_render_query_pict_formats_reply (conn, cookie, NULL);
iter_forminfo = xcb_render_query_pict_formats_formats_iterator (rep);
for (; iter_forminfo.rem; xcb_render_pictforminfo_next (&iter_forminfo)) {
if (mask & xcb_render_pictforminfo_id)
if (template->id != iter_forminfo.data->id)
continue;
if (mask & xcb_render_pictforminfo_type_t)
if (template->type != iter_forminfo.data->type)
continue;
if (mask & xcb_render_pictforminfo_depth_t)
if (template->depth != iter_forminfo.data->depth)
continue;
if (mask & xcb_render_pictforminfo_red_shift_t)
if (template->direct.red_shift != iter_forminfo.data->direct.red_shift)
continue;
if (mask & xcb_render_pictforminfo_red_mask_t)
if (template->direct.red_mask != iter_forminfo.data->direct.red_mask)
continue;
if (mask & xcb_render_pictforminfo_green_shift_t)
if (template->direct.green_shift != iter_forminfo.data->direct.green_shift)
continue;
if (mask & xcb_render_pictforminfo_green_mask_t)
if (template->direct.green_mask != iter_forminfo.data->direct.green_mask)
continue;
if (mask & xcb_render_pictforminfo_blue_shift_t)
if (template->direct.blue_shift != iter_forminfo.data->direct.blue_shift)
continue;
if (mask & xcb_render_pictforminfo_blue_mask_t)
if (template->direct.blue_mask != iter_forminfo.data->direct.blue_mask)
continue;
if (mask & xcb_render_pictforminfo_alpha_shift_t)
if (template->direct.alpha_shift != iter_forminfo.data->direct.alpha_shift)
continue;
if (mask & xcb_render_pictforminfo_alpha_mask_t)
if (template->direct.alpha_mask != iter_forminfo.data->direct.alpha_mask)
continue;
if (mask & xcb_render_pictforminfo_colormap_t)
if (template->colormap != iter_forminfo.data->colormap)
continue;
if (count-- == 0) {
xcb_render_pictforminfo_t *forminfo;
forminfo = (xcb_render_pictforminfo_t *)malloc (sizeof (xcb_render_pictforminfo_t));
memcpy (forminfo, iter_forminfo.data, sizeof (xcb_render_pictforminfo_t));
free (rep);
return forminfo;
}
}
free (rep);
return NULL;
}
static xcb_render_pictforminfo_t *
xcb_render_find_standard_pictforminfo (xcb_connection_t *conn, int format)
{
xcb_render_pictforminfo_t *forminfo = NULL;
struct {
xcb_render_pictforminfo_t template;
uint32_t mask;
} standardFormats[xcb_render_standard_pictforminfo_count_t] = {
/* StandardPICTFORMINFOARGB32 */
{
{
0, /* id */
XCB_RENDER_PICT_TYPE_DIRECT, /* type */
32, /* depth */
{ 0, 0 }, /* pad */
{ /* direct */
16, /* direct.red_shift */
0xff, /* direct.red_mask */
8, /* direct.green_shift */
0xff, /* direct.green_mask */
0, /* direct.blue_shift */
0xff, /* direct.blue_mask */
24, /* direct.alpha_shift */
0xff /* direct.alpha_mask */
},
0 /* colormap */
},
xcb_render_pictforminfo_type_t |
xcb_render_pictforminfo_depth_t |
xcb_render_pictforminfo_red_shift_t |
xcb_render_pictforminfo_red_mask_t |
xcb_render_pictforminfo_green_shift_t |
xcb_render_pictforminfo_green_mask_t |
xcb_render_pictforminfo_blue_shift_t |
xcb_render_pictforminfo_blue_mask_t |
xcb_render_pictforminfo_alpha_shift_t |
xcb_render_pictforminfo_alpha_mask_t
},
/* StandardPICTFORMINFORGB24 */
{
{
0, /* id */
XCB_RENDER_PICT_TYPE_DIRECT, /* type */
24, /* depth */
{ 0, 0 }, /* pad */
{ /* direct */
16, /* direct.red_shift */
0xff, /* direct.red_mask */
8, /* direct.green_shift */
0xff, /* direct.green_mask */
0, /* direct.blue_shift */
0xff, /* direct.blue_mask */
0, /* direct.alpha_shift */
0x00 /* direct.alpha_mask */
},
0 /* colormap */
},
xcb_render_pictforminfo_type_t |
xcb_render_pictforminfo_depth_t |
xcb_render_pictforminfo_red_shift_t |
xcb_render_pictforminfo_red_mask_t |
xcb_render_pictforminfo_green_shift_t |
xcb_render_pictforminfo_green_mask_t |
xcb_render_pictforminfo_blue_shift_t |
xcb_render_pictforminfo_blue_mask_t |
xcb_render_pictforminfo_alpha_mask_t
},
/* StandardPICTFORMINFOA8 */
{
{
0, /* id */
XCB_RENDER_PICT_TYPE_DIRECT, /* type */
8, /* depth */
{ 0, 0 }, /* pad */
{ /* direct */
0, /* direct.red_shift */
0x00, /* direct.red_mask */
0, /* direct.green_shift */
0x00, /* direct.green_mask */
0, /* direct.blue_shift */
0x00, /* direct.blue_mask */
0, /* direct.alpha_shift */
0xff /* direct.alpha_mask */
},
0 /* colormap */
},
xcb_render_pictforminfo_type_t |
xcb_render_pictforminfo_depth_t |
xcb_render_pictforminfo_red_mask_t |
xcb_render_pictforminfo_green_mask_t |
xcb_render_pictforminfo_blue_mask_t |
xcb_render_pictforminfo_alpha_shift_t |
xcb_render_pictforminfo_alpha_mask_t
},
/* StandardPICTFORMINFOA4 */
{
{
0, /* id */
XCB_RENDER_PICT_TYPE_DIRECT, /* type */
4, /* depth */
{ 0, 0 }, /* pad */
{ /* direct */
0, /* direct.red_shift */
0x00, /* direct.red_mask */
0, /* direct.green_shift */
0x00, /* direct.green_mask */
0, /* direct.blue_shift */
0x00, /* direct.blue_mask */
0, /* direct.alpha_shift */
0x0f /* direct.alpha_mask */
},
0 /* colormap */
},
xcb_render_pictforminfo_type_t |
xcb_render_pictforminfo_depth_t |
xcb_render_pictforminfo_red_mask_t |
xcb_render_pictforminfo_green_mask_t |
xcb_render_pictforminfo_blue_mask_t |
xcb_render_pictforminfo_alpha_shift_t |
xcb_render_pictforminfo_alpha_mask_t
},
/* StandardPICTFORMINFOA1 */
{
{
0, /* id */
XCB_RENDER_PICT_TYPE_DIRECT, /* type */
1, /* depth */
{ 0, 0 }, /* pad */
{ /* direct */
0, /* direct.red_shift */
0x00, /* direct.red_mask */
0, /* direct.green_shift */
0x00, /* direct.green_mask */
0, /* direct.blue_shift */
0x00, /* direct.blue_mask */
0, /* direct.alpha_shift */
0x01 /* direct.alpha_mask */
},
0 /* colormap */
},
xcb_render_pictforminfo_type_t |
xcb_render_pictforminfo_depth_t |
xcb_render_pictforminfo_red_mask_t |
xcb_render_pictforminfo_green_mask_t |
xcb_render_pictforminfo_blue_mask_t |
xcb_render_pictforminfo_alpha_shift_t |
xcb_render_pictforminfo_alpha_mask_t
},
};
if ((format >= 0) && (format < xcb_render_standard_pictforminfo_count_t))
forminfo = xcb_render_find_pictforminfo (conn,
standardFormats[format].mask,
&standardFormats[format].template,
0);
return forminfo;
}
static void
_tmp_xcb_err(xcb_connection_t *conn __UNUSED__/* , XErrorEvent *ev */)
{
_xcb_err = 1;
return;
}
Ximage_Info *
_xr_xcb_image_info_get(xcb_connection_t *conn, xcb_screen_t *screen, xcb_drawable_t draw, xcb_visualtype_t *visual)
{
xcb_get_geometry_cookie_t cookie;
xcb_get_geometry_reply_t *rep;
Ximage_Info *xinf;
Ximage_Info *xinf2;
Eina_List *l;
xinf2 = NULL;
EINA_LIST_FOREACH(_image_info_list, l, xinf)
{
if (xinf->x11.connection == conn)
{
xinf2 = xinf;
break;
}
}
xinf = calloc(1, sizeof(Ximage_Info));
if (!xinf) return NULL;
xinf->references = 1;
xinf->x11.connection = conn;
xinf->x11.screen = screen;
xinf->x11.draw = draw;
cookie = xcb_get_geometry_unchecked(xinf->x11.connection, xinf->x11.draw);
rep = xcb_get_geometry_reply(xinf->x11.connection, cookie, NULL);
xinf->x11.root = rep->root;
free(rep);
xinf->x11.visual = visual;
xinf->x11.fmt32 = xcb_render_find_standard_pictforminfo(xinf->x11.connection, xcb_render_standard_pictforminfoargb_32_t);
xinf->x11.fmt24 = xcb_render_find_standard_pictforminfo(xinf->x11.connection, xcb_render_standard_pictforminforgb_24_t);
xinf->x11.fmt8 = xcb_render_find_standard_pictforminfo(xinf->x11.connection, xcb_render_standard_pictforminfoa_8_t);
xinf->x11.fmt4 = xcb_render_find_standard_pictforminfo(xinf->x11.connection, xcb_render_standard_pictforminfoa_4_t);
xinf->x11.fmt1 = xcb_render_find_standard_pictforminfo(xinf->x11.connection, xcb_render_standard_pictforminfoa_1_t);
xinf->mul = _xr_xcb_render_surface_new(xinf, 1, 1, xinf->x11.fmt32, 1);
_xr_xcb_render_surface_repeat_set(xinf->mul, 1);
xinf->mul_r = xinf->mul_g = xinf->mul_b = xinf->mul_a = 0xff;
_xr_xcb_render_surface_solid_rectangle_set(xinf->mul, xinf->mul_r, xinf->mul_g, xinf->mul_b, xinf->mul_a, 0, 0, 1, 1);
if (xinf2)
{
xinf->can_do_shm = xinf2->can_do_shm;
xinf->depth = xinf2->depth;
}
else
{
xcb_depth_iterator_t iter_depth;
xcb_shm_segment_info_t shm_info;
xcb_image_t *xim;
iter_depth = xcb_screen_allowed_depths_iterator (xinf->x11.screen);
for (; iter_depth.rem ; xcb_depth_next (&iter_depth))
{
xcb_visualtype_iterator_t iter_visual;
iter_visual = xcb_depth_visuals_iterator (iter_depth.data);
for (; iter_visual.rem ; xcb_visualtype_next (&iter_visual))
{
if (iter_visual.data->visual_id == visual->visual_id)
xinf->depth = iter_depth.data->depth;
}
}
xinf->can_do_shm = 0;
shm_info.shmseg = xcb_generate_id(xinf->x11.connection);
xim = xcb_image_create_native(xinf->x11.connection, 1, 1,
XCB_IMAGE_FORMAT_Z_PIXMAP,
xinf->depth, NULL, ~0, NULL);
if (xim) {
shm_info.shmid = shmget(IPC_PRIVATE, xim->size, IPC_CREAT | 0777);
if (shm_info.shmid >= 0) {
shm_info.shmaddr = xim->data = shmat(shm_info.shmid, 0, 0);
if ((shm_info.shmaddr) && (shm_info.shmaddr != (void *) -1)) {
xcb_get_input_focus_reply_t *reply;
/*
* FIXME: no error mechanism
*/
/* XErrorHandler ph; */
/* we sync */
reply = xcb_get_input_focus_reply(xinf->x11.connection,
xcb_get_input_focus_unchecked(xinf->x11.connection),
NULL);
free(reply);
_xcb_err = 0;
/* ph = XSetErrorHandler((XErrorHandler)_tmp_xcb_err); */
xcb_shm_attach(xinf->x11.connection, shm_info.shmseg, shm_info.shmid, 0);
/* we sync */
reply = xcb_get_input_focus_reply(xinf->x11.connection,
xcb_get_input_focus_unchecked(xinf->x11.connection),
NULL);
free(reply);
/* XSetErrorHandler((XErrorHandler)ph); */
if (!_xcb_err) xinf->can_do_shm = 1;
shmdt(shm_info.shmaddr);
}
shmctl(shm_info.shmid, IPC_RMID, 0);
}
xcb_image_destroy(xim);
}
}
_image_info_list = eina_list_prepend(_image_info_list, xinf);
return xinf;
}
void
_xr_xcb_image_info_free(Ximage_Info *xinf)
{
if (!xinf) return;
if (xinf->pool)
{
xcb_get_input_focus_reply_t *reply;
reply = xcb_get_input_focus_reply(xinf->x11.connection,
xcb_get_input_focus_unchecked(xinf->x11.connection),
NULL);
free(reply);
}
_xr_xcb_image_info_pool_flush(xinf, 0, 0);
xinf->references--;
if (xinf->references != 0) return;
_xr_xcb_render_surface_free(xinf->mul);
if (xinf->x11.fmt1)
free(xinf->x11.fmt1);
if (xinf->x11.fmt4)
free(xinf->x11.fmt4);
if (xinf->x11.fmt8)
free(xinf->x11.fmt8);
if (xinf->x11.fmt24)
free(xinf->x11.fmt24);
if (xinf->x11.fmt32)
free(xinf->x11.fmt32);
free(xinf);
_image_info_list = eina_list_remove(_image_info_list, xinf);
}
void
_xr_xcb_image_info_pool_flush(Ximage_Info *xinf, unsigned int max_num, unsigned int max_mem)
{
if ((xinf->pool_mem <= max_mem) && (eina_list_count(xinf->pool) <= max_num)) return;
while ((xinf->pool_mem > max_mem) || (eina_list_count(xinf->pool) > max_num))
{
Ximage_Image *xim;
if (!xinf->pool) break;
xim = xinf->pool->data;
_xr_xcb_image_free(xim);
}
}
Ximage_Image *
_xr_xcb_image_new(Ximage_Info *xinf, int w, int h, int depth)
{
Ximage_Image *xim;
Ximage_Image *xim2;
Eina_List *l;
xim2 = NULL;
EINA_LIST_FOREACH(xinf->pool, l, xim)
{
if ((xim->width >= w) && (xim->height >= h) && (xim->depth == depth) && (xim->available))
{
if (!xim2) xim2 = xim;
else if ((xim->width * xim->height) < (xim2->width * xim2->height)) xim2 = xim;
}
}
if (xim2)
{
xim2->available = 0;
return xim2;
}
xim = calloc(1, sizeof(Ximage_Image));
if (xim)
{
xim->xinf = xinf;
xim->width = w;
xim->height = h;
xim->depth = depth;
xim->available = 0;
if (xim->xinf->can_do_shm)
{
xim->x11.xcb.shm_info = calloc(1, sizeof(xcb_shm_segment_info_t));
if (xim->x11.xcb.shm_info)
{
xim->x11.xcb.shm_info->shmseg = xcb_generate_id(xinf->x11.connection);
xim->x11.xcb.xim = xcb_image_create_native(xim->xinf->x11.connection, xim->width, xim->height, XCB_IMAGE_FORMAT_Z_PIXMAP, xim->depth, NULL, ~0, NULL);
if (xim->x11.xcb.xim)
{
xim->x11.xcb.shm_info->shmid = shmget(IPC_PRIVATE, xim->x11.xcb.xim->size, IPC_CREAT | 0777);
if (xim->x11.xcb.shm_info->shmid >= 0)
{
xim->x11.xcb.shm_info->shmaddr = xim->x11.xcb.xim->data = shmat(xim->x11.xcb.shm_info->shmid, 0, 0);
if ((xim->x11.xcb.shm_info->shmaddr) && (xim->x11.xcb.shm_info->shmaddr != (void *) -1))
{
xcb_get_input_focus_reply_t *reply;
/*
* FIXME: no error mechanism
*/
/* XErrorHandler ph; */
/* we sync */
reply = xcb_get_input_focus_reply(xim->xinf->x11.connection,
xcb_get_input_focus_unchecked(xim->xinf->x11.connection),
NULL);
free(reply);
_xcb_err = 0;
/* ph = XSetErrorHandler((XErrorHandler)_tmp_xcb_err); */
xcb_shm_attach(xim->xinf->x11.connection, xim->x11.xcb.shm_info->shmseg, xim->x11.xcb.shm_info->shmid, 0);
/* we sync */
reply = xcb_get_input_focus_reply(xim->xinf->x11.connection,
xcb_get_input_focus_unchecked(xim->xinf->x11.connection),
NULL);
free(reply);
/* XSetErrorHandler((XErrorHandler)ph); */
if (!_xcb_err) goto xim_ok;
shmdt(xim->x11.xcb.shm_info->shmaddr);
}
shmctl(xim->x11.xcb.shm_info->shmid, IPC_RMID, 0);
}
xcb_image_destroy(xim->x11.xcb.xim);
}
free(xim->x11.xcb.shm_info);
xim->x11.xcb.shm_info = NULL;
}
}
xim->x11.xcb.xim = xcb_image_create_native(xim->xinf->x11.connection, xim->width, xim->height, XCB_IMAGE_FORMAT_Z_PIXMAP, xim->depth, NULL, ~0, NULL);
if (!xim->x11.xcb.xim)
{
free(xim);
return NULL;
}
xim->x11.xcb.xim->data = malloc(xim->x11.xcb.xim->size);
if (!xim->x11.xcb.xim->data)
{
xcb_image_destroy(xim->x11.xcb.xim);
free(xim);
return NULL;
}
}
xim_ok:
_xr_xcb_image_info_pool_flush(xinf, 32, (1600 * 1200 * 32 * 2));
xim->line_bytes = xim->x11.xcb.xim->stride;
xim->data = (void *)(xim->x11.xcb.xim->data);
xinf->pool_mem += (xim->width * xim->height * xim->depth);
xinf->pool = eina_list_append(xinf->pool, xim);
return xim;
}
void
_xr_xcb_image_free(Ximage_Image *xim)
{
if (xim->x11.xcb.shm_info)
{
if (!xim->available)
{
xcb_get_input_focus_reply_t *reply;
reply = xcb_get_input_focus_reply(xim->xinf->x11.connection,
xcb_get_input_focus_unchecked(xim->xinf->x11.connection),
NULL);
free(reply);
}
xcb_shm_detach(xim->xinf->x11.connection, xim->x11.xcb.shm_info->shmseg);
xcb_image_destroy(xim->x11.xcb.xim);
shmdt(xim->x11.xcb.shm_info->shmaddr);
shmctl(xim->x11.xcb.shm_info->shmid, IPC_RMID, 0);
free(xim->x11.xcb.shm_info);
}
else
{
free(xim->x11.xcb.xim->data);
xim->x11.xcb.xim->data = NULL;
xcb_image_destroy(xim->x11.xcb.xim);
}
xim->xinf->pool_mem -= (xim->width * xim->height * xim->depth);
xim->xinf->pool = eina_list_remove(xim->xinf->pool, xim);
free(xim);
}
void
_xr_xcb_image_put(Ximage_Image *xim, xcb_drawable_t draw, int x, int y, int w, int h)
{
xcb_get_input_focus_reply_t *reply;
xcb_gcontext_t gc;
gc = xcb_generate_id(xim->xinf->x11.connection);
xcb_create_gc(xim->xinf->x11.connection, gc, draw, 0, NULL);
if (xim->x11.xcb.shm_info)
{
xcb_shm_put_image(xim->xinf->x11.connection, draw, gc,
xim->x11.xcb.xim->width, xim->x11.xcb.xim->height,
0, 0,
w, h,
x, y,
xim->x11.xcb.xim->depth, xim->x11.xcb.xim->format,
0,
xim->x11.xcb.shm_info->shmseg,
xim->x11.xcb.xim->data - xim->x11.xcb.shm_info->shmaddr);
/* we sync */
reply = xcb_get_input_focus_reply(xim->xinf->x11.connection,
xcb_get_input_focus_unchecked(xim->xinf->x11.connection),
NULL);
free(reply);
}
else
xcb_image_put(xim->xinf->x11.connection, draw, gc, xim->x11.xcb.xim, x, y, 0);
xim->available = 1;
xcb_free_gc(xim->xinf->x11.connection, gc);
}

View File

@ -1,192 +0,0 @@
#include "evas_common.h"
#include "evas_private.h"
#include "evas_engine.h"
#include "Evas_Engine_XRender_X11.h"
static Eina_Hash *_xr_fg_pool = NULL;
XR_Font_Surface *
_xre_xlib_font_surface_new(Ximage_Info *xinf, RGBA_Font_Glyph *fg)
{
XR_Font_Surface *fs;
DATA8 *data;
int w, h, j;
XRenderPictureAttributes att;
XRenderPictFormat *fmt;
Ximage_Image *xim;
Eina_Hash *pool;
char buf[256], buf2[256];
data = fg->glyph_out->bitmap.buffer;
w = fg->glyph_out->bitmap.width;
h = fg->glyph_out->bitmap.rows;
j = fg->glyph_out->bitmap.pitch;
if (j < w) j = w;
if ((w <= 0) || (h <= 0)) return NULL;
if (fg->ext_dat)
{
fs = fg->ext_dat;
if ((fs->xinf->x11.connection == xinf->x11.connection) && (fs->xinf->x11.root == xinf->x11.root))
return fs;
snprintf(buf, sizeof(buf), "@%p@/@%lx@", fs->xinf->x11.connection, (unsigned long int)fs->xinf->x11.root);
pool = eina_hash_find(_xr_fg_pool, buf);
if (pool)
{
snprintf(buf, sizeof(buf), "%p", fg);
fs = eina_hash_find(pool, buf);
if (fs) return fs;
}
}
fs = calloc(1, sizeof(XR_Font_Surface));
if (!fs) return NULL;
fs->xinf = xinf;
fs->fg = fg;
fs->xinf->references++;
fs->w = w;
fs->h = h;
snprintf(buf, sizeof(buf), "@%p@/@%lx@", fs->xinf->x11.connection, (unsigned long int)fs->xinf->x11.root);
pool = eina_hash_find(_xr_fg_pool, buf);
if (!pool) pool = eina_hash_string_superfast_new(NULL);
snprintf(buf2, sizeof(buf2), "%p", fg);
eina_hash_add(pool, buf2, fs);
if (!_xr_fg_pool) _xr_fg_pool = eina_hash_string_superfast_new(NULL);
eina_hash_add(_xr_fg_pool, buf, pool);
/* FIXME: maybe use fmt4? */
fmt = xinf->x11.fmt8;
fs->draw = XCreatePixmap(xinf->x11.connection, xinf->x11.root, w, h,fmt->depth);
att.dither = 0;
att.component_alpha = 0;
att.repeat = 0;
fs->pic = XRenderCreatePicture(xinf->x11.connection, fs->draw,fmt,
CPRepeat | CPDither | CPComponentAlpha, &att);
/* FIXME: handle if fmt->depth != 8 */
xim = _xr_xlib_image_new(fs->xinf, w, h,fmt->depth);
if ((fg->glyph_out->bitmap.num_grays == 256) &&
(fg->glyph_out->bitmap.pixel_mode == ft_pixel_mode_grays))
{
int x, y;
DATA8 *p1, *p2;
for (y = 0; y < h; y++)
{
p1 = data + (j * y);
p2 = ((DATA8 *)xim->data) + (xim->line_bytes * y);
for (x = 0; x < w; x++)
{
*p2 = *p1;
p1++;
p2++;
}
}
}
else
{
DATA8 *tmpbuf = NULL, *dp, *tp, bits;
int bi, bj, end;
const DATA8 bitrepl[2] = {0x0, 0xff};
tmpbuf = alloca(w);
{
int x, y;
DATA8 *p1, *p2;
for (y = 0; y < h; y++)
{
p1 = tmpbuf;
p2 = ((DATA8 *)xim->data) + (xim->line_bytes * y);
tp = tmpbuf;
dp = data + (y * fg->glyph_out->bitmap.pitch);
for (bi = 0; bi < w; bi += 8)
{
bits = *dp;
if ((w - bi) < 8) end = w - bi;
else end = 8;
for (bj = 0; bj < end; bj++)
{
*tp = bitrepl[(bits >> (7 - bj)) & 0x1];
tp++;
}
dp++;
}
for (x = 0; x < w; x++)
{
*p2 = *p1;
p1++;
p2++;
}
}
}
}
_xr_xlib_image_put(xim, fs->draw, 0, 0, w, h);
return fs;
}
static Eina_Bool
_xre_xlib_font_pool_cb(const Eina_Hash *hash __UNUSED__, const void *key __UNUSED__, void *data, void *fdata)
{
char buf[256];
Eina_Hash *pool;
XR_Font_Surface *fs;
fs = fdata;
pool = data;
snprintf(buf, sizeof(buf), "@%p@/@%lx@", fs->xinf->x11.connection, (unsigned long int)fs->xinf->x11.root);
eina_hash_del(pool, buf, fs);
return 1;
}
void
_xre_xlib_font_surface_free(XR_Font_Surface *fs)
{
if (!fs) return;
eina_hash_foreach(_xr_fg_pool, _xre_xlib_font_pool_cb, fs);
XFreePixmap(fs->xinf->x11.connection, fs->draw);
XRenderFreePicture(fs->xinf->x11.connection, fs->pic);
_xr_xlib_image_info_free(fs->xinf);
free(fs);
}
void
_xre_xlib_font_surface_draw(Ximage_Info *xinf __UNUSED__, RGBA_Image *surface, RGBA_Draw_Context *dc, RGBA_Font_Glyph *fg, int x, int y)
{
XR_Font_Surface *fs;
Xrender_Surface *target_surface;
XRectangle rect;
int r, g, b, a;
fs = fg->ext_dat;
if (!fs || !fs->xinf || !dc || !dc->col.col) return;
if (!surface || !surface->image.data) return;
target_surface = (Xrender_Surface *)(surface->image.data);
a = (dc->col.col >> 24) & 0xff;
r = (dc->col.col >> 16) & 0xff;
g = (dc->col.col >> 8 ) & 0xff;
b = (dc->col.col ) & 0xff;
if ((fs->xinf->mul_r != r) || (fs->xinf->mul_g != g) ||
(fs->xinf->mul_b != b) || (fs->xinf->mul_a != a))
{
fs->xinf->mul_r = r;
fs->xinf->mul_g = g;
fs->xinf->mul_b = b;
fs->xinf->mul_a = a;
_xr_xlib_render_surface_solid_rectangle_set(fs->xinf->mul, r, g, b, a, 0, 0, 1, 1);
}
rect.x = x; rect.y = y; rect.width = fs->w; rect.height = fs->h;
if (dc->clip.use)
{
RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.width, rect.height,
dc->clip.x, dc->clip.y, dc->clip.w, dc->clip.h);
}
XRenderSetPictureClipRectangles(target_surface->xinf->x11.connection,
target_surface->x11.xlib.pic, 0, 0, &rect, 1);
XRenderComposite(fs->xinf->x11.connection, PictOpOver, fs->xinf->mul->x11.xlib.pic,
fs->pic, target_surface->x11.xlib.pic,
0, 0, 0, 0, x, y, fs->w, fs->h);
}

View File

@ -1,705 +0,0 @@
#include "evas_common.h"
#include "evas_private.h"
#include "evas_engine.h"
#include "Evas_Engine_XRender_X11.h"
static Eina_Hash *_xr_image_hash = NULL;
static int _xr_image_cache_size = 0;
static int _xr_image_cache_usage = 0;
static Eina_List *_xr_image_cache = NULL;
static Eina_Hash *_xr_image_dirty_hash = NULL;
static void
__xre_xlib_image_dirty_hash_add(XR_Image *im)
{
char buf[64];
if (!im->data) return;
snprintf(buf, sizeof(buf), "%p", im->data);
if (!_xr_image_dirty_hash) _xr_image_dirty_hash = eina_hash_string_superfast_new(NULL);
eina_hash_add(_xr_image_dirty_hash, buf, im);
}
static void
__xre_xlib_image_dirty_hash_del(XR_Image *im)
{
char buf[64];
if (!im->data) return;
snprintf(buf, sizeof(buf), "%p", im->data);
eina_hash_del(_xr_image_dirty_hash, buf, im);
}
static XR_Image *
__xre_xlib_image_dirty_hash_find(void *data)
{
char buf[64];
snprintf(buf, sizeof(buf), "%p", data);
return eina_hash_find(_xr_image_dirty_hash, buf);
}
static XR_Image *
__xre_xlib_image_find(char *fkey)
{
XR_Image *im;
im = eina_hash_find(_xr_image_hash, fkey);
if (!im)
{
Eina_List *l;
for (l = _xr_image_cache; l; l = l->next)
{
im = l->data;
if (!strcmp(im->fkey, fkey))
{
_xr_image_cache = eina_list_remove_list(_xr_image_cache, l);
if (!_xr_image_hash) _xr_image_hash = eina_hash_string_superfast_new(NULL);
eina_hash_add(_xr_image_hash, im->fkey, im);
_xr_image_cache_usage -= (im->w * im->h * 4);
break;
}
im = NULL;
}
}
if (im) im->references++;
return im;
}
XR_Image *
_xre_xlib_image_load(Ximage_Info *xinf, const char *file, const char *key, Evas_Image_Load_Opts *lo, int *error)
{
XR_Image *im;
char buf[4096];
if (!file)
{
*error = EVAS_LOAD_ERROR_GENERIC;
return NULL;
}
if (!lo)
{
if (key)
snprintf(buf, sizeof(buf), "/@%p@%lx@/%s//://%s", xinf->x11.connection, (unsigned long int)xinf->x11.root, file, key);
else
snprintf(buf, sizeof(buf), "/@%p@%lx@/%s", xinf->x11.connection, (unsigned long int)xinf->x11.root, file);
}
else
{
if (key)
snprintf(buf, sizeof(buf), "//@/%i/%1.5f/%ix%i//@%p@%lx@/%s//://%s", lo->scale_down_by, lo->dpi, lo->w, lo->h, xinf->x11.connection, (unsigned long int)xinf->x11.root, file, key);
else
snprintf(buf, sizeof(buf), "//@/%i/%1.5f/%ix%i//@%p@%lx@/%s", lo->scale_down_by, lo->dpi, lo->w, lo->h, xinf->x11.connection, (unsigned long int)xinf->x11.root, file);
}
im = __xre_xlib_image_find(buf);
if (im)
{
*error = EVAS_LOAD_ERROR_NONE;
return im;
}
im = calloc(1, sizeof(XR_Image));
if (!im)
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
return NULL;
}
im->im = evas_common_load_image_from_file(file, key, lo, error);
if (!im->im)
{
free(im);
return NULL;
}
im->xinf = xinf;
im->xinf->references++;
im->cs.space = EVAS_COLORSPACE_ARGB8888;
im->fkey = strdup(buf);
im->file = eina_stringshare_add(file);
if (key) im->key = eina_stringshare_add(key);
im->w = im->im->cache_entry.w;
im->h = im->im->cache_entry.h;
im->references = 1;
if (lo) im->load_opts = *lo;
im->load_error = error; /* points to object's load_error */
if (im->im->info.comment) im->comment = eina_stringshare_add(im->im->info.comment);
// if (im->im->info.format == 1) im->format = eina_stringshare_add("png");
if (im->im->cache_entry.flags.alpha) im->alpha = 1;
if (!_xr_image_hash) _xr_image_hash = eina_hash_string_superfast_new(NULL);
eina_hash_direct_add(_xr_image_hash, im->fkey, im);
return im;
}
XR_Image *
_xre_xlib_image_new_from_data(Ximage_Info *xinf, int w, int h, void *data, int alpha, int cspace)
{
XR_Image *im;
im = calloc(1, sizeof(XR_Image));
if (!im) return NULL;
im->xinf = xinf;
im->xinf->references++;
im->cs.space = cspace;
im->w = w;
im->h = h;
im->references = 1;
switch (im->cs.space)
{
case EVAS_COLORSPACE_ARGB8888:
im->data = data;
im->alpha = alpha;
break;
case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL:
im->cs.data = data;
im->cs.no_free = 1;
break;
default:
abort();
break;
}
im->dirty = 1;
__xre_xlib_image_dirty_hash_add(im);
return im;
}
XR_Image *
_xre_xlib_image_new_from_copied_data(Ximage_Info *xinf, int w, int h, void *data, int alpha, int cspace)
{
XR_Image *im;
im = calloc(1, sizeof(XR_Image));
if (!im) return NULL;
im->cs.space = cspace;
switch (im->cs.space)
{
case EVAS_COLORSPACE_ARGB8888:
im->data = malloc(w * h * 4);
if (!im->data)
{
free(im);
return NULL;
}
if (data)
{
Gfx_Func_Copy func;
func = evas_common_draw_func_copy_get(w * h, 0);
if (func) func(data, im->data, w * h);
evas_common_cpu_end_opt();
}
im->alpha = alpha;
im->free_data = 1;
break;
case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL:
im->cs.no_free = 0;
im->cs.data = calloc(1, h * sizeof(unsigned char *) * 2);
if ((data) && (im->cs.data))
memcpy(im->cs.data, data, h * sizeof(unsigned char *) * 2);
break;
default:
abort();
break;
}
im->w = w;
im->h = h;
im->references = 1;
im->xinf = xinf;
im->xinf->references++;
im->dirty = 1;
__xre_xlib_image_dirty_hash_add(im);
return im;
}
XR_Image *
_xre_xlib_image_new(Ximage_Info *xinf, int w, int h)
{
XR_Image *im;
im = calloc(1, sizeof(XR_Image));
if (!im) return NULL;
im->data = malloc(w * h * 4);
if (!im->data)
{
free(im);
return NULL;
}
im->w = w;
im->h = h;
im->references = 1;
im->cs.space = EVAS_COLORSPACE_ARGB8888;
im->xinf = xinf;
im->xinf->references++;
im->free_data = 1;
im->alpha = 1;
im->dirty = 1;
__xre_xlib_image_dirty_hash_add(im);
return im;
}
static void
__xre_xlib_image_real_free(XR_Image *im)
{
if (im->cs.data)
{
if (!im->cs.no_free) free(im->cs.data);
}
if (im->file) eina_stringshare_del(im->file);
if (im->key) eina_stringshare_del(im->key);
if (im->fkey) free(im->fkey);
if (im->im) evas_cache_image_drop(&im->im->cache_entry);
if ((im->data) && (im->dirty)) __xre_xlib_image_dirty_hash_del(im);
if ((im->free_data) && (im->data)) free(im->data);
if (im->surface) _xr_xlib_render_surface_free(im->surface);
if (im->format) eina_stringshare_del(im->format);
if (im->comment) eina_stringshare_del(im->comment);
if (im->updates) evas_common_tilebuf_free(im->updates);
_xr_xlib_image_info_free(im->xinf);
free(im);
}
void
_xre_xlib_image_free(XR_Image *im)
{
im->references--;
if (im->references != 0) return;
if (!im->dirty)
{
if (im->fkey)
eina_hash_del(_xr_image_hash, im->fkey, im);
_xr_image_cache = eina_list_prepend(_xr_image_cache, im);
_xr_image_cache_usage += (im->w * im->h * 4);
_xre_xlib_image_cache_set(_xr_image_cache_size);
}
else
{
__xre_xlib_image_real_free(im);
}
}
void
_xre_xlib_image_region_dirty(XR_Image *im, int x, int y, int w, int h)
{
if (!im->updates)
{
im->updates = evas_common_tilebuf_new(im->w, im->h);
if (im->updates) evas_common_tilebuf_set_tile_size(im->updates, 8, 8);
}
if (im->updates)
evas_common_tilebuf_add_redraw(im->updates, x, y, w, h);
}
void
_xre_xlib_image_dirty(XR_Image *im)
{
if (im->dirty) return;
if (im->fkey)
eina_hash_del(_xr_image_hash, im->fkey, im);
im->dirty = 1;
__xre_xlib_image_dirty_hash_add(im);
}
XR_Image *
_xre_xlib_image_copy(XR_Image *im)
{
XR_Image *im2;
void *data = NULL;
if (im->data) data = im->data;
else if (im->cs.data) data = im->cs.data;
else
{
if (!im->im)
im->im = evas_common_load_image_from_file(im->file, im->key, &(im->load_opts), im->load_error);
if (im->im)
{
evas_cache_image_load_data(&im->im->cache_entry);
data = im->im->image.data;
}
}
if (!data) return NULL;
im2 = _xre_xlib_image_new_from_copied_data(im->xinf, im->w, im->h, data, im->alpha, im->cs.space);
return im2;
}
void
_xre_xlib_image_resize(XR_Image *im, int w, int h)
{
if ((w == im->w) && (h == im->h)) return;
if (im->surface)
{
Xrender_Surface *old_surface;
old_surface = im->surface;
im->surface = _xr_xlib_render_surface_new(old_surface->xinf, w + 2, h + 2, old_surface->x11.xlib.fmt, old_surface->alpha);
_xr_xlib_render_surface_free(old_surface);
}
switch (im->cs.space)
{
case EVAS_COLORSPACE_ARGB8888:
if (im->data)
{
if (im->free_data)
{
if (im->data) free(im->data);
im->data = malloc(w * h * 4);
}
}
else if (im->im)
{
evas_cache_image_drop(&im->im->cache_entry);
im->im = NULL;
if (im->free_data)
{
if (im->data) free(im->data);
im->data = malloc(w * h * 4);
}
}
else
{
im->data = malloc(w * h * 4);
im->free_data = 1;
}
break;
case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL:
if (im->data)
{
if (im->free_data)
{
if (im->data) free(im->data);
}
im->data = NULL;
}
if (im->im)
{
evas_cache_image_drop(&im->im->cache_entry);
im->im = NULL;
}
if (!im->cs.no_free)
{
if (im->cs.data) free(im->cs.data);
im->cs.data = calloc(1, h * sizeof(unsigned char *) * 2);
}
break;
default:
abort();
break;
}
__xre_xlib_image_dirty_hash_del(im);
__xre_xlib_image_dirty_hash_add(im);
im->w = w;
im->h = h;
}
void *
_xre_xlib_image_data_get(XR_Image *im)
{
void *data = NULL;
if (im->data) data = im->data;
else if (im->cs.data) data = im->cs.data;
else
{
if (!im->im)
im->im = evas_common_load_image_from_file(im->file, im->key, &(im->load_opts), im->load_error);
if (im->im)
{
evas_cache_image_load_data(&im->im->cache_entry);
data = im->im->image.data;
}
}
return data;
}
XR_Image *
_xre_xlib_image_data_find(void *data)
{
XR_Image *im;
im = __xre_xlib_image_dirty_hash_find(data);
if (im)
{
im->references++;
}
return im;
}
void
_xre_xlib_image_data_put(XR_Image *im, void *data)
{
if (!data) return;
switch (im->cs.space)
{
case EVAS_COLORSPACE_ARGB8888:
if (im->im)
{
if (data == im->im->image.data) return;
evas_cache_image_drop(&im->im->cache_entry);
im->im = NULL;
}
if (im->cs.data == data) return;
if (im->data)
{
if (im->data == data) return;
if (im->free_data) free(im->data);
im->free_data = 0;
}
im->data = data;
im->free_data = 0;
break;
case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL:
if (im->data)
{
if (im->free_data) free(im->data);
im->data = NULL;
}
im->free_data = 0;
if (data == im->cs.data) return;
if (!im->cs.no_free)
{
if (im->cs.data) free(im->cs.data);
}
im->cs.data = data;
break;
default:
abort();
break;
}
__xre_xlib_image_dirty_hash_del(im);
__xre_xlib_image_dirty_hash_add(im);
if (im->surface)
{
_xr_xlib_render_surface_free(im->surface);
im->surface = NULL;
}
if (!im->dirty)
{
if (im->fkey)
eina_hash_del(_xr_image_hash, im->fkey, im);
im->dirty = 1;
}
if (im->updates)
{
evas_common_tilebuf_free(im->updates);
im->updates = NULL;
}
}
void
_xre_xlib_image_alpha_set(XR_Image *im, int alpha)
{
if (im->alpha == alpha) return;
switch (im->cs.space)
{
case EVAS_COLORSPACE_ARGB8888:
im->alpha = alpha;
if (im->surface)
{
Xrender_Surface *old_surface;
old_surface = im->surface;
im->surface = NULL;
if (im->alpha)
im->surface = _xr_xlib_render_surface_new(im->xinf, im->w + 2, im->h + 2, im->xinf->x11.fmt32, 1);
else
{
/* FIXME: if im->depth == 16, use xinf->x11.fmtdef */
if ((im->xinf->depth == 16) &&
(((Visual *)im->xinf->x11.visual)->red_mask == 0xf800) &&
(((Visual *)im->xinf->x11.visual)->green_mask == 0x07e0) &&
(((Visual *)im->xinf->x11.visual)->blue_mask == 0x001f))
im->surface = _xr_xlib_render_surface_new(im->xinf, im->w + 2, im->h + 2, im->xinf->x11.fmtdef, 0);
else
im->surface = _xr_xlib_render_surface_new(im->xinf, im->w + 2, im->h + 2, im->xinf->x11.fmt24, 0);
}
if (im->surface)
_xr_xlib_render_surface_copy(old_surface, im->surface, 0, 0, 0, 0, im->w + 2, im->h + 2);
_xr_xlib_render_surface_free(old_surface);
}
if (im->updates)
{
evas_common_tilebuf_free(im->updates);
im->updates = NULL;
}
default:
break;
}
}
int
_xre_xlib_image_alpha_get(XR_Image *im)
{
if (im->im)
{
if (im->im->cache_entry.space != EVAS_COLORSPACE_ARGB8888) return 0;
}
return im->alpha;
}
void
_xre_xlib_image_border_set(XR_Image *im, int l, int r, int t, int b)
{
if (!im) return;
_xre_xlib_image_surface_gen(im);
if (l < 1) l = 0;
if (r < 1) r = 0;
if (t < 1) t = 0;
if (b < 1) b = 0;
if (im->surface)
{
if (l | r | t | b)
im->surface->bordered = 1;
else
im->surface->bordered = 0;
}
}
void
_xre_xlib_image_border_get(XR_Image *im __UNUSED__, int *l __UNUSED__, int *r __UNUSED__, int *t __UNUSED__, int *b __UNUSED__)
{
}
void
_xre_xlib_image_surface_gen(XR_Image *im)
{
void *data = NULL, *tdata = NULL;
if ((im->surface) && (!im->updates)) return;
if (im->data) data = im->data;
else
{
if (!im->im)
im->im = evas_common_load_image_from_file(im->file, im->key, &(im->load_opts), im->load_error);
if (im->im)
{
evas_cache_image_load_data(&im->im->cache_entry);
data = im->im->image.data;
}
}
if (!data)
{
switch (im->cs.space)
{
case EVAS_COLORSPACE_ARGB8888:
return;
break;
case EVAS_COLORSPACE_YCBCR422P601_PL:
case EVAS_COLORSPACE_YCBCR422P709_PL:
if ((im->cs.data) && (*((unsigned char **)im->cs.data)))
{
tdata = malloc(im->w * im->h * sizeof(DATA32));
if (tdata)
evas_common_convert_yuv_420p_601_rgba(im->cs.data,
tdata,
im->w, im->h);
data = tdata;
}
break;
default:
abort();
break;
}
if (!data) return;
}
if (im->surface)
{
if (im->updates)
{
Tilebuf_Rect *rects, *r;
rects = evas_common_tilebuf_get_render_rects(im->updates);
if (rects)
{
EINA_INLIST_FOREACH(rects, r)
{
int rx, ry, rw, rh;
rx = r->x; ry = r->y; rw = r->w, rh = r->h;
RECTS_CLIP_TO_RECT(rx, ry, rw, rh, 0, 0, im->w, im->h);
if (im->alpha)
_xr_xlib_render_surface_argb_pixels_fill(im->surface, im->w, im->h, data, rx, ry, rw, rh, 1, 1);
else
/* FIXME: if im->depth == 16 - convert to 16bpp then
* upload */
_xr_xlib_render_surface_rgb_pixels_fill(im->surface, im->w, im->h, data, rx, ry, rw, rh, 1, 1);
}
evas_common_tilebuf_free_render_rects(rects);
}
evas_common_tilebuf_free(im->updates);
im->updates = NULL;
}
if (tdata) free(tdata);
return;
}
if (im->alpha)
{
im->surface = _xr_xlib_render_surface_new(im->xinf, im->w + 2, im->h + 2, im->xinf->x11.fmt32, 1);
_xr_xlib_render_surface_argb_pixels_fill(im->surface, im->w, im->h, data, 0, 0, im->w, im->h, 1, 1);
}
else
{
/* FIXME: if im->xinf->depth == 16, use xinf->x11.fmtdef */
if ((im->xinf->depth == 16) &&
(((Visual *)im->xinf->x11.visual)->red_mask == 0xf800) &&
(((Visual *)im->xinf->x11.visual)->green_mask == 0x07e0) &&
(((Visual *)im->xinf->x11.visual)->blue_mask == 0x001f))
im->surface = _xr_xlib_render_surface_new(im->xinf, im->w + 2, im->h + 2, im->xinf->x11.fmtdef, 0);
else
im->surface = _xr_xlib_render_surface_new(im->xinf, im->w + 2, im->h + 2, im->xinf->x11.fmt24, 0);
/* FIXME: if im->depth == 16 - convert to 16bpp then
* upload */
_xr_xlib_render_surface_rgb_pixels_fill(im->surface, im->w, im->h, data, 0, 0, im->w, im->h, 1, 1);
}
/* fill borders */
_xr_xlib_render_surface_copy(im->surface, im->surface,
1, 1,
0, 1,
1, im->h);
_xr_xlib_render_surface_copy(im->surface, im->surface,
0, 1,
0, 0,
im->w + 2, 1);
_xr_xlib_render_surface_copy(im->surface, im->surface,
im->w, 1,
im->w + 1, 1,
1, im->h);
_xr_xlib_render_surface_copy(im->surface, im->surface,
0, im->h,
0, im->h + 1,
im->w + 2, 1);
if ((im->im) && (!im->dirty))
{
evas_cache_image_drop(&im->im->cache_entry);
im->im = NULL;
}
if (tdata) free(tdata);
}
void
_xre_xlib_image_cache_set(int size)
{
_xr_image_cache_size = size;
while (_xr_image_cache_usage > _xr_image_cache_size)
{
Eina_List *l;
l = eina_list_last(_xr_image_cache);
if (l)
{
XR_Image *im;
im = l->data;
_xr_image_cache = eina_list_remove_list(_xr_image_cache, l);
_xr_image_cache_usage -= (im->w * im->h * 4);
__xre_xlib_image_real_free(im);
}
}
}
int
_xre_xlib_image_cache_get(void)
{
return _xr_image_cache_size;
}

View File

@ -1,744 +0,0 @@
#include "evas_common.h"
//#include "evas_macros.h"
#include "evas_private.h"
#include "evas_engine.h"
#include "Evas_Engine_XRender_X11.h"
#include <math.h>
/* this is a work around broken xrender - when/if this ever gets fixed in xorg
* we can comment this out and one day remove it - for now keep it until such
* a fix is spotted in the wild
*/
#define BROKEN_XORG_XRENDER 1
/* should be const char*, but the prototype for XRenderSetPictureFilter
* is silly
*/
static inline char *
get_filter(int smooth)
{
return smooth ? FilterBest : FilterNearest;
}
Xrender_Surface *
_xr_xlib_render_surface_new(Ximage_Info *xinf, int w, int h, XRenderPictFormat *fmt, int alpha)
{
Xrender_Surface *rs;
XRenderPictureAttributes att;
if ((!xinf) || (!fmt) || (w < 1) || (h < 1)) return NULL;
rs = calloc(1, sizeof(Xrender_Surface));
if (!rs) return NULL;
rs->xinf = xinf;
rs->width = w;
rs->height = h;
rs->x11.xlib.fmt = fmt;
rs->alpha = alpha;
rs->depth = fmt->depth;
rs->allocated = 1;
rs->x11.xlib.draw = XCreatePixmap(xinf->x11.connection, xinf->x11.root, w, h, fmt->depth);
if (rs->x11.xlib.draw == None)
{
free(rs);
return NULL;
}
rs->xinf->references++;
att.dither = 1;
att.component_alpha = 0;
att.repeat = 0;
rs->x11.xlib.pic = XRenderCreatePicture(xinf->x11.connection, rs->x11.xlib.draw, fmt,
CPRepeat | CPDither | CPComponentAlpha, &att);
if (rs->x11.xlib.pic == None)
{
XFreePixmap(rs->xinf->x11.connection, rs->x11.xlib.draw);
rs->xinf->references--;
free(rs);
return NULL;
}
return rs;
}
Xrender_Surface *
_xr_xlib_render_surface_adopt(Ximage_Info *xinf, Drawable draw, int w, int h, int alpha)
{
Xrender_Surface *rs;
XRenderPictFormat *fmt;
XRenderPictureAttributes att;
if ((!xinf) || (draw == None) || (w < 1) || (h < 1)) return NULL;
fmt = XRenderFindVisualFormat(xinf->x11.connection, xinf->x11.visual);
if (!fmt) return NULL;
rs = calloc(1, sizeof(Xrender_Surface));
if (!rs) return NULL;
rs->xinf = xinf;
rs->width = w;
rs->height = h;
rs->x11.xlib.fmt = fmt;
rs->alpha = alpha;
rs->depth = fmt->depth;
if (fmt->depth == 32) rs->alpha = 1;
rs->allocated = 0;
rs->x11.xlib.draw = draw;
rs->xinf->references++;
att.dither = 1;
att.component_alpha = 0;
att.repeat = 0;
rs->x11.xlib.pic = XRenderCreatePicture(xinf->x11.connection, rs->x11.xlib.draw, fmt,
CPRepeat | CPDither | CPComponentAlpha, &att);
if (rs->x11.xlib.pic == None)
{
rs->xinf->references--;
free(rs);
return NULL;
}
return rs;
}
Xrender_Surface *
_xr_xlib_render_surface_format_adopt(Ximage_Info *xinf, Drawable draw, int w, int h, XRenderPictFormat *fmt, int alpha)
{
Xrender_Surface *rs;
XRenderPictureAttributes att;
if ((!xinf) || (!fmt) || (draw == None) || (w < 1) || (h < 1)) return NULL;
rs = calloc(1, sizeof(Xrender_Surface));
if (!rs) return NULL;
rs->xinf = xinf;
rs->width = w;
rs->height = h;
rs->x11.xlib.fmt = fmt;
rs->alpha = alpha;
rs->depth = fmt->depth;
if (fmt->depth == 32) rs->alpha = 1;
rs->xinf->references++;
rs->allocated = 0;
rs->x11.xlib.draw = draw;
att.dither = 1;
att.component_alpha = 0;
att.repeat = 0;
rs->x11.xlib.pic = XRenderCreatePicture(xinf->x11.connection, rs->x11.xlib.draw, fmt,
CPRepeat | CPDither | CPComponentAlpha, &att);
if (rs->x11.xlib.pic == None)
{
rs->xinf->references--;
free(rs);
return NULL;
}
return rs;
}
void
_xr_xlib_render_surface_free(Xrender_Surface *rs)
{
if (!rs) return;
if (rs->xinf)
{
if ((rs->allocated) && (rs->x11.xlib.draw != None))
XFreePixmap(rs->xinf->x11.connection, rs->x11.xlib.draw);
if (rs->x11.xlib.pic != None)
XRenderFreePicture(rs->xinf->x11.connection, rs->x11.xlib.pic);
_xr_xlib_image_info_free(rs->xinf);
rs->xinf = NULL;
}
free(rs);
}
void
_xr_xlib_render_surface_repeat_set(Xrender_Surface *rs, int repeat)
{
XRenderPictureAttributes att;
att.repeat = repeat;
XRenderChangePicture(rs->xinf->x11.connection, rs->x11.xlib.pic, CPRepeat, &att);
}
void
_xr_xlib_render_surface_solid_rectangle_set(Xrender_Surface *rs, int r, int g, int b, int a, int x, int y, int w, int h)
{
XRenderColor col;
col.red = (r << 8) | r;
col.green = (g << 8) | g;
col.blue = (b << 8) | b;
col.alpha = (a << 8) | a;
XRenderFillRectangle(rs->xinf->x11.connection, PictOpSrc, rs->x11.xlib.pic, &col, x, y, w, h);
}
void
_xr_xlib_render_surface_argb_pixels_fill(Xrender_Surface *rs, int sw, int sh __UNUSED__, void *pixels, int x, int y, int w, int h, int ox, int oy)
{
Ximage_Image *xim;
unsigned int *p, *sp, *sple, *spe;
unsigned int jump, sjump;
xim = _xr_xlib_image_new(rs->xinf, w, h, rs->depth);
if (!xim) return;
p = (unsigned int *)xim->data;
sp = ((unsigned int *)pixels) + (y * sw) + x;
jump = ((xim->line_bytes / 4) - w);
sjump = sw - w;
spe = sp + ((h - 1) * sw) + w;
if
#ifdef WORDS_BIGENDIAN
(xim->x11.xlib.xim->byte_order == LSBFirst)
#else
(xim->x11.xlib.xim->byte_order == MSBFirst)
#endif
{
while (sp < spe)
{
sple = sp + w;
while (sp < sple)
{
*p++ = (*sp << 24) + ((*sp << 8) & 0xff0000) + ((*sp >> 8) & 0xff00) + (*sp >> 24);
// *p++ = (B_VAL(sp) << 24) | (G_VAL(sp) << 16) | (R_VAL(sp) << 8) | A_VAL(sp);
sp++;
}
p += jump;
sp += sjump;
}
}
else
{
while (sp < spe)
{
sple = sp + w;
while (sp < sple)
*p++ = *sp++;
p += jump;
sp += sjump;
}
}
_xr_xlib_image_put(xim, rs->x11.xlib.draw, x + ox, y + oy, w, h);
}
void
_xr_xlib_render_surface_rgb_pixels_fill(Xrender_Surface *rs, int sw, int sh __UNUSED__, void *pixels, int x, int y, int w, int h, int ox, int oy)
{
Ximage_Image *xim;
unsigned int *p, *sp, *sple, *spe;
unsigned int jump, sjump;
xim = _xr_xlib_image_new(rs->xinf, w, h, rs->depth);
if (!xim) return;
p = (unsigned int *)xim->data;
sp = ((unsigned int *)pixels) + (y * sw) + x;
sjump = sw - w;
spe = sp + ((h - 1) * sw) + w;
if (rs->depth == 16)
{
jump = ((xim->line_bytes / 2) - w);
/* FIXME: if rs->depth == 16 - convert */
Gfx_Func_Convert conv_func;
int swap;
#ifdef WORDS_BIGENDIAN
swap = (int)(xim->x11.xlib.xim->byte_order == LSBFirst);
#else
swap = (int)(xim->x11.xlib.xim->byte_order == MSBFirst);
#endif
/* FIXME: swap not handled */
conv_func = evas_common_convert_func_get((DATA8 *)sp, w, h, rs->depth,
((Visual *)rs->xinf->x11.visual)->red_mask,
((Visual *)rs->xinf->x11.visual)->green_mask,
((Visual *)rs->xinf->x11.visual)->blue_mask,
PAL_MODE_NONE, 0);
if (conv_func)
conv_func(sp, (DATA8 *)p, sjump, jump, w, h, x, y, NULL);
}
else
{
jump = ((xim->line_bytes / 4) - w);
if
#ifdef WORDS_BIGENDIAN
(xim->x11.xlib.xim->byte_order == LSBFirst)
#else
(xim->x11.xlib.xim->byte_order == MSBFirst)
#endif
{
while (sp < spe)
{
sple = sp + w;
while (sp < sple)
{
*p++ = (*sp << 24) + ((*sp << 8) & 0xff0000) + ((*sp >> 8) & 0xff00) + 0xff;
// *p++ = ((B_VAL(sp)) << 24) | ((G_VAL(sp)) << 16) | ((R_VAL(sp)) << 8) | 0x000000ff;
sp++;
}
p += jump;
sp += sjump;
}
}
else
{
while (sp < spe)
{
sple = sp + w;
while (sp < sple)
*p++ = 0xff000000 | *sp++;
p += jump;
sp += sjump;
}
}
}
_xr_xlib_image_put(xim, rs->x11.xlib.draw, x + ox, y + oy, w, h);
}
void
_xr_xlib_render_surface_clips_set(Xrender_Surface *rs, RGBA_Draw_Context *dc, int rx, int ry, int rw, int rh)
{
int num = 0;
XRectangle *rect = NULL;
if ((dc) && (dc->clip.use))
{
RECTS_CLIP_TO_RECT(rx, ry, rw, rh,
dc->clip.x, dc->clip.y, dc->clip.w, dc->clip.h);
}
if ((!dc) || (!dc->cutout.rects))
{
rect = malloc(sizeof(XRectangle));
if (!rect) return;
rect->x = rx;
rect->y = ry;
rect->width = rw;
rect->height = rh;
num = 1;
}
else
{
Cutout_Rects *rects;
Cutout_Rect *r;
int i;
rects = evas_common_draw_context_apply_cutouts(dc);
num = rects->active;
rect = malloc(num * sizeof(XRectangle));
if (!rect) return;
for (i = 0; i < num; i++)
{
r = rects->rects + i;
rect[i].x = r->x;
rect[i].y = r->y;
rect[i].width = r->w;
rect[i].height = r->h;
}
evas_common_draw_context_apply_clear_cutouts(rects);
}
if (!rect) return;
XRenderSetPictureClipRectangles(rs->xinf->x11.connection, rs->x11.xlib.pic, 0, 0, rect, num);
free(rect);
}
/* initialized the transform to the identity */
static void
init_xtransform(XTransform *t)
{
int i, j;
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++)
t->matrix[i][j] = XDoubleToFixed((i == j) ? 1 : 0);
}
static void
set_xtransform_scale(XTransform *t, int sw, int sh, int w, int h, int tx, int ty)
{
// if ((sw > 1) && (w > 1))
// { sw--; w--; }
// if ((sh > 1) && (h > 1))
// { sh--; h--; }
t->matrix[0][0] = XDoubleToFixed((double)(sw) / (double)(w));
t->matrix[1][1] = XDoubleToFixed((double)(sh) / (double)(h));
t->matrix[2][0] = (tx * sw) / w;
t->matrix[2][1] = (ty * sh) / h;
}
// when color multiplier is used want: instead
// CA src IN mask SRC temp; non-CA temp OVER dst. - i think. need to check.
void
_xr_xlib_render_surface_composite(Xrender_Surface *srs, Xrender_Surface *drs, RGBA_Draw_Context *dc, int sx, int sy, int sw, int sh, int x, int y, int w, int h, int smooth)
{
Xrender_Surface *trs = NULL;
XTransform xf;
XRenderPictureAttributes att;
Picture mask = None;
int e, is_scaling, op;
if ((sw <= 0) || (sh <= 0) || (w <= 0) || (h <= 0)) return;
is_scaling = e = ((sw != w) || (sh != h));
att.clip_mask = None;
XRenderChangePicture(srs->xinf->x11.connection, srs->x11.xlib.pic, CPClipMask, &att);
XRenderChangePicture(drs->xinf->x11.connection, drs->x11.xlib.pic, CPClipMask, &att);
init_xtransform(&xf);
op = PictOpOver;
if (dc->render_op == _EVAS_RENDER_BLEND)
{
if (!srs->alpha) op = PictOpSrc;
}
else if (dc->render_op == _EVAS_RENDER_BLEND_REL)
op = PictOpAtop;
else if (dc->render_op == _EVAS_RENDER_MUL)
op = PictOpIn;
else if (dc->render_op == _EVAS_RENDER_COPY)
op = PictOpSrc;
else if (dc->render_op == _EVAS_RENDER_COPY_REL)
op = PictOpIn;
else if (dc->render_op == _EVAS_RENDER_MASK)
op = PictOpInReverse;
if ((dc) && (dc->mul.use))
{
unsigned int r, g, b, a;
if ((op == PictOpOver) && (!dc->mul.col)) return;
a = dc->mul.col >> 24;
r = (dc->mul.col >> 16) & 0xff;
g = (dc->mul.col >> 8) & 0xff;
b = dc->mul.col & 0xff;
if (a < 255) op = PictOpOver;
if (dc->mul.col != 0xffffffff)
{
if ((srs->xinf->mul_r != r) || (srs->xinf->mul_g != g) ||
(srs->xinf->mul_b != b) || (srs->xinf->mul_a != a))
{
srs->xinf->mul_r = r;
srs->xinf->mul_g = g;
srs->xinf->mul_b = b;
srs->xinf->mul_a = a;
_xr_xlib_render_surface_solid_rectangle_set(srs->xinf->mul,
r, g, b, a,
0, 0, 1, 1);
}
mask = srs->xinf->mul->x11.xlib.pic;
if (dc->mul.col == (a * 0x01010101))
{
att.component_alpha = 0;
XRenderChangePicture(srs->xinf->x11.connection, mask, CPComponentAlpha, &att);
}
else
{
if ((srs->alpha) || (a != 0xff))
trs = _xr_xlib_render_surface_new(srs->xinf, sw + 2, sh + 2,
srs->xinf->x11.fmt32, 1);
else
trs = _xr_xlib_render_surface_new(srs->xinf, sw + 2, sh + 2,
srs->x11.xlib.fmt, srs->alpha);
if (!trs) return;
att.component_alpha = 1;
XRenderChangePicture(srs->xinf->x11.connection, mask, CPComponentAlpha, &att);
XRenderSetPictureTransform(srs->xinf->x11.connection, srs->x11.xlib.pic, &xf);
XRenderComposite(srs->xinf->x11.connection, PictOpSrc, srs->x11.xlib.pic, mask,
trs->x11.xlib.pic,
sx, sy,
sx, sy,
0, 0, sw + 2, sh + 2);
mask = None;
}
}
}
//#define HFW + (sw / 2)
//#define HFH + (sh / 2)
#define HFW
#define HFH
_xr_xlib_render_surface_clips_set(drs, dc, x, y, w, h);
if (trs)
{
XRenderSetPictureFilter(trs->xinf->x11.connection, trs->x11.xlib.pic, get_filter(smooth), NULL, 0);
set_xtransform_scale(&xf, sw, sh, w, h, -1, -1);
XRenderSetPictureTransform(trs->xinf->x11.connection, trs->x11.xlib.pic, &xf);
att.component_alpha = 0;
if (dc->render_op == _EVAS_RENDER_MUL) att.component_alpha = 1;
XRenderChangePicture(trs->xinf->x11.connection, trs->x11.xlib.pic, CPComponentAlpha, &att);
XRenderComposite(trs->xinf->x11.connection, op, trs->x11.xlib.pic, mask, drs->x11.xlib.pic,
(w HFW) / sw, (h HFH) / sh,
(w HFW) / sw, (h HFH) / sh,
x, y, w, h);
_xr_xlib_render_surface_free(trs);
}
else
{
if (srs->bordered && is_scaling)
{
trs = _xr_xlib_render_surface_new(srs->xinf, sw + 2, sh + 2,
srs->x11.xlib.fmt, srs->alpha);
if (!trs) return;
att.component_alpha = 0;
XRenderChangePicture(srs->xinf->x11.connection, srs->x11.xlib.pic, CPComponentAlpha, &att);
XRenderSetPictureTransform(srs->xinf->x11.connection, srs->x11.xlib.pic, &xf);
XRenderComposite(srs->xinf->x11.connection, PictOpSrc, srs->x11.xlib.pic, None,
trs->x11.xlib.pic, sx, sy, sx, sy, 0, 0, sw + 2, sh + 2);
XRenderSetPictureFilter(trs->xinf->x11.connection, trs->x11.xlib.pic, get_filter(smooth), NULL, 0);
set_xtransform_scale(&xf, sw, sh, w, h, -1, -1);
XRenderSetPictureTransform(trs->xinf->x11.connection, trs->x11.xlib.pic, &xf);
if (dc->render_op == _EVAS_RENDER_MUL)
{
att.component_alpha = 1;
XRenderChangePicture(trs->xinf->x11.connection, trs->x11.xlib.pic, CPComponentAlpha, &att);
}
XRenderComposite(trs->xinf->x11.connection, op, trs->x11.xlib.pic, mask, drs->x11.xlib.pic,
(w HFW) / sw, (h HFH) / sh,
(w HFW) / sw, (h HFH) / sh,
// 1, 1, 1, 1,
x, y, w, h);
_xr_xlib_render_surface_free(trs);
}
else
{
XRenderSetPictureFilter(srs->xinf->x11.connection, srs->x11.xlib.pic, get_filter(smooth), NULL, 0);
set_xtransform_scale(&xf, sw, sh, w, h, 0, 0);
XRenderSetPictureTransform(srs->xinf->x11.connection, srs->x11.xlib.pic, &xf);
att.component_alpha = 0;
if (dc->render_op == _EVAS_RENDER_MUL)
att.component_alpha = 1;
XRenderChangePicture(srs->xinf->x11.connection, srs->x11.xlib.pic, CPComponentAlpha, &att);
XRenderComposite(srs->xinf->x11.connection, op, srs->x11.xlib.pic, mask, drs->x11.xlib.pic,
((((sx + 1) * w) HFW) / sw),
((((sy + 1) * h) HFH) / sh),
((((sx + 1) * w) HFW) / sw),
((((sy + 1) * h) HFH) / sh),
x, y, w, h);
}
}
}
void
_xr_xlib_render_surface_copy(Xrender_Surface *srs, Xrender_Surface *drs, int sx, int sy, int x, int y, int w, int h)
{
XTransform xf;
XRenderPictureAttributes att;
if ((w <= 0) || (h <= 0) || (!srs) || (!drs)) return;
init_xtransform(&xf);
#ifdef BROKEN_XORG_XRENDER
/* FIXME: why do we need to change the identity matrix ifthe src surface
* is 1 bit deep?
*/
if (srs->depth == 1)
{
xf.matrix[0][0] = xf.matrix[1][1] = xf.matrix[2][2] = 1;
}
#endif
XRenderSetPictureTransform(srs->xinf->x11.connection, srs->x11.xlib.pic, &xf);
// XRenderSetPictureFilter(srs->xinf->x11.connection, srs->x11.xlib.pic, FilterNearest, NULL, 0);
att.clip_mask = None;
XRenderChangePicture(srs->xinf->x11.connection, srs->x11.xlib.pic, CPClipMask, &att);
XRenderChangePicture(drs->xinf->x11.connection, drs->x11.xlib.pic, CPClipMask, &att);
XRenderComposite(srs->xinf->x11.connection, PictOpSrc, srs->x11.xlib.pic, None, drs->x11.xlib.pic,
sx, sy, 0, 0, x, y, w, h);
}
void
_xr_xlib_render_surface_rectangle_draw(Xrender_Surface *rs, RGBA_Draw_Context *dc, int x, int y, int w, int h)
{
XRenderColor col;
XRenderPictureAttributes att;
int r, g, b, a, op;
if ((!rs) || (!dc)) return;
if ((w <= 0) || (h <= 0)) return;
a = dc->col.col >> 24;
r = (dc->col.col >> 16) & 0xff;
g = (dc->col.col >> 8 ) & 0xff;
b = (dc->col.col ) & 0xff;
col.red = (r << 8) | r;
col.green = (g << 8) | g;
col.blue = (b << 8) | b;
col.alpha = (a << 8) | a;
op = PictOpOver;
if (dc->render_op == _EVAS_RENDER_BLEND)
{
if (!dc->col.col) return;
if (a == 0xff) op = PictOpSrc;
}
else if (dc->render_op == _EVAS_RENDER_BLEND_REL)
{
if (!dc->col.col) return;
op = PictOpAtop;
}
else if (dc->render_op == _EVAS_RENDER_MUL)
{
if (dc->col.col == 0xffffffff) return;
op = PictOpIn;
}
else if (dc->render_op == _EVAS_RENDER_COPY)
op = PictOpSrc;
else if (dc->render_op == _EVAS_RENDER_COPY_REL)
op = PictOpIn;
else if (dc->render_op == _EVAS_RENDER_MASK)
op = PictOpInReverse;
att.clip_mask = None;
XRenderChangePicture(rs->xinf->x11.connection, rs->x11.xlib.pic, CPClipMask, &att);
_xr_xlib_render_surface_clips_set(rs, dc, x, y, w, h);
XRenderFillRectangle(rs->xinf->x11.connection, op, rs->x11.xlib.pic, &col, x, y, w, h);
}
void
_xr_xlib_render_surface_line_draw(Xrender_Surface *rs, RGBA_Draw_Context *dc, int x1, int y1, int x2, int y2)
{
XRenderPictureAttributes att;
int op;
if ((!rs) || (!dc) || (!dc->col.col)) return;
op = PictOpOver;
if (dc->render_op == _EVAS_RENDER_BLEND)
{
if (!dc->col.col) return;
}
else if (dc->render_op == _EVAS_RENDER_BLEND_REL)
{
if (!dc->col.col) return;
op = PictOpAtop;
}
else if (dc->render_op == _EVAS_RENDER_MUL)
{
if (dc->col.col == 0xffffffff) return;
op = PictOpIn;
}
else if (dc->render_op == _EVAS_RENDER_COPY)
op = PictOpSrc;
else if (dc->render_op == _EVAS_RENDER_COPY_REL)
op = PictOpIn;
else if (dc->render_op == _EVAS_RENDER_MASK)
op = PictOpInReverse;
att.clip_mask = None;
XRenderChangePicture(rs->xinf->x11.connection, rs->x11.xlib.pic, CPClipMask, &att);
_xr_xlib_render_surface_clips_set(rs, dc, 0, 0, rs->width, rs->height);
{
int r, g, b, a;
XPointDouble poly[4];
int dx, dy;
double len, ddx, ddy;
dx = x2 - x1;
dy = y2 - y1;
len = sqrt((double)(dx * dx) + (double)(dy * dy));
ddx = (0.5 * dx) / len;
ddy = (0.5 * dy) / len;
if (ddx < 0) ddx = -0.5 - ddx;
else ddx = 0.5 - ddx;
if (ddy < 0) ddy = -0.5 - ddy;
else ddy = 0.5 - ddy;
poly[0].x = (x1 + ddx);
poly[0].y = (y1 - ddy);
poly[1].x = (x2 + ddx);
poly[1].y = (y2 - ddy);
poly[2].x = (x2 - ddx);
poly[2].y = (y2 + ddy);
poly[3].x = (x1 - ddx);
poly[3].y = (y1 + ddy);
a = (dc->col.col >> 24) & 0xff;
r = (dc->col.col >> 16) & 0xff;
g = (dc->col.col >> 8 ) & 0xff;
b = (dc->col.col ) & 0xff;
if ((rs->xinf->mul_r != r) || (rs->xinf->mul_g != g) ||
(rs->xinf->mul_b != b) || (rs->xinf->mul_a != a))
{
rs->xinf->mul_r = r;
rs->xinf->mul_g = g;
rs->xinf->mul_b = b;
rs->xinf->mul_a = a;
_xr_xlib_render_surface_solid_rectangle_set(rs->xinf->mul, r, g, b, a, 0, 0, 1, 1);
}
XRenderCompositeDoublePoly(rs->xinf->x11.connection, op,
rs->xinf->mul->x11.xlib.pic, rs->x11.xlib.pic,
rs->xinf->x11.fmt8, 0, 0, 0, 0,
poly, 4, EvenOddRule);
}
}
void
_xr_xlib_render_surface_polygon_draw(Xrender_Surface *rs, RGBA_Draw_Context *dc, RGBA_Polygon_Point *points, int x, int y)
{
RGBA_Polygon_Point *pt;
int i, num;
XPointDouble *pts;
int r, g, b, a;
XRenderPictureAttributes att;
int op;
if ((!rs) || (!dc)) return;
num = 0; EINA_INLIST_FOREACH(points, pt) num++;
if (num < 3) return;
op = PictOpOver;
if (dc->render_op == _EVAS_RENDER_BLEND)
{
if (!dc->col.col) return;
}
else if (dc->render_op == _EVAS_RENDER_BLEND_REL)
{
if (!dc->col.col) return;
op = PictOpAtop;
}
else if (dc->render_op == _EVAS_RENDER_MUL)
{
if (dc->col.col == 0xffffffff) return;
op = PictOpIn;
}
else if (dc->render_op == _EVAS_RENDER_COPY)
op = PictOpSrc;
else if (dc->render_op == _EVAS_RENDER_COPY_REL)
op = PictOpIn;
else if (dc->render_op == _EVAS_RENDER_MASK)
op = PictOpInReverse;
a = (dc->col.col >> 24) & 0xff;
r = (dc->col.col >> 16) & 0xff;
g = (dc->col.col >> 8 ) & 0xff;
b = (dc->col.col ) & 0xff;
if ((rs->xinf->mul_r != r) || (rs->xinf->mul_g != g) ||
(rs->xinf->mul_b != b) || (rs->xinf->mul_a != a))
{
rs->xinf->mul_r = r;
rs->xinf->mul_g = g;
rs->xinf->mul_b = b;
rs->xinf->mul_a = a;
_xr_xlib_render_surface_solid_rectangle_set(rs->xinf->mul, r, g, b, a, 0, 0, 1, 1);
}
pts = malloc(num * sizeof(XPointDouble));
if (!pts) return;
i = 0;
EINA_INLIST_FOREACH(points, pt)
{
if (i < num)
{
pts[i].x = pt->x + x;
pts[i].y = pt->y + y;
i++;
}
}
att.clip_mask = None;
XRenderChangePicture(rs->xinf->x11.connection, rs->x11.xlib.pic, CPClipMask, &att);
_xr_xlib_render_surface_clips_set(rs, dc, 0, 0, rs->width, rs->height);
XRenderCompositeDoublePoly(rs->xinf->x11.connection, op,
rs->xinf->mul->x11.xlib.pic, rs->x11.xlib.pic,
rs->xinf->x11.fmt8, 0, 0, 0, 0,
pts, num, Complex);
free(pts);
}

View File

@ -1,262 +0,0 @@
#include "evas_common.h"
#include "evas_private.h"
#include "evas_engine.h"
#include "Evas_Engine_XRender_X11.h"
static Eina_List *_image_info_list = NULL;
static int _x_err = 0;
static void
_tmp_x_err(Display *d __UNUSED__, XErrorEvent *ev __UNUSED__)
{
_x_err = 1;
return;
}
Ximage_Info *
_xr_xlib_image_info_get(Display *display, Drawable draw, Visual *visual)
{
Ximage_Info *xinf;
Ximage_Info *xinf2;
Eina_List *l;
int di;
unsigned int dui;
Window root;
xinf2 = NULL;
EINA_LIST_FOREACH(_image_info_list, l, xinf)
if (xinf->x11.connection == display)
{
xinf2 = xinf;
break;
}
xinf = calloc(1, sizeof(Ximage_Info));
if (!xinf) return NULL;
xinf->references = 1;
xinf->x11.connection = display;
xinf->x11.draw = draw;
XGetGeometry(xinf->x11.connection, xinf->x11.draw,
&root,
&di, &di, &dui, &dui, &dui, &dui);
xinf->x11.root = root;
xinf->x11.visual = visual;
xinf->x11.fmt32 = XRenderFindStandardFormat(xinf->x11.connection, PictStandardARGB32);
xinf->x11.fmt24 = XRenderFindStandardFormat(xinf->x11.connection, PictStandardRGB24);
xinf->x11.fmt8 = XRenderFindStandardFormat(xinf->x11.connection, PictStandardA8);
xinf->x11.fmt4 = XRenderFindStandardFormat(xinf->x11.connection, PictStandardA4);
xinf->x11.fmt1 = XRenderFindStandardFormat(xinf->x11.connection, PictStandardA1);
/* find fmt for default visual */
xinf->x11.fmtdef = XRenderFindVisualFormat(xinf->x11.connection, xinf->x11.visual);
xinf->mul = _xr_xlib_render_surface_new(xinf, 1, 1, xinf->x11.fmt32, 1);
_xr_xlib_render_surface_repeat_set(xinf->mul, 1);
xinf->mul_r = xinf->mul_g = xinf->mul_b = xinf->mul_a = 0xff;
_xr_xlib_render_surface_solid_rectangle_set(xinf->mul, xinf->mul_r, xinf->mul_g, xinf->mul_b, xinf->mul_a, 0, 0, 1, 1);
if (xinf2)
{
xinf->can_do_shm = xinf2->can_do_shm;
xinf->depth = xinf2->depth;
}
else
{
XVisualInfo *vi, vit;
XShmSegmentInfo shm_info;
XImage *xim;
int num = 0;
vit.visualid = XVisualIDFromVisual(xinf->x11.visual);
vi = XGetVisualInfo(xinf->x11.connection, VisualIDMask, &vit, &num);
if (!vi) xinf->depth = 32;
else
{
xinf->depth = vi->depth;
XFree(vi);
}
xinf->can_do_shm = 0;
xim = XShmCreateImage(xinf->x11.connection, xinf->x11.visual, xinf->depth, ZPixmap, NULL, &shm_info, 1, 1);
if (xim)
{
shm_info.shmid = shmget(IPC_PRIVATE, xim->bytes_per_line * xim->height, IPC_CREAT | 0777);
if (shm_info.shmid >= 0)
{
shm_info.shmaddr = xim->data = shmat(shm_info.shmid, 0, 0);
if ((shm_info.shmaddr) && (shm_info.shmaddr != (void *) -1))
{
XErrorHandler ph;
XSync(xinf->x11.connection, False);
_x_err = 0;
ph = XSetErrorHandler((XErrorHandler)_tmp_x_err);
XShmAttach(xinf->x11.connection, &shm_info);
XSync(xinf->x11.connection, False);
XSetErrorHandler((XErrorHandler)ph);
if (!_x_err) xinf->can_do_shm = 1;
shmdt(shm_info.shmaddr);
}
shmctl(shm_info.shmid, IPC_RMID, 0);
}
XDestroyImage(xim);
}
}
_image_info_list = eina_list_prepend(_image_info_list, xinf);
return xinf;
}
void
_xr_xlib_image_info_free(Ximage_Info *xinf)
{
if (xinf->pool) XSync(xinf->x11.connection, False);
_xr_xlib_image_info_pool_flush(xinf, 0, 0);
xinf->references--;
if (xinf->references != 0) return;
_xr_xlib_render_surface_free(xinf->mul);
free(xinf);
_image_info_list = eina_list_remove(_image_info_list, xinf);
}
void
_xr_xlib_image_info_pool_flush(Ximage_Info *xinf, unsigned int max_num, unsigned int max_mem)
{
if ((xinf->pool_mem <= max_mem) && (eina_list_count(xinf->pool) <= max_num)) return;
while ((xinf->pool_mem > max_mem) || (eina_list_count(xinf->pool) > max_num))
{
Ximage_Image *xim;
if (!xinf->pool) break;
xim = xinf->pool->data;
_xr_xlib_image_free(xim);
}
}
Ximage_Image *
_xr_xlib_image_new(Ximage_Info *xinf, int w, int h, int depth)
{
Ximage_Image *xim, *xim2;
Eina_List *l;
xim2 = NULL;
EINA_LIST_FOREACH(xinf->pool, l, xim)
{
if ((xim->width >= w) && (xim->height >= h) && (xim->depth == depth) && (xim->available))
{
if (!xim2) xim2 = xim;
else if ((xim->width * xim->height) < (xim2->width * xim2->height)) xim2 = xim;
}
}
if (xim2)
{
xim2->available = 0;
return xim2;
}
xim = calloc(1, sizeof(Ximage_Image));
if (xim)
{
xim->xinf = xinf;
xim->width = w;
xim->height = h;
xim->depth = depth;
xim->available = 0;
if (xim->xinf->can_do_shm)
{
xim->x11.xlib.shm_info = calloc(1, sizeof(XShmSegmentInfo));
if (xim->x11.xlib.shm_info)
{
xim->x11.xlib.xim = XShmCreateImage(xim->xinf->x11.connection, xim->xinf->x11.visual, xim->depth, ZPixmap, NULL, xim->x11.xlib.shm_info, xim->width, xim->height);
if (xim->x11.xlib.xim)
{
xim->x11.xlib.shm_info->shmid = shmget(IPC_PRIVATE, xim->x11.xlib.xim->bytes_per_line * xim->x11.xlib.xim->height, IPC_CREAT | 0777);
if (xim->x11.xlib.shm_info->shmid >= 0)
{
xim->x11.xlib.shm_info->shmaddr = xim->x11.xlib.xim->data = shmat(xim->x11.xlib.shm_info->shmid, 0, 0);
if ((xim->x11.xlib.shm_info->shmaddr) && (xim->x11.xlib.shm_info->shmaddr != (void *) -1))
{
XErrorHandler ph;
XSync(xim->xinf->x11.connection, False);
_x_err = 0;
ph = XSetErrorHandler((XErrorHandler)_tmp_x_err);
XShmAttach(xim->xinf->x11.connection, xim->x11.xlib.shm_info);
XSync(xim->xinf->x11.connection, False);
XSetErrorHandler((XErrorHandler)ph);
if (!_x_err) goto xim_ok;
shmdt(xim->x11.xlib.shm_info->shmaddr);
}
shmctl(xim->x11.xlib.shm_info->shmid, IPC_RMID, 0);
}
XDestroyImage(xim->x11.xlib.xim);
}
free(xim->x11.xlib.shm_info);
xim->x11.xlib.shm_info = NULL;
}
}
xim->x11.xlib.xim = XCreateImage(xim->xinf->x11.connection, xim->xinf->x11.visual, xim->depth, ZPixmap, 0, NULL, xim->width, xim->height, 32, 0);
if (!xim->x11.xlib.xim)
{
free(xim);
return NULL;
}
xim->x11.xlib.xim->data = malloc(xim->x11.xlib.xim->bytes_per_line * xim->x11.xlib.xim->height);
if (!xim->x11.xlib.xim->data)
{
XDestroyImage(xim->x11.xlib.xim);
free(xim);
return NULL;
}
}
else
{
return NULL;
}
xim_ok:
_xr_xlib_image_info_pool_flush(xinf, 32, (1600 * 1200 * 32 * 2));
xim->line_bytes = xim->x11.xlib.xim->bytes_per_line;
xim->data = (void *)(xim->x11.xlib.xim->data);
xinf->pool_mem += (xim->width * xim->height * xim->depth);
xinf->pool = eina_list_append(xinf->pool, xim);
return xim;
}
void
_xr_xlib_image_free(Ximage_Image *xim)
{
if (xim->x11.xlib.shm_info)
{
if (!xim->available) XSync(xim->xinf->x11.connection, False);
XShmDetach(xim->xinf->x11.connection, xim->x11.xlib.shm_info);
XDestroyImage(xim->x11.xlib.xim);
shmdt(xim->x11.xlib.shm_info->shmaddr);
shmctl(xim->x11.xlib.shm_info->shmid, IPC_RMID, 0);
free(xim->x11.xlib.shm_info);
}
else
{
free(xim->x11.xlib.xim->data);
xim->x11.xlib.xim->data = NULL;
XDestroyImage(xim->x11.xlib.xim);
}
xim->xinf->pool_mem -= (xim->width * xim->height * xim->depth);
xim->xinf->pool = eina_list_remove(xim->xinf->pool, xim);
free(xim);
}
void
_xr_xlib_image_put(Ximage_Image *xim, Drawable draw, int x, int y, int w, int h)
{
XGCValues gcv;
GC gc;
gc = XCreateGC(xim->xinf->x11.connection, draw, 0, &gcv);
if (xim->x11.xlib.shm_info)
{
XShmPutImage(xim->xinf->x11.connection, draw, gc, xim->x11.xlib.xim, 0, 0, x, y, w, h, False);
XSync(xim->xinf->x11.connection, False);
}
else
XPutImage(xim->xinf->x11.connection, draw, gc, xim->x11.xlib.xim, 0, 0, x, y, w, h);
xim->available = 1;
XFreeGC(xim->xinf->x11.connection, gc);
}