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:
parent
6dd7a6b47d
commit
f4a8513aa4
|
@ -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 |
|
@ -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
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -12,4 +12,5 @@ directfb \
|
|||
gl_common \
|
||||
gl_x11 \
|
||||
cairo_common \
|
||||
cairo_x11
|
||||
cairo_x11 \
|
||||
xrender_x11
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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 \
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue