gdk: add i386 MMX pixel compositing
This commit is contained in:
parent
9253e9b278
commit
ed405c407b
6 changed files with 189 additions and 4 deletions
16
configure.ac
16
configure.ac
|
|
@ -199,6 +199,22 @@ esac
|
|||
dnl Initialize libtool
|
||||
AC_PROG_CC
|
||||
|
||||
GDK_PIXELOPS_X86_MMX_CFLAGS=
|
||||
|
||||
case "$host_cpu:$gdk_pixelops_arch" in
|
||||
i?86:x86)
|
||||
GDK_PIXELOPS_X86_MMX_CFLAGS="-mmmx -mno-sse -mno-sse2 -mno-3dnow"
|
||||
AC_DEFINE([HAVE_GDK_PIXELOPS_X86_MMX], [1],
|
||||
[Define if the GDK 32-bit x86 MMX pixel operations backend is built])
|
||||
AC_DEFINE([HAVE_GDK_PIXELOPS_INIT], [1],
|
||||
[Define if GDK pixel operations require runtime dispatch initialization])
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_SUBST(GDK_PIXELOPS_X86_MMX_CFLAGS)
|
||||
AM_CONDITIONAL(GDK_PIXELOPS_X86_MMX,
|
||||
test -n "$GDK_PIXELOPS_X86_MMX_CFLAGS")
|
||||
|
||||
dnl
|
||||
dnl Check for a working C++ compiler, but do not bail out, if none is found.
|
||||
dnl We use this for an automated test for C++ header correctness.
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ DIST_SUBDIRS = win32 x11 quartz directfb tests
|
|||
|
||||
CLEANFILES =
|
||||
|
||||
noinst_LTLIBRARIES =
|
||||
|
||||
EXTRA_DIST += \
|
||||
keynames.txt \
|
||||
keyname-table.h \
|
||||
|
|
@ -120,11 +122,22 @@ gdk_private_headers = \
|
|||
gdkregion-generic.h
|
||||
|
||||
gdk_pixelops_arch_sources =
|
||||
gdk_pixelops_arch_libs =
|
||||
|
||||
if GDK_PIXELOPS_X86
|
||||
gdk_pixelops_arch_sources += gdkpixelops-x86.c
|
||||
endif
|
||||
|
||||
if GDK_PIXELOPS_X86_MMX
|
||||
noinst_LTLIBRARIES += libgdk-pixelops-x86-mmx.la
|
||||
gdk_pixelops_arch_libs += libgdk-pixelops-x86-mmx.la
|
||||
|
||||
libgdk_pixelops_x86_mmx_la_SOURCES = gdkpixelops-x86-mmx.c
|
||||
libgdk_pixelops_x86_mmx_la_CFLAGS = \
|
||||
$(AM_CFLAGS) \
|
||||
$(GDK_PIXELOPS_X86_MMX_CFLAGS)
|
||||
endif
|
||||
|
||||
gdk_pixelops_private_sources = \
|
||||
gdkpixelops-generic.c \
|
||||
$(gdk_pixelops_arch_sources)
|
||||
|
|
@ -188,19 +201,19 @@ common_sources = \
|
|||
gdkmarshalers.h
|
||||
|
||||
libgdk_directfb_2_0_la_SOURCES = $(common_sources)
|
||||
libgdk_directfb_2_0_la_LIBADD = directfb/libgdk-directfb.la $(GDK_DEP_LIBS)
|
||||
libgdk_directfb_2_0_la_LIBADD = directfb/libgdk-directfb.la $(gdk_pixelops_arch_libs) $(GDK_DEP_LIBS)
|
||||
libgdk_directfb_2_0_la_LDFLAGS = $(LDADD)
|
||||
|
||||
libgdk_x11_2_0_la_SOURCES = $(common_sources)
|
||||
libgdk_x11_2_0_la_LIBADD = x11/libgdk-x11.la $(GDK_DEP_LIBS)
|
||||
libgdk_x11_2_0_la_LIBADD = x11/libgdk-x11.la $(gdk_pixelops_arch_libs) $(GDK_DEP_LIBS)
|
||||
libgdk_x11_2_0_la_LDFLAGS = $(LDADD)
|
||||
|
||||
libgdk_quartz_2_0_la_SOURCES = $(common_sources) gdkkeynames.c
|
||||
libgdk_quartz_2_0_la_LIBADD = quartz/libgdk-quartz.la $(GDK_DEP_LIBS)
|
||||
libgdk_quartz_2_0_la_LIBADD = quartz/libgdk-quartz.la $(gdk_pixelops_arch_libs) $(GDK_DEP_LIBS)
|
||||
libgdk_quartz_2_0_la_LDFLAGS = $(LDADD)
|
||||
|
||||
libgdk_win32_2_0_la_SOURCES = $(common_sources) gdkkeynames.c
|
||||
libgdk_win32_2_0_la_LIBADD = win32/libgdk-win32.la $(GDK_DEP_LIBS)
|
||||
libgdk_win32_2_0_la_LIBADD = win32/libgdk-win32.la $(gdk_pixelops_arch_libs) $(GDK_DEP_LIBS)
|
||||
libgdk_win32_2_0_la_DEPENDENCIES = win32/libgdk-win32.la win32/rc/gdk-win32-res.o gdk.def
|
||||
libgdk_win32_2_0_la_LDFLAGS = -Wl,win32/rc/gdk-win32-res.o -export-symbols $(srcdir)/gdk.def $(LDADD)
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include "gdk.h"
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkintl.h"
|
||||
#include "gdkpixelops.h"
|
||||
|
||||
#ifndef HAVE_XCONVERTCASE
|
||||
#include "gdkkeysyms.h"
|
||||
|
|
@ -189,6 +190,8 @@ gdk_pre_parse_libgtk_only (void)
|
|||
{
|
||||
gdk_initialized = TRUE;
|
||||
|
||||
_gdk_pixel_ops_init ();
|
||||
|
||||
/* We set the fallback program class here, rather than lazily in
|
||||
* gdk_get_program_class, since we don't want -name to override it.
|
||||
*/
|
||||
|
|
|
|||
116
gdk/gdkpixelops-x86-mmx.c
Normal file
116
gdk/gdkpixelops-x86-mmx.c
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
/* GDK - The GIMP Drawing Kit
|
||||
*
|
||||
* MMX pixel operations for 32-bit x86.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <mmintrin.h>
|
||||
|
||||
#include "gdkpixelops.h"
|
||||
|
||||
#ifndef __i386__
|
||||
#error "gdkpixelops-x86-mmx.c requires a 32-bit x86 target"
|
||||
#endif
|
||||
|
||||
G_GNUC_INTERNAL void
|
||||
_gdk_pixel_ops_composite_0888_generic (guchar *src_buf,
|
||||
gint src_rowstride,
|
||||
guchar *dest_buf,
|
||||
gint dest_rowstride,
|
||||
GdkByteOrder dest_byte_order,
|
||||
gint width,
|
||||
gint height);
|
||||
|
||||
G_GNUC_INTERNAL void
|
||||
_gdk_pixel_ops_composite_0888_mmx (guchar *src_buf,
|
||||
gint src_rowstride,
|
||||
guchar *dest_buf,
|
||||
gint dest_rowstride,
|
||||
GdkByteOrder dest_byte_order,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
if (dest_byte_order != GDK_LSB_FIRST)
|
||||
{
|
||||
_gdk_pixel_ops_composite_0888_generic (src_buf,
|
||||
src_rowstride,
|
||||
dest_buf,
|
||||
dest_rowstride,
|
||||
dest_byte_order,
|
||||
width,
|
||||
height);
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
const __m64 zero = _mm_setzero_si64 ();
|
||||
const __m64 ones = _mm_cmpeq_pi16 (zero, zero);
|
||||
const __m64 ff = _mm_srli_pi16 (ones, 8);
|
||||
const __m64 bias = _mm_set1_pi16 (0x80);
|
||||
const __m64 rgb_mask = _mm_srli_si64 (ones, 16);
|
||||
guchar *src = src_buf;
|
||||
guchar *dest = dest_buf;
|
||||
|
||||
while (height--)
|
||||
{
|
||||
gint twidth = width;
|
||||
guchar *p = src;
|
||||
guchar *q = dest;
|
||||
|
||||
while (twidth--)
|
||||
{
|
||||
guint32 sp;
|
||||
guint32 dp;
|
||||
guint32 result;
|
||||
__m64 s;
|
||||
__m64 d;
|
||||
__m64 a;
|
||||
__m64 ia;
|
||||
__m64 t;
|
||||
__m64 packed;
|
||||
|
||||
memcpy (&sp, p, sizeof sp);
|
||||
memcpy (&dp, q, sizeof dp);
|
||||
|
||||
sp = ((sp & 0xff00ff00U) |
|
||||
((sp & 0x000000ffU) << 16) |
|
||||
((sp & 0x00ff0000U) >> 16));
|
||||
|
||||
s = _mm_cvtsi32_si64 ((int) sp);
|
||||
d = _mm_cvtsi32_si64 ((int) dp);
|
||||
|
||||
s = _mm_unpacklo_pi8 (s, zero);
|
||||
d = _mm_unpacklo_pi8 (d, zero);
|
||||
|
||||
a = _mm_srli_si64 (s, 48);
|
||||
a = _mm_unpacklo_pi16 (a, a);
|
||||
a = _mm_unpacklo_pi32 (a, a);
|
||||
a = _mm_and_si64 (a, rgb_mask);
|
||||
|
||||
ia = _mm_sub_pi16 (ff, a);
|
||||
|
||||
t = _mm_add_pi16 (_mm_mullo_pi16 (s, a),
|
||||
_mm_mullo_pi16 (d, ia));
|
||||
|
||||
t = _mm_add_pi16 (t, bias);
|
||||
t = _mm_add_pi16 (t, _mm_srli_pi16 (t, 8));
|
||||
t = _mm_srli_pi16 (t, 8);
|
||||
|
||||
packed = _mm_packs_pu16 (t, t);
|
||||
result = (guint32) _mm_cvtsi64_si32 (packed);
|
||||
|
||||
memcpy (q, &result, sizeof result);
|
||||
|
||||
p += 4;
|
||||
q += 4;
|
||||
}
|
||||
|
||||
src += src_rowstride;
|
||||
dest += dest_rowstride;
|
||||
}
|
||||
|
||||
_mm_empty ();
|
||||
}
|
||||
}
|
||||
|
|
@ -7,7 +7,38 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkpixelops.h"
|
||||
|
||||
#if !defined(__i386__) && !defined(__x86_64__) && \
|
||||
!defined(_M_IX86) && !defined(_M_X64)
|
||||
#error "gdkpixelops-x86.c must only be built for an x86 target"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GDK_PIXELOPS_X86_MMX
|
||||
|
||||
#include <cpuid.h>
|
||||
|
||||
G_GNUC_INTERNAL void
|
||||
_gdk_pixel_ops_composite_0888_mmx (guchar *src_buf,
|
||||
gint src_rowstride,
|
||||
guchar *dest_buf,
|
||||
gint dest_rowstride,
|
||||
GdkByteOrder dest_byte_order,
|
||||
gint width,
|
||||
gint height);
|
||||
|
||||
G_GNUC_INTERNAL void
|
||||
_gdk_pixel_ops_init (void)
|
||||
{
|
||||
unsigned int eax;
|
||||
unsigned int ebx;
|
||||
unsigned int ecx;
|
||||
unsigned int edx;
|
||||
|
||||
if (__get_cpuid (1, &eax, &ebx, &ecx, &edx) &&
|
||||
(edx & bit_MMX) != 0)
|
||||
_gdk_pixel_ops.composite_0888 =
|
||||
_gdk_pixel_ops_composite_0888_mmx;
|
||||
}
|
||||
|
||||
#endif /* HAVE_GDK_PIXELOPS_X86_MMX */
|
||||
|
|
|
|||
|
|
@ -26,6 +26,12 @@ typedef struct
|
|||
|
||||
extern G_GNUC_INTERNAL GdkPixelOps _gdk_pixel_ops;
|
||||
|
||||
#ifdef HAVE_GDK_PIXELOPS_INIT
|
||||
G_GNUC_INTERNAL void _gdk_pixel_ops_init (void);
|
||||
#else
|
||||
#define _gdk_pixel_ops_init() ((void) 0)
|
||||
#endif
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_PIXEL_OPS_H__ */
|
||||
|
|
|
|||
Loading…
Reference in a new issue