an xrender engine. fully complete - but it doesnt support shaped window masks

and destination alpha like software_x11 does so its not a 100% dropin
replacement... yet


SVN revision: 17112
This commit is contained in:
Carsten Haitzler 2005-10-02 15:15:44 +00:00
parent 6dd7a6b47d
commit f4a8513aa4
26 changed files with 3100 additions and 43 deletions

View File

@ -511,6 +511,60 @@ else
AM_CONDITIONAL(BUILD_ENGINE_CAIRO_COMMON, false)
fi
#######################################
## Check if we should build the xrender_x11 engine
have_evas_xrender_x11="no";
ENGINE_XRENDER_X11_PRG="";
## Automatic check...
AC_CHECK_HEADER(X11/X.h,
[ have_evas_xrender_x11="yes" ],
[ have_evas_xrender_x11="no" ]
)
## Manual override
AC_MSG_CHECKING(whether xrender x11 backend is to be built)
AC_ARG_ENABLE(xrender-x11, [ --enable-xrender-x11 enable the XRender X11 rendering backend], [
if [ test "$enableval" = "yes" ]; then
AC_MSG_RESULT(yes)
have_evas_xrender_x11="yes"
else
AC_MSG_RESULT(no)
have_evas_xrender_x11="no"
fi
], [
AC_MSG_RESULT($have_evas_xrender_x11)
]
)
if test "x$have_evas_xrender_x11" = "xyes"; then
AC_PATH_XTRA
AC_CHECK_HEADER(X11/X.h,
[
AC_CHECK_HEADER(X11/extensions/Xrender.h,
[
AM_CONDITIONAL(BUILD_ENGINE_XRENDER_X11, true)
AC_DEFINE(BUILD_ENGINE_XRENDER_X11, 1, [XRender X11 Rendering Backend])
x_dir=${x_dir:-/usr/X11R6}
x_cflags=${x_cflags:--I${x_includes:-$x_dir/include}}
x_libs="${x_libs:--L${x_libraries:-$x_dir/lib}} -lX11 -lXext -lXrender"
ENGINE_XRENDER_X11_PRG="evas_xrender_x11_test"
],
[
AM_CONDITIONAL(BUILD_ENGINE_XRENDER_X11, false)
AC_MSG_RESULT(disabling xrender X11 engine)
have_evas_xrender_x11="no"
]
)
],
[
AM_CONDITIONAL(BUILD_ENGINE_XRENDER_X11, false)
AC_MSG_RESULT(disabling xrender X11 engine)
have_evas_xrender_x11="no"
]
)
else
AM_CONDITIONAL(BUILD_ENGINE_XRENDER_X11, false)
fi
#####################################################################
## Image loaders
@ -1543,6 +1597,7 @@ AC_SUBST(ENGINE_BUFFER_PRG)
AC_SUBST(ENGINE_SOFTWARE_QTOPIA_PRG)
AC_SUBST(ENGINE_GL_X11_PRG)
AC_SUBST(ENGINE_CAIRO_X11_PRG)
AC_SUBST(ENGINE_XRENDER_X11_PRG)
AC_SUBST(altivec_cflags)
@ -1574,6 +1629,7 @@ src/lib/engines/gl_common/Makefile
src/lib/engines/gl_x11/Makefile
src/lib/engines/cairo_common/Makefile
src/lib/engines/cairo_x11/Makefile
src/lib/engines/xrender_x11/Makefile
src/lib/include/Makefile
proj/Makefile
proj/win32_gdi/Makefile
@ -1610,7 +1666,8 @@ echo " Software Qtopia.........: $have_evas_qtopia"
echo " Software Memory Buffer..: $have_evas_buffer"
echo " DirectFB................: $have_evas_directfb"
echo " OpenGL X11..............: $have_evas_gl_x11"
echo " Cairo X11..............: $have_evas_cairo_x11"
echo " Cairo X11...............: $have_evas_cairo_x11"
echo " XRender X11.............: $have_evas_xrender_x11"
# FIXME: opengl engine needs to be fixed and tested lots for all drivers
# FIXME: xrender engine to be written
echo

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -12,7 +12,8 @@ bin_PROGRAMS = \
@ENGINE_BUFFER_PRG@ \
@ENGINE_SOFTWARE_QTOPIA_PRG@ \
@ENGINE_GL_X11_PRG@ \
@ENGINE_CAIRO_X11_PRG@
@ENGINE_CAIRO_X11_PRG@ \
@ENGINE_XRENDER_X11_PRG@
EXTRA_PROGRAMS = \
evas_software_x11_test \
@ -27,7 +28,8 @@ evas_fb_test \
evas_buffer_test \
evas_software_qtopia_test \
evas_gl_x11_test \
evas_cairo_x11_test
evas_cairo_x11_test \
evas_xrender_x11_test
SUBDIRS = evas_software_win32
@ -102,4 +104,9 @@ evas_cairo_x11_test_LDADD = $(top_builddir)/src/lib/libevas.la -lm @x_libs@ @CAI
evas_cairo_x11_test_CFLAGS = $(CFLAGS) @x_cflags@ @CAIRO_CFLAGS@
evas_cairo_x11_test_DEPENDENCIES = $(top_builddir)/src/lib/libevas.la
evas_xrender_x11_test_SOURCES = evas_test_main.h evas_test_main.c evas_xrender_x11_main.c
evas_xrender_x11_test_LDADD = $(top_builddir)/src/lib/libevas.la -lm @x_libs@
evas_xrender_x11_test_CFLAGS = $(CFLAGS) @x_cflags@
evas_xrender_x11_test_DEPENDENCIES = $(top_builddir)/src/lib/libevas.la
EXTRA_DIST = evas_software_qtopia_main.h evas_software_qtopia_main.cpp moc_evas_software_qtopia_main.cpp

View File

@ -342,7 +342,7 @@ loop(void)
printf("# EVAS BENCH: %3.3f\n", ((double)frames / (t - time_start)) / 60.0);
printf("#\n");
printf("####################################################\n");
exit(0);
// exit(0);
for (i = 0; i < 16; i++) evas_object_del(p_s[i]);
for (i = 0; i < 2; i++) evas_object_del(p_i[i]);
for (i = 0; i < 16; i++) evas_object_del(p_t[i]);

View File

@ -0,0 +1,132 @@
#include "evas_test_main.h"
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "Evas.h"
#include "Evas_Engine_XRender_X11.h"
int
main(int argc, char **argv)
{
int pause_me = 0;
Display *disp;
Window win;
XSetWindowAttributes attr;
XClassHint chint;
disp = XOpenDisplay(NULL);
if (!disp)
{
printf("Error: cannot open display.\n");
exit(-1);
}
attr.backing_store = NotUseful;
attr.colormap = DefaultColormap(disp, DefaultScreen(disp));
attr.border_pixel = 0;
attr.background_pixmap = None;
attr.event_mask =
ExposureMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask |
StructureNotifyMask;
attr.bit_gravity = ForgetGravity;
win = XCreateWindow(disp, DefaultRootWindow(disp), 0, 0, win_w, win_h, 0,
DefaultDepth(disp, DefaultScreen(disp)), InputOutput,
DefaultVisual(disp, DefaultScreen(disp)),
CWBackingStore | CWColormap |
CWBackPixmap | CWBorderPixel |
CWBitGravity | CWEventMask, &attr);
XStoreName(disp, win, "Evas XRender X11 Test");
chint.res_name = "Evas_XRender_X11_Test";
chint.res_class = "Main";
XSetClassHint(disp, win, &chint);
#if 0
szhints.flags = PMinSize | PMaxSize | PSize | USSize;
szhints.min_width = szhints.max_width = win_w;
szhints.min_height = szhints.max_height = win_h;
XSetWMNormalHints(disp, win, &szhints);
#endif
XMapWindow(disp, win);
XSync(disp, False);
/* test evas_free.... :) */
evas = evas_new();
evas_output_method_set(evas, evas_render_method_lookup("xrender_x11"));
evas_output_size_set(evas, win_w, win_h);
evas_output_viewport_set(evas, 0, 0, win_w, win_h);
{
Evas_Engine_Info_XRender_X11 *einfo;
einfo = (Evas_Engine_Info_XRender_X11 *) evas_engine_info_get(evas);
/* the following is specific to the engine */
einfo->info.display = disp;
einfo->info.visual = DefaultVisual(disp, DefaultScreen(disp));
einfo->info.drawable = win;
evas_engine_info_set(evas, (Evas_Engine_Info *) einfo);
}
setup();
orig_start_time = start_time = get_time();
for (;;)
{
XEvent ev;
while (XCheckMaskEvent(disp,
ExposureMask |
StructureNotifyMask |
KeyPressMask |
KeyReleaseMask |
ButtonPressMask |
ButtonReleaseMask | PointerMotionMask, &ev))
{
switch (ev.type)
{
case ButtonPress:
if (ev.xbutton.button == 3)
exit(0);
#if 0
if (!pause_me)
pause_me = 1;
else if (pause_me == 1)
pause_me = 2;
else
pause_me = 1;
#endif
evas_event_feed_mouse_move(evas, ev.xbutton.x, ev.xbutton.y, 0, NULL);
evas_event_feed_mouse_down(evas, ev.xbutton.button, EVAS_BUTTON_NONE, 0, NULL);
break;
case ButtonRelease:
evas_event_feed_mouse_move(evas, ev.xbutton.x, ev.xbutton.y, 0, NULL);
evas_event_feed_mouse_up(evas, ev.xbutton.button, EVAS_BUTTON_NONE, 0, NULL);
break;
case MotionNotify:
evas_event_feed_mouse_move(evas, ev.xmotion.x, ev.xmotion.y, 0, NULL);
break;
case Expose:
evas_damage_rectangle_add(evas,
ev.xexpose.x,
ev.xexpose.y,
ev.xexpose.width,
ev.xexpose.height);
break;
case ConfigureNotify:
evas_output_size_set(evas,
ev.xconfigure.width,
ev.xconfigure.height);
break;
default:
break;
}
}
if (!(pause_me == 1))
{
loop();
evas_render(evas);
XFlush(disp);
}
if (pause_me == 2)
usleep(100000);
}
return 0;
}

View File

@ -0,0 +1,117 @@
#! /bin/sh
# evas_xrender_x11_test - temporary wrapper script for .libs/evas_xrender_x11_test
# Generated by ltmain.sh - GNU libtool 1.5.6 (1.1220.2.95 2004/04/11 05:50:42) Debian: 224 $
#
# The evas_xrender_x11_test program cannot be directly executed until all the libtool
# libraries that it depends on are installed.
#
# This wrapper script should never be moved out of the build directory.
# If it is, it will not operate correctly.
# Sed substitution that helps us do robust quoting. It backslashifies
# metacharacters that are still active within double-quoted strings.
Xsed='/bin/sed -e 1s/^X//'
sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
# The HP-UX ksh and POSIX shell print the target directory to stdout
# if CDPATH is set.
if test "${CDPATH+set}" = set; then CDPATH=:; export CDPATH; fi
relink_command="(cd /home/raster/C/evas/src/bin; { test -z \"\${LIBRARY_PATH+set}\" || unset LIBRARY_PATH || { LIBRARY_PATH=; export LIBRARY_PATH; }; }; { test -z \"\${COMPILER_PATH+set}\" || unset COMPILER_PATH || { COMPILER_PATH=; export COMPILER_PATH; }; }; { test -z \"\${GCC_EXEC_PREFIX+set}\" || unset GCC_EXEC_PREFIX || { GCC_EXEC_PREFIX=; export GCC_EXEC_PREFIX; }; }; { test -z \"\${LD_RUN_PATH+set}\" || unset LD_RUN_PATH || { LD_RUN_PATH=; export LD_RUN_PATH; }; }; PATH=\"/home/raster/bin:/home/raster/s:/usr/local/bin:/usr/local/sbin:/bin:/usr/bin:/usr/X11R6/bin:/usr/games:/sbin:/usr/sbin:/usr/X11R6/lib/xscreensaver:/opt/arm/3.3.2-vfp/bin:/opt/bitkeeper:/opt/java.sun/java.current/bin:.:\"; export PATH; ccache gcc -g3 -O0 -ggdb -o \$progdir/\$file evas_test_main.o evas_xrender_x11_main.o ../../src/lib/.libs/libevas.so -lm -L/usr/X11R6/lib -lX11 -lXext /usr/lib/libXrender.so -Wl,--rpath -Wl,/home/raster/C/evas/src/lib/.libs)"
# This environment variable determines our operation mode.
if test "$libtool_install_magic" = "%%%MAGIC variable%%%"; then
# install mode needs the following variable:
notinst_deplibs=' ../../src/lib/libevas.la'
else
# When we are sourced in execute mode, $file and $echo are already set.
if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then
echo="echo"
file="$0"
# Make sure echo works.
if test "X$1" = X--no-reexec; then
# Discard the --no-reexec flag, and continue.
shift
elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
# Yippee, $echo works!
:
else
# Restart under the correct shell, and then maybe $echo will work.
exec /bin/sh "$0" --no-reexec ${1+"$@"}
fi
fi
# Find the directory that this script lives in.
thisdir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
test "x$thisdir" = "x$file" && thisdir=.
# Follow symbolic links until we get to the real thisdir.
file=`ls -ld "$file" | /bin/sed -n 's/.*-> //p'`
while test -n "$file"; do
destdir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
# If there was a directory component, then change thisdir.
if test "x$destdir" != "x$file"; then
case "$destdir" in
[\\/]* | [A-Za-z]:[\\/]*) thisdir="$destdir" ;;
*) thisdir="$thisdir/$destdir" ;;
esac
fi
file=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
file=`ls -ld "$thisdir/$file" | /bin/sed -n 's/.*-> //p'`
done
# Try to get the absolute directory name.
absdir=`cd "$thisdir" && pwd`
test -n "$absdir" && thisdir="$absdir"
program=lt-'evas_xrender_x11_test'
progdir="$thisdir/.libs"
if test ! -f "$progdir/$program" || \
{ file=`ls -1dt "$progdir/$program" "$progdir/../$program" 2>/dev/null | /bin/sed 1q`; \
test "X$file" != "X$progdir/$program"; }; then
file="$$-$program"
if test ! -d "$progdir"; then
mkdir "$progdir"
else
rm -f "$progdir/$file"
fi
# relink executable if necessary
if test -n "$relink_command"; then
if relink_command_output=`eval $relink_command 2>&1`; then :
else
echo "$relink_command_output" >&2
rm -f "$progdir/$file"
exit 1
fi
fi
mv -f "$progdir/$file" "$progdir/$program" 2>/dev/null ||
{ rm -f "$progdir/$program";
mv -f "$progdir/$file" "$progdir/$program"; }
rm -f "$progdir/$file"
fi
if test -f "$progdir/$program"; then
if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then
# Run the actual program with our arguments.
exec $progdir/$program ${1+"$@"}
$echo "$0: cannot exec $program ${1+"$@"}"
exit 1
fi
else
# The program doesn't exist.
$echo "$0: error: $progdir/$program does not exist" 1>&2
$echo "This script is just a wrapper for $program." 1>&2
echo "See the libtool documentation for more information." 1>&2
exit 1
fi
fi

View File

@ -309,6 +309,7 @@ extern "C" {
EAPI Evas_Hash *evas_hash_add (Evas_Hash *hash, const char *key, const void*data);
EAPI Evas_Hash *evas_hash_del (Evas_Hash *hash, const char *key, const void*data);
EAPI void *evas_hash_find (Evas_Hash *hash, const char *key);
EAPI void *evas_hash_modify (Evas_Hash *hash, const char *key, const void*data);
EAPI int evas_hash_size (Evas_Hash *hash);
EAPI void evas_hash_free (Evas_Hash *hash);
EAPI void evas_hash_foreach (Evas_Hash *hash, Evas_Bool (*func) (Evas_Hash *hash, const char *key, void *data, void *fdata), const void *fdata);

View File

@ -0,0 +1,31 @@
#ifndef _EVAS_ENGINE_XRENDER_X11_H
#define _EVAS_ENGINE_XRENDER_X11_H
#include <X11/Xlib.h>
typedef struct _Evas_Engine_Info_XRender_X11 Evas_Engine_Info_XRender_X11;
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 {
Display *display;
Drawable drawable;
Pixmap mask;
Visual *visual;
} info;
/* engine specific function calls to query stuff about the destination */
/* engine (what visual & colormap & depth to use, performance info etc. */
struct {
Visual * (*best_visual_get) (Display *disp, int screen);
Colormap (*best_colormap_get) (Display *disp, int screen);
int (*best_depth_get) (Display *disp, int screen);
} func;
};
#endif

View File

@ -20,7 +20,8 @@ Evas_Engine_Buffer.h \
Evas_Engine_Software_Win32_GDI.h \
Evas_Engine_Software_Qtopia.h \
Evas_Engine_GL_X11.h \
Evas_Engine_Cairo_X11.h
Evas_Engine_Cairo_X11.h \
Evas_Engine_XRender_X11.h
if BUILD_ENGINE_SOFTWARE_X11
ENGINE_SOFTWARE_X11 = engines/software_x11/libevas_engine_software_x11.la
@ -102,6 +103,14 @@ ENGINE_CAIRO_X11 =
ENGINE_CAIRO_X11_INC =
endif
if BUILD_ENGINE_XRENDER_X11
ENGINE_XRENDER_X11 = engines/xrender_x11/libevas_engine_xrender_x11.la
ENGINE_XRENDER_X11_INC = Evas_Engine_XRender_X11.h
else
ENGINE_XRENDER_X11 =
ENGINE_XRENDER_X11_INC =
endif
include_HEADERS = \
Evas.h \
$(ENGINE_SOFTWARE_X11_INC) \
@ -113,7 +122,8 @@ $(ENGINE_SOFTWARE_QTOPIA_INC) \
$(ENGINE_GL_COMMON_INC) \
$(ENGINE_GL_X11_INC) \
$(ENGINE_CAIRO_COMMON_INC) \
$(ENGINE_CAIRO_X11_INC)
$(ENGINE_CAIRO_X11_INC) \
$(ENGINE_XRENDER_X11_INC)
libevas_la_SOURCES = \
main.c
@ -136,7 +146,8 @@ libevas_la_LIBADD = \
$(ENGINE_GL_COMMON) \
$(ENGINE_GL_X11) \
$(ENGINE_CAIRO_COMMON) \
$(ENGINE_CAIRO_X11)
$(ENGINE_CAIRO_X11) \
$(ENGINE_XRENDER_X11)
libevas_la_DEPENDENCIES = \
@ -155,6 +166,7 @@ libevas_la_DEPENDENCIES = \
$(ENGINE_GL_COMMON) \
$(ENGINE_GL_X11) \
$(ENGINE_CAIRO_COMMON) \
$(ENGINE_CAIRO_X11)
$(ENGINE_CAIRO_X11) \
$(ENGINE_XRENDER_X11)
libevas_la_LDFLAGS = -version-info 1:0:0

View File

@ -27,6 +27,9 @@
#ifdef BUILD_ENGINE_CAIRO_X11
#include "evas_engine_api_cairo_x11.h"
#endif
#ifdef BUILD_ENGINE_XRENDER_X11
#include "evas_engine_api_xrender_x11.h"
#endif
static int initcount = 0;
@ -226,6 +229,11 @@ evas_output_method_set(Evas *e, int render_method)
e->engine.func = &evas_engine_software_x11_func;
else
#endif
#ifdef BUILD_ENGINE_XRENDER_X11
if (e->output.render_method == RENDER_METHOD_XRENDER_X11)
e->engine.func = &evas_engine_xrender_x11_func;
else
#endif
#ifdef BUILD_ENGINE_SOFTWARE_XCB
if (e->output.render_method == RENDER_METHOD_SOFTWARE_XCB)
e->engine.func = &evas_engine_software_xcb_func;
@ -676,6 +684,9 @@ evas_render_method_lookup(const char *name)
#ifdef BUILD_ENGINE_SOFTWARE_X11
if (!strcmp(name, "software_x11")) return RENDER_METHOD_SOFTWARE_X11;
#endif
#ifdef BUILD_ENGINE_XRENDER_X11
if (!strcmp(name, "xrender_x11")) return RENDER_METHOD_XRENDER_X11;
#endif
#ifdef BUILD_ENGINE_SOFTWARE_XCB
if (!strcmp(name, "software_xcb")) return RENDER_METHOD_SOFTWARE_XCB;
#endif
@ -746,6 +757,9 @@ evas_render_method_list(void)
#ifdef BUILD_ENGINE_SOFTWARE_X11
methods = evas_list_append(methods, strdup("software_x11"));
#endif
#ifdef BUILD_ENGINE_XRENDER_X11
methods = evas_list_append(methods, strdup("xrender_x11"));
#endif
#ifdef BUILD_ENGINE_SOFTWARE_XCB
methods = evas_list_append(methods, strdup("software_xcb"));
#endif

View File

@ -831,7 +831,7 @@ evas_object_image_reload(Evas_Object *obj)
if ((!o->cur.file) ||
(o->pixels_checked_out > 0)) return;
if (o->engine_data)
o->engine_data = obj->layer->evas->engine.func->image_dirty_region(obj->layer->evas->engine.data.output, o->engine_data, 0, 0, 1, 1);
o->engine_data = obj->layer->evas->engine.func->image_dirty_region(obj->layer->evas->engine.data.output, o->engine_data, 0, 0, o->cur.image.w, o->cur.image.h);
evas_object_image_unload(obj);
/* evas_image_cache_flush(obj->layer->evas);*/
evas_object_image_load(obj);
@ -1615,6 +1615,8 @@ evas_object_image_render_pre(Evas_Object *obj)
rr = o->pixel_updates->data;
o->pixel_updates = evas_list_remove(o->pixel_updates, rr);
obj->layer->evas->engine.func->image_dirty_region(obj->layer->evas->engine.data.output, o->engine_data, rr->x, rr->y, rr->w, rr->h);
idx = evas_object_image_figure_x_fill(obj, o->cur.fill.x, o->cur.fill.w, &idw);
idy = evas_object_image_figure_y_fill(obj, o->cur.fill.y, o->cur.fill.h, &idh);
@ -1662,6 +1664,7 @@ evas_object_image_render_pre(Evas_Object *obj)
o->pixel_updates = evas_list_remove(o->pixel_updates, r);
free(r);
}
obj->layer->evas->engine.func->image_dirty_region(obj->layer->evas->engine.data.output, o->engine_data, 0, 0, o->cur.image.w, o->cur.image.h);
updates = evas_object_render_pre_prev_cur_add(updates, obj);
goto done;
}

View File

@ -208,14 +208,8 @@ evas_hash_find(Evas_Hash *hash, const char *key)
{
if (l != hash->buckets[hash_num])
{
/* FIXME: move to front of list without alloc */
hash->buckets[hash_num] = evas_object_list_remove(hash->buckets[hash_num], el);
hash->buckets[hash_num] = evas_object_list_prepend(hash->buckets[hash_num], el);
if (evas_list_alloc_error())
{
_evas_hash_alloc_error = 1;
return el->data;
}
}
return el->data;
}
@ -223,6 +217,47 @@ evas_hash_find(Evas_Hash *hash, const char *key)
return NULL;
}
/**
* Modifies the entry pointer at the specified key and returns the old entry
* @param hash The given hash table.
* @param key The key string of the entry to modify.
* @param data The data to replace the old entry, if it exists.
* @return The data pointer for the old stored entry, or @c NULL if not
* found. If an existing entry is not found, nothing is added to the
* hash.
* @ingroup Evas_Hash_Data
*/
void *
evas_hash_modify(Evas_Hash *hash, const char *key, const void *data)
{
int hash_num;
Evas_Hash_El *el;
Evas_Object_List *l;
_evas_hash_alloc_error = 0;
if (!hash) return NULL;
hash_num = evas_hash_gen(key);
for (l = hash->buckets[hash_num]; l; l = l->next)
{
el = (Evas_Hash_El *)l;
if (((el->key) && (key) && (!strcmp(el->key, key))) ||
((!el->key) && (!key)))
{
void *old_data;
if (l != hash->buckets[hash_num])
{
hash->buckets[hash_num] = evas_object_list_remove(hash->buckets[hash_num], el);
hash->buckets[hash_num] = evas_object_list_prepend(hash->buckets[hash_num], el);
}
old_data = el->data;
el->data = data;
return old_data;
}
}
return NULL;
}
/**
* @defgroup Evas_Hash_General_Group Hash General Functions
*

View File

@ -12,4 +12,5 @@ directfb \
gl_common \
gl_x11 \
cairo_common \
cairo_x11
cairo_x11 \
xrender_x11

View File

@ -147,7 +147,7 @@ evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int
fg = evas_common_font_int_cache_glyph_get(fi, index);
if (!fg) continue;
if ((dc->font_ext.func.gl_new) && (!fg->ext_dat))
if (dc->font_ext.func.gl_new)
{
/* extension calls */
fg->ext_dat = dc->font_ext.func.gl_new(dc->font_ext.data, fg);
@ -179,7 +179,7 @@ evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int
{
/* ext glyph draw */
dc->font_ext.func.gl_draw(dc->font_ext.data,
(void *)c,
(void *)dst,
dc, fg,
chr_x,
y - (chr_y - y)

View File

@ -153,6 +153,7 @@ evas_gl_font_texture_new(Evas_GL_Context *gc, RGBA_Font_Glyph *fg)
void
evas_gl_font_texture_free(Evas_GL_Font_Texture *ft)
{
if (!ft) return NULL;
if (ft->gc->font_texture == ft->texture)
{
ft->gc->font_texture = 0;
@ -170,7 +171,7 @@ evas_gl_font_texture_draw(Evas_GL_Context *gc, void *surface, RGBA_Draw_Context
/* 35 */
ft = fg->ext_dat;
if (!ft) return;
if (surface == 0)
// if (surface == 0)
{
int r, g, b, a;

View File

@ -0,0 +1,17 @@
Makefile.in
Makefile
.deps
.libs
libevas_engine_xrender_x11.la
evas_engine_font.lo
evas_engine_font.o
evas_engine_gradient.lo
evas_engine_gradient.o
evas_engine_image.lo
evas_engine_image.o
evas_engine.lo
evas_engine.o
evas_engine_ximage.lo
evas_engine_ximage.o
evas_engine_xrender.lo
evas_engine_xrender.o

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,149 @@
#ifndef EVAS_ENGINE_H
#define EVAS_ENGINE_H
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/extensions/XShm.h>
#include <X11/extensions/Xrender.h>
#include <sys/ipc.h>
#include <sys/shm.h>
typedef struct _Ximage_Info Ximage_Info;
typedef struct _Ximage_Image Ximage_Image;
typedef struct _Xrender_Surface Xrender_Surface;
struct _Ximage_Info
{
Display *disp;
Drawable root;
Drawable draw;
int depth;
Visual *vis;
int pool_mem;
Evas_List *pool;
unsigned char can_do_shm;
XRenderPictFormat *fmt32;
XRenderPictFormat *fmt24;
XRenderPictFormat *fmt8;
XRenderPictFormat *fmt4;
XRenderPictFormat *fmt1;
unsigned char mul_r, mul_g, mul_b, mul_a;
Xrender_Surface *mul;
int references;
};
struct _Ximage_Image
{
Ximage_Info *xinf;
XImage *xim;
XShmSegmentInfo *shm_info;
int w, h;
int depth;
int line_bytes;
unsigned char *data;
unsigned char available : 1;
};
struct _Xrender_Surface
{
Ximage_Info *xinf;
int w, h;
int depth;
XRenderPictFormat *fmt;
Drawable draw;
Picture pic;
unsigned char alpha : 1;
unsigned char allocated : 1;
};
/* ximage support calls (ximage vs xshmimage, cache etc.) */
Ximage_Info *_xr_image_info_get(Display *disp, Drawable draw, Visual *vis);
void _xr_image_info_free(Ximage_Info *xinf);
void _xr_image_info_pool_flush(Ximage_Info *xinf, int max_num, int max_mem);
Ximage_Image *_xr_image_new(Ximage_Info *xinf, int w, int h, int depth);
void _xr_image_free(Ximage_Image *xim);
void _xr_image_put(Ximage_Image *xim, Drawable draw, int x, int y, int w, int h);
/* xrender support calls */
Xrender_Surface *_xr_render_surface_new(Ximage_Info *xinf, int w, int h, XRenderPictFormat *fmt, int alpha);
Xrender_Surface *_xr_render_surface_adopt(Ximage_Info *xinf, Drawable draw, int w, int h, int alpha);
void _xr_render_surface_free(Xrender_Surface *rs);
void _xr_render_surface_repeat_set(Xrender_Surface *rs, int repeat);
void _xr_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_render_surface_argb_pixels_fill(Xrender_Surface *rs, int sw, int sh, void *pixels, int x, int y, int w, int h);
void _xr_render_surface_rgb_pixels_fill(Xrender_Surface *rs, int sw, int sh, void *pixels, int x, int y, int w, int h);
void _xr_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_render_surface_copy(Xrender_Surface *srs, Xrender_Surface *drs, int sx, int sy, int x, int y, int w, int h);
void _xr_render_surface_rectangle_draw(Xrender_Surface *rs, RGBA_Draw_Context *dc, int x, int y, int w, int h);
void _xr_render_surface_line_draw(Xrender_Surface *rs, RGBA_Draw_Context *dc, int x1, int y1, int x2, int y2);
void _xre_poly_draw(Xrender_Surface *rs, RGBA_Draw_Context *dc, RGBA_Polygon_Point *points);
typedef struct _XR_Image XR_Image;
struct _XR_Image
{
Ximage_Info *xinf;
char *file;
char *key;
char *fkey;
RGBA_Image *im;
void *data;
int w, h;
Xrender_Surface *surface;
int references;
char *format;
char *comment;
Tilebuf *updates;
unsigned char alpha : 1;
unsigned char dirty : 1;
unsigned char free_data : 1;
};
XR_Image *_xre_image_load(Ximage_Info *xinf, char *file, char *key);
XR_Image *_xre_image_new_from_data(Ximage_Info *xinf, int w, int h, void *data);
XR_Image *_xre_image_new_from_copied_data(Ximage_Info *xinf, int w, int h, void *data);
XR_Image *_xre_image_new(Ximage_Info *xinf, int w, int h);
void _xre_image_free(XR_Image *im);
void _xre_image_region_dirty(XR_Image *im, int x, int y, int w, int h);
void _xre_image_dirty(XR_Image *im);
XR_Image *_xre_image_copy(XR_Image *im);
void *_xre_image_data_get(XR_Image *im);
void _xre_image_data_put(XR_Image *im, void *data);
void _xre_image_alpha_set(XR_Image *im, int alpha);
int _xre_image_alpha_get(XR_Image *im);
void _xre_image_surface_gen(XR_Image *im);
void _xre_image_cache_set(int size);
int _xre_image_cache_get(void);
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_font_surface_new(Ximage_Info *xinf, RGBA_Font_Glyph *fg);
void _xre_font_surface_free(XR_Font_Surface *fs);
void _xre_font_surface_draw(Ximage_Info *xinf, RGBA_Image *surface, RGBA_Draw_Context *dc, RGBA_Font_Glyph *fg, int x, int y);
typedef struct _XR_Gradient XR_Gradient;
struct _XR_Gradient
{
Ximage_Info *xinf;
Xrender_Surface *surface;
RGBA_Gradient *grad;
double angle;
};
XR_Gradient *_xre_gradient_color_add(Ximage_Info *xinf, XR_Gradient *gr, int r, int g, int b, int a, int distance);
XR_Gradient *_xre_gradient_colors_clear(XR_Gradient *gr);
void _xre_gradient_draw(Xrender_Surface *rs, RGBA_Draw_Context *dc, XR_Gradient *gr, int x, int y, int w, int h, double angle);
#endif

View File

@ -0,0 +1,189 @@
#include "evas_common.h"
#include "evas_private.h"
#include "evas_engine.h"
#include "evas_engine_api_xrender_x11.h"
#include "Evas_Engine_XRender_X11.h"
static Evas_Hash *_xr_fg_pool = NULL;
XR_Font_Surface *
_xre_font_surface_new(Ximage_Info *xinf, RGBA_Font_Glyph *fg)
{
XR_Font_Surface *fs;
DATA8 *data;
int w, h, j;
DATA8 *ndata;
XRenderPictureAttributes att;
Ximage_Image *xim;
Evas_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->disp == xinf->disp) && (fs->xinf->root == xinf->root))
return fs;
snprintf(buf, sizeof(buf), "@%p@/@%x@", fs->xinf->disp, fs->xinf->root);
pool = evas_hash_find(_xr_fg_pool, buf);
if (pool)
{
snprintf(buf, sizeof(buf), "%p", fg);
fs = evas_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->disp, fs->xinf->root);
pool = evas_hash_find(_xr_fg_pool, buf);
snprintf(buf2, sizeof(buf2), "%p", fg);
pool = evas_hash_add(pool, buf2, fs);
_xr_fg_pool = evas_hash_add(_xr_fg_pool, buf, pool);
fs->draw = XCreatePixmap(xinf->disp, xinf->root, w, h, xinf->fmt8->depth);
att.dither = 1;
att.component_alpha = 1;
att.repeat = 0;
fs->pic = XRenderCreatePicture(xinf->disp, fs->draw, xinf->fmt8, CPRepeat | CPDither | CPComponentAlpha, &att);
xim = _xr_image_new(fs->xinf, w, h, xinf->fmt8->depth);
if (fg->glyph_out->bitmap.num_grays == 256)
{
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 if (fg->glyph_out->bitmap.num_grays == 0)
{
DATA8 *tmpbuf = NULL, *dp, *tp, bits;
int bi, bj, end;
const DATA8 bitrepl[2] = {0x0, 0xff};
tmpbuf = malloc(w);
if (tmpbuf)
{
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++;
}
}
free(tmpbuf);
}
}
_xr_image_put(xim, fs->draw, 0, 0, w, h);
return fs;
}
static Evas_Bool
_xre_font_pool_cb(Evas_Hash *hash, const char *key, void *data, void *fdata)
{
Evas_Hash *pool;
XR_Font_Surface *fs;
char buf[256], buf2[256];
fs = fdata;
pool = data;
snprintf(buf, sizeof(buf), "@%p@/@%x@", fs->xinf->disp, fs->xinf->root);
pool = evas_hash_del(pool, buf, fs);
hash = evas_hash_modify(hash, key, pool);
return 1;
}
void
_xre_font_surface_free(XR_Font_Surface *fs)
{
if (!fs) return;
evas_hash_foreach(_xr_fg_pool, _xre_font_pool_cb, fs);
XFreePixmap(fs->xinf->disp, fs->draw);
XRenderFreePicture(fs->xinf->disp, fs->pic);
_xr_image_info_free(fs->xinf);
free(fs);
}
void
_xre_font_surface_draw(Ximage_Info *xinf, 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;
XRenderPictureAttributes att;
int r, g, b, a;
fs = fg->ext_dat;
if (!fs) 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_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) && (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->disp,
target_surface->pic, 0, 0, &rect, 1);
XRenderComposite(fs->xinf->disp, PictOpOver, fs->xinf->mul->pic,
fs->pic, target_surface->pic,
0, 0, 0, 0, x, y, fs->w, fs->h);
}

View File

@ -0,0 +1,98 @@
#include "evas_common.h"
#include "evas_private.h"
#include "evas_engine.h"
#include "evas_engine_api_xrender_x11.h"
#include "Evas_Engine_XRender_X11.h"
#include <math.h>
XR_Gradient *
_xre_gradient_color_add(Ximage_Info *xinf, XR_Gradient *gr, int r, int g, int b, int a, int distance)
{
if (!gr)
{
gr = calloc(1, sizeof(XR_Gradient));
if (!gr) return NULL;
gr->xinf = xinf;
gr->xinf->references++;
gr->grad = evas_common_gradient_new();
if (!gr->grad)
{
gr->xinf->references--;
free(gr);
return NULL;
}
}
evas_common_gradient_color_add(gr->grad, r, g, b, a, distance);
if (gr->surface)
{
_xr_render_surface_free(gr->surface);
gr->surface = NULL;
}
return gr;
}
XR_Gradient *
_xre_gradient_colors_clear(XR_Gradient *gr)
{
if (!gr) return NULL;
if (gr->grad)
{
evas_common_gradient_free(gr->grad);
gr->grad = NULL;
}
if (gr->surface)
{
_xr_render_surface_free(gr->surface);
gr->surface = NULL;
}
_xr_image_info_free(gr->xinf);
free(gr);
return NULL;
}
void
_xre_gradient_draw(Xrender_Surface *rs, RGBA_Draw_Context *dc, XR_Gradient *gr, int x, int y, int w, int h, double angle)
{
XTransform xf;
XRectangle rect;
XRenderPictureAttributes att;
Picture mask;
int r, g, b, a, op;
RGBA_Image *im;
double a2;
if ((w <= 0) || (h <= 0)) return;
if (angle != gr->angle)
{
if (gr->surface)
{
_xr_render_surface_free(gr->surface);
gr->surface = NULL;
}
}
if (!gr->surface)
{
im = evas_common_image_create(w, h);
if (im)
{
RGBA_Draw_Context *dc2;
dc2 = evas_common_draw_context_new();
if (dc2)
{
im->flags |= RGBA_IMAGE_HAS_ALPHA;
memset(im->image->data, 0, im->image->w * im->image->h * sizeof(DATA32));
evas_common_gradient_draw(im, dc2, 0, 0, w, h, gr->grad, angle);
gr->surface = _xr_render_surface_new(gr->xinf, w, h, gr->xinf->fmt32, 1);
if (gr->surface)
_xr_render_surface_argb_pixels_fill(gr->surface, w, h, im->image->data, 0, 0, w, h);
evas_common_draw_context_free(dc2);
gr->angle = angle;
}
evas_common_image_free(im);
}
}
if (gr->surface)
_xr_render_surface_composite(gr->surface, rs, dc, 0, 0, gr->surface->w, gr->surface->h, x, y, w, h, 1);
}

View File

@ -0,0 +1,492 @@
#include "evas_common.h"
#include "evas_private.h"
#include "evas_engine.h"
#include "evas_engine_api_xrender_x11.h"
#include "Evas_Engine_XRender_X11.h"
static Evas_Hash *_xr_image_hash = NULL;
static int _xr_image_cache_size = 0;
static int _xr_image_cache_usage = 0;
static Evas_List *_xr_image_cache = NULL;
static XR_Image *
__xre_image_find(char *fkey)
{
XR_Image *im;
im = evas_hash_find(_xr_image_hash, fkey);
if (!im)
{
Evas_List *l;
for (l = _xr_image_cache; l; l = l->next)
{
im = l->data;
if (!strcmp(im->fkey, fkey))
{
_xr_image_cache = evas_list_remove_list(_xr_image_cache, l);
_xr_image_hash = evas_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_image_load(Ximage_Info *xinf, char *file, char *key)
{
XR_Image *im;
char buf[4096];
if (!file) return NULL;
if (key)
snprintf(buf, sizeof(buf), "/@%p@%x@/%s//://%s", xinf->disp, xinf->root, file, key);
else
snprintf(buf, sizeof(buf), "/@%p@%x@/%s", xinf->disp, xinf->root, file);
im = __xre_image_find(buf);
if (im) return im;
im = calloc(1, sizeof(XR_Image));
if (!im) return NULL;
im->im = evas_common_load_image_from_file(file, key);
if (!im->im)
{
free(im);
return NULL;
}
im->xinf = xinf;
im->xinf->references++;
im->fkey = strdup(buf);
im->file = strdup(file);
if (key) im->key = strdup(key);
im->w = im->im->image->w;
im->h = im->im->image->h;
im->references = 1;
if (im->im->info.comment) im->comment = strdup(im->im->info.comment);
if (im->im->info.format == 1) im->format = strdup("png");
if (im->im->flags & RGBA_IMAGE_HAS_ALPHA) im->alpha = 1;
_xr_image_hash = evas_hash_add(_xr_image_hash, im->fkey, im);
return im;
}
XR_Image *
_xre_image_new_from_data(Ximage_Info *xinf, int w, int h, void *data)
{
XR_Image *im;
im = calloc(1, sizeof(XR_Image));
if (!im) return NULL;
im->xinf = xinf;
im->xinf->references++;
im->w = w;
im->h = h;
im->references = 1;
im->data = data;
im->alpha = 1;
im->dirty = 1;
return im;
}
XR_Image *
_xre_image_new_from_copied_data(Ximage_Info *xinf, int w, int h, void *data)
{
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->xinf = xinf;
im->xinf->references++;
im->free_data = 1;
{
Gfx_Func_Blend_Src_Dst 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 = 1;
im->dirty = 1;
return im;
}
XR_Image *
_xre_image_new(Ximage_Info *xinf, int w, int h)
{
XR_Image *im;
im = calloc(1, sizeof(XR_Image));
if (!im) return NULL;
im->xinf = xinf;
im->xinf->references++;
im->w = w;
im->h = h;
im->references = 1;
im->data = malloc(w * h * 4);
if (!im->data)
{
im->xinf->references--;
free(im);
}
im->free_data = 1;
im->alpha = 1;
im->dirty = 1;
return im;
}
static void
__xre_image_real_free(XR_Image *im)
{
if (im->file) free(im->file);
if (im->key) free(im->key);
if (im->fkey) free(im->fkey);
if (im->im) evas_common_image_unref(im->im);
if ((im->free_data) && (im->data)) free(im->data);
if (im->surface) _xr_render_surface_free(im->surface);
if (im->format) free(im->format);
if (im->comment) free(im->comment);
if (im->updates) evas_common_tilebuf_free(im->updates);
_xr_image_info_free(im->xinf);
free(im);
}
void
_xre_image_free(XR_Image *im)
{
im->references--;
if (im->references != 0) return;
if (!im->dirty)
{
if (im->fkey)
_xr_image_hash = evas_hash_del(_xr_image_hash, im->fkey, im);
_xr_image_cache = evas_list_prepend(_xr_image_cache, im);
_xr_image_cache_usage += (im->w * im->h * 4);
_xre_image_cache_set(_xr_image_cache_size);
}
else
__xre_image_real_free(im);
}
void
_xre_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_image_dirty(XR_Image *im)
{
if (im->dirty) return;
if (im->fkey)
_xr_image_hash = evas_hash_del(_xr_image_hash, im->fkey, im);
im->dirty = 1;
}
XR_Image *
_xre_image_copy(XR_Image *im)
{
XR_Image *im2;
void *data = NULL;
if (im->data) data = im->data;
else
{
if (!im->im) im->im = evas_common_load_image_from_file(im->file, im->key);
if (im->im)
{
evas_common_load_image_data_from_file(im->im);
data = im->im->image->data;
}
}
if (!data) return NULL;
im2 = _xre_image_new_from_copied_data(im->xinf, im->w, im->h, data);
if (im2) im2->alpha = im->alpha;
if ((im->im) && (!im->dirty))
{
evas_common_image_unref(im->im);
im->im = NULL;
}
return im2;
}
void
_xre_image_resize(XR_Image *im, int w, int h)
{
if ((w == im->w) && (h == im->h)) return;
if (im->surface)
{
Xrender_Surface *old_surface;
int x = 0, y = 0, ww, hh;
ww = w; hh = h;
RECTS_CLIP_TO_RECT(x, y, ww, hh, 0, 0, im->w, im->h);
old_surface = im->surface;
im->surface = _xr_render_surface_new(old_surface->xinf, w, h, old_surface->fmt, old_surface->alpha);
if (im->surface)
_xr_render_surface_copy(old_surface, im->surface, 0, 0, 0, 0, ww, hh);
_xr_render_surface_free(old_surface);
}
if (im->data)
{
Gfx_Func_Blend_Src_Dst func;
int x = 0, y = 0, ww, hh;
unsigned int *sp, *dp;
void *data;
data = malloc(w * h * 4);
if (!data)
{
if (im->surface)
{
_xr_render_surface_free(im->surface);
im->surface = NULL;
}
return;
}
ww = w; hh = h;
RECTS_CLIP_TO_RECT(x, y, ww, hh, 0, 0, im->w, im->h);
func = evas_common_draw_func_copy_get(w * h, 0);
if (func)
{
for (y = 0; y < hh; y++)
{
sp = ((unsigned int *)im->data) + (y * im->w);
dp = ((unsigned int *)data) + (y * w);
func(sp, dp, ww);
}
evas_common_cpu_end_opt();
}
free(im->data);
im->data = data;
}
else if (im->im)
{
RGBA_Image *im_old;
im_old = im->im;
im->im = evas_common_image_create(w, h);
if (!im->im)
{
im->im = im_old;
if (im->surface)
{
_xr_render_surface_free(im->surface);
im->surface = NULL;
}
return;
}
evas_common_load_image_data_from_file(im_old);
if (im_old->image->data)
{
int x = 0, y = 0, ww, hh;
ww = w; hh = h;
RECTS_CLIP_TO_RECT(x, y, ww, hh, 0, 0, im->w, im->h);
evas_common_blit_rectangle(im_old, im->im, 0, 0, ww, hh, 0, 0);
evas_common_cpu_end_opt();
}
evas_common_image_unref(im_old);
}
else
{
im->data = malloc(w * h * 4);
im->free_data = 1;
}
im->w = w;
im->h = h;
}
void *
_xre_image_data_get(XR_Image *im)
{
void *data = NULL;
if (im->data) data = im->data;
else
{
if (!im->im) im->im = evas_common_load_image_from_file(im->file, im->key);
if (im->im)
{
evas_common_load_image_data_from_file(im->im);
data = im->im->image->data;
}
}
return data;
}
void
_xre_image_data_put(XR_Image *im, void *data)
{
void *imdata = NULL;
if (!data) return;
if (im->data)
{
imdata = im->data;
if (data == imdata) return;
if (im->free_data) free(im->data);
}
else
{
if (im->im) imdata = im->im->image->data;
if (data == imdata) return;
if (im->im)
{
evas_common_image_unref(im->im);
im->im = NULL;
}
}
im->data = data;
im->free_data = 0;
if (im->surface)
{
_xr_render_surface_free(im->surface);
im->surface = NULL;
}
_xre_image_dirty(im);
if (im->updates)
{
evas_common_tilebuf_free(im->updates);
im->updates = NULL;
}
}
void
_xre_image_alpha_set(XR_Image *im, int alpha)
{
if (im->alpha == alpha) return;
im->alpha = alpha;
if (im->surface)
{
Xrender_Surface *old_surface;
old_surface = im->surface;
im->surface = NULL;
if (im->alpha)
im->surface = _xr_render_surface_new(im->xinf, im->w, im->h, im->xinf->fmt32, 1);
else
im->surface = _xr_render_surface_new(im->xinf, im->w, im->h, im->xinf->fmt24, 0);
if (im->surface)
_xr_render_surface_copy(old_surface, im->surface, 0, 0, 0, 0, im->w, im->h);
_xr_render_surface_free(old_surface);
}
if (im->updates)
{
evas_common_tilebuf_free(im->updates);
im->updates = NULL;
}
}
int
_xre_image_alpha_get(XR_Image *im)
{
return im->alpha;
}
void
_xre_image_surface_gen(XR_Image *im)
{
void *data = NULL;
if (im->data) data = im->data;
else
{
if (!im->im) im->im = evas_common_load_image_from_file(im->file, im->key);
if (im->im)
{
evas_common_load_image_data_from_file(im->im);
data = im->im->image->data;
}
}
if (!data) return;
if (im->surface)
{
if (im->updates)
{
Tilebuf_Rect *rects, *r;
rects = evas_common_tilebuf_get_render_rects(im->updates);
if (rects)
{
for (r = rects; r; r = (Tilebuf_Rect *)((Evas_Object_List *)r)->next)
{
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_render_surface_argb_pixels_fill(im->surface, im->w, im->h, data, rx, ry, rw, rh);
else
_xr_render_surface_rgb_pixels_fill(im->surface, im->w, im->h, data, rx, ry, rw, rh);
}
evas_common_tilebuf_free_render_rects(rects);
}
evas_common_tilebuf_free(im->updates);
im->updates = NULL;
}
return;
}
if (im->alpha)
{
im->surface = _xr_render_surface_new(im->xinf, im->w, im->h, im->xinf->fmt32, 1);
_xr_render_surface_argb_pixels_fill(im->surface, im->w, im->h, data, 0, 0, im->w, im->h);
}
else
{
im->surface = _xr_render_surface_new(im->xinf, im->w, im->h, im->xinf->fmt24, 0);
_xr_render_surface_rgb_pixels_fill(im->surface, im->w, im->h, data, 0, 0, im->w, im->h);
}
if ((im->im) && (!im->dirty))
{
evas_common_image_unref(im->im);
im->im = NULL;
}
}
void
_xre_image_cache_set(int size)
{
_xr_image_cache_size = size;
while (_xr_image_cache_usage > _xr_image_cache_size)
{
Evas_List *l;
l = evas_list_last(_xr_image_cache);
if (l)
{
XR_Image *im;
im = l->data;
_xr_image_cache = evas_list_remove_list(_xr_image_cache, l);
_xr_image_cache_usage -= (im->w * im->h * 4);
__xre_image_real_free(im);
}
}
}
int
_xre_image_cache_get(void)
{
return _xr_image_cache_size;
}

View File

@ -0,0 +1,254 @@
#include "evas_common.h"
#include "evas_private.h"
#include "evas_engine.h"
#include "evas_engine_api_xrender_x11.h"
#include "Evas_Engine_XRender_X11.h"
static Evas_List *_image_info_list = NULL;
static int _x_err = 0;
static void
_tmp_x_err(Display *d, XErrorEvent *ev)
{
_x_err = 1;
return;
}
Ximage_Info *
_xr_image_info_get(Display *disp, Drawable draw, Visual *vis)
{
Ximage_Info *xinf, *xinf2;
Evas_List *l;
int di;
unsigned int dui;
xinf2 = NULL;
for (l = _image_info_list; l; l = l->next)
{
xinf = l->data;
if (xinf->disp == disp)
{
xinf2 = xinf;
break;
}
}
xinf = calloc(1, sizeof(Ximage_Info));
if (!xinf) return NULL;
xinf->references = 1;
xinf->disp = disp;
xinf->draw = draw;
XGetGeometry(xinf->disp, xinf->draw, &(xinf->root), &di, &di, &dui, &dui, &dui, &dui);
xinf->vis = vis;
xinf->fmt32 = XRenderFindStandardFormat(xinf->disp, PictStandardARGB32);
xinf->fmt24 = XRenderFindStandardFormat(xinf->disp, PictStandardRGB24);
xinf->fmt8 = XRenderFindStandardFormat(xinf->disp, PictStandardA8);
xinf->fmt4 = XRenderFindStandardFormat(xinf->disp, PictStandardA4);
xinf->fmt1 = XRenderFindStandardFormat(xinf->disp, PictStandardA1);
xinf->mul = _xr_render_surface_new(xinf, 1, 1, xinf->fmt32, 1);
_xr_render_surface_repeat_set(xinf->mul, 1);
xinf->mul_r = xinf->mul_g = xinf->mul_b = xinf->mul_a = 0xff;
_xr_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->vis);
vi = XGetVisualInfo(xinf->disp, VisualIDMask, &vit, &num);
if (!vi) xinf->depth = 32;
else
{
xinf->depth = vi->depth;
XFree(vi);
}
xinf->can_do_shm = 0;
xim = XShmCreateImage(xinf->disp, xinf->vis, 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 != NULL)
{
XErrorHandler ph;
XSync(xinf->disp, False);
_x_err = 0;
ph = XSetErrorHandler((XErrorHandler)_tmp_x_err);
XShmAttach(xinf->disp, &shm_info);
XSync(xinf->disp, 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 = evas_list_prepend(_image_info_list, xinf);
return xinf;
}
void
_xr_image_info_free(Ximage_Info *xinf)
{
if (xinf->pool) XSync(xinf->disp, False);
_xr_image_info_pool_flush(xinf, 0, 0);
xinf->references--;
if (xinf->references != 0) return;
_xr_render_surface_free(xinf->mul);
free(xinf);
_image_info_list = evas_list_remove(_image_info_list, xinf);
}
void
_xr_image_info_pool_flush(Ximage_Info *xinf, int max_num, int max_mem)
{
if ((xinf->pool_mem <= max_mem) && (evas_list_count(xinf->pool) <= max_num)) return;
while ((xinf->pool_mem > max_mem) || (evas_list_count(xinf->pool) > max_num))
{
Ximage_Image *xim;
if (!xinf->pool) break;
xim = xinf->pool->data;
_xr_image_free(xim);
}
}
Ximage_Image *
_xr_image_new(Ximage_Info *xinf, int w, int h, int depth)
{
Ximage_Image *xim, *xim2;
Evas_List *l;
xim2 = NULL;
for (l = xinf->pool; l; l = l->next)
{
xim = l->data;
if ((xim->w >= w) && (xim->h >= h) && (xim->depth == depth) && (xim->available))
{
if (!xim2) xim2 = xim;
else if ((xim->w * xim->h) < (xim2->w * xim2->h)) xim2 = xim;
}
}
if (xim2)
{
xim2->available = 0;
return xim2;
}
xim = calloc(1, sizeof(Ximage_Image));
if (xim)
{
xim->xinf = xinf;
xim->w = w;
xim->h = h;
xim->depth = depth;
xim->available = 0;
if (xim->xinf->can_do_shm)
{
xim->shm_info = calloc(1, sizeof(XShmSegmentInfo));
if (xim->shm_info)
{
xim->xim = XShmCreateImage(xim->xinf->disp, xim->xinf->vis, xim->depth, ZPixmap, NULL, xim->shm_info, xim->w, xim->h);
if (xim->xim)
{
xim->shm_info->shmid = shmget(IPC_PRIVATE, xim->xim->bytes_per_line * xim->xim->height, IPC_CREAT | 0777);
if (xim->shm_info->shmid >= 0)
{
xim->shm_info->shmaddr = xim->xim->data = shmat(xim->shm_info->shmid, 0, 0);
if (xim->shm_info->shmaddr != NULL)
{
XErrorHandler ph;
XSync(xim->xinf->disp, False);
_x_err = 0;
ph = XSetErrorHandler((XErrorHandler)_tmp_x_err);
XShmAttach(xim->xinf->disp, xim->shm_info);
XSync(xim->xinf->disp, False);
XSetErrorHandler((XErrorHandler)ph);
if (!_x_err) goto xim_ok;
}
shmdt(xim->shm_info->shmaddr);
shmctl(xim->shm_info->shmid, IPC_RMID, 0);
}
XDestroyImage(xim->xim);
}
free(xim->shm_info);
xim->shm_info = NULL;
}
}
xim->xim = XCreateImage(xim->xinf->disp, xim->xinf->vis, xim->depth, ZPixmap, 0, NULL, xim->w, xim->h, 32, 0);
if (!xim->xim)
{
free(xim);
return NULL;
}
xim->xim->data = malloc(xim->xim->bytes_per_line * xim->xim->height);
if (!xim->xim->data)
{
XDestroyImage(xim->xim);
free(xim);
return NULL;
}
}
xim_ok:
_xr_image_info_pool_flush(xinf, 32, (1600 * 1200 * 32 * 2));
xim->line_bytes = xim->xim->bytes_per_line;
xim->data = (void *)(xim->xim->data);
xinf->pool_mem += (xim->w * xim->h * xim->depth);
xinf->pool = evas_list_append(xinf->pool, xim);
return xim;
}
void
_xr_image_free(Ximage_Image *xim)
{
if (xim->shm_info)
{
if (!xim->available) XSync(xim->xinf->disp, False);
XShmDetach(xim->xinf->disp, xim->shm_info);
XDestroyImage(xim->xim);
shmdt(xim->shm_info->shmaddr);
shmctl(xim->shm_info->shmid, IPC_RMID, 0);
free(xim->shm_info);
}
else
{
free(xim->xim->data);
xim->xim->data = NULL;
XDestroyImage(xim->xim);
}
xim->xinf->pool_mem -= (xim->w * xim->h * xim->depth);
xim->xinf->pool = evas_list_remove(xim->xinf->pool, xim);
free(xim);
}
void
_xr_image_put(Ximage_Image *xim, Drawable draw, int x, int y, int w, int h)
{
XGCValues gcv;
GC gc;
gc = XCreateGC(xim->xinf->disp, draw, 0, &gcv);
if (xim->shm_info)
{
XShmPutImage(xim->xinf->disp, draw, gc, xim->xim, 0, 0, x, y, w, h, False);
XSync(xim->xinf->disp, False);
}
else
XPutImage(xim->xinf->disp, draw, gc, xim->xim, 0, 0, x, y, w, h);
xim->available = 1;
XFreeGC(xim->xinf->disp, gc);
}

View File

@ -0,0 +1,421 @@
#include "evas_common.h"
#include "evas_private.h"
#include "evas_engine.h"
#include "evas_engine_api_xrender_x11.h"
#include "Evas_Engine_XRender_X11.h"
Xrender_Surface *
_xr_render_surface_new(Ximage_Info *xinf, int w, int h, XRenderPictFormat *fmt, int alpha)
{
Xrender_Surface *rs;
XRenderPictureAttributes att;
rs = calloc(1, sizeof(Xrender_Surface));
if (!rs) return NULL;
rs->xinf = xinf;
rs->w = w;
rs->h = h;
rs->fmt = fmt;
rs->alpha = alpha;
rs->depth = fmt->depth;
rs->allocated = 1;
rs->draw = XCreatePixmap(xinf->disp, xinf->root, w, h, fmt->depth);
att.dither = 1;
att.component_alpha = 1;
att.repeat = 0;
rs->pic = XRenderCreatePicture(xinf->disp, rs->draw, fmt, CPRepeat | CPDither | CPComponentAlpha, &att);
return rs;
}
Xrender_Surface *
_xr_render_surface_adopt(Ximage_Info *xinf, Drawable draw, int w, int h, int alpha)
{
Xrender_Surface *rs;
XRenderPictFormat *fmt;
XRenderPictureAttributes att;
rs = calloc(1, sizeof(Xrender_Surface));
fmt = XRenderFindVisualFormat(xinf->disp, xinf->vis);
rs->xinf = xinf;
rs->w = w;
rs->h = h;
rs->fmt = fmt;
rs->alpha = alpha;
rs->depth = fmt->depth;
rs->allocated = 0;
rs->draw = draw;
att.dither = 1;
att.component_alpha = 1;
att.repeat = 0;
rs->pic = XRenderCreatePicture(xinf->disp, rs->draw, fmt, CPRepeat | CPDither | CPComponentAlpha, &att);
return rs;
}
void
_xr_render_surface_free(Xrender_Surface *rs)
{
if (rs->allocated) XFreePixmap(rs->xinf->disp, rs->draw);
XRenderFreePicture(rs->xinf->disp, rs->pic);
free(rs);
}
void
_xr_render_surface_repeat_set(Xrender_Surface *rs, int repeat)
{
XRenderPictureAttributes att;
att.repeat = repeat;
XRenderChangePicture(rs->xinf->disp, rs->pic, CPRepeat, &att);
}
void
_xr_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;
int aa;
aa = a +1;
r = (r * aa) >> 8;
g = (g * aa) >> 8;
b = (b * aa) >> 8;
col.red = (r << 8) | r;
col.green = (g << 8) | g;
col.blue = (b << 8) | b;
col.alpha = (a << 8) | a;
XRenderFillRectangle(rs->xinf->disp, PictOpSrc, rs->pic, &col, x, y, w, h);
}
void
_xr_render_surface_argb_pixels_fill(Xrender_Surface *rs, int sw, int sh, void *pixels, int x, int y, int w, int h)
{
Ximage_Image *xim;
unsigned int *p, *sp, *sple, *spe;
unsigned int jump, sjump;
unsigned int a, r, g, b, aa;
xim = _xr_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;
while (sp < spe)
{
sple = sp + w;
while (sp < sple)
{
a = A_VAL(sp);
aa = a + 1;
r = ((R_VAL(sp)) * aa) >> 8;
g = ((G_VAL(sp)) * aa) >> 8;
b = ((B_VAL(sp)) * aa) >> 8;
*p = (a << 24) | (r << 16) | (g << 8) | b;
p++;
sp++;
}
p += jump;
sp += sjump;
}
_xr_image_put(xim, rs->draw, x, y, w, h);
}
void
_xr_render_surface_rgb_pixels_fill(Xrender_Surface *rs, int sw, int sh, void *pixels, int x, int y, int w, int h)
{
Ximage_Image *xim;
unsigned int *p, *sp, *sple, *spe;
unsigned int jump, sjump;
xim = _xr_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;
while (sp < spe)
{
sple = sp + w;
while (sp < sple)
{
*p = 0xff000000 | ((R_VAL(sp)) << 16) | ((G_VAL(sp)) << 8) | (B_VAL(sp));
p++;
sp++;
}
p += jump;
sp += sjump;
}
_xr_image_put(xim, rs->draw, x, y, w, h);
}
void
_xr_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)
{
XTransform xf;
XRectangle rect;
XRenderPictureAttributes att;
Picture mask;
int r, g, b, a, op;
if ((sw <= 0) || (sh <= 0) || (w <= 0) || (h <= 0)) return;
xf.matrix[0][0] = (0x10000 * sw) / w;
xf.matrix[0][1] = 0;
xf.matrix[0][2] = 0;
xf.matrix[1][0] = 0;
xf.matrix[1][1] = (0x10000 * sh) / h;
xf.matrix[1][2] = 0;
xf.matrix[2][0] = 0;
xf.matrix[2][1] = 0;
xf.matrix[2][2] = 0x10000;
op = PictOpSrc;
if (srs->alpha) op = PictOpOver;
mask = None;
if ((dc) && (dc->mul.use))
{
r = (int)(R_VAL(&dc->mul.col));
g = (int)(G_VAL(&dc->mul.col));
b = (int)(B_VAL(&dc->mul.col));
a = (int)(A_VAL(&dc->mul.col));
if (!(r == g == b == a == 0xff))
{
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_render_surface_solid_rectangle_set(srs->xinf->mul, r, g, b, a, 0, 0, 1, 1);
}
op = PictOpOver;
mask = srs->xinf->mul->pic;
}
}
XRenderSetPictureTransform(srs->xinf->disp, srs->pic, &xf);
att.clip_mask = None;
XRenderChangePicture(srs->xinf->disp, srs->pic, CPClipMask, &att);
XRenderChangePicture(srs->xinf->disp, drs->pic, CPClipMask, &att);
rect.x = x; rect.y = y; rect.width = w; rect.height = h;
if ((dc) && (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);
}
if (smooth) XRenderSetPictureFilter(srs->xinf->disp, srs->pic, "bilinear", NULL, 0);
else XRenderSetPictureFilter(srs->xinf->disp, srs->pic, "nearest", NULL, 0);
XRenderSetPictureClipRectangles(srs->xinf->disp, drs->pic, 0, 0, &rect, 1);
XRenderComposite(srs->xinf->disp, op, srs->pic, mask, drs->pic,
((sx * w) + (sw / 2)) / sw,
((sy * h) + (sh / 2)) / sh,
0, 0, x, y, w, h);
}
void
_xr_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)) return;
xf.matrix[0][0] = 1;
xf.matrix[0][1] = 0;
xf.matrix[0][2] = 0;
xf.matrix[1][0] = 0;
xf.matrix[1][1] = 1;
xf.matrix[1][2] = 0;
xf.matrix[2][0] = 0;
xf.matrix[2][1] = 0;
xf.matrix[2][2] = 1;
XRenderSetPictureTransform(srs->xinf->disp, srs->pic, &xf);
att.clip_mask = None;
XRenderChangePicture(srs->xinf->disp, srs->pic, CPClipMask, &att);
XRenderChangePicture(srs->xinf->disp, drs->pic, CPClipMask, &att);
XRenderSetPictureFilter(srs->xinf->disp, srs->pic, "nearest", NULL, 0);
XRenderComposite(srs->xinf->disp, PictOpSrc, srs->pic, None, drs->pic,
sx, sy, 0, 0, x, y, w, h);
}
void
_xr_render_surface_rectangle_draw(Xrender_Surface *rs, RGBA_Draw_Context *dc, int x, int y, int w, int h)
{
XRenderColor col;
XRectangle rect;
XRenderPictureAttributes att;
int r, g, b, a, aa, op;
if ((w <= 0) || (h <= 0)) return;
a = (dc->col.col >> 24) & 0xff;
if (a == 0) return;
r = (dc->col.col >> 16) & 0xff;
g = (dc->col.col >> 8 ) & 0xff;
b = (dc->col.col ) & 0xff;
aa = a +1;
r = (r * aa) >> 8;
g = (g * aa) >> 8;
b = (b * aa) >> 8;
col.red = (r << 8) | r;
col.green = (g << 8) | g;
col.blue = (b << 8) | b;
col.alpha = (a << 8) | a;
op = PictOpSrc;
if (a < 0xff) op = PictOpOver;
att.clip_mask = None;
XRenderChangePicture(rs->xinf->disp, rs->pic, CPClipMask, &att);
if ((dc) && (dc->clip.use))
{
rect.x = dc->clip.x; rect.y = dc->clip.y;
rect.width = dc->clip.w; rect.height = dc->clip.h;
XRenderSetPictureClipRectangles(rs->xinf->disp, rs->pic, 0, 0, &rect, 1);
}
XRenderFillRectangle(rs->xinf->disp, op, rs->pic, &col, x, y, w, h);
}
void
_xr_render_surface_line_draw(Xrender_Surface *rs, RGBA_Draw_Context *dc, int x1, int y1, int x2, int y2)
{
XRectangle rect;
XRenderPictureAttributes att;
int op;
op = PictOpSrc;
att.clip_mask = None;
XRenderChangePicture(rs->xinf->disp, rs->pic, CPClipMask, &att);
if ((dc) && (dc->clip.use))
{
rect.x = dc->clip.x; rect.y = dc->clip.y;
rect.width = dc->clip.w; rect.height = dc->clip.h;
XRenderSetPictureClipRectangles(rs->xinf->disp, rs->pic, 0, 0, &rect, 1);
}
if ((y1 == y2) || (x1 == x2))
{
XRenderColor col;
int r, g, b, a, aa;
a = (dc->col.col >> 24) & 0xff;
if (a == 0) return;
if (a < 0xff) op = PictOpOver;
r = (dc->col.col >> 16) & 0xff;
g = (dc->col.col >> 8 ) & 0xff;
b = (dc->col.col ) & 0xff;
aa = a +1;
r = (r * aa) >> 8;
g = (g * aa) >> 8;
b = (b * aa) >> 8;
col.red = (r << 8) | r;
col.green = (g << 8) | g;
col.blue = (b << 8) | b;
col.alpha = (a << 8) | a;
if (y1 == y2)
XRenderFillRectangle(rs->xinf->disp, op, rs->pic, &col, x1, y1, x2 - x1 + 1, 1);
else
XRenderFillRectangle(rs->xinf->disp, op, rs->pic, &col, x1, y1, 1, y2 - y1 + 1);
}
else
{
int r, g, b, a;
XPointDouble poly[4];
int dx, dy;
double len, ddx, ddy;
dx = x2 - x1;
dy = y2 - y1;
len = sqrt((dx * dx) + (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 = PictOpOver;
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_render_surface_solid_rectangle_set(rs->xinf->mul, r, g, b, a, 0, 0, 1, 1);
}
XRenderCompositeDoublePoly(rs->xinf->disp, op,
rs->xinf->mul->pic, rs->pic,
rs->xinf->fmt8, 0, 0, 0, 0,
poly, 4, EvenOddRule);
}
}
void
_xre_poly_draw(Xrender_Surface *rs, RGBA_Draw_Context *dc, RGBA_Polygon_Point *points)
{
RGBA_Polygon_Point *pt;
int i, num;
XPointDouble *pts;
int r, g, b, a;
XRectangle rect;
XRenderPictureAttributes att;
int op;
op = PictOpSrc;
num = 0;
for (pt = points; pt; pt = (RGBA_Polygon_Point *)(((Evas_Object_List *)pt)->next)) num++;
if (num < 3) return;
a = (dc->col.col >> 24) & 0xff;
if (a == 0) return;
if (a < 0xff) op = PictOpOver;
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_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;
for (pt = points; pt; pt = (RGBA_Polygon_Point *)(((Evas_Object_List *)pt)->next))
{
pts[i].x = pt->x;
pts[i].y = pt->y;
i++;
}
rect.x = 0; rect.y = 0; rect.width = rs->w; rect.height = rs->h;
att.clip_mask = None;
XRenderChangePicture(rs->xinf->disp, rs->pic, CPClipMask, &att);
if ((dc) && (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(rs->xinf->disp, rs->pic, 0, 0, &rect, 1);
XRenderCompositeDoublePoly(rs->xinf->disp, op,
rs->xinf->mul->pic, rs->pic,
rs->xinf->fmt8, 0, 0, 0, 0,
pts, num, Complex);
free(pts);
}

View File

@ -10,6 +10,7 @@ evas_engine_api_buffer.h \
evas_engine_api_software_qtopia.h \
evas_engine_api_gl_x11.h \
evas_engine_api_cairo_x11.h \
evas_engine_api_xrender_x11.h \
evas_gl_common.h \
evas_cairo_common.h \
evas_mmx.h \

View File

@ -0,0 +1,7 @@
#ifndef EVAS_ENGINE_XRENDER_X11_H
#define EVAS_ENGINE_XRENDER_X11_H
#include <X11/Xlib.h>
extern Evas_Func evas_engine_xrender_x11_func;
#endif

View File

@ -19,33 +19,10 @@
#define RENDER_METHOD_GL_X11 0x00000007
#define RENDER_METHOD_CAIRO_X11 0x00000008
#define RENDER_METHOD_SOFTWARE_XCB 0x00000009
#define RENDER_METHOD_XRENDER_X11 0x0000000a
#define RENDER_METHOD_INVALID 0x00000000
typedef enum _Evas_Format_Type
{
EVAS_FORMAT_NONE = 0,
EVAS_FORMAT_FONT,
EVAS_FORMAT_SIZE,
EVAS_FORMAT_COLOR,
EVAS_FORMAT_COLOR2,
EVAS_FORMAT_COLOR3,
EVAS_FORMAT_ALIGN,
EVAS_FORMAT_STYLE,
EVAS_FORMAT_UNDERLINE,
EVAS_FORMAT_NEWLINE,
EVAS_FORMAT_TAB,
EVAS_FORMAT_L2R,
EVAS_FORMAT_R2L,
EVAS_FORMAT_ANCHOR
} Evas_Format_Type;
typedef enum _Evas_Format_Direction
{
EVAS_FORMAT_DIRECTION_VERTICAL = 0,
EVAS_FORMAT_DIRECTION_HORIZONTAL = 1
} Evas_Format_Direction;
typedef struct _Evas_Layer Evas_Layer;
typedef struct _Evas_Font_Dir Evas_Font_Dir;
typedef struct _Evas_Font Evas_Font;