summaryrefslogtreecommitdiff
path: root/src/sna/fb
diff options
context:
space:
mode:
Diffstat (limited to 'src/sna/fb')
-rw-r--r--src/sna/fb/Makefile.am38
-rw-r--r--src/sna/fb/Makefile.in755
-rw-r--r--src/sna/fb/README1
-rw-r--r--src/sna/fb/fb.h566
-rw-r--r--src/sna/fb/fbarc.c122
-rw-r--r--src/sna/fb/fbarcbits.h204
-rw-r--r--src/sna/fb/fbbitmap.c159
-rw-r--r--src/sna/fb/fbblt.c321
-rw-r--r--src/sna/fb/fbbltone.c413
-rw-r--r--src/sna/fb/fbclip.c92
-rw-r--r--src/sna/fb/fbclip.h85
-rw-r--r--src/sna/fb/fbcopy.c225
-rw-r--r--src/sna/fb/fbfill.c221
-rw-r--r--src/sna/fb/fbgc.c198
-rw-r--r--src/sna/fb/fbglyph.c277
-rw-r--r--src/sna/fb/fbglyphbits.h140
-rw-r--r--src/sna/fb/fbimage.c254
-rw-r--r--src/sna/fb/fbline.c179
-rw-r--r--src/sna/fb/fblinebits.h284
-rw-r--r--src/sna/fb/fbpict.c354
-rw-r--r--src/sna/fb/fbpict.h45
-rw-r--r--src/sna/fb/fbpoint.c134
-rw-r--r--src/sna/fb/fbpointbits.h148
-rw-r--r--src/sna/fb/fbpush.c177
-rw-r--r--src/sna/fb/fbrop.h111
-rw-r--r--src/sna/fb/fbseg.c563
-rw-r--r--src/sna/fb/fbsegbits.h212
-rw-r--r--src/sna/fb/fbspan.c131
-rw-r--r--src/sna/fb/fbstipple.c223
-rw-r--r--src/sna/fb/fbtile.c151
-rw-r--r--src/sna/fb/fbutil.c126
-rw-r--r--src/sna/fb/sfb.h40
32 files changed, 6949 insertions, 0 deletions
diff --git a/src/sna/fb/Makefile.am b/src/sna/fb/Makefile.am
new file mode 100644
index 000000000..72d9bbf5b
--- /dev/null
+++ b/src/sna/fb/Makefile.am
@@ -0,0 +1,38 @@
+noinst_LTLIBRARIES = libfb.la
+
+libfb_la_CFLAGS = @CWARNFLAGS@ @XORG_CFLAGS@
+libfb_la_LIBADD = $(PIXMAN_LIBS)
+
+libfb_la_SOURCES = \
+ fb.h \
+ sfb.h \
+ fbarc.c \
+ fbarcbits.h \
+ fbbitmap.c \
+ fbblt.c \
+ fbbltone.c \
+ fbclip.c \
+ fbclip.h \
+ fbcopy.c \
+ fbfill.c \
+ fbgc.c \
+ fbglyph.c \
+ fbglyphbits.h \
+ fbimage.c \
+ fbline.c \
+ fblinebits.h \
+ fbpict.c \
+ fbpict.h \
+ fbpoint.c \
+ fbpointbits.h \
+ fbpush.c \
+ fbrop.h \
+ fbseg.c \
+ fbsegbits.h \
+ fbspan.c \
+ fbstipple.c \
+ fbtile.c \
+ fbutil.c \
+ $(NULL)
+
+EXTRA_DIST = README
diff --git a/src/sna/fb/Makefile.in b/src/sna/fb/Makefile.in
new file mode 100644
index 000000000..d9ca271f0
--- /dev/null
+++ b/src/sna/fb/Makefile.in
@@ -0,0 +1,755 @@
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/sna/fb
+DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libfb_la_DEPENDENCIES =
+am_libfb_la_OBJECTS = libfb_la-fbarc.lo libfb_la-fbbitmap.lo \
+ libfb_la-fbblt.lo libfb_la-fbbltone.lo libfb_la-fbclip.lo \
+ libfb_la-fbcopy.lo libfb_la-fbfill.lo libfb_la-fbgc.lo \
+ libfb_la-fbglyph.lo libfb_la-fbimage.lo libfb_la-fbline.lo \
+ libfb_la-fbpict.lo libfb_la-fbpoint.lo libfb_la-fbpush.lo \
+ libfb_la-fbseg.lo libfb_la-fbspan.lo libfb_la-fbstipple.lo \
+ libfb_la-fbtile.lo libfb_la-fbutil.lo
+libfb_la_OBJECTS = $(am_libfb_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+libfb_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libfb_la_CFLAGS) \
+ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+SOURCES = $(libfb_la_SOURCES)
+DIST_SOURCES = $(libfb_la_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ADMIN_MAN_DIR = @ADMIN_MAN_DIR@
+ADMIN_MAN_SUFFIX = @ADMIN_MAN_SUFFIX@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+APP_MAN_DIR = @APP_MAN_DIR@
+APP_MAN_SUFFIX = @APP_MAN_SUFFIX@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BASE_CFLAGS = @BASE_CFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CHANGELOG_CMD = @CHANGELOG_CMD@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CWARNFLAGS = @CWARNFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DRI2_CFLAGS = @DRI2_CFLAGS@
+DRI2_LIBS = @DRI2_LIBS@
+DRIVER_MAN_DIR = @DRIVER_MAN_DIR@
+DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@
+DRIVER_NAME = @DRIVER_NAME@
+DRI_CFLAGS = @DRI_CFLAGS@
+DRI_LIBS = @DRI_LIBS@
+DRMINTEL_CFLAGS = @DRMINTEL_CFLAGS@
+DRMINTEL_LIBS = @DRMINTEL_LIBS@
+DRM_CFLAGS = @DRM_CFLAGS@
+DRM_LIBS = @DRM_LIBS@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+FILE_MAN_DIR = @FILE_MAN_DIR@
+FILE_MAN_SUFFIX = @FILE_MAN_SUFFIX@
+GEN4ASM_CFLAGS = @GEN4ASM_CFLAGS@
+GEN4ASM_LIBS = @GEN4ASM_LIBS@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_CMD = @INSTALL_CMD@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTEL_GEN4ASM = @INTEL_GEN4ASM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBGLAMOR_CFLAGS = @LIBGLAMOR_CFLAGS@
+LIBGLAMOR_EGL_CFLAGS = @LIBGLAMOR_EGL_CFLAGS@
+LIBGLAMOR_EGL_LIBS = @LIBGLAMOR_EGL_LIBS@
+LIBGLAMOR_LIBS = @LIBGLAMOR_LIBS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIB_MAN_DIR = @LIB_MAN_DIR@
+LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MAN_SUBSTS = @MAN_SUBSTS@
+MISC_MAN_DIR = @MISC_MAN_DIR@
+MISC_MAN_SUFFIX = @MISC_MAN_SUFFIX@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PCIACCESS_CFLAGS = @PCIACCESS_CFLAGS@
+PCIACCESS_LIBS = @PCIACCESS_LIBS@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRICT_CFLAGS = @STRICT_CFLAGS@
+STRIP = @STRIP@
+UDEV_CFLAGS = @UDEV_CFLAGS@
+UDEV_LIBS = @UDEV_LIBS@
+VALGRIND_CFLAGS = @VALGRIND_CFLAGS@
+VALGRIND_LIBS = @VALGRIND_LIBS@
+VERSION = @VERSION@
+X11_CFLAGS = @X11_CFLAGS@
+X11_LIBS = @X11_LIBS@
+XORG_CFLAGS = @XORG_CFLAGS@
+XORG_LIBS = @XORG_LIBS@
+XORG_MAN_PAGE = @XORG_MAN_PAGE@
+XVMCLIB_CFLAGS = @XVMCLIB_CFLAGS@
+XVMCLIB_LIBS = @XVMCLIB_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+moduledir = @moduledir@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+noinst_LTLIBRARIES = libfb.la
+libfb_la_CFLAGS = @CWARNFLAGS@ @XORG_CFLAGS@
+libfb_la_LIBADD = $(PIXMAN_LIBS)
+libfb_la_SOURCES = \
+ fb.h \
+ sfb.h \
+ fbarc.c \
+ fbarcbits.h \
+ fbbitmap.c \
+ fbblt.c \
+ fbbltone.c \
+ fbclip.c \
+ fbclip.h \
+ fbcopy.c \
+ fbfill.c \
+ fbgc.c \
+ fbglyph.c \
+ fbglyphbits.h \
+ fbimage.c \
+ fbline.c \
+ fblinebits.h \
+ fbpict.c \
+ fbpict.h \
+ fbpoint.c \
+ fbpointbits.h \
+ fbpush.c \
+ fbrop.h \
+ fbseg.c \
+ fbsegbits.h \
+ fbspan.c \
+ fbstipple.c \
+ fbtile.c \
+ fbutil.c \
+ $(NULL)
+
+EXTRA_DIST = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/sna/fb/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign src/sna/fb/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libfb.la: $(libfb_la_OBJECTS) $(libfb_la_DEPENDENCIES) $(EXTRA_libfb_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libfb_la_LINK) $(libfb_la_OBJECTS) $(libfb_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbarc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbbitmap.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbblt.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbbltone.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbclip.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbcopy.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbfill.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbgc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbglyph.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbimage.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbline.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbpict.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbpoint.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbpush.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbseg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbspan.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbstipple.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbtile.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfb_la-fbutil.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+libfb_la-fbarc.lo: fbarc.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbarc.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbarc.Tpo -c -o libfb_la-fbarc.lo `test -f 'fbarc.c' || echo '$(srcdir)/'`fbarc.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbarc.Tpo $(DEPDIR)/libfb_la-fbarc.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbarc.c' object='libfb_la-fbarc.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbarc.lo `test -f 'fbarc.c' || echo '$(srcdir)/'`fbarc.c
+
+libfb_la-fbbitmap.lo: fbbitmap.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbbitmap.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbbitmap.Tpo -c -o libfb_la-fbbitmap.lo `test -f 'fbbitmap.c' || echo '$(srcdir)/'`fbbitmap.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbbitmap.Tpo $(DEPDIR)/libfb_la-fbbitmap.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbbitmap.c' object='libfb_la-fbbitmap.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbbitmap.lo `test -f 'fbbitmap.c' || echo '$(srcdir)/'`fbbitmap.c
+
+libfb_la-fbblt.lo: fbblt.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbblt.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbblt.Tpo -c -o libfb_la-fbblt.lo `test -f 'fbblt.c' || echo '$(srcdir)/'`fbblt.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbblt.Tpo $(DEPDIR)/libfb_la-fbblt.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbblt.c' object='libfb_la-fbblt.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbblt.lo `test -f 'fbblt.c' || echo '$(srcdir)/'`fbblt.c
+
+libfb_la-fbbltone.lo: fbbltone.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbbltone.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbbltone.Tpo -c -o libfb_la-fbbltone.lo `test -f 'fbbltone.c' || echo '$(srcdir)/'`fbbltone.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbbltone.Tpo $(DEPDIR)/libfb_la-fbbltone.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbbltone.c' object='libfb_la-fbbltone.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbbltone.lo `test -f 'fbbltone.c' || echo '$(srcdir)/'`fbbltone.c
+
+libfb_la-fbclip.lo: fbclip.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbclip.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbclip.Tpo -c -o libfb_la-fbclip.lo `test -f 'fbclip.c' || echo '$(srcdir)/'`fbclip.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbclip.Tpo $(DEPDIR)/libfb_la-fbclip.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbclip.c' object='libfb_la-fbclip.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbclip.lo `test -f 'fbclip.c' || echo '$(srcdir)/'`fbclip.c
+
+libfb_la-fbcopy.lo: fbcopy.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbcopy.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbcopy.Tpo -c -o libfb_la-fbcopy.lo `test -f 'fbcopy.c' || echo '$(srcdir)/'`fbcopy.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbcopy.Tpo $(DEPDIR)/libfb_la-fbcopy.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbcopy.c' object='libfb_la-fbcopy.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbcopy.lo `test -f 'fbcopy.c' || echo '$(srcdir)/'`fbcopy.c
+
+libfb_la-fbfill.lo: fbfill.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbfill.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbfill.Tpo -c -o libfb_la-fbfill.lo `test -f 'fbfill.c' || echo '$(srcdir)/'`fbfill.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbfill.Tpo $(DEPDIR)/libfb_la-fbfill.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbfill.c' object='libfb_la-fbfill.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbfill.lo `test -f 'fbfill.c' || echo '$(srcdir)/'`fbfill.c
+
+libfb_la-fbgc.lo: fbgc.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbgc.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbgc.Tpo -c -o libfb_la-fbgc.lo `test -f 'fbgc.c' || echo '$(srcdir)/'`fbgc.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbgc.Tpo $(DEPDIR)/libfb_la-fbgc.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbgc.c' object='libfb_la-fbgc.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbgc.lo `test -f 'fbgc.c' || echo '$(srcdir)/'`fbgc.c
+
+libfb_la-fbglyph.lo: fbglyph.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbglyph.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbglyph.Tpo -c -o libfb_la-fbglyph.lo `test -f 'fbglyph.c' || echo '$(srcdir)/'`fbglyph.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbglyph.Tpo $(DEPDIR)/libfb_la-fbglyph.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbglyph.c' object='libfb_la-fbglyph.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbglyph.lo `test -f 'fbglyph.c' || echo '$(srcdir)/'`fbglyph.c
+
+libfb_la-fbimage.lo: fbimage.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbimage.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbimage.Tpo -c -o libfb_la-fbimage.lo `test -f 'fbimage.c' || echo '$(srcdir)/'`fbimage.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbimage.Tpo $(DEPDIR)/libfb_la-fbimage.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbimage.c' object='libfb_la-fbimage.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbimage.lo `test -f 'fbimage.c' || echo '$(srcdir)/'`fbimage.c
+
+libfb_la-fbline.lo: fbline.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbline.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbline.Tpo -c -o libfb_la-fbline.lo `test -f 'fbline.c' || echo '$(srcdir)/'`fbline.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbline.Tpo $(DEPDIR)/libfb_la-fbline.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbline.c' object='libfb_la-fbline.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbline.lo `test -f 'fbline.c' || echo '$(srcdir)/'`fbline.c
+
+libfb_la-fbpict.lo: fbpict.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbpict.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbpict.Tpo -c -o libfb_la-fbpict.lo `test -f 'fbpict.c' || echo '$(srcdir)/'`fbpict.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbpict.Tpo $(DEPDIR)/libfb_la-fbpict.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbpict.c' object='libfb_la-fbpict.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbpict.lo `test -f 'fbpict.c' || echo '$(srcdir)/'`fbpict.c
+
+libfb_la-fbpoint.lo: fbpoint.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbpoint.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbpoint.Tpo -c -o libfb_la-fbpoint.lo `test -f 'fbpoint.c' || echo '$(srcdir)/'`fbpoint.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbpoint.Tpo $(DEPDIR)/libfb_la-fbpoint.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbpoint.c' object='libfb_la-fbpoint.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbpoint.lo `test -f 'fbpoint.c' || echo '$(srcdir)/'`fbpoint.c
+
+libfb_la-fbpush.lo: fbpush.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbpush.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbpush.Tpo -c -o libfb_la-fbpush.lo `test -f 'fbpush.c' || echo '$(srcdir)/'`fbpush.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbpush.Tpo $(DEPDIR)/libfb_la-fbpush.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbpush.c' object='libfb_la-fbpush.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbpush.lo `test -f 'fbpush.c' || echo '$(srcdir)/'`fbpush.c
+
+libfb_la-fbseg.lo: fbseg.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbseg.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbseg.Tpo -c -o libfb_la-fbseg.lo `test -f 'fbseg.c' || echo '$(srcdir)/'`fbseg.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbseg.Tpo $(DEPDIR)/libfb_la-fbseg.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbseg.c' object='libfb_la-fbseg.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbseg.lo `test -f 'fbseg.c' || echo '$(srcdir)/'`fbseg.c
+
+libfb_la-fbspan.lo: fbspan.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbspan.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbspan.Tpo -c -o libfb_la-fbspan.lo `test -f 'fbspan.c' || echo '$(srcdir)/'`fbspan.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbspan.Tpo $(DEPDIR)/libfb_la-fbspan.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbspan.c' object='libfb_la-fbspan.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbspan.lo `test -f 'fbspan.c' || echo '$(srcdir)/'`fbspan.c
+
+libfb_la-fbstipple.lo: fbstipple.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbstipple.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbstipple.Tpo -c -o libfb_la-fbstipple.lo `test -f 'fbstipple.c' || echo '$(srcdir)/'`fbstipple.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbstipple.Tpo $(DEPDIR)/libfb_la-fbstipple.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbstipple.c' object='libfb_la-fbstipple.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbstipple.lo `test -f 'fbstipple.c' || echo '$(srcdir)/'`fbstipple.c
+
+libfb_la-fbtile.lo: fbtile.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbtile.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbtile.Tpo -c -o libfb_la-fbtile.lo `test -f 'fbtile.c' || echo '$(srcdir)/'`fbtile.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbtile.Tpo $(DEPDIR)/libfb_la-fbtile.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbtile.c' object='libfb_la-fbtile.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbtile.lo `test -f 'fbtile.c' || echo '$(srcdir)/'`fbtile.c
+
+libfb_la-fbutil.lo: fbutil.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -MT libfb_la-fbutil.lo -MD -MP -MF $(DEPDIR)/libfb_la-fbutil.Tpo -c -o libfb_la-fbutil.lo `test -f 'fbutil.c' || echo '$(srcdir)/'`fbutil.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libfb_la-fbutil.Tpo $(DEPDIR)/libfb_la-fbutil.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fbutil.c' object='libfb_la-fbutil.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfb_la_CFLAGS) $(CFLAGS) -c -o libfb_la-fbutil.lo `test -f 'fbutil.c' || echo '$(srcdir)/'`fbutil.c
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/sna/fb/README b/src/sna/fb/README
new file mode 100644
index 000000000..154212409
--- /dev/null
+++ b/src/sna/fb/README
@@ -0,0 +1 @@
+Note this code is intended to live inside pixman in the long term.
diff --git a/src/sna/fb/fb.h b/src/sna/fb/fb.h
new file mode 100644
index 000000000..e58e03967
--- /dev/null
+++ b/src/sna/fb/fb.h
@@ -0,0 +1,566 @@
+/*
+ * Copyright © 1998 Keith Packard
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef FB_H
+#define FB_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <xorg-server.h>
+#include <servermd.h>
+#include <gcstruct.h>
+#include <colormap.h>
+#include <windowstr.h>
+
+#include <stdbool.h>
+#include <pixman.h>
+
+#if HAS_DEBUG_FULL
+#define DBG(x) ErrorF x
+#else
+#define DBG(x)
+#endif
+
+#include "sfb.h"
+
+#define WRITE(ptr, val) (*(ptr) = (val))
+#define READ(ptr) (*(ptr))
+
+/*
+ * This single define controls the basic size of data manipulated
+ * by this software; it must be log2(sizeof (FbBits) * 8)
+ */
+#define FB_SHIFT LOG2_BITMAP_PAD
+
+#define FB_UNIT (1 << FB_SHIFT)
+#define FB_HALFUNIT (1 << (FB_SHIFT-1))
+#define FB_MASK (FB_UNIT - 1)
+#define FB_ALLONES ((FbBits) -1)
+
+#if IMAGE_BYTE_ORDER != LSBFirst
+#error "IMAGE_BYTE_ORDER must be LSBFirst"
+#endif
+
+#if GLYPHPADBYTES != 4
+#error "GLYPHPADBYTES must be 4"
+#endif
+
+#if FB_SHIFT != 5
+#error "FB_SHIFT ala LOG2_BITMAP_PAD must be 5"
+#endif
+
+#define FB_STIP_SHIFT LOG2_BITMAP_PAD
+#define FB_STIP_UNIT (1 << FB_STIP_SHIFT)
+#define FB_STIP_MASK (FB_STIP_UNIT - 1)
+#define FB_STIP_ALLONES ((FbStip) -1)
+#define FbFullMask(n) ((n) == FB_UNIT ? FB_ALLONES : ((((FbBits) 1) << n) - 1))
+
+typedef uint32_t FbBits;
+typedef FbBits FbStip;
+typedef int FbStride;
+
+#include "fbrop.h"
+
+#define FbScrLeft(x,n) ((x) >> (n))
+#define FbScrRight(x,n) ((x) << (n))
+/* #define FbLeftBits(x,n) ((x) & ((((FbBits) 1) << (n)) - 1)) */
+#define FbLeftStipBits(x,n) ((x) & ((((FbStip) 1) << (n)) - 1))
+#define FbStipMoveLsb(x,s,n) (FbStipRight (x,(s)-(n)))
+#define FbPatternOffsetBits 0
+
+#define FbStipLeft(x,n) FbScrLeft(x,n)
+#define FbStipRight(x,n) FbScrRight(x,n)
+
+#define FbRotLeft(x,n) FbScrLeft(x,n) | (n ? FbScrRight(x,FB_UNIT-n) : 0)
+#define FbRotRight(x,n) FbScrRight(x,n) | (n ? FbScrLeft(x,FB_UNIT-n) : 0)
+
+#define FbRotStipLeft(x,n) FbStipLeft(x,n) | (n ? FbStipRight(x,FB_STIP_UNIT-n) : 0)
+#define FbRotStipRight(x,n) FbStipRight(x,n) | (n ? FbStipLeft(x,FB_STIP_UNIT-n) : 0)
+
+#define FbLeftMask(x) ( ((x) & FB_MASK) ? \
+ FbScrRight(FB_ALLONES,(x) & FB_MASK) : 0)
+#define FbRightMask(x) ( ((FB_UNIT - (x)) & FB_MASK) ? \
+ FbScrLeft(FB_ALLONES,(FB_UNIT - (x)) & FB_MASK) : 0)
+
+#define FbLeftStipMask(x) ( ((x) & FB_STIP_MASK) ? \
+ FbStipRight(FB_STIP_ALLONES,(x) & FB_STIP_MASK) : 0)
+#define FbRightStipMask(x) ( ((FB_STIP_UNIT - (x)) & FB_STIP_MASK) ? \
+ FbScrLeft(FB_STIP_ALLONES,(FB_STIP_UNIT - (x)) & FB_STIP_MASK) : 0)
+
+#define FbBitsMask(x,w) (FbScrRight(FB_ALLONES,(x) & FB_MASK) & \
+ FbScrLeft(FB_ALLONES,(FB_UNIT - ((x) + (w))) & FB_MASK))
+
+#define FbStipMask(x,w) (FbStipRight(FB_STIP_ALLONES,(x) & FB_STIP_MASK) & \
+ FbStipLeft(FB_STIP_ALLONES,(FB_STIP_UNIT - ((x)+(w))) & FB_STIP_MASK))
+
+#define FbMaskBits(x,w,l,n,r) { \
+ n = (w); \
+ r = FbRightMask((x)+n); \
+ l = FbLeftMask(x); \
+ if (l) { \
+ n -= FB_UNIT - ((x) & FB_MASK); \
+ if (n < 0) { \
+ n = 0; \
+ l &= r; \
+ r = 0; \
+ } \
+ } \
+ n >>= FB_SHIFT; \
+}
+
+#define FbByteMaskInvalid 0x10
+
+#define FbPatternOffset(o,t) ((o) ^ (FbPatternOffsetBits & ~(sizeof (t) - 1)))
+
+#define FbPtrOffset(p,o,t) ((t *) ((CARD8 *) (p) + (o)))
+#define FbSelectPatternPart(xor,o,t) ((xor) >> (FbPatternOffset (o,t) << 3))
+#define FbStorePart(dst,off,t,xor) (WRITE(FbPtrOffset(dst,off,t), \
+ FbSelectPart(xor,off,t)))
+#ifndef FbSelectPart
+#define FbSelectPart(x,o,t) FbSelectPatternPart(x,o,t)
+#endif
+
+#define FbMaskBitsBytes(x,w,copy,l,lb,n,r,rb) { \
+ n = (w); \
+ lb = 0; \
+ rb = 0; \
+ r = FbRightMask((x)+n); \
+ if (r) { \
+ /* compute right byte length */ \
+ if ((copy) && (((x) + n) & 7) == 0) { \
+ rb = (((x) + n) & FB_MASK) >> 3; \
+ } else { \
+ rb = FbByteMaskInvalid; \
+ } \
+ } \
+ l = FbLeftMask(x); \
+ if (l) { \
+ /* compute left byte length */ \
+ if ((copy) && ((x) & 7) == 0) { \
+ lb = ((x) & FB_MASK) >> 3; \
+ } else { \
+ lb = FbByteMaskInvalid; \
+ } \
+ /* subtract out the portion painted by leftMask */ \
+ n -= FB_UNIT - ((x) & FB_MASK); \
+ if (n < 0) { \
+ if (lb != FbByteMaskInvalid) { \
+ if (rb == FbByteMaskInvalid) { \
+ lb = FbByteMaskInvalid; \
+ } else if (rb) { \
+ lb |= (rb - lb) << (FB_SHIFT - 3); \
+ rb = 0; \
+ } \
+ } \
+ n = 0; \
+ l &= r; \
+ r = 0; \
+ }\
+ } \
+ n >>= FB_SHIFT; \
+}
+
+#define FbDoLeftMaskByteRRop(dst,lb,l,and,xor) { \
+ switch (lb) { \
+ case (sizeof (FbBits) - 3) | (1 << (FB_SHIFT - 3)): \
+ FbStorePart(dst,sizeof (FbBits) - 3,CARD8,xor); \
+ break; \
+ case (sizeof (FbBits) - 3) | (2 << (FB_SHIFT - 3)): \
+ FbStorePart(dst,sizeof (FbBits) - 3,CARD8,xor); \
+ FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \
+ break; \
+ case (sizeof (FbBits) - 2) | (1 << (FB_SHIFT - 3)): \
+ FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \
+ break; \
+ case sizeof (FbBits) - 3: \
+ FbStorePart(dst,sizeof (FbBits) - 3,CARD8,xor); \
+ case sizeof (FbBits) - 2: \
+ FbStorePart(dst,sizeof (FbBits) - 2,CARD16,xor); \
+ break; \
+ case sizeof (FbBits) - 1: \
+ FbStorePart(dst,sizeof (FbBits) - 1,CARD8,xor); \
+ break; \
+ default: \
+ WRITE(dst, FbDoMaskRRop(READ(dst), and, xor, l)); \
+ break; \
+ } \
+}
+
+#define FbDoRightMaskByteRRop(dst,rb,r,and,xor) { \
+ switch (rb) { \
+ case 1: \
+ FbStorePart(dst,0,CARD8,xor); \
+ break; \
+ case 2: \
+ FbStorePart(dst,0,CARD16,xor); \
+ break; \
+ case 3: \
+ FbStorePart(dst,0,CARD16,xor); \
+ FbStorePart(dst,2,CARD8,xor); \
+ break; \
+ default: \
+ WRITE(dst, FbDoMaskRRop (READ(dst), and, xor, r)); \
+ } \
+}
+
+#define FbMaskStip(x,w,l,n,r) { \
+ n = (w); \
+ r = FbRightStipMask((x)+n); \
+ l = FbLeftStipMask(x); \
+ if (l) { \
+ n -= FB_STIP_UNIT - ((x) & FB_STIP_MASK); \
+ if (n < 0) { \
+ n = 0; \
+ l &= r; \
+ r = 0; \
+ } \
+ } \
+ n >>= FB_STIP_SHIFT; \
+}
+
+/*
+ * These macros are used to transparently stipple
+ * in copy mode; the expected usage is with 'n' constant
+ * so all of the conditional parts collapse into a minimal
+ * sequence of partial word writes
+ *
+ * 'n' is the bytemask of which bytes to store, 'a' is the address
+ * of the FbBits base unit, 'o' is the offset within that unit
+ *
+ * The term "lane" comes from the hardware term "byte-lane" which
+ */
+
+#define FbLaneCase1(n,a,o) \
+ if ((n) == 0x01) { \
+ WRITE((CARD8 *) ((a)+FbPatternOffset(o,CARD8)), fgxor); \
+ }
+
+#define FbLaneCase2(n,a,o) \
+ if ((n) == 0x03) { \
+ WRITE((CARD16 *) ((a)+FbPatternOffset(o,CARD16)), fgxor); \
+ } else { \
+ FbLaneCase1((n)&1,a,o) \
+ FbLaneCase1((n)>>1,a,(o)+1) \
+ }
+
+#define FbLaneCase4(n,a,o) \
+ if ((n) == 0x0f) { \
+ WRITE((CARD32 *) ((a)+FbPatternOffset(o,CARD32)), fgxor); \
+ } else { \
+ FbLaneCase2((n)&3,a,o) \
+ FbLaneCase2((n)>>2,a,(o)+2) \
+ }
+
+#define FbLaneCase(n,a) FbLaneCase4(n,(CARD8 *) (a),0)
+
+typedef struct {
+ long changes;
+ long serial;
+ GCFuncs *old_funcs;
+ void *priv;
+
+ FbBits and, xor; /* reduced rop values */
+ FbBits bgand, bgxor; /* for stipples */
+ FbBits fg, bg, pm; /* expanded and filled */
+ unsigned int dashLength; /* total of all dash elements */
+ unsigned char evenStipple; /* stipple is even */
+ unsigned char bpp; /* current drawable bpp */
+} FbGCPrivate, *FbGCPrivPtr;
+
+extern DevPrivateKeyRec sna_gc_key;
+extern DevPrivateKeyRec sna_window_key;
+
+static inline FbGCPrivate *fb_gc(GCPtr gc)
+{
+ return dixGetPrivateAddr(&gc->devPrivates, &sna_gc_key);
+}
+
+static inline PixmapPtr fbGetWindowPixmap(WindowPtr window)
+{
+ return *(PixmapPtr *)dixGetPrivateAddr(&window->devPrivates, &sna_window_key);
+}
+
+#ifdef ROOTLESS
+#define __fbPixDrawableX(p) ((p)->drawable.x)
+#define __fbPixDrawableY(p) ((p)->drawable.y)
+#else
+#define __fbPixDrawableX(p) 0
+#define __fbPixDrawableY(p) 0
+#endif
+
+#ifdef COMPOSITE
+#define __fbPixOffXWin(p) (__fbPixDrawableX(p) - (p)->screen_x)
+#define __fbPixOffYWin(p) (__fbPixDrawableY(p) - (p)->screen_y)
+#else
+#define __fbPixOffXWin(p) (__fbPixDrawableX(p))
+#define __fbPixOffYWin(p) (__fbPixDrawableY(p))
+#endif
+#define __fbPixOffXPix(p) (__fbPixDrawableX(p))
+#define __fbPixOffYPix(p) (__fbPixDrawableY(p))
+
+#define fbGetDrawablePixmap(drawable, pixmap, xoff, yoff) { \
+ if ((drawable)->type != DRAWABLE_PIXMAP) { \
+ (pixmap) = fbGetWindowPixmap((WindowPtr)drawable); \
+ (xoff) = __fbPixOffXWin(pixmap); \
+ (yoff) = __fbPixOffYWin(pixmap); \
+ } else { \
+ (pixmap) = (PixmapPtr) (drawable); \
+ (xoff) = __fbPixOffXPix(pixmap); \
+ (yoff) = __fbPixOffYPix(pixmap); \
+ } \
+}
+
+#define fbGetPixmapBitsData(pixmap, pointer, stride, bpp) { \
+ (pointer) = (FbBits *) (pixmap)->devPrivate.ptr; \
+ (stride) = ((int) (pixmap)->devKind) / sizeof (FbBits); (void)(stride);\
+ (bpp) = (pixmap)->drawable.bitsPerPixel; (void)(bpp); \
+}
+
+#define fbGetPixmapStipData(pixmap, pointer, stride, bpp) { \
+ (pointer) = (FbStip *) (pixmap)->devPrivate.ptr; \
+ (stride) = ((int) (pixmap)->devKind) / sizeof (FbStip); (void)(stride);\
+ (bpp) = (pixmap)->drawable.bitsPerPixel; (void)(bpp); \
+}
+
+#define fbGetDrawable(drawable, pointer, stride, bpp, xoff, yoff) { \
+ PixmapPtr _pPix; \
+ fbGetDrawablePixmap(drawable, _pPix, xoff, yoff); \
+ fbGetPixmapBitsData(_pPix, pointer, stride, bpp); \
+}
+
+#define fbGetStipDrawable(drawable, pointer, stride, bpp, xoff, yoff) { \
+ PixmapPtr _pPix; \
+ fbGetDrawablePixmap(drawable, _pPix, xoff, yoff); \
+ fbGetPixmapStipData(_pPix, pointer, stride, bpp); \
+}
+
+/*
+ * XFree86 empties the root BorderClip when the VT is inactive,
+ * here's a macro which uses that to disable GetImage and GetSpans
+ */
+#define fbWindowEnabled(pWin) \
+ RegionNotEmpty(&(pWin)->drawable.pScreen->root->borderClip)
+#define fbDrawableEnabled(drawable) \
+ ((drawable)->type == DRAWABLE_PIXMAP ? \
+ TRUE : fbWindowEnabled((WindowPtr) drawable))
+
+#define FbPowerOfTwo(w) (((w) & ((w) - 1)) == 0)
+/*
+ * Accelerated tiles are power of 2 width <= FB_UNIT
+ */
+#define FbEvenTile(w) ((w) <= FB_UNIT && FbPowerOfTwo(w))
+/*
+ * Accelerated stipples are power of 2 width and <= FB_UNIT/dstBpp
+ * with dstBpp a power of 2 as well
+ */
+#define FbEvenStip(w,bpp) ((w) * (bpp) <= FB_UNIT && FbPowerOfTwo(w) && FbPowerOfTwo(bpp))
+
+inline static int16_t fbBound(int16_t a, uint16_t b)
+{
+ int v = (int)a + (int)b;
+ if (v > MAXSHORT)
+ return MAXSHORT;
+ return v;
+}
+
+extern void
+fbPolyArc(DrawablePtr drawable, GCPtr gc, int narcs, xArc * parcs);
+
+extern void
+fbBlt(FbBits *src, FbStride srcStride, int srcX,
+ FbBits *dst, FbStride dstStride, int dstX,
+ int width, int height,
+ int alu, FbBits pm, int bpp,
+ Bool reverse, Bool upsidedown);
+
+#if FB_STIP_SHIFT == FB_SHIFT
+static inline void
+fbBltStip(FbStip *src, FbStride srcStride, int srcX,
+ FbStip *dst, FbStride dstStride, int dstX,
+ int width, int height, int alu, FbBits pm, int bpp)
+{
+ fbBlt((FbBits *)src, srcStride, srcX,
+ (FbBits *)dst, dstStride, dstX,
+ width, height, alu, pm, bpp,
+ FALSE, FALSE);
+}
+#else
+#error FB_STIP_SHIFT must equal FB_SHIFT
+#endif
+
+extern void
+fbBltOne(FbStip *src, FbStride srcStride, int srcX,
+ FbBits *dst, FbStride dstStride, int dstX,
+ int dstBpp, int width, int height,
+ FbBits fgand, FbBits fbxor, FbBits bgand, FbBits bgxor);
+
+extern void
+fbBltPlane(FbBits *src, FbStride srcStride, int srcX, int srcBpp,
+ FbStip *dst, FbStride dstStride, int dstX,
+ int width, int height,
+ FbStip fgand, FbStip fgxor, FbStip bgand, FbStip bgxor,
+ Pixel planeMask);
+
+extern void
+fbCopyNtoN(DrawablePtr src, DrawablePtr dst, GCPtr gc,
+ BoxPtr pbox, int nbox,
+ int dx, int dy,
+ Bool reverse, Bool upsidedown, Pixel bitplane, void *closure);
+
+extern void
+fbCopy1toN(DrawablePtr src, DrawablePtr dst, GCPtr gc,
+ BoxPtr pbox, int nbox,
+ int dx, int dy,
+ Bool reverse, Bool upsidedown, Pixel bitplane, void *closure);
+
+extern void
+fbCopyNto1(DrawablePtr src, DrawablePtr dst, GCPtr gc,
+ BoxPtr pbox, int nbox,
+ int dx, int dy,
+ Bool reverse, Bool upsidedown, Pixel bitplane, void *closure);
+
+extern RegionPtr
+fbCopyArea(DrawablePtr src, DrawablePtr dst, GCPtr gc,
+ int sx, int sy,
+ int width, int height,
+ int dx, int dy);
+
+extern RegionPtr
+fbCopyPlane(DrawablePtr src, DrawablePtr dst, GCPtr gc,
+ int sx, int sy,
+ int width, int height,
+ int dx, int dy,
+ unsigned long bitplane);
+
+extern void
+fbFill(DrawablePtr drawable, GCPtr gc, int x, int y, int width, int height);
+
+extern void
+fbSolidBoxClipped(DrawablePtr drawable, GCPtr gc,
+ int x1, int y1, int x2, int y2);
+
+extern void
+fbPolyFillRect(DrawablePtr drawable, GCPtr gc, int n, xRectangle *rec);
+
+extern void
+fbFillSpans(DrawablePtr drawable, GCPtr gc,
+ int n, DDXPointPtr pt, int *width, int fSorted);
+
+extern void
+fbPadPixmap(PixmapPtr pPixmap);
+
+extern void
+fbValidateGC(GCPtr gc, unsigned long changes, DrawablePtr drawable);
+
+extern void
+fbGetSpans(DrawablePtr drawable, int wMax,
+ DDXPointPtr pt, int *width, int n, char *dst);
+
+extern void
+fbPolyGlyphBlt(DrawablePtr drawable, GCPtr gc, int x, int y,
+ unsigned int n, CharInfoPtr *info, pointer glyphs);
+
+extern void
+fbImageGlyphBlt(DrawablePtr drawable, GCPtr gc, int x, int y,
+ unsigned int n, CharInfoPtr *info, pointer glyphs);
+
+extern void
+fbPutImage(DrawablePtr drawable, GCPtr gc, int depth,
+ int x, int y, int w, int h,
+ int leftPad, int format, char *image);
+
+extern void
+fbPutXYImage(DrawablePtr drawable, GCPtr gc,
+ FbBits fg, FbBits bg, FbBits pm,
+ int alu, Bool opaque,
+ int x, int y, int width, int height,
+ FbStip * src, FbStride srcStride, int srcX);
+
+extern void
+fbGetImage(DrawablePtr drawable,
+ int x, int y, int w, int h,
+ unsigned int format, unsigned long planeMask, char *d);
+
+extern void
+fbPolyLine(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr pt);
+
+extern void
+fbFixCoordModePrevious(int n, DDXPointPtr pt);
+
+extern void
+fbPolySegment(DrawablePtr drawable, GCPtr gc, int n, xSegment *seg);
+
+extern RegionPtr
+fbBitmapToRegion(PixmapPtr pixmap);
+
+extern void
+fbPolyPoint(DrawablePtr drawable, GCPtr gc,
+ int mode, int n, xPoint *pt,
+ unsigned flags);
+
+extern void
+fbPushImage(DrawablePtr drawable, GCPtr gc,
+ FbStip *src, FbStride srcStride, int srcX,
+ int x, int y, int width, int height);
+
+extern void
+fbPushPixels(GCPtr gc, PixmapPtr pBitmap, DrawablePtr drawable,
+ int dx, int dy, int xOrg, int yOrg);
+
+extern void
+fbSetSpans(DrawablePtr drawable, GCPtr gc,
+ char *src, DDXPointPtr pt, int *width, int n, int fSorted);
+
+extern void
+fbSegment(DrawablePtr drawable, GCPtr gc,
+ int xa, int ya, int xb, int yb,
+ bool drawLast, int *dashOffset);
+
+extern void
+fbSegment1(DrawablePtr drawable, GCPtr gc, const BoxRec *clip,
+ int xa, int ya, int xb, int yb,
+ bool drawLast, int *dashOffset);
+
+extern void
+fbTransparentSpan(FbBits * dst, FbBits stip, FbBits fgxor, int n);
+
+extern void
+fbStipple(FbBits *dst, FbStride dstStride, int dstX, int dstBpp,
+ int width, int height,
+ FbStip *stip, FbStride stipStride,
+ int stipWidth, int stipHeight,
+ Bool even,
+ FbBits fgand, FbBits fgxor, FbBits bgand, FbBits bgxor,
+ int xRot, int yRot);
+
+extern void
+fbTile(FbBits *dst, FbStride dstStride, int dstX, int width, int height,
+ FbBits *tile, FbStride tileStride, int tileWidth, int tileHeight,
+ int alu, FbBits pm, int bpp,
+ int xRot, int yRot);
+
+extern FbBits fbReplicatePixel(Pixel p, int bpp);
+
+#endif /* FB_H */
diff --git a/src/sna/fb/fbarc.c b/src/sna/fb/fbarc.c
new file mode 100644
index 000000000..2222d0b6b
--- /dev/null
+++ b/src/sna/fb/fbarc.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright © 1998 Keith Packard
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "fb.h"
+#include <mi.h>
+#include <mizerarc.h>
+#include <limits.h>
+
+#define ARC fbArc8
+#define BITS BYTE
+#define BITS2 CARD16
+#define BITS4 CARD32
+#include "fbarcbits.h"
+#undef BITS
+#undef BITS2
+#undef BITS4
+#undef ARC
+
+#define ARC fbArc16
+#define BITS CARD16
+#define BITS2 CARD32
+#include "fbarcbits.h"
+#undef BITS
+#undef BITS2
+#undef ARC
+
+#define ARC fbArc32
+#define BITS CARD32
+#include "fbarcbits.h"
+#undef BITS
+#undef ARC
+
+void
+fbPolyArc(DrawablePtr drawable, GCPtr gc, int n, xArc *arc)
+{
+ DBG(("%s x %d, width=%d, fill=%d, line=%d\n",
+ __FUNCTION__, n, gc->lineWidth, gc->lineStyle, gc->fillStyle));
+
+ if (gc->lineWidth == 0) {
+ void (*raster)(FbBits *dst, FbStride dstStride, int dstBpp,
+ xArc *arc, int dx, int dy,
+ FbBits and, FbBits xor);
+
+ raster = 0;
+ if (gc->lineStyle == LineSolid && gc->fillStyle == FillSolid) {
+ switch (drawable->bitsPerPixel) {
+ case 8:
+ raster = fbArc8;
+ break;
+ case 16:
+ raster = fbArc16;
+ break;
+ case 32:
+ raster = fbArc32;
+ break;
+ }
+ }
+ if (raster) {
+ FbGCPrivPtr pgc = fb_gc(gc);
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+ BoxRec box;
+ int x2, y2;
+
+ fbGetDrawable(drawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+ while (n--) {
+ if (miCanZeroArc(arc)) {
+ box.x1 = arc->x + drawable->x;
+ box.y1 = arc->y + drawable->y;
+ /*
+ * Because box.x2 and box.y2 get truncated to 16 bits, and the
+ * RECT_IN_REGION test treats the resulting number as a signed
+ * integer, the RECT_IN_REGION test alone can go the wrong way.
+ * This can result in a server crash because the rendering
+ * routines in this file deal directly with cpu addresses
+ * of pixels to be stored, and do not clip or otherwise check
+ * that all such addresses are within their respective pixmaps.
+ * So we only allow the RECT_IN_REGION test to be used for
+ * values that can be expressed correctly in a signed short.
+ */
+ x2 = box.x1 + (int) arc->width + 1;
+ box.x2 = x2;
+ y2 = box.y1 + (int) arc->height + 1;
+ box.y2 = y2;
+ if ((x2 <= SHRT_MAX) && (y2 <= SHRT_MAX) &&
+ (RegionContainsRect(gc->pCompositeClip, &box) == rgnIN)) {
+ raster(dst, dstStride, dstBpp,
+ arc, drawable->x + dstXoff,
+ drawable->y + dstYoff, pgc->and, pgc->xor);
+ } else
+ miZeroPolyArc(drawable, gc, 1, arc);
+ } else
+ miPolyArc(drawable, gc, 1, arc);
+ arc++;
+ }
+ } else
+ miZeroPolyArc(drawable, gc, n, arc);
+ } else
+ miPolyArc(drawable, gc, n, arc);
+}
diff --git a/src/sna/fb/fbarcbits.h b/src/sna/fb/fbarcbits.h
new file mode 100644
index 000000000..a37206cd3
--- /dev/null
+++ b/src/sna/fb/fbarcbits.h
@@ -0,0 +1,204 @@
+/*
+ * Copyright © 1998 Keith Packard
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define isClipped(c,ul,lr) (((c) | ((c) - (ul)) | ((lr) - (c))) & 0x80008000)
+#define RROP(b,a,x) WRITE((b), FbDoRRop (READ(b), (a), (x)))
+
+#define ARCCOPY(d) WRITE(d,xorBits)
+#define ARCRROP(d) RROP(d,andBits,xorBits)
+
+static void
+ARC(FbBits * dst,
+ FbStride dstStride,
+ int dstBpp, xArc * arc, int drawX, int drawY, FbBits and, FbBits xor)
+{
+ BITS *bits;
+ FbStride bitsStride;
+ miZeroArcRec info;
+ Bool do360;
+ int x;
+ BITS *yorgp, *yorgop;
+ BITS andBits, xorBits;
+ int yoffset, dyoffset;
+ int y, a, b, d, mask;
+ int k1, k3, dx, dy;
+
+ bits = (BITS *) dst;
+ bitsStride = dstStride * (sizeof(FbBits) / sizeof(BITS));
+ andBits = (BITS) and;
+ xorBits = (BITS) xor;
+ do360 = miZeroArcSetup(arc, &info, TRUE);
+ yorgp = bits + ((info.yorg + drawY) * bitsStride);
+ yorgop = bits + ((info.yorgo + drawY) * bitsStride);
+ info.xorg = (info.xorg + drawX);
+ info.xorgo = (info.xorgo + drawX);
+ MIARCSETUP();
+ yoffset = y ? bitsStride : 0;
+ dyoffset = 0;
+ mask = info.initialMask;
+
+ if (!(arc->width & 1)) {
+ if (andBits == 0) {
+ if (mask & 2)
+ ARCCOPY(yorgp + info.xorgo);
+ if (mask & 8)
+ ARCCOPY(yorgop + info.xorgo);
+ } else {
+ if (mask & 2)
+ ARCRROP(yorgp + info.xorgo);
+ if (mask & 8)
+ ARCRROP(yorgop + info.xorgo);
+ }
+ }
+ if (!info.end.x || !info.end.y) {
+ mask = info.end.mask;
+ info.end = info.altend;
+ }
+ if (do360 && (arc->width == arc->height) && !(arc->width & 1)) {
+ int xoffset = bitsStride;
+ BITS *yorghb = yorgp + (info.h * bitsStride) + info.xorg;
+ BITS *yorgohb = yorghb - info.h;
+
+ yorgp += info.xorg;
+ yorgop += info.xorg;
+ yorghb += info.h;
+ while (1) {
+ if (andBits == 0) {
+ ARCCOPY(yorgp + yoffset + x);
+ ARCCOPY(yorgp + yoffset - x);
+ ARCCOPY(yorgop - yoffset - x);
+ ARCCOPY(yorgop - yoffset + x);
+ } else {
+ ARCRROP(yorgp + yoffset + x);
+ ARCRROP(yorgp + yoffset - x);
+ ARCRROP(yorgop - yoffset - x);
+ ARCRROP(yorgop - yoffset + x);
+ }
+ if (a < 0)
+ break;
+ if (andBits == 0) {
+ ARCCOPY(yorghb - xoffset - y);
+ ARCCOPY(yorgohb - xoffset + y);
+ ARCCOPY(yorgohb + xoffset + y);
+ ARCCOPY(yorghb + xoffset - y);
+ } else {
+ ARCRROP(yorghb - xoffset - y);
+ ARCRROP(yorgohb - xoffset + y);
+ ARCRROP(yorgohb + xoffset + y);
+ ARCRROP(yorghb + xoffset - y);
+ }
+ xoffset += bitsStride;
+ MIARCCIRCLESTEP(yoffset += bitsStride;
+ );
+ }
+ yorgp -= info.xorg;
+ yorgop -= info.xorg;
+ x = info.w;
+ yoffset = info.h * bitsStride;
+ } else if (do360) {
+ while (y < info.h || x < info.w) {
+ MIARCOCTANTSHIFT(dyoffset = bitsStride;
+ );
+ if (andBits == 0) {
+ ARCCOPY(yorgp + yoffset + info.xorg + x);
+ ARCCOPY(yorgp + yoffset + info.xorgo - x);
+ ARCCOPY(yorgop - yoffset + info.xorgo - x);
+ ARCCOPY(yorgop - yoffset + info.xorg + x);
+ } else {
+ ARCRROP(yorgp + yoffset + info.xorg + x);
+ ARCRROP(yorgp + yoffset + info.xorgo - x);
+ ARCRROP(yorgop - yoffset + info.xorgo - x);
+ ARCRROP(yorgop - yoffset + info.xorg + x);
+ }
+ MIARCSTEP(yoffset += dyoffset;
+ , yoffset += bitsStride;
+ );
+ }
+ } else {
+ while (y < info.h || x < info.w) {
+ MIARCOCTANTSHIFT(dyoffset = bitsStride;
+ );
+ if ((x == info.start.x) || (y == info.start.y)) {
+ mask = info.start.mask;
+ info.start = info.altstart;
+ }
+ if (andBits == 0) {
+ if (mask & 1)
+ ARCCOPY(yorgp + yoffset + info.xorg + x);
+ if (mask & 2)
+ ARCCOPY(yorgp + yoffset + info.xorgo - x);
+ if (mask & 4)
+ ARCCOPY(yorgop - yoffset + info.xorgo - x);
+ if (mask & 8)
+ ARCCOPY(yorgop - yoffset + info.xorg + x);
+ } else {
+ if (mask & 1)
+ ARCRROP(yorgp + yoffset + info.xorg + x);
+ if (mask & 2)
+ ARCRROP(yorgp + yoffset + info.xorgo - x);
+ if (mask & 4)
+ ARCRROP(yorgop - yoffset + info.xorgo - x);
+ if (mask & 8)
+ ARCRROP(yorgop - yoffset + info.xorg + x);
+ }
+ if ((x == info.end.x) || (y == info.end.y)) {
+ mask = info.end.mask;
+ info.end = info.altend;
+ }
+ MIARCSTEP(yoffset += dyoffset;
+ , yoffset += bitsStride;
+ );
+ }
+ }
+ if ((x == info.start.x) || (y == info.start.y))
+ mask = info.start.mask;
+ if (andBits == 0) {
+ if (mask & 1)
+ ARCCOPY(yorgp + yoffset + info.xorg + x);
+ if (mask & 4)
+ ARCCOPY(yorgop - yoffset + info.xorgo - x);
+ if (arc->height & 1) {
+ if (mask & 2)
+ ARCCOPY(yorgp + yoffset + info.xorgo - x);
+ if (mask & 8)
+ ARCCOPY(yorgop - yoffset + info.xorg + x);
+ }
+ } else {
+ if (mask & 1)
+ ARCRROP(yorgp + yoffset + info.xorg + x);
+ if (mask & 4)
+ ARCRROP(yorgop - yoffset + info.xorgo - x);
+ if (arc->height & 1) {
+ if (mask & 2)
+ ARCRROP(yorgp + yoffset + info.xorgo - x);
+ if (mask & 8)
+ ARCRROP(yorgop - yoffset + info.xorg + x);
+ }
+ }
+}
+
+#undef ARCCOPY
+#undef ARCRROP
+
+#undef RROP
+#undef isClipped
diff --git a/src/sna/fb/fbbitmap.c b/src/sna/fb/fbbitmap.c
new file mode 100644
index 000000000..7c037fe36
--- /dev/null
+++ b/src/sna/fb/fbbitmap.c
@@ -0,0 +1,159 @@
+/*
+ * Copyright © 1998 Keith Packard
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <stdlib.h>
+
+#include "fb.h"
+
+static inline void add(RegionPtr region,
+ int16_t x1, int16_t y1, int16_t x2, int16_t y2)
+{
+ BoxPtr r;
+
+ if (region->data->numRects == region->data->size)
+ RegionRectAlloc(region, 1);
+
+ r = RegionBoxptr(region) + region->data->numRects++;
+ r->x1 = x1; r->y1 = y1;
+ r->x2 = x2; r->y2 = y2;
+
+ DBG(("%s[%d/%d]: (%d, %d), (%d, %d)\n",
+ __FUNCTION__,
+ region->data->numRects, region->data->size,
+ x1, y1, x2, y2));
+
+ if (x1 < region->extents.x1)
+ region->extents.x1 = x1;
+ if (x2 > region->extents.x2)
+ region->extents.x2 = x2;
+}
+
+#define MASK_0 (FB_ALLONES & ~FbScrRight(FB_ALLONES, 1))
+
+/* Convert bitmap clip mask into clipping region.
+ * First, goes through each line and makes boxes by noting the transitions
+ * from 0 to 1 and 1 to 0.
+ * Then it coalesces the current line with the previous if they have boxes
+ * at the same X coordinates.
+ */
+RegionPtr
+fbBitmapToRegion(PixmapPtr pixmap)
+{
+ FbBits maskw;
+ register RegionPtr region;
+ const FbBits *bits, *line, *end;
+ int width, y1, y2, base, x1;
+ int stride, i;
+
+ DBG(("%s bitmap=%dx%d\n", __FUNCTION__,
+ pixmap->drawable.width, pixmap->drawable.height));
+
+ region = RegionCreate(NULL, 1);
+ if (!region)
+ return NullRegion;
+
+ line = (FbBits *) pixmap->devPrivate.ptr;
+ stride = pixmap->devKind >> (FB_SHIFT - 3);
+
+ width = pixmap->drawable.width;
+ maskw = 0;
+ if (width & 7)
+ maskw = FB_ALLONES & ~FbScrRight(FB_ALLONES, width & FB_MASK);
+ region->extents.x1 = width;
+ region->extents.x2 = 0;
+ y2 = 0;
+ while (y2 < pixmap->drawable.height) {
+ y1 = y2++;
+ bits = line;
+ line += stride;
+ while (y2 < pixmap->drawable.height &&
+ memcmp(bits, line, width >> 3) == 0 &&
+ (maskw == 0 || (bits[width >> FB_SHIFT] & maskw) == (line[width >> FB_SHIFT] & maskw)))
+ line += stride, y2++;
+
+ if (READ(bits) & MASK_0)
+ x1 = 0;
+ else
+ x1 = -1;
+
+ /* Process all words which are fully in the pixmap */
+ end = bits + (width >> FB_SHIFT);
+ for (base = 0; bits < end; base += FB_UNIT) {
+ FbBits w = READ(bits++);
+ if (x1 < 0) {
+ if (!w)
+ continue;
+ } else {
+ if (!~w)
+ continue;
+ }
+ for (i = 0; i < FB_UNIT; i++) {
+ if (w & MASK_0) {
+ if (x1 < 0)
+ x1 = base + i;
+ } else {
+ if (x1 >= 0) {
+ add(region, x1, y1, base + i, y2);
+ x1 = -1;
+ }
+ }
+ w = FbScrLeft(w, 1);
+ }
+ }
+ if (width & FB_MASK) {
+ FbBits w = READ(bits++);
+ for (i = 0; i < (width & FB_MASK); i++) {
+ if (w & MASK_0) {
+ if (x1 < 0)
+ x1 = base + i;
+ } else {
+ if (x1 >= 0) {
+ add(region, x1, y1, base + i, y2);
+ x1 = -1;
+ }
+ }
+ w = FbScrLeft(w, 1);
+ }
+ }
+ if (x1 >= 0)
+ add(region, x1, y1, width, y2);
+ }
+
+ if (region->data->numRects) {
+ region->extents.y1 = RegionBoxptr(region)->y1;
+ region->extents.y2 = RegionEnd(region)->y2;
+ if (region->data->numRects == 1) {
+ free(region->data);
+ region->data = NULL;
+ }
+ } else
+ region->extents.x1 = region->extents.x2 = 0;
+
+ DBG(("%s: region extents=(%d, %d), (%d, %d) x %d\n",
+ __FUNCTION__,
+ region->extents.x1, region->extents.y1,
+ region->extents.x2, region->extents.y2,
+ RegionNumRects(region)));
+
+ return region;
+}
diff --git a/src/sna/fb/fbblt.c b/src/sna/fb/fbblt.c
new file mode 100644
index 000000000..d4d20b68b
--- /dev/null
+++ b/src/sna/fb/fbblt.c
@@ -0,0 +1,321 @@
+/*
+ * Copyright © 1998 Keith Packard
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <string.h>
+#include "fb.h"
+
+typedef struct _mergeRopBits {
+ FbBits ca1, cx1, ca2, cx2;
+} FbMergeRopRec, *FbMergeRopPtr;
+
+#define O 0
+#define I FB_ALLONES
+
+static const FbMergeRopRec FbMergeRopBits[16] = {
+ {O, O, O, O}, /* clear 0x0 0 */
+ {I, O, O, O}, /* and 0x1 src AND dst */
+ {I, O, I, O}, /* andReverse 0x2 src AND NOT dst */
+ {O, O, I, O}, /* copy 0x3 src */
+ {I, I, O, O}, /* andInverted 0x4 NOT src AND dst */
+ {O, I, O, O}, /* noop 0x5 dst */
+ {O, I, I, O}, /* xor 0x6 src XOR dst */
+ {I, I, I, O}, /* or 0x7 src OR dst */
+ {I, I, I, I}, /* nor 0x8 NOT src AND NOT dst */
+ {O, I, I, I}, /* equiv 0x9 NOT src XOR dst */
+ {O, I, O, I}, /* invert 0xa NOT dst */
+ {I, I, O, I}, /* orReverse 0xb src OR NOT dst */
+ {O, O, I, I}, /* copyInverted 0xc NOT src */
+ {I, O, I, I}, /* orInverted 0xd NOT src OR dst */
+ {I, O, O, I}, /* nand 0xe NOT src OR NOT dst */
+ {O, O, O, I}, /* set 0xf 1 */
+};
+
+#undef O
+#undef I
+
+#define FbDeclareMergeRop() FbBits _ca1, _cx1, _ca2, _cx2;
+#define FbDeclarePrebuiltMergeRop() FbBits _cca, _ccx;
+
+#define FbInitializeMergeRop(alu,pm) {\
+ const FbMergeRopRec *_bits; \
+ _bits = &FbMergeRopBits[alu]; \
+ _ca1 = _bits->ca1 & pm; \
+ _cx1 = _bits->cx1 | ~pm; \
+ _ca2 = _bits->ca2 & pm; \
+ _cx2 = _bits->cx2 & pm; \
+}
+
+#define InitializeShifts(sx,dx,ls,rs) { \
+ if (sx != dx) { \
+ if (sx > dx) { \
+ ls = sx - dx; \
+ rs = FB_UNIT - ls; \
+ } else { \
+ rs = dx - sx; \
+ ls = FB_UNIT - rs; \
+ } \
+ } \
+}
+
+static void
+fbBlt__rop(FbBits *srcLine, FbStride srcStride, int srcX,
+ FbBits *dstLine, FbStride dstStride, int dstX,
+ int width, int height,
+ int alu, FbBits pm, int bpp,
+ Bool reverse, Bool upsidedown)
+{
+ FbBits *src, *dst;
+ int leftShift, rightShift;
+ FbBits startmask, endmask;
+ FbBits bits, bits1;
+ int n, nmiddle;
+ Bool destInvarient;
+ int startbyte, endbyte;
+
+ FbDeclareMergeRop();
+
+ FbInitializeMergeRop(alu, pm);
+ destInvarient = FbDestInvarientMergeRop();
+ if (upsidedown) {
+ srcLine += (height - 1) * (srcStride);
+ dstLine += (height - 1) * (dstStride);
+ srcStride = -srcStride;
+ dstStride = -dstStride;
+ }
+ FbMaskBitsBytes(dstX, width, destInvarient, startmask, startbyte,
+ nmiddle, endmask, endbyte);
+ if (reverse) {
+ srcLine += ((srcX + width - 1) >> FB_SHIFT) + 1;
+ dstLine += ((dstX + width - 1) >> FB_SHIFT) + 1;
+ srcX = (srcX + width - 1) & FB_MASK;
+ dstX = (dstX + width - 1) & FB_MASK;
+ } else {
+ srcLine += srcX >> FB_SHIFT;
+ dstLine += dstX >> FB_SHIFT;
+ srcX &= FB_MASK;
+ dstX &= FB_MASK;
+ }
+ if (srcX == dstX) {
+ while (height--) {
+ src = srcLine;
+ srcLine += srcStride;
+ dst = dstLine;
+ dstLine += dstStride;
+ if (reverse) {
+ if (endmask) {
+ bits = READ(--src);
+ --dst;
+ FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
+ }
+ n = nmiddle;
+ if (destInvarient) {
+ while (n--)
+ WRITE(--dst, FbDoDestInvarientMergeRop(READ(--src)));
+ } else {
+ while (n--) {
+ bits = READ(--src);
+ --dst;
+ WRITE(dst, FbDoMergeRop(bits, READ(dst)));
+ }
+ }
+ if (startmask) {
+ bits = READ(--src);
+ --dst;
+ FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask);
+ }
+ } else {
+ if (startmask) {
+ bits = READ(src++);
+ FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask);
+ dst++;
+ }
+ n = nmiddle;
+ if (destInvarient) {
+ while (n--)
+ WRITE(dst++, FbDoDestInvarientMergeRop(READ(src++)));
+ } else {
+ while (n--) {
+ bits = READ(src++);
+ WRITE(dst, FbDoMergeRop(bits, READ(dst)));
+ dst++;
+ }
+ }
+ if (endmask) {
+ bits = READ(src);
+ FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
+ }
+ }
+ }
+ } else {
+ if (srcX > dstX) {
+ leftShift = srcX - dstX;
+ rightShift = FB_UNIT - leftShift;
+ } else {
+ rightShift = dstX - srcX;
+ leftShift = FB_UNIT - rightShift;
+ }
+ while (height--) {
+ src = srcLine;
+ srcLine += srcStride;
+ dst = dstLine;
+ dstLine += dstStride;
+
+ bits1 = 0;
+ if (reverse) {
+ if (srcX < dstX)
+ bits1 = READ(--src);
+ if (endmask) {
+ bits = FbScrRight(bits1, rightShift);
+ if (FbScrRight(endmask, leftShift)) {
+ bits1 = READ(--src);
+ bits |= FbScrLeft(bits1, leftShift);
+ }
+ --dst;
+ FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
+ }
+ n = nmiddle;
+ if (destInvarient) {
+ while (n--) {
+ bits = FbScrRight(bits1, rightShift);
+ bits1 = READ(--src);
+ bits |= FbScrLeft(bits1, leftShift);
+ --dst;
+ WRITE(dst, FbDoDestInvarientMergeRop(bits));
+ }
+ } else {
+ while (n--) {
+ bits = FbScrRight(bits1, rightShift);
+ bits1 = READ(--src);
+ bits |= FbScrLeft(bits1, leftShift);
+ --dst;
+ WRITE(dst, FbDoMergeRop(bits, READ(dst)));
+ }
+ }
+ if (startmask) {
+ bits = FbScrRight(bits1, rightShift);
+ if (FbScrRight(startmask, leftShift)) {
+ bits1 = READ(--src);
+ bits |= FbScrLeft(bits1, leftShift);
+ }
+ --dst;
+ FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask);
+ }
+ } else {
+ if (srcX > dstX)
+ bits1 = READ(src++);
+ if (startmask) {
+ bits = FbScrLeft(bits1, leftShift);
+ if (FbScrLeft(startmask, rightShift)) {
+ bits1 = READ(src++);
+ bits |= FbScrRight(bits1, rightShift);
+ }
+ FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask);
+ dst++;
+ }
+ n = nmiddle;
+ if (destInvarient) {
+ while (n--) {
+ bits = FbScrLeft(bits1, leftShift);
+ bits1 = READ(src++);
+ bits |= FbScrRight(bits1, rightShift);
+ WRITE(dst, FbDoDestInvarientMergeRop(bits));
+ dst++;
+ }
+ } else {
+ while (n--) {
+ bits = FbScrLeft(bits1, leftShift);
+ bits1 = READ(src++);
+ bits |= FbScrRight(bits1, rightShift);
+ WRITE(dst, FbDoMergeRop(bits, READ(dst)));
+ dst++;
+ }
+ }
+ if (endmask) {
+ bits = FbScrLeft(bits1, leftShift);
+ if (FbScrLeft(endmask, rightShift)) {
+ bits1 = READ(src);
+ bits |= FbScrRight(bits1, rightShift);
+ }
+ FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
+ }
+ }
+ }
+ }
+}
+
+void
+fbBlt(FbBits *srcLine, FbStride srcStride, int srcX,
+ FbBits *dstLine, FbStride dstStride, int dstX,
+ int width, int height,
+ int alu, FbBits pm, int bpp,
+ Bool reverse, Bool upsidedown)
+{
+ DBG(("%s %dx%d, alu=%d, pm=%d, bpp=%d (reverse=%d, upsidedown=%d)\n",
+ __FUNCTION__, width, height, alu, pm, bpp, reverse, upsidedown));
+
+ if (alu == GXcopy && pm == FB_ALLONES && ((srcX|dstX|width) & 7) == 0) {
+ CARD8 *s = (CARD8 *) srcLine;
+ CARD8 *d = (CARD8 *) dstLine;
+ void *(*func)(void *, const void *, size_t);
+ int i;
+
+ srcStride *= sizeof(FbBits);
+ dstStride *= sizeof(FbBits);
+ width >>= 3;
+ s += srcX >> 3;
+ d += dstX >> 3;
+
+ DBG(("%s fast blt, src_stride=%d, dst_stride=%d, width=%d (offset=%d)\n",
+ __FUNCTION__,
+ srcStride, dstStride, width, s - d));
+
+ if (width == srcStride && width == dstStride) {
+ width *= height;
+ height = 1;
+ }
+
+ if ((s < d && s + width > d) || (d < s && d + width > s))
+ func = memmove;
+ else
+ func = memcpy;
+ if (!upsidedown) {
+ for (i = 0; i < height; i++)
+ func(d + i * dstStride,
+ s + i * srcStride,
+ width);
+ } else {
+ for (i = height; i--; )
+ func(d + i * dstStride,
+ s + i * srcStride,
+ width);
+ }
+
+ return;
+ }
+
+ fbBlt__rop(srcLine, srcStride, srcX,
+ dstLine, dstStride, dstX,
+ width, height,
+ alu, pm, bpp,
+ reverse, upsidedown);
+}
diff --git a/src/sna/fb/fbbltone.c b/src/sna/fb/fbbltone.c
new file mode 100644
index 000000000..697d20b5c
--- /dev/null
+++ b/src/sna/fb/fbbltone.c
@@ -0,0 +1,413 @@
+/*
+ * Copyright © 1998 Keith Packard
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "fb.h"
+
+#ifdef __clang__
+/* shift overflow is intentional */
+#pragma clang diagnostic ignored "-Wshift-overflow"
+#endif
+
+/*
+ * Example: srcX = 13 dstX = 8 (FB unit 32 dstBpp 8)
+ *
+ * **** **** **** **** **** **** **** ****
+ * ^
+ * ******** ******** ******** ********
+ * ^
+ * leftShift = 12
+ * rightShift = 20
+ *
+ * Example: srcX = 0 dstX = 8 (FB unit 32 dstBpp 8)
+ *
+ * **** **** **** **** **** **** **** ****
+ * ^
+ * ******** ******** ******** ********
+ * ^
+ *
+ * leftShift = 24
+ * rightShift = 8
+ */
+
+#define LoadBits {\
+ if (leftShift) { \
+ bitsRight = (src < srcEnd ? READ(src++) : 0); \
+ bits = (FbStipLeft (bitsLeft, leftShift) | \
+ FbStipRight(bitsRight, rightShift)); \
+ bitsLeft = bitsRight; \
+ } else \
+ bits = (src < srcEnd ? READ(src++) : 0); \
+}
+
+#define LaneCases1(n,a) case n: FbLaneCase(n,a); break
+#define LaneCases2(n,a) LaneCases1(n,a); LaneCases1(n+1,a)
+#define LaneCases4(n,a) LaneCases2(n,a); LaneCases2(n+2,a)
+#define LaneCases8(n,a) LaneCases4(n,a); LaneCases4(n+4,a)
+#define LaneCases16(n,a) LaneCases8(n,a); LaneCases8(n+8,a)
+#define LaneCases32(n,a) LaneCases16(n,a); LaneCases16(n+16,a)
+#define LaneCases64(n,a) LaneCases32(n,a); LaneCases32(n+32,a)
+#define LaneCases128(n,a) LaneCases64(n,a); LaneCases64(n+64,a)
+#define LaneCases256(n,a) LaneCases128(n,a); LaneCases128(n+128,a)
+
+#define LaneCases(a) LaneCases16(0,a)
+
+static const CARD8 fb8Lane[16] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
+};
+
+static const CARD8 fb16Lane[16] = {
+ 0, 3, 12, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const CARD8 fb32Lane[16] = {
+ 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const CARD8 * const fbLaneTable[33] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ fb8Lane, 0, 0, 0, 0, 0, 0, 0,
+ fb16Lane, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ fb32Lane
+};
+
+void
+fbBltOne(FbStip * src, FbStride srcStride, /* FbStip units per scanline */
+ int srcX, /* bit position of source */
+ FbBits * dst, FbStride dstStride, /* FbBits units per scanline */
+ int dstX, /* bit position of dest */
+ int dstBpp, /* bits per destination unit */
+ int width, /* width in bits of destination */
+ int height, /* height in scanlines */
+ FbBits fgand, /* rrop values */
+ FbBits fgxor, FbBits bgand, FbBits bgxor)
+{
+ const FbBits *fbBits;
+ FbBits *srcEnd;
+ int pixelsPerDst; /* dst pixels per FbBits */
+ int unitsPerSrc; /* src patterns per FbStip */
+ int leftShift, rightShift; /* align source with dest */
+ FbBits startmask, endmask; /* dest scanline masks */
+ FbStip bits = 0, bitsLeft, bitsRight; /* source bits */
+ FbStip left;
+ FbBits mask;
+ int nDst; /* dest longwords (w.o. end) */
+ int w;
+ int n, nmiddle;
+ int dstS; /* stipple-relative dst X coordinate */
+ Bool copy; /* accelerate dest-invariant */
+ Bool transparent; /* accelerate 0 nop */
+ int srcinc; /* source units consumed */
+ Bool endNeedsLoad = FALSE; /* need load for endmask */
+ const CARD8 *fbLane;
+ int startbyte, endbyte;
+
+ /*
+ * Do not read past the end of the buffer!
+ */
+ srcEnd = src + height * srcStride;
+
+ /*
+ * Number of destination units in FbBits == number of stipple pixels
+ * used each time
+ */
+ pixelsPerDst = FB_UNIT / dstBpp;
+
+ /*
+ * Number of source stipple patterns in FbStip
+ */
+ unitsPerSrc = FB_STIP_UNIT / pixelsPerDst;
+
+ copy = FALSE;
+ transparent = FALSE;
+ if (bgand == 0 && fgand == 0)
+ copy = TRUE;
+ else if (bgand == FB_ALLONES && bgxor == 0)
+ transparent = TRUE;
+
+ /*
+ * Adjust source and dest to nearest FbBits boundary
+ */
+ src += srcX >> FB_STIP_SHIFT;
+ dst += dstX >> FB_SHIFT;
+ srcX &= FB_STIP_MASK;
+ dstX &= FB_MASK;
+
+ FbMaskBitsBytes(dstX, width, copy,
+ startmask, startbyte, nmiddle, endmask, endbyte);
+
+ /*
+ * Compute effective dest alignment requirement for
+ * source -- must align source to dest unit boundary
+ */
+ dstS = dstX / dstBpp;
+ /*
+ * Compute shift constants for effective alignement
+ */
+ if (srcX >= dstS) {
+ leftShift = srcX - dstS;
+ rightShift = FB_STIP_UNIT - leftShift;
+ } else {
+ rightShift = dstS - srcX;
+ leftShift = FB_STIP_UNIT - rightShift;
+ }
+ /*
+ * Get pointer to stipple mask array for this depth
+ */
+ fbBits = 0; /* unused */
+ if (pixelsPerDst <= 8)
+ fbBits = fbStippleTable[pixelsPerDst];
+ fbLane = 0;
+ if (transparent && fgand == 0 && dstBpp >= 8)
+ fbLane = fbLaneTable[dstBpp];
+
+ /*
+ * Compute total number of destination words written, but
+ * don't count endmask
+ */
+ nDst = nmiddle;
+ if (startmask)
+ nDst++;
+
+ dstStride -= nDst;
+
+ /*
+ * Compute total number of source words consumed
+ */
+
+ srcinc = (nDst + unitsPerSrc - 1) / unitsPerSrc;
+
+ if (srcX > dstS)
+ srcinc++;
+ if (endmask) {
+ endNeedsLoad = nDst % unitsPerSrc == 0;
+ if (endNeedsLoad)
+ srcinc++;
+ }
+
+ srcStride -= srcinc;
+
+ /*
+ * Copy rectangle
+ */
+ while (height--) {
+ w = nDst; /* total units across scanline */
+ n = unitsPerSrc; /* units avail in single stipple */
+ if (n > w)
+ n = w;
+
+ bitsLeft = 0;
+ if (srcX > dstS)
+ bitsLeft = READ(src++);
+ if (n) {
+ /*
+ * Load first set of stipple bits
+ */
+ LoadBits;
+
+ /*
+ * Consume stipple bits for startmask
+ */
+ if (startmask) {
+ mask = fbBits[FbLeftStipBits(bits, pixelsPerDst)];
+ if (fbLane) {
+ fbTransparentSpan(dst, mask & startmask, fgxor, 1);
+ } else {
+ if (mask || !transparent)
+ FbDoLeftMaskByteStippleRRop(dst, mask,
+ fgand, fgxor, bgand, bgxor,
+ startbyte, startmask);
+ }
+ bits = FbStipLeft(bits, pixelsPerDst);
+ dst++;
+ n--;
+ w--;
+ }
+ /*
+ * Consume stipple bits across scanline
+ */
+ for (;;) {
+ w -= n;
+ if (copy) {
+ while (n--) {
+#if FB_UNIT > 32
+ if (pixelsPerDst == 16)
+ mask = FbStipple16Bits(FbLeftStipBits(bits, 16));
+ else
+#endif
+ mask = fbBits[FbLeftStipBits(bits, pixelsPerDst)];
+ WRITE(dst, FbOpaqueStipple(mask, fgxor, bgxor));
+ dst++;
+ bits = FbStipLeft(bits, pixelsPerDst);
+ }
+ }
+ else {
+ if (fbLane) {
+ while (bits && n) {
+ switch (fbLane[FbLeftStipBits(bits, pixelsPerDst)]) {
+ LaneCases((CARD8 *) dst);
+ }
+ bits = FbStipLeft(bits, pixelsPerDst);
+ dst++;
+ n--;
+ }
+ dst += n;
+ } else {
+ while (n--) {
+ left = FbLeftStipBits(bits, pixelsPerDst);
+ if (left || !transparent) {
+ mask = fbBits[left];
+ WRITE(dst, FbStippleRRop(READ(dst), mask,
+ fgand, fgxor, bgand,
+ bgxor));
+ }
+ dst++;
+ bits = FbStipLeft(bits, pixelsPerDst);
+ }
+ }
+ }
+ if (!w)
+ break;
+ /*
+ * Load another set and reset number of available units
+ */
+ LoadBits;
+ n = unitsPerSrc;
+ if (n > w)
+ n = w;
+ }
+ }
+ /*
+ * Consume stipple bits for endmask
+ */
+ if (endmask) {
+ if (endNeedsLoad) {
+ LoadBits;
+ }
+ mask = fbBits[FbLeftStipBits(bits, pixelsPerDst)];
+ if (fbLane) {
+ fbTransparentSpan(dst, mask & endmask, fgxor, 1);
+ } else {
+ if (mask || !transparent)
+ FbDoRightMaskByteStippleRRop(dst, mask,
+ fgand, fgxor, bgand, bgxor,
+ endbyte, endmask);
+ }
+ }
+ dst += dstStride;
+ src += srcStride;
+ }
+}
+
+/*
+ * Not very efficient, but simple -- copy a single plane
+ * from an N bit image to a 1 bit image
+ */
+
+void
+fbBltPlane(FbBits * src,
+ FbStride srcStride,
+ int srcX,
+ int srcBpp,
+ FbStip * dst,
+ FbStride dstStride,
+ int dstX,
+ int width,
+ int height,
+ FbStip fgand,
+ FbStip fgxor, FbStip bgand, FbStip bgxor, Pixel planeMask)
+{
+ FbBits *s;
+ FbBits pm;
+ FbBits srcMask;
+ FbBits srcMaskFirst;
+ FbBits srcMask0 = 0;
+ FbBits srcBits;
+
+ FbStip dstBits;
+ FbStip *d;
+ FbStip dstMask;
+ FbStip dstMaskFirst;
+ FbStip dstUnion;
+ int w;
+ int wt;
+
+ if (!width)
+ return;
+
+ src += srcX >> FB_SHIFT;
+ srcX &= FB_MASK;
+
+ dst += dstX >> FB_STIP_SHIFT;
+ dstX &= FB_STIP_MASK;
+
+ w = width / srcBpp;
+
+ pm = fbReplicatePixel(planeMask, srcBpp);
+ srcMaskFirst = pm & FbBitsMask(srcX, srcBpp);
+ srcMask0 = pm & FbBitsMask(0, srcBpp);
+
+ dstMaskFirst = FbStipMask(dstX, 1);
+ while (height--) {
+ d = dst;
+ dst += dstStride;
+ s = src;
+ src += srcStride;
+
+ srcMask = srcMaskFirst;
+ srcBits = READ(s++);
+
+ dstMask = dstMaskFirst;
+ dstUnion = 0;
+ dstBits = 0;
+
+ wt = w;
+
+ while (wt--) {
+ if (!srcMask) {
+ srcBits = READ(s++);
+ srcMask = srcMask0;
+ }
+ if (!dstMask) {
+ WRITE(d, FbStippleRRopMask(READ(d), dstBits,
+ fgand, fgxor, bgand, bgxor,
+ dstUnion));
+ d++;
+ dstMask = FbStipMask(0, 1);
+ dstUnion = 0;
+ dstBits = 0;
+ }
+ if (srcBits & srcMask)
+ dstBits |= dstMask;
+ dstUnion |= dstMask;
+ if (srcBpp == FB_UNIT)
+ srcMask = 0;
+ else
+ srcMask = FbScrRight(srcMask, srcBpp);
+ dstMask = FbStipRight(dstMask, 1);
+ }
+ if (dstUnion)
+ WRITE(d, FbStippleRRopMask(READ(d), dstBits,
+ fgand, fgxor, bgand, bgxor, dstUnion));
+ }
+}
diff --git a/src/sna/fb/fbclip.c b/src/sna/fb/fbclip.c
new file mode 100644
index 000000000..37011a723
--- /dev/null
+++ b/src/sna/fb/fbclip.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ *
+ */
+
+#include "fb.h"
+#include "fbclip.h"
+
+static const BoxRec *
+find_clip_row_for_y(const BoxRec *begin, const BoxRec *end, int16_t y)
+{
+ const BoxRec *mid;
+
+ if (end == begin)
+ return end;
+
+ if (end - begin == 1) {
+ if (begin->y2 > y)
+ return begin;
+ else
+ return end;
+ }
+
+ mid = begin + (end - begin) / 2;
+ if (mid->y2 > y)
+ return find_clip_row_for_y(begin, mid, y);
+ else
+ return find_clip_row_for_y(mid, end, y);
+}
+
+const BoxRec *
+fbClipBoxes(const RegionRec *region, const BoxRec *box, const BoxRec **end)
+{
+ const BoxRec *c0, *c1;
+
+ DBG(("%s: box=(%d, %d),(%d, %d); region=(%d, %d),(%d, %d) x %ld\n",
+ __FUNCTION__,
+ box->x1, box->y1, box->x2, box->y2,
+ region->extents.x1, region->extents.y1,
+ region->extents.x2, region->extents.y2,
+ region->data ? region->data->numRects : 1));
+
+ if (box->x1 >= region->extents.x2 || box->x2 <= region->extents.x1 ||
+ box->y1 >= region->extents.y2 || box->y2 <= region->extents.y1) {
+ DBG(("%s: no intersection\n", __FUNCTION__));
+ return *end = box;
+ }
+
+ if (region->data == NULL) {
+ *end = &region->extents + 1;
+ return &region->extents;
+ }
+
+ c0 = (const BoxRec *)(region->data + 1);
+ c1 = c0 + region->data->numRects;
+
+ if (c0->y2 <= box->y1) {
+ DBG(("%s: first clip (%d, %d), (%d, %d) before box (%d, %d), (%d, %d)\n",
+ __FUNCTION__,
+ c0->x1, c0->y1, c0->x2, c0->y2,
+ box->x1, box->y1, box->x2, box->y2));
+ c0 = find_clip_row_for_y(c0, c1, box->y1);
+ }
+
+ DBG(("%s: c0=(%d, %d),(%d, %d) x %ld\n",
+ __FUNCTION__, c0->x1, c0->y1, c0->x2, c0->y2, c1 - c0));
+
+ *end = c1;
+ return c0;
+}
diff --git a/src/sna/fb/fbclip.h b/src/sna/fb/fbclip.h
new file mode 100644
index 000000000..f07e63ca6
--- /dev/null
+++ b/src/sna/fb/fbclip.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Chris Wilson <chris@chris-wilson.co.uk>
+ *
+ */
+
+#ifndef FBCLIP_H
+#define FBCLIP_H
+
+extern const BoxRec *
+fbClipBoxes(const RegionRec *region, const BoxRec *box, const BoxRec **end);
+
+inline static bool
+box_intersect(BoxPtr a, const BoxRec *b)
+{
+ if (a->x1 < b->x1)
+ a->x1 = b->x1;
+ if (a->x2 > b->x2)
+ a->x2 = b->x2;
+ if (a->y1 < b->y1)
+ a->y1 = b->y1;
+ if (a->y2 > b->y2)
+ a->y2 = b->y2;
+
+ return a->x1 < a->x2 && a->y1 < a->y2;
+}
+
+#define run_box(b, c) \
+ DBG(("%s: box=(%d, %d), (%d, %d), clip=(%d, %d), (%d, %d)\n", \
+ __FUNCTION__, (b)->x1, (b)->y1, (b)->x2, (b)->y2, (c)->x1, (c)->y1, (c)->x2, (c)->y2)); \
+ if ((b)->y2 <= (c)->y1) break; \
+ if ((b)->x1 >= (c)->x2) continue; \
+ if ((b)->x2 <= (c)->x1) { if ((b)->y2 <= (c)->y2) break; continue; }
+
+static inline void
+fbDrawableRun(DrawablePtr d, GCPtr gc, const BoxRec *box,
+ void (*func)(DrawablePtr, GCPtr, const BoxRec *b, void *data),
+ void *data)
+{
+ const BoxRec *c, *end;
+ for (c = fbClipBoxes(gc->pCompositeClip, box, &end); c != end; c++) {
+ BoxRec b;
+
+ run_box(box, c);
+
+ b = *box;
+ if (box_intersect(&b, c))
+ func(d, gc, &b, data);
+ }
+}
+
+static inline void
+fbDrawableRunUnclipped(DrawablePtr d, GCPtr gc, const BoxRec *box,
+ void (*func)(DrawablePtr, GCPtr, const BoxRec *b, void *data),
+ void *data)
+{
+ const BoxRec *c, *end;
+ for (c = fbClipBoxes(gc->pCompositeClip, box, &end); c != end; c++) {
+ run_box(box, c);
+ func(d, gc, c, data);
+ }
+}
+
+#endif /* FBCLIP_H */
diff --git a/src/sna/fb/fbcopy.c b/src/sna/fb/fbcopy.c
new file mode 100644
index 000000000..a486a5b1d
--- /dev/null
+++ b/src/sna/fb/fbcopy.c
@@ -0,0 +1,225 @@
+/*
+ * Copyright © 1998 Keith Packard
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <stdlib.h>
+
+#include "fb.h"
+#include <mi.h>
+
+void
+fbCopyNtoN(DrawablePtr src_drawable, DrawablePtr dst_drawable, GCPtr gc,
+ BoxPtr box, int nbox,
+ int dx, int dy,
+ Bool reverse, Bool upsidedown, Pixel bitplane,
+ void *closure)
+{
+ CARD8 alu = gc ? gc->alu : GXcopy;
+ FbBits pm = gc ? fb_gc(gc)->pm : FB_ALLONES;
+ FbBits *src, *dst;
+ FbStride srcStride, dstStride;
+ int dstBpp, srcBpp;
+ int srcXoff, srcYoff;
+ int dstXoff, dstYoff;
+
+ fbGetDrawable(src_drawable, src, srcStride, srcBpp, srcXoff, srcYoff);
+ fbGetDrawable(dst_drawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+
+ src += (dy + srcYoff) * srcStride;
+ srcXoff += dx;
+ dst += dstYoff * dstStride;
+ do {
+ fbBlt(src + box->y1 * srcStride, srcStride,
+ (box->x1 + srcXoff) * srcBpp,
+ dst + box->y1 * dstStride, dstStride,
+ (box->x1 + dstXoff) * dstBpp,
+ (box->x2 - box->x1) * dstBpp,
+ (box->y2 - box->y1),
+ alu, pm, dstBpp, reverse, upsidedown);
+ } while (box++, --nbox);
+}
+
+void
+fbCopy1toN(DrawablePtr src_drawable, DrawablePtr dst_drawable, GCPtr gc,
+ BoxPtr box, int nbox,
+ int dx, int dy,
+ Bool reverse, Bool upsidedown, Pixel bitplane,
+ void *closure)
+{
+ FbGCPrivPtr pgc = fb_gc(gc);
+ FbBits *src;
+ FbStride srcStride;
+ int srcBpp;
+ int srcXoff, srcYoff;
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+
+ fbGetDrawable(src_drawable, src, srcStride, srcBpp, srcXoff, srcYoff);
+ fbGetDrawable(dst_drawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+
+ while (nbox--) {
+ if (dstBpp == 1) {
+ fbBlt(src + (box->y1 + dy + srcYoff) * srcStride,
+ srcStride,
+ (box->x1 + dx + srcXoff) * srcBpp,
+ dst + (box->y1 + dstYoff) * dstStride,
+ dstStride,
+ (box->x1 + dstXoff) * dstBpp,
+ (box->x2 - box->x1) * dstBpp,
+ (box->y2 - box->y1),
+ FbOpaqueStipple1Rop(gc->alu,
+ gc->fgPixel, gc->bgPixel),
+ pgc->pm, dstBpp, reverse, upsidedown);
+ } else {
+ fbBltOne((FbStip *) (src + (box->y1 + dy + srcYoff) * srcStride),
+ srcStride * (FB_UNIT / FB_STIP_UNIT),
+ (box->x1 + dx + srcXoff),
+ dst + (box->y1 + dstYoff) * dstStride,
+ dstStride,
+ (box->x1 + dstXoff) * dstBpp,
+ dstBpp,
+ (box->x2 - box->x1) * dstBpp,
+ (box->y2 - box->y1),
+ pgc->and, pgc->xor, pgc->bgand, pgc->bgxor);
+ }
+ box++;
+ }
+}
+
+void
+fbCopyNto1(DrawablePtr src_drawable, DrawablePtr dst_drawable, GCPtr gc,
+ BoxPtr box, int nbox,
+ int dx, int dy,
+ Bool reverse, Bool upsidedown, Pixel bitplane, void *closure)
+{
+ FbGCPrivPtr pgc = fb_gc(gc);
+
+ while (nbox--) {
+ if (dst_drawable->bitsPerPixel == 1) {
+ FbBits *src;
+ FbStride srcStride;
+ int srcBpp;
+ int srcXoff, srcYoff;
+
+ FbStip *dst;
+ FbStride dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+
+ fbGetDrawable(src_drawable, src,
+ srcStride, srcBpp, srcXoff, srcYoff);
+ fbGetStipDrawable(dst_drawable,
+ dst, dstStride, dstBpp, dstXoff, dstYoff);
+ fbBltPlane(src + (box->y1 + dy + srcYoff) * srcStride, srcStride,
+ (box->x1 + dx + srcXoff) * srcBpp, srcBpp,
+ dst + (box->y1 + dstYoff) * dstStride, dstStride,
+ (box->x1 + dstXoff) * dstBpp,
+ (box->x2 - box->x1) * srcBpp, (box->y2 - box->y1),
+ (FbStip) pgc->and, (FbStip) pgc->xor,
+ (FbStip) pgc->bgand, (FbStip) pgc->bgxor, bitplane);
+ } else {
+ FbBits *src;
+ FbStride srcStride;
+ int srcBpp;
+ int srcXoff, srcYoff;
+
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+
+ FbStip *tmp;
+ FbStride tmpStride;
+ int width, height;
+
+ width = box->x2 - box->x1;
+ height = box->y2 - box->y1;
+
+ tmpStride = ((width + FB_STIP_MASK) >> FB_STIP_SHIFT);
+ tmp = malloc(tmpStride * height * sizeof(FbStip));
+ if (!tmp)
+ return;
+
+ fbGetDrawable(src_drawable, src,
+ srcStride, srcBpp, srcXoff, srcYoff);
+ fbGetDrawable(dst_drawable, dst,
+ dstStride, dstBpp, dstXoff, dstYoff);
+
+ fbBltPlane(src + (box->y1 + dy + srcYoff) * srcStride,
+ srcStride,
+ (box->x1 + dx + srcXoff) * srcBpp,
+ srcBpp,
+ tmp,
+ tmpStride,
+ 0,
+ width * srcBpp,
+ height,
+ fbAndStip(GXcopy, FB_ALLONES, FB_ALLONES),
+ fbXorStip(GXcopy, FB_ALLONES, FB_ALLONES),
+ fbAndStip(GXcopy, 0, FB_ALLONES),
+ fbXorStip(GXcopy, 0, FB_ALLONES), bitplane);
+ fbBltOne(tmp,
+ tmpStride,
+ 0,
+ dst + (box->y1 + dstYoff) * dstStride,
+ dstStride,
+ (box->x1 + dstXoff) * dstBpp,
+ dstBpp,
+ width * dstBpp,
+ height,
+ pgc->and, pgc->xor, pgc->bgand, pgc->bgxor);
+ free(tmp);
+ }
+ box++;
+ }
+}
+
+RegionPtr
+fbCopyArea(DrawablePtr src, DrawablePtr dst, GCPtr gc,
+ int sx, int sy,
+ int width, int height,
+ int dx, int dy)
+{
+ return miDoCopy(src, dst, gc, sx, sy, width, height, dx, dy,
+ fbCopyNtoN, 0, 0);
+}
+
+RegionPtr
+fbCopyPlane(DrawablePtr src, DrawablePtr dst, GCPtr gc,
+ int sx, int sy,
+ int width, int height,
+ int dx, int dy,
+ unsigned long bitplane)
+{
+ if (src->bitsPerPixel > 1)
+ return miDoCopy(src, dst, gc, sx, sy, width, height, dx, dy,
+ fbCopyNto1, (Pixel) bitplane, 0);
+ else if (bitplane & 1)
+ return miDoCopy(src, dst, gc, sx, sy, width, height, dx, dy,
+ fbCopy1toN, (Pixel) bitplane, 0);
+ else
+ return miHandleExposures(src, dst, gc,
+ sx, sy, width, height, dx, dy,
+ bitplane);
+}
diff --git a/src/sna/fb/fbfill.c b/src/sna/fb/fbfill.c
new file mode 100644
index 000000000..a9ae2bcd7
--- /dev/null
+++ b/src/sna/fb/fbfill.c
@@ -0,0 +1,221 @@
+/*
+ * Copyright © 1998 Keith Packard
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "fb.h"
+#include "fbclip.h"
+
+static void
+fbSolid(FbBits * dst,
+ FbStride dstStride,
+ int dstX, int bpp, int width, int height, FbBits and, FbBits xor)
+{
+ FbBits startmask, endmask;
+ int n, nmiddle;
+ int startbyte, endbyte;
+
+ dst += dstX >> FB_SHIFT;
+ dstX &= FB_MASK;
+ FbMaskBitsBytes(dstX, width, and == 0, startmask, startbyte,
+ nmiddle, endmask, endbyte);
+ if (startmask)
+ dstStride--;
+ dstStride -= nmiddle;
+ while (height--) {
+ if (startmask) {
+ FbDoLeftMaskByteRRop(dst, startbyte, startmask, and, xor);
+ dst++;
+ }
+ n = nmiddle;
+ if (!and)
+ while (n--)
+ WRITE(dst++, xor);
+ else
+ while (n--) {
+ WRITE(dst, FbDoRRop(READ(dst), and, xor));
+ dst++;
+ }
+ if (endmask)
+ FbDoRightMaskByteRRop(dst, endbyte, endmask, and, xor);
+ dst += dstStride;
+ }
+}
+
+void
+fbFill(DrawablePtr drawable, GCPtr gc, int x, int y, int width, int height)
+{
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+ FbGCPrivPtr pgc = fb_gc(gc);
+
+ DBG(("%s (%d, %d)x(%d, %d), style=%d\n",
+ __FUNCTION__, x, y, width, height, gc->fillStyle));
+
+ fbGetDrawable(drawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+
+ switch (gc->fillStyle) {
+ case FillSolid:
+ if (pgc->and ||
+ !pixman_fill((uint32_t *) dst, dstStride, dstBpp,
+ x + dstXoff, y + dstYoff,
+ width, height, pgc->xor))
+ fbSolid(dst + (y + dstYoff) * dstStride,
+ dstStride,
+ (x + dstXoff) * dstBpp,
+ dstBpp, width * dstBpp, height, pgc->and, pgc->xor);
+ break;
+
+ case FillStippled:
+ case FillOpaqueStippled:
+ {
+ PixmapPtr pStip = gc->stipple;
+ int stipWidth = pStip->drawable.width;
+ int stipHeight = pStip->drawable.height;
+
+ if (dstBpp == 1) {
+ int alu;
+ FbBits *stip;
+ FbStride stipStride;
+ int stipBpp;
+ _X_UNUSED int stipXoff, stipYoff;
+
+ if (gc->fillStyle == FillStippled)
+ alu = FbStipple1Rop(gc->alu, gc->fgPixel);
+ else
+ alu = FbOpaqueStipple1Rop(gc->alu, gc->fgPixel, gc->bgPixel);
+ fbGetDrawable(&pStip->drawable, stip, stipStride, stipBpp, stipXoff,
+ stipYoff);
+ fbTile(dst + (y + dstYoff) * dstStride, dstStride, x + dstXoff,
+ width, height, stip, stipStride, stipWidth, stipHeight, alu,
+ pgc->pm, dstBpp, (gc->patOrg.x + drawable->x + dstXoff),
+ gc->patOrg.y + drawable->y - y);
+ } else {
+ FbStip *stip;
+ FbStride stipStride;
+ int stipBpp;
+ _X_UNUSED int stipXoff, stipYoff;
+ FbBits fgand, fgxor, bgand, bgxor;
+
+ fgand = pgc->and;
+ fgxor = pgc->xor;
+ if (gc->fillStyle == FillStippled) {
+ bgand = fbAnd(GXnoop, (FbBits) 0, FB_ALLONES);
+ bgxor = fbXor(GXnoop, (FbBits) 0, FB_ALLONES);
+ } else {
+ bgand = pgc->bgand;
+ bgxor = pgc->bgxor;
+ }
+
+ fbGetStipDrawable(&pStip->drawable, stip, stipStride, stipBpp,
+ stipXoff, stipYoff);
+ fbStipple(dst + (y + dstYoff) * dstStride, dstStride,
+ (x + dstXoff) * dstBpp, dstBpp, width * dstBpp, height,
+ stip, stipStride, stipWidth, stipHeight,
+ pgc->evenStipple, fgand, fgxor, bgand, bgxor,
+ gc->patOrg.x + drawable->x + dstXoff,
+ gc->patOrg.y + drawable->y - y);
+ }
+ break;
+ }
+
+ case FillTiled:
+ {
+ PixmapPtr tile = gc->tile.pixmap;
+
+ fbTile(dst + (y + dstYoff) * dstStride, dstStride,
+ (x + dstXoff) * dstBpp, width * dstBpp, height,
+ tile->devPrivate.ptr, tile->devKind / sizeof(FbBits),
+ tile->drawable.width * tile->drawable.bitsPerPixel,
+ tile->drawable.height,
+ gc->alu, pgc->pm, dstBpp,
+ (gc->patOrg.x + drawable->x + dstXoff) * dstBpp,
+ gc->patOrg.y + drawable->y - y);
+ break;
+ }
+ }
+}
+
+static void
+_fbSolidBox(DrawablePtr drawable, GCPtr gc, const BoxRec *b, void *_data)
+{
+ FbBits *dst;
+ FbStride stride;
+ int dx, dy, bpp;
+ FbBits and = fbAnd(GXcopy, fb_gc(gc)->bg, fb_gc(gc)->pm);
+ FbBits xor = fbXor(GXcopy, fb_gc(gc)->bg, fb_gc(gc)->pm);
+
+ fbGetDrawable(drawable, dst, stride, bpp, dx, dy);
+
+ if (and ||
+ !pixman_fill((uint32_t *) dst, stride, bpp,
+ b->x1 + dx, b->y1 + dy,
+ (b->x2 - b->x1), (b->y2 - b->y1), xor))
+ fbSolid(dst + (b->y1 + dy) * stride, stride,
+ (b->x1 + dx) * bpp, bpp,
+ (b->x2 - b->x1) * bpp, (b->y2 - b->y1),
+ and, xor);
+}
+
+void
+fbSolidBoxClipped(DrawablePtr drawable, GCPtr gc,
+ int x1, int y1, int x2, int y2)
+{
+ BoxRec box;
+
+ box.x1 = x1;
+ box.y1 = y1;
+ box.x2 = x2;
+ box.y2 = y2;
+
+ fbDrawableRun(drawable, gc, &box, _fbSolidBox, NULL);
+}
+
+inline static void
+fbFillBox(DrawablePtr drawable, GCPtr gc, const BoxRec *box, void *data)
+{
+ DBG(("%s box=(%d, %d), (%d, %d)\n", __FUNCTION__,
+ box->x1, box->y1, box->x2, box->y2));
+ fbFill(drawable, gc,
+ box->x1, box->y1,
+ box->x2 - box->x1, box->y2 - box->y1);
+}
+
+void
+fbPolyFillRect(DrawablePtr drawable, GCPtr gc, int n, xRectangle *r)
+{
+ DBG(("%s x %d\n", __FUNCTION__, n));
+ while (n--) {
+ BoxRec b;
+
+ b.x1 = r->x + drawable->x;
+ b.y1 = r->y + drawable->y;
+ b.x2 = fbBound(b.x1, r->width);
+ b.y2 = fbBound(b.y1, r->height);
+ r++;
+
+ DBG(("%s: rectangle (%d, %d), (%d, %d)\n",
+ __FUNCTION__, b.x1, b.y1, b.x2, b.y2));
+ fbDrawableRun(drawable, gc, &b, fbFillBox, NULL);
+ }
+}
diff --git a/src/sna/fb/fbgc.c b/src/sna/fb/fbgc.c
new file mode 100644
index 000000000..83956c414
--- /dev/null
+++ b/src/sna/fb/fbgc.c
@@ -0,0 +1,198 @@
+/*
+ * Copyright © 1998 Keith Packard
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "fb.h"
+#include <gcstruct.h>
+#include <migc.h>
+#include <scrnintstr.h>
+
+/*
+ * Pad pixmap to FB_UNIT bits wide
+ */
+void
+fbPadPixmap(PixmapPtr pPixmap)
+{
+ int width;
+ FbBits *bits;
+ FbBits b;
+ FbBits mask;
+ int height;
+ int w;
+ int stride;
+ int bpp;
+ _X_UNUSED int xOff, yOff;
+
+ fbGetDrawable(&pPixmap->drawable, bits, stride, bpp, xOff, yOff);
+
+ width = pPixmap->drawable.width * pPixmap->drawable.bitsPerPixel;
+ height = pPixmap->drawable.height;
+ mask = FbBitsMask(0, width);
+ while (height--) {
+ b = READ(bits) & mask;
+ w = width;
+ while (w < FB_UNIT) {
+ b = b | FbScrRight(b, w);
+ w <<= 1;
+ }
+ WRITE(bits, b);
+ bits += stride;
+ }
+}
+
+/*
+ * Verify that 'bits' repeats every 'len' bits
+ */
+static Bool
+fbBitsRepeat(FbBits bits, int len, int width)
+{
+ FbBits mask = FbBitsMask(0, len);
+ FbBits orig = bits & mask;
+ int i;
+
+ if (width > FB_UNIT)
+ width = FB_UNIT;
+ for (i = 0; i < width / len; i++) {
+ if ((bits & mask) != orig)
+ return FALSE;
+ bits = FbScrLeft(bits, len);
+ }
+ return TRUE;
+}
+
+/*
+ * Check whether an entire bitmap line is a repetition of
+ * the first 'len' bits
+ */
+static Bool
+fbLineRepeat(FbBits * bits, int len, int width)
+{
+ FbBits first = bits[0];
+
+ if (!fbBitsRepeat(first, len, width))
+ return FALSE;
+ width = (width + FB_UNIT - 1) >> FB_SHIFT;
+ bits++;
+ while (--width)
+ if (READ(bits) != first)
+ return FALSE;
+ return TRUE;
+}
+
+/*
+ * The even stipple code wants the first FB_UNIT/bpp bits on
+ * each scanline to represent the entire stipple
+ */
+static Bool
+fbCanEvenStipple(PixmapPtr pStipple, int bpp)
+{
+ int len = FB_UNIT / bpp;
+ FbBits *bits;
+ int stride;
+ int stip_bpp;
+ _X_UNUSED int stipXoff, stipYoff;
+ int h;
+
+ /* make sure the stipple width is a multiple of the even stipple width */
+ if (pStipple->drawable.width % len != 0)
+ return FALSE;
+
+ fbGetDrawable(&pStipple->drawable, bits, stride, stip_bpp, stipXoff,
+ stipYoff);
+ h = pStipple->drawable.height;
+ /* check to see that the stipple repeats horizontally */
+ while (h--) {
+ if (!fbLineRepeat(bits, len, pStipple->drawable.width))
+ return FALSE;
+
+ bits += stride;
+ }
+ return TRUE;
+}
+
+void
+fbValidateGC(GCPtr gc, unsigned long changes, DrawablePtr drawable)
+{
+ FbGCPrivPtr pgc = fb_gc(gc);
+ FbBits mask;
+
+ DBG(("%s changes=%lx\n", __FUNCTION__, changes));
+
+ if (changes & GCStipple) {
+ pgc->evenStipple = FALSE;
+
+ if (gc->stipple) {
+ /* can we do an even stipple ?? */
+ if (FbEvenStip(gc->stipple->drawable.width,
+ drawable->bitsPerPixel) &&
+ (fbCanEvenStipple(gc->stipple, drawable->bitsPerPixel)))
+ pgc->evenStipple = TRUE;
+ }
+ }
+
+ /*
+ * Recompute reduced rop values
+ */
+ if (changes & (GCForeground | GCBackground | GCPlaneMask | GCFunction)) {
+ int s;
+ FbBits depthMask;
+
+ mask = FbFullMask(drawable->bitsPerPixel);
+ depthMask = FbFullMask(drawable->depth);
+
+ DBG(("%s: computing rrop mask=%08x, depthMask=%08x, fg=%08x, bg=%08x, planemask=%08x\n",
+ __FUNCTION__, mask, depthMask, (int)gc->fgPixel, (int)gc->bgPixel, (int)gc->planemask));
+
+ pgc->fg = gc->fgPixel & mask;
+ pgc->bg = gc->bgPixel & mask;
+
+ if ((gc->planemask & depthMask) == depthMask)
+ pgc->pm = mask;
+ else
+ pgc->pm = gc->planemask & mask;
+
+ s = drawable->bitsPerPixel;
+ while (s < FB_UNIT) {
+ pgc->fg |= pgc->fg << s;
+ pgc->bg |= pgc->bg << s;
+ pgc->pm |= pgc->pm << s;
+ s <<= 1;
+ }
+ pgc->and = fbAnd(gc->alu, pgc->fg, pgc->pm);
+ pgc->xor = fbXor(gc->alu, pgc->fg, pgc->pm);
+ pgc->bgand = fbAnd(gc->alu, pgc->bg, pgc->pm);
+ pgc->bgxor = fbXor(gc->alu, pgc->bg, pgc->pm);
+
+ DBG(("%s: rrop fg=%08x, bg=%08x, pm=%08x, and=%08x, xor=%08x, bgand=%08x, bgxor=%08x\n",
+ __FUNCTION__, pgc->fg, pgc->bg, pgc->pm, pgc->and, pgc->xor, pgc->bgand, pgc->bgxor));
+ }
+
+ if (changes & GCDashList) {
+ unsigned short n = gc->numInDashList;
+ unsigned char *dash = gc->dash;
+ unsigned int dashLength = 0;
+
+ while (n--)
+ dashLength += (unsigned int) *dash++;
+ pgc->dashLength = dashLength;
+ }
+}
diff --git a/src/sna/fb/fbglyph.c b/src/sna/fb/fbglyph.c
new file mode 100644
index 000000000..789e5b849
--- /dev/null
+++ b/src/sna/fb/fbglyph.c
@@ -0,0 +1,277 @@
+/*
+ * Copyright © 1998 Keith Packard
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "fb.h"
+#include <X11/fonts/fontstruct.h>
+#include <dixfontstr.h>
+
+#define GLYPH fbGlyph8
+#define BITS BYTE
+#define BITS2 CARD16
+#define BITS4 CARD32
+#include "fbglyphbits.h"
+#undef BITS
+#undef BITS2
+#undef BITS4
+#undef GLYPH
+
+#define GLYPH fbGlyph16
+#define BITS CARD16
+#define BITS2 CARD32
+#include "fbglyphbits.h"
+#undef BITS
+#undef BITS2
+#undef GLYPH
+
+#define GLYPH fbGlyph32
+#define BITS CARD32
+#include "fbglyphbits.h"
+#undef BITS
+#undef GLYPH
+
+static bool
+fbGlyphIn(GCPtr gc, int x, int y, int width, int height)
+{
+ BoxRec box;
+ BoxPtr extents = RegionExtents(gc->pCompositeClip);
+
+ /*
+ * Check extents by hand to avoid 16 bit overflows
+ */
+ if (x < (int) extents->x1 || (int) extents->x2 < x + width)
+ return FALSE;
+ if (y < (int) extents->y1 || (int) extents->y2 < y + height)
+ return FALSE;
+
+ box.x1 = x;
+ box.x2 = x + width;
+ box.y1 = y;
+ box.y2 = y + height;
+ return RegionContainsRect(gc->pCompositeClip, &box) == rgnIN;
+}
+
+#define WRITE1(d,n,fg) WRITE((d) + (n), (CARD8) fg)
+#define WRITE2(d,n,fg) WRITE((CARD16 *) &(d[n]), (CARD16) fg)
+#define WRITE4(d,n,fg) WRITE((CARD32 *) &(d[n]), (CARD32) fg)
+
+/*
+ * This is a bit tricky, but it's brief. Write 12 bytes worth
+ * of dest, which is four pixels, at a time. This gives constant
+ * code for each pattern as they're always aligned the same
+ *
+ * a b c d a b c d a b c d bytes
+ * A B C A B C A B C A B C pixels
+ *
+ * f0 f1 f2
+ * A B C A B C A B C A B C pixels LSB
+ * C A B C A B C A B C A B pixels MSB
+ *
+ * LSB MSB
+ * A f0 f1
+ * B f1 f2
+ * C f2 f0
+ * A B f0 f2
+ * B C f1 f0
+ * C A f2 f1
+ * A B C A f0 f1
+ * B C A B f1 f2
+ * C A B C f2 f0
+ */
+
+#undef _A
+#undef _B
+#undef _C
+#undef _AB
+#undef _BC
+#undef _CA
+#undef _ABCA
+#undef _BCAB
+#undef _CABC
+
+#define _A f0
+#define _B f1
+#define _C f2
+#define _AB f0
+#define _BC f1
+#define _CA f2
+#define _ABCA f0
+#define _BCAB f1
+#define _CABC f2
+#define CASE(a,b,c,d) (a | (b << 1) | (c << 2) | (d << 3))
+
+void
+fbPolyGlyphBlt(DrawablePtr drawable, GCPtr gc,
+ int x, int y,
+ unsigned int nglyph, CharInfoPtr * ppci, pointer glyphs)
+{
+ FbGCPrivPtr pgc = fb_gc(gc);
+ CharInfoPtr pci;
+ unsigned char *pglyph; /* pointer bits in glyph */
+ int gx, gy;
+ int gWidth, gHeight; /* width and height of glyph */
+ FbStride gStride; /* stride of glyph */
+ void (*raster) (FbBits *, FbStride, int, FbStip *, FbBits, int, int);
+ FbBits *dst = 0;
+ FbStride dstStride = 0;
+ int dstBpp = 0;
+ int dstXoff = 0, dstYoff = 0;
+
+ DBG(("%s x %d\n", __FUNCTION__, nglyph));
+
+ raster = 0;
+ if (gc->fillStyle == FillSolid && pgc->and == 0) {
+ dstBpp = drawable->bitsPerPixel;
+ switch (dstBpp) {
+ case 8:
+ raster = fbGlyph8;
+ break;
+ case 16:
+ raster = fbGlyph16;
+ break;
+ case 32:
+ raster = fbGlyph32;
+ break;
+ }
+ }
+ x += drawable->x;
+ y += drawable->y;
+
+ while (nglyph--) {
+ pci = *ppci++;
+ pglyph = FONTGLYPHBITS(glyphs, pci);
+ gWidth = GLYPHWIDTHPIXELS(pci);
+ gHeight = GLYPHHEIGHTPIXELS(pci);
+ if (gWidth && gHeight) {
+ gx = x + pci->metrics.leftSideBearing;
+ gy = y - pci->metrics.ascent;
+ if (raster && gWidth <= sizeof(FbStip) * 8 &&
+ fbGlyphIn(gc, gx, gy, gWidth, gHeight)) {
+ fbGetDrawable(drawable, dst, dstStride, dstBpp, dstXoff,
+ dstYoff);
+ raster(dst + (gy + dstYoff) * dstStride, dstStride, dstBpp,
+ (FbStip *) pglyph, pgc->xor, gx + dstXoff, gHeight);
+ } else {
+ gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof(FbStip);
+ fbPushImage(drawable, gc,
+ (FbStip *)pglyph,
+ gStride, 0, gx, gy, gWidth, gHeight);
+ }
+ }
+ x += pci->metrics.characterWidth;
+ }
+}
+
+void
+fbImageGlyphBlt(DrawablePtr drawable, GCPtr gc,
+ int x, int y,
+ unsigned int nglyph, CharInfoPtr * ppciInit, pointer glyphs)
+{
+ FbGCPrivPtr pgc = fb_gc(gc);
+ CharInfoPtr *ppci;
+ CharInfoPtr pci;
+ unsigned char *pglyph; /* pointer bits in glyph */
+ int gWidth, gHeight; /* width and height of glyph */
+ FbStride gStride; /* stride of glyph */
+ bool opaque;
+ int n;
+ int gx, gy;
+ void (*raster)(FbBits *, FbStride, int, FbStip *, FbBits, int, int);
+ FbBits *dst = 0;
+ FbStride dstStride = 0;
+ int dstBpp = 0;
+ int dstXoff = 0, dstYoff = 0;
+
+ DBG(("%s x %d\n", __FUNCTION__, nglyph));
+
+ raster = 0;
+ if (pgc->and == 0) {
+ dstBpp = drawable->bitsPerPixel;
+ switch (dstBpp) {
+ case 8:
+ raster = fbGlyph8;
+ break;
+ case 16:
+ raster = fbGlyph16;
+ break;
+ case 32:
+ raster = fbGlyph32;
+ break;
+ }
+ }
+
+ x += drawable->x;
+ y += drawable->y;
+
+ if (TERMINALFONT(gc->font) && !raster) {
+ opaque = TRUE;
+ } else {
+ int xBack, widthBack;
+ int yBack, heightBack;
+
+ ppci = ppciInit;
+ n = nglyph;
+ widthBack = 0;
+ while (n--)
+ widthBack += (*ppci++)->metrics.characterWidth;
+
+ xBack = x;
+ if (widthBack < 0) {
+ xBack += widthBack;
+ widthBack = -widthBack;
+ }
+ yBack = y - FONTASCENT(gc->font);
+ heightBack = FONTASCENT(gc->font) + FONTDESCENT(gc->font);
+ fbSolidBoxClipped(drawable, gc,
+ xBack, yBack,
+ xBack + widthBack,
+ yBack + heightBack);
+ opaque = FALSE;
+ }
+
+ ppci = ppciInit;
+ while (nglyph--) {
+ pci = *ppci++;
+ pglyph = FONTGLYPHBITS(glyphs, pci);
+ gWidth = GLYPHWIDTHPIXELS(pci);
+ gHeight = GLYPHHEIGHTPIXELS(pci);
+ if (gWidth && gHeight) {
+ gx = x + pci->metrics.leftSideBearing;
+ gy = y - pci->metrics.ascent;
+ if (raster && gWidth <= sizeof(FbStip) * 8 &&
+ fbGlyphIn(gc, gx, gy, gWidth, gHeight)) {
+ fbGetDrawable(drawable, dst, dstStride, dstBpp, dstXoff,
+ dstYoff);
+ raster(dst + (gy + dstYoff) * dstStride, dstStride, dstBpp,
+ (FbStip *) pglyph, pgc->fg, gx + dstXoff, gHeight);
+ } else {
+ gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof(FbStip);
+ fbPutXYImage(drawable, gc,
+ pgc->fg, pgc->bg, pgc->pm,
+ GXcopy, opaque,
+ gx, gy, gWidth, gHeight,
+ (FbStip *) pglyph, gStride, 0);
+ }
+ }
+ x += pci->metrics.characterWidth;
+ }
+}
diff --git a/src/sna/fb/fbglyphbits.h b/src/sna/fb/fbglyphbits.h
new file mode 100644
index 000000000..af0f00ffa
--- /dev/null
+++ b/src/sna/fb/fbglyphbits.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright © 1998 Keith Packard
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define isClipped(c,ul,lr) (((c) | ((c) - (ul)) | ((lr) - (c))) & 0x80008000)
+#define RROP(b,a,x) WRITE((b), FbDoRRop (READ(b), (a), (x)))
+
+#define WRITE_ADDR1(n) (n)
+#define WRITE_ADDR2(n) (n)
+#define WRITE_ADDR4(n) (n)
+
+#define WRITE1(d,n,fg) WRITE(d + WRITE_ADDR1(n), (BITS) (fg))
+
+#ifdef BITS2
+#define WRITE2(d,n,fg) WRITE((BITS2 *) &((d)[WRITE_ADDR2(n)]), (BITS2) (fg))
+#else
+#define WRITE2(d,n,fg) (WRITE1(d,n,fg), WRITE1(d,(n)+1,fg))
+#endif
+
+#ifdef BITS4
+#define WRITE4(d,n,fg) WRITE((BITS4 *) &((d)[WRITE_ADDR4(n)]), (BITS4) (fg))
+#else
+#define WRITE4(d,n,fg) (WRITE2(d,n,fg), WRITE2(d,(n)+2,fg))
+#endif
+
+static void
+GLYPH(FbBits * dstBits,
+ FbStride dstStride,
+ int dstBpp, FbStip * stipple, FbBits fg, int x, int height)
+{
+ int lshift;
+ FbStip bits;
+ BITS *dstLine;
+ BITS *dst;
+ int n;
+ int shift;
+
+ dstLine = (BITS *) dstBits;
+ dstLine += x & ~3;
+ dstStride *= (sizeof(FbBits) / sizeof(BITS));
+ shift = x & 3;
+ lshift = 4 - shift;
+ while (height--) {
+ bits = *stipple++;
+ dst = (BITS *) dstLine;
+ n = lshift;
+ while (bits) {
+ switch (FbStipMoveLsb(FbLeftStipBits(bits, n), 4, n)) {
+ case 0:
+ break;
+ case 1:
+ WRITE1(dst, 0, fg);
+ break;
+ case 2:
+ WRITE1(dst, 1, fg);
+ break;
+ case 3:
+ WRITE2(dst, 0, fg);
+ break;
+ case 4:
+ WRITE1(dst, 2, fg);
+ break;
+ case 5:
+ WRITE1(dst, 0, fg);
+ WRITE1(dst, 2, fg);
+ break;
+ case 6:
+ WRITE1(dst, 1, fg);
+ WRITE1(dst, 2, fg);
+ break;
+ case 7:
+ WRITE2(dst, 0, fg);
+ WRITE1(dst, 2, fg);
+ break;
+ case 8:
+ WRITE1(dst, 3, fg);
+ break;
+ case 9:
+ WRITE1(dst, 0, fg);
+ WRITE1(dst, 3, fg);
+ break;
+ case 10:
+ WRITE1(dst, 1, fg);
+ WRITE1(dst, 3, fg);
+ break;
+ case 11:
+ WRITE2(dst, 0, fg);
+ WRITE1(dst, 3, fg);
+ break;
+ case 12:
+ WRITE2(dst, 2, fg);
+ break;
+ case 13:
+ WRITE1(dst, 0, fg);
+ WRITE2(dst, 2, fg);
+ break;
+ case 14:
+ WRITE1(dst, 1, fg);
+ WRITE2(dst, 2, fg);
+ break;
+ case 15:
+ WRITE4(dst, 0, fg);
+ break;
+ }
+ bits = FbStipLeft(bits, n);
+ n = 4;
+ dst += 4;
+ }
+ dstLine += dstStride;
+ }
+}
+
+#undef WRITE_ADDR1
+#undef WRITE_ADDR2
+#undef WRITE_ADDR4
+#undef WRITE1
+#undef WRITE2
+#undef WRITE4
+
+#undef RROP
+#undef isClipped
diff --git a/src/sna/fb/fbimage.c b/src/sna/fb/fbimage.c
new file mode 100644
index 000000000..5af238902
--- /dev/null
+++ b/src/sna/fb/fbimage.c
@@ -0,0 +1,254 @@
+/*
+ * Copyright © 1998 Keith Packard
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <string.h>
+
+#include "fb.h"
+#include "fbclip.h"
+
+struct fbPutZImage {
+ FbStip *src, *dst;
+ FbStride src_stride, dst_stride;
+
+ int dst_x, dst_y;
+ int x0, y0;
+};
+
+inline static void
+_fbPutZImage(DrawablePtr drawable, GCPtr gc, const BoxRec *b, void *_data)
+{
+ struct fbPutZImage *data = _data;
+ int bpp = drawable->bitsPerPixel;
+
+ fbBltStip(data->src + (b->y1 - data->y0) * data->src_stride, data->src_stride,
+ (b->x1 - data->x0) * bpp,
+ data->dst + (b->y1 + data->dst_y) * data->dst_stride,
+ data->dst_stride,
+ (b->x1 + data->dst_x) * bpp,
+ (b->x2 - b->x1) * bpp, (b->y2 - b->y1),
+ gc->alu, fb_gc(gc)->pm, bpp);
+}
+
+static void
+fbPutZImage(DrawablePtr drawable, GCPtr gc,
+ int x, int y, int width, int height,
+ FbStip *src, FbStride srcStride)
+{
+ PixmapPtr pixmap;
+ struct fbPutZImage data;
+ BoxRec box;
+
+ box.x1 = data.x0 = x;
+ box.y1 = data.y0 = y;
+ box.x2 = x + width;
+ box.y2 = y + height;
+ data.src = src;
+ data.src_stride = srcStride;
+
+ fbGetDrawablePixmap(drawable, pixmap, data.dst_x, data.dst_y);
+ data.dst = pixmap->devPrivate.ptr;
+ data.dst_stride = pixmap->devKind / sizeof(FbStip);
+
+ fbDrawableRun(drawable, gc, &box, _fbPutZImage, &data);
+}
+
+struct fbPutXYImage {
+ FbStip *src, *dst;
+ FbStride src_stride, dst_stride;
+
+ int dst_x, dst_y, src_x;
+ int x0, y0;
+
+ int alu, pm;
+ FbBits fgand, fgxor, bgand, bgxor;
+};
+
+inline static void
+_fbPutXYImage1(DrawablePtr drawable, GCPtr gc, const BoxRec *b, void *_data)
+{
+ struct fbPutXYImage *data = _data;
+ int bpp = drawable->bitsPerPixel;
+
+ fbBltStip(data->src + (b->y1 - data->y0) * data->src_stride, data->src_stride,
+ (b->x1 - data->x0) + data->src_x,
+ (FbStip *) (data->dst + (b->y1 + data->dst_y) * data->dst_stride),
+ data->dst_stride,
+ (b->x1 + data->dst_x) * bpp,
+ (b->x2 - b->x1) * bpp, (b->y2 - b->y1),
+ data->alu, data->pm, bpp);
+}
+
+inline static void
+_fbPutXYImageN(DrawablePtr drawable, GCPtr gc, const BoxRec *b, void *_data)
+{
+ struct fbPutXYImage *data = _data;
+ int bpp = drawable->bitsPerPixel;
+
+ fbBltOne(data->src + (b->y1 - data->y0) * data->src_stride,
+ data->src_stride,
+ (b->x1 - data->x0) + data->src_x,
+ data->dst + (b->y1 + data->dst_y) * data->dst_stride,
+ data->dst_stride,
+ (b->x1 + data->dst_x) * bpp, bpp,
+ (b->x2 - b->x1) * bpp, (b->y2 - b->y1),
+ data->fgand, data->fgxor,
+ data->bgand, data->bgxor);
+}
+
+void
+fbPutXYImage(DrawablePtr drawable, GCPtr gc,
+ FbBits fg, FbBits bg, FbBits pm, int alu, Bool opaque,
+ int x, int y, int width, int height,
+ FbStip *src, FbStride srcStride, int srcX)
+{
+ PixmapPtr pixmap;
+ struct fbPutXYImage data;
+ BoxRec box;
+
+ box.x1 = data.x0 = x;
+ box.y1 = data.y0 = y;
+ box.x2 = x + width;
+ box.y2 = y + height;
+ data.src = src;
+ data.src_stride = srcStride;
+ data.src_x = srcX;
+
+ fbGetDrawablePixmap(drawable, pixmap, data.dst_x, data.dst_y);
+ data.dst = pixmap->devPrivate.ptr;
+ data.dst_stride = pixmap->devKind / sizeof(FbStip);
+
+ if (drawable->bitsPerPixel == 1) {
+ if (opaque)
+ data.alu = FbOpaqueStipple1Rop(alu, fg, bg);
+ else
+ data.alu = FbStipple1Rop(alu, fg);
+ data.pm = pm;
+
+ fbDrawableRun(drawable, gc, &box, _fbPutXYImage1, &data);
+ } else {
+ data.fgand = fbAnd(alu, fg, pm);
+ data.fgxor = fbXor(alu, fg, pm);
+ if (opaque) {
+ data.bgand = fbAnd(alu, bg, pm);
+ data.bgxor = fbXor(alu, bg, pm);
+ } else {
+ data.bgand = fbAnd(GXnoop, (FbBits) 0, FB_ALLONES);
+ data.bgxor = fbXor(GXnoop, (FbBits) 0, FB_ALLONES);
+ }
+
+ fbDrawableRun(drawable, gc, &box, _fbPutXYImageN, &data);
+ }
+}
+
+void
+fbPutImage(DrawablePtr drawable, GCPtr gc, int depth,
+ int x, int y, int w, int h,
+ int leftPad, int format, char *image)
+{
+ FbGCPrivPtr pgc = fb_gc(gc);
+ unsigned long i;
+ FbStride srcStride;
+ FbStip *src = (FbStip *)image;
+
+ DBG(("%s (%d, %d)x(%d, %d)\n", __FUNCTION__, x, y, w, h));
+
+ x += drawable->x;
+ y += drawable->y;
+
+ switch (format) {
+ case XYBitmap:
+ srcStride = BitmapBytePad(w + leftPad) / sizeof(FbStip);
+ fbPutXYImage(drawable, gc,
+ pgc->fg, pgc->bg, pgc->pm,
+ gc->alu, TRUE,
+ x, y, w, h,
+ src, srcStride, leftPad);
+ break;
+ case XYPixmap:
+ srcStride = BitmapBytePad(w + leftPad) / sizeof(FbStip);
+ for (i = (unsigned long) 1 << (drawable->depth - 1); i; i >>= 1) {
+ if (i & gc->planemask) {
+ fbPutXYImage(drawable, gc,
+ FB_ALLONES,
+ 0,
+ fbReplicatePixel(i, drawable->bitsPerPixel),
+ gc->alu,
+ TRUE, x, y, w, h, src, srcStride, leftPad);
+ src += srcStride * h;
+ }
+ }
+ break;
+ case ZPixmap:
+ srcStride = PixmapBytePad(w, drawable->depth) / sizeof(FbStip);
+ fbPutZImage(drawable, gc,
+ x, y, w, h, src, srcStride);
+ }
+}
+
+void
+fbGetImage(DrawablePtr drawable,
+ int x, int y, int w, int h,
+ unsigned int format, unsigned long planeMask, char *d)
+{
+ FbBits *src;
+ FbStride srcStride;
+ int srcBpp;
+ int srcXoff, srcYoff;
+ FbStip *dst;
+ FbStride dstStride;
+
+ DBG(("%s (%d, %d)x(%d, %d)\n", __FUNCTION__, x, y, w, h));
+
+ fbGetDrawable(drawable, src, srcStride, srcBpp, srcXoff, srcYoff);
+
+ x += drawable->x;
+ y += drawable->y;
+
+ dst = (FbStip *) d;
+ if (format == ZPixmap || srcBpp == 1) {
+ FbBits pm;
+
+ pm = fbReplicatePixel(planeMask, srcBpp);
+ dstStride = PixmapBytePad(w, drawable->depth);
+ if (pm != FB_ALLONES)
+ memset(d, 0, dstStride * h);
+ dstStride /= sizeof(FbStip);
+ fbBltStip((FbStip *)(src + (y + srcYoff) * srcStride), srcStride,
+ (x + srcXoff) * srcBpp,
+ dst, dstStride, 0, w * srcBpp, h, GXcopy, pm, srcBpp);
+ } else {
+ dstStride = BitmapBytePad(w) / sizeof(FbStip);
+ fbBltPlane(src + (y + srcYoff) * srcStride,
+ srcStride,
+ (x + srcXoff) * srcBpp,
+ srcBpp,
+ dst,
+ dstStride,
+ 0,
+ w * srcBpp, h,
+ fbAndStip(GXcopy, FB_STIP_ALLONES, FB_STIP_ALLONES),
+ fbXorStip(GXcopy, FB_STIP_ALLONES, FB_STIP_ALLONES),
+ fbAndStip(GXcopy, 0, FB_STIP_ALLONES),
+ fbXorStip(GXcopy, 0, FB_STIP_ALLONES), planeMask);
+ }
+}
diff --git a/src/sna/fb/fbline.c b/src/sna/fb/fbline.c
new file mode 100644
index 000000000..04d5343c4
--- /dev/null
+++ b/src/sna/fb/fbline.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright © 1998 Keith Packard
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "fb.h"
+#include <mi.h>
+#include <micoord.h>
+#include <miline.h>
+#include <scrnintstr.h>
+
+#define POLYLINE fbPolyline8
+#define POLYSEGMENT fbPolySegment8
+#define BITS BYTE
+#define BITS2 CARD16
+#define BITS4 CARD32
+#include "fblinebits.h"
+#undef BITS
+#undef BITS2
+#undef BITS4
+#undef POLYSEGMENT
+#undef POLYLINE
+
+#define POLYLINE fbPolyline16
+#define POLYSEGMENT fbPolySegment16
+#define BITS CARD16
+#define BITS2 CARD32
+#include "fblinebits.h"
+#undef BITS
+#undef BITS2
+#undef POLYSEGMENT
+#undef POLYLINE
+
+#define POLYLINE fbPolyline32
+#define POLYSEGMENT fbPolySegment32
+#define BITS CARD32
+#include "fblinebits.h"
+#undef BITS
+#undef POLYSEGMENT
+#undef POLYLINE
+
+static void
+fbZeroLine(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr pt)
+{
+ int x1, y1, x2, y2;
+ int x, y;
+ int dashOffset;
+
+ x = drawable->x;
+ y = drawable->y;
+ x1 = pt->x;
+ y1 = pt->y;
+ dashOffset = gc->dashOffset;
+ while (--n) {
+ ++pt;
+ x2 = pt->x;
+ y2 = pt->y;
+ if (mode == CoordModePrevious) {
+ x2 += x1;
+ y2 += y1;
+ }
+ fbSegment(drawable, gc,
+ x1 + x, y1 + y,
+ x2 + x, y2 + y,
+ n == 1 && gc->capStyle != CapNotLast, &dashOffset);
+ x1 = x2;
+ y1 = y2;
+ }
+}
+
+static void
+fbZeroSegment(DrawablePtr drawable, GCPtr gc, int n, xSegment *seg)
+{
+ int dashOffset;
+ int16_t x, y;
+ Bool drawLast = gc->capStyle != CapNotLast;
+
+ x = drawable->x;
+ y = drawable->y;
+ while (n--) {
+ dashOffset = gc->dashOffset;
+ fbSegment(drawable, gc,
+ seg->x1 + x, seg->y1 + y,
+ seg->x2 + x, seg->y2 + y,
+ drawLast, &dashOffset);
+ seg++;
+ }
+}
+
+void
+fbFixCoordModePrevious(int n, DDXPointPtr pt)
+{
+ int16_t x = pt->x;
+ int16_t y = pt->y;
+ while (--n) {
+ pt++;
+ x = (pt->x += x);
+ y = (pt->y += y);
+ }
+}
+
+void
+fbPolyLine(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr pt)
+{
+ void (*raster)(DrawablePtr, GCPtr, int mode, int n, DDXPointPtr pt);
+
+ DBG(("%s x %d, width=%d, fill=%d, line=%d\n",
+ __FUNCTION__, n, gc->lineWidth, gc->fillStyle, gc->lineStyle));
+
+ if (gc->lineWidth == 0) {
+ raster = fbZeroLine;
+ if (gc->fillStyle == FillSolid && gc->lineStyle == LineSolid) {
+ switch (drawable->bitsPerPixel) {
+ case 8:
+ raster = fbPolyline8;
+ break;
+ case 16:
+ raster = fbPolyline16;
+ break;
+ case 32:
+ raster = fbPolyline32;
+ break;
+ }
+ }
+ } else {
+ if (gc->lineStyle != LineSolid)
+ raster = miWideDash;
+ else
+ raster = miWideLine;
+ }
+ raster(drawable, gc, mode, n, pt);
+}
+
+void
+fbPolySegment(DrawablePtr drawable, GCPtr gc, int n, xSegment *seg)
+{
+ void (*raster)(DrawablePtr drawable, GCPtr gc, int n, xSegment * seg);
+
+ DBG(("%s x %d, width=%d, fill=%d, line=%d\n",
+ __FUNCTION__, n, gc->lineWidth, gc->fillStyle, gc->lineStyle));
+
+ if (gc->lineWidth == 0) {
+ raster = fbZeroSegment;
+ if (gc->fillStyle == FillSolid && gc->lineStyle == LineSolid) {
+ switch (drawable->bitsPerPixel) {
+ case 8:
+ raster = fbPolySegment8;
+ break;
+ case 16:
+ raster = fbPolySegment16;
+ break;
+ case 32:
+ raster = fbPolySegment32;
+ break;
+ }
+ }
+ } else
+ raster = miPolySegment;
+
+ raster(drawable, gc, n, seg);
+}
diff --git a/src/sna/fb/fblinebits.h b/src/sna/fb/fblinebits.h
new file mode 100644
index 000000000..db315d818
--- /dev/null
+++ b/src/sna/fb/fblinebits.h
@@ -0,0 +1,284 @@
+/*
+ * Copyright © 1998 Keith Packard
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define isClipped(c,ul,lr) (((c) | ((c) - (ul)) | ((lr) - (c))) & 0x80008000)
+#define RROP(b,a,x) WRITE((b), FbDoRRop (READ(b), (a), (x)))
+
+static void
+POLYLINE(DrawablePtr drawable, GCPtr gc, int mode, int n_0, DDXPointPtr pt_0)
+{
+ int xoff = drawable->x;
+ int yoff = drawable->y;
+ unsigned int bias = miGetZeroLineBias(drawable->pScreen);
+ const BoxRec *clip = RegionRects(gc->pCompositeClip);
+ const BoxRec *const last_clip = clip + RegionNumRects(gc->pCompositeClip);
+
+ FbBits *dst;
+ int dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+
+ BITS *bits, *bitsBase;
+ FbStride bitsStride;
+ BITS xor = fb_gc(gc)->xor;
+ BITS and = fb_gc(gc)->and;
+
+
+ int e, e1, e3, len;
+ int stepmajor, stepminor;
+ int octant;
+
+ if (mode == CoordModePrevious)
+ fbFixCoordModePrevious(n_0, pt_0);
+
+ fbGetDrawable(drawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+ bitsStride = dstStride * (sizeof(FbBits) / sizeof(BITS));
+ bitsBase =
+ ((BITS *) dst) + (yoff + dstYoff) * bitsStride + (xoff + dstXoff);
+ do {
+ INT32 *pt = (INT32 *)pt_0;
+ int n = n_0;
+ INT32 pt1, pt2;
+
+ INT32 ul = coordToInt(clip->x1 - xoff, clip->y1 - yoff);
+ INT32 lr = coordToInt(clip->x2 - xoff - 1, clip->y2 - yoff - 1);
+
+ pt1 = *pt++; n--;
+ pt2 = *pt++; n--;
+ for (;;) {
+ if (isClipped(pt1, ul, lr) | isClipped(pt2, ul, lr)) {
+ int dashoffset = 0;
+ fbSegment1(drawable, gc, clip,
+ intToX(pt1) + xoff, intToY(pt1) + yoff,
+ intToX(pt2) + xoff, intToY(pt2) + yoff,
+ n == 0 && gc->capStyle != CapNotLast, &dashoffset);
+ if (!n)
+ return;
+
+ pt1 = pt2;
+ pt2 = *pt++;
+ n--;
+ } else {
+ bits = bitsBase + intToY(pt1) * bitsStride + intToX(pt1);
+ for (;;) {
+ CalcLineDeltas(intToX(pt1), intToY(pt1),
+ intToX(pt2), intToY(pt2),
+ len, e1, stepmajor, stepminor, 1, bitsStride,
+ octant);
+ if (len < e1) {
+ e3 = len;
+ len = e1;
+ e1 = e3;
+
+ e3 = stepminor;
+ stepminor = stepmajor;
+ stepmajor = e3;
+ SetYMajorOctant(octant);
+ }
+ e = -len;
+ e1 <<= 1;
+ e3 = e << 1;
+ FIXUP_ERROR(e, octant, bias);
+ if (and == 0) {
+ while (len--) {
+ WRITE(bits, xor);
+ bits += stepmajor;
+ e += e1;
+ if (e >= 0) {
+ bits += stepminor;
+ e += e3;
+ }
+ }
+ } else {
+ while (len--) {
+ RROP(bits, and, xor);
+ bits += stepmajor;
+ e += e1;
+ if (e >= 0) {
+ bits += stepminor;
+ e += e3;
+ }
+ }
+ }
+ if (!n) {
+ if (gc->capStyle != CapNotLast &&
+ pt2 != *((INT32 *)pt_0)) {
+ RROP(bits, and, xor);
+ }
+ return;
+ }
+ pt1 = pt2;
+ pt2 = *pt++;
+ --n;
+ if (isClipped(pt2, ul, lr))
+ break;
+ }
+ }
+ }
+ } while (++clip != last_clip);
+}
+
+static void
+POLYSEGMENT(DrawablePtr drawable, GCPtr gc, int n_0, xSegment *seg_0)
+{
+ int xoff = drawable->x;
+ int yoff = drawable->y;
+ unsigned int bias = miGetZeroLineBias(drawable->pScreen);
+ const BoxRec *clip = RegionRects(gc->pCompositeClip);
+ const BoxRec *const last_clip = clip + RegionNumRects(gc->pCompositeClip);
+
+ FbBits *dst;
+ int dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+
+ BITS *bits, *bitsBase;
+ FbStride bitsStride;
+ FbBits xor = fb_gc(gc)->xor;
+ FbBits and = fb_gc(gc)->and;
+
+ int e, e1, e3, len;
+ int stepmajor, stepminor;
+ int octant;
+ bool capNotLast = gc->capStyle == CapNotLast;
+
+ fbGetDrawable(drawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+ bitsStride = dstStride * (sizeof(FbBits) / sizeof(BITS));
+ bitsBase =
+ ((BITS *) dst) + (yoff + dstYoff) * bitsStride + (xoff + dstXoff);
+
+ do {
+ INT32 ul = coordToInt(clip->x1 - xoff, clip->y1 - yoff);
+ INT32 lr = coordToInt(clip->x2 - xoff - 1, clip->y2 - yoff - 1);
+ uint64_t *pt = (uint64_t *)seg_0;
+ int n = n_0;
+
+ while (n--) {
+ union {
+ int32_t pt32[2];
+ uint64_t pt64;
+ } u;
+
+ u.pt64 = *pt++;
+ if (isClipped(u.pt32[0], ul, lr) | isClipped(u.pt32[1], ul, lr)) {
+ int dashoffset = 0;
+ fbSegment1(drawable, gc, clip,
+ intToX(u.pt32[0]) + xoff, intToY(u.pt32[0]) + yoff,
+ intToX(u.pt32[1]) + xoff, intToY(u.pt32[1]) + yoff,
+ !capNotLast, &dashoffset);
+ } else {
+ CalcLineDeltas(intToX(u.pt32[0]), intToY(u.pt32[0]),
+ intToX(u.pt32[1]), intToY(u.pt32[1]),
+ len, e1, stepmajor, stepminor, 1, bitsStride,
+ octant);
+ if (e1 == 0 && len > 3) {
+ int x1, x2;
+ FbBits *dstLine;
+ int dstX, width;
+ FbBits startmask, endmask;
+ int nmiddle;
+
+ if (stepmajor < 0) {
+ x1 = intToX(u.pt32[1]);
+ x2 = intToX(u.pt32[0]) + 1;
+ if (capNotLast)
+ x1++;
+ } else {
+ x1 = intToX(u.pt32[0]);
+ x2 = intToX(u.pt32[1]);
+ if (!capNotLast)
+ x2++;
+ }
+ dstX = (x1 + xoff + dstXoff) * (sizeof(BITS) * 8);
+ width = (x2 - x1) * (sizeof(BITS) * 8);
+
+ dstLine = dst + (intToY(u.pt32[0]) + yoff + dstYoff) * dstStride;
+ dstLine += dstX >> FB_SHIFT;
+ dstX &= FB_MASK;
+ FbMaskBits(dstX, width, startmask, nmiddle, endmask);
+ if (startmask) {
+ WRITE(dstLine,
+ FbDoMaskRRop(READ(dstLine), and, xor,
+ startmask));
+ dstLine++;
+ }
+ if (!and)
+ while (nmiddle--)
+ WRITE(dstLine++, xor);
+ else
+ while (nmiddle--) {
+ WRITE(dstLine,
+ FbDoRRop(READ(dstLine), and, xor));
+ dstLine++;
+ }
+ if (endmask)
+ WRITE(dstLine,
+ FbDoMaskRRop(READ(dstLine), and, xor,
+ endmask));
+ } else {
+ bits = bitsBase + intToY(u.pt32[0]) * bitsStride + intToX(u.pt32[0]);
+ if (len < e1) {
+ e3 = len;
+ len = e1;
+ e1 = e3;
+
+ e3 = stepminor;
+ stepminor = stepmajor;
+ stepmajor = e3;
+ SetYMajorOctant(octant);
+ }
+ e = -len;
+ e1 <<= 1;
+ e3 = e << 1;
+ FIXUP_ERROR(e, octant, bias);
+ if (!capNotLast)
+ len++;
+ if (and == 0) {
+ while (len--) {
+ WRITE(bits, xor);
+ bits += stepmajor;
+ e += e1;
+ if (e >= 0) {
+ bits += stepminor;
+ e += e3;
+ }
+ }
+ } else {
+ while (len--) {
+ RROP(bits, and, xor);
+ bits += stepmajor;
+ e += e1;
+ if (e >= 0) {
+ bits += stepminor;
+ e += e3;
+ }
+ }
+ }
+ }
+ }
+ }
+ } while (++clip != last_clip);
+}
+
+#undef RROP
+#undef isClipped
diff --git a/src/sna/fb/fbpict.c b/src/sna/fb/fbpict.c
new file mode 100644
index 000000000..a2038518e
--- /dev/null
+++ b/src/sna/fb/fbpict.c
@@ -0,0 +1,354 @@
+/*
+ * Copyright © 2000 SuSE, Inc.
+ * Copyright © 2007 Red Hat, Inc.
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. SuSE makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Keith Packard, SuSE, Inc.
+ */
+
+#include <string.h>
+
+#include "fb.h"
+
+#include <picturestr.h>
+#include <mipict.h>
+#include "fbpict.h"
+
+static void
+SourceValidateOnePicture(PicturePtr picture)
+{
+ DrawablePtr drawable = picture->pDrawable;
+ ScreenPtr screen;
+
+ if (!drawable)
+ return;
+
+ screen = drawable->pScreen;
+ if (screen->SourceValidate)
+ screen->SourceValidate(drawable,
+ 0, 0, drawable->width, drawable->height,
+ picture->subWindowMode);
+}
+
+static void
+fbCompositeSourceValidate(PicturePtr picture)
+{
+ SourceValidateOnePicture(picture);
+ if (picture->alphaMap)
+ SourceValidateOnePicture(picture->alphaMap);
+}
+
+void
+fbComposite(CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
+{
+ pixman_image_t *src, *mask, *dest;
+ int src_xoff, src_yoff;
+ int msk_xoff, msk_yoff;
+ int dst_xoff, dst_yoff;
+
+ fbCompositeSourceValidate(pSrc);
+ if (pMask)
+ fbCompositeSourceValidate(pMask);
+
+ src = image_from_pict(pSrc, FALSE, &src_xoff, &src_yoff);
+ mask = image_from_pict(pMask, FALSE, &msk_xoff, &msk_yoff);
+ dest = image_from_pict(pDst, TRUE, &dst_xoff, &dst_yoff);
+
+ if (src && dest && !(pMask && !mask)) {
+ pixman_image_composite(op, src, mask, dest,
+ xSrc + src_xoff, ySrc + src_yoff,
+ xMask + msk_xoff, yMask + msk_yoff,
+ xDst + dst_xoff, yDst + dst_yoff, width, height);
+ }
+
+ free_pixman_pict(pSrc, src);
+ free_pixman_pict(pMask, mask);
+ free_pixman_pict(pDst, dest);
+}
+
+static pixman_image_t *
+create_solid_fill_image(PicturePtr pict)
+{
+ PictSolidFill *solid = &pict->pSourcePict->solidFill;
+ pixman_color_t color;
+ CARD32 a, r, g, b;
+
+ a = (solid->color & 0xff000000) >> 24;
+ r = (solid->color & 0x00ff0000) >> 16;
+ g = (solid->color & 0x0000ff00) >> 8;
+ b = (solid->color & 0x000000ff) >> 0;
+
+ color.alpha = (a << 8) | a;
+ color.red = (r << 8) | r;
+ color.green = (g << 8) | g;
+ color.blue = (b << 8) | b;
+
+ return pixman_image_create_solid_fill(&color);
+}
+
+static pixman_image_t *
+create_linear_gradient_image(PictGradient * gradient)
+{
+ PictLinearGradient *linear = (PictLinearGradient *) gradient;
+ pixman_point_fixed_t p1;
+ pixman_point_fixed_t p2;
+
+ p1.x = linear->p1.x;
+ p1.y = linear->p1.y;
+ p2.x = linear->p2.x;
+ p2.y = linear->p2.y;
+
+ return pixman_image_create_linear_gradient(&p1, &p2,
+ (pixman_gradient_stop_t *)
+ gradient->stops,
+ gradient->nstops);
+}
+
+static pixman_image_t *
+create_radial_gradient_image(PictGradient * gradient)
+{
+ PictRadialGradient *radial = (PictRadialGradient *) gradient;
+ pixman_point_fixed_t c1;
+ pixman_point_fixed_t c2;
+
+ c1.x = radial->c1.x;
+ c1.y = radial->c1.y;
+ c2.x = radial->c2.x;
+ c2.y = radial->c2.y;
+
+ return pixman_image_create_radial_gradient(&c1, &c2, radial->c1.radius,
+ radial->c2.radius,
+ (pixman_gradient_stop_t *)
+ gradient->stops,
+ gradient->nstops);
+}
+
+static pixman_image_t *
+create_conical_gradient_image(PictGradient * gradient)
+{
+ PictConicalGradient *conical = (PictConicalGradient *) gradient;
+ pixman_point_fixed_t center;
+
+ center.x = conical->center.x;
+ center.y = conical->center.y;
+
+ return pixman_image_create_conical_gradient(&center, conical->angle,
+ (pixman_gradient_stop_t *)
+ gradient->stops,
+ gradient->nstops);
+}
+
+static pixman_image_t *
+create_bits_picture(PicturePtr pict, Bool has_clip, int *xoff, int *yoff)
+{
+ PixmapPtr pixmap;
+ FbBits *bits;
+ FbStride stride;
+ int bpp;
+ pixman_image_t *image;
+
+ fbGetDrawablePixmap(pict->pDrawable, pixmap, *xoff, *yoff);
+ fbGetPixmapBitsData(pixmap, bits, stride, bpp);
+
+ image = pixman_image_create_bits((pixman_format_code_t) pict->format,
+ pixmap->drawable.width,
+ pixmap->drawable.height, (uint32_t *) bits,
+ stride * sizeof(FbStride));
+
+ if (!image)
+ return NULL;
+
+ /* pCompositeClip is undefined for source pictures, so
+ * only set the clip region for pictures with drawables
+ */
+ if (has_clip) {
+ if (pict->clientClipType != CT_NONE)
+ pixman_image_set_has_client_clip(image, TRUE);
+
+ if (*xoff || *yoff)
+ pixman_region_translate(pict->pCompositeClip, *xoff, *yoff);
+
+ pixman_image_set_clip_region(image, pict->pCompositeClip);
+
+ if (*xoff || *yoff)
+ pixman_region_translate(pict->pCompositeClip, -*xoff, -*yoff);
+ }
+
+ /* Indexed table */
+ if (pict->pFormat->index.devPrivate)
+ pixman_image_set_indexed(image, pict->pFormat->index.devPrivate);
+
+ /* Add in drawable origin to position within the image */
+ *xoff += pict->pDrawable->x;
+ *yoff += pict->pDrawable->y;
+
+ return image;
+}
+
+static pixman_image_t *image_from_pict_internal(PicturePtr pict, Bool has_clip,
+ int *xoff, int *yoff,
+ Bool is_alpha_map);
+
+static void
+set_image_properties(pixman_image_t * image, PicturePtr pict, Bool has_clip,
+ int *xoff, int *yoff, Bool is_alpha_map)
+{
+ pixman_repeat_t repeat;
+ pixman_filter_t filter;
+
+ if (pict->transform) {
+ /* For source images, adjust the transform to account
+ * for the drawable offset within the pixman image,
+ * then set the offset to 0 as it will be used
+ * to compute positions within the transformed image.
+ */
+ if (!has_clip) {
+ struct pixman_transform adjusted;
+
+ adjusted = *pict->transform;
+ pixman_transform_translate(&adjusted,
+ NULL,
+ pixman_int_to_fixed(*xoff),
+ pixman_int_to_fixed(*yoff));
+ pixman_image_set_transform(image, &adjusted);
+ *xoff = 0;
+ *yoff = 0;
+ }
+ else
+ pixman_image_set_transform(image, pict->transform);
+ }
+
+ switch (pict->repeatType) {
+ default:
+ case RepeatNone:
+ repeat = PIXMAN_REPEAT_NONE;
+ break;
+
+ case RepeatPad:
+ repeat = PIXMAN_REPEAT_PAD;
+ break;
+
+ case RepeatNormal:
+ repeat = PIXMAN_REPEAT_NORMAL;
+ break;
+
+ case RepeatReflect:
+ repeat = PIXMAN_REPEAT_REFLECT;
+ break;
+ }
+
+ pixman_image_set_repeat(image, repeat);
+
+ /* Fetch alpha map unless 'pict' is being used
+ * as the alpha map for this operation
+ */
+ if (pict->alphaMap && !is_alpha_map) {
+ int alpha_xoff, alpha_yoff;
+ pixman_image_t *alpha_map =
+ image_from_pict_internal(pict->alphaMap, FALSE, &alpha_xoff,
+ &alpha_yoff, TRUE);
+
+ pixman_image_set_alpha_map(image, alpha_map, pict->alphaOrigin.x,
+ pict->alphaOrigin.y);
+
+ free_pixman_pict(pict->alphaMap, alpha_map);
+ }
+
+ pixman_image_set_component_alpha(image, pict->componentAlpha);
+
+ switch (pict->filter) {
+ default:
+ case PictFilterNearest:
+ case PictFilterFast:
+ filter = PIXMAN_FILTER_NEAREST;
+ break;
+
+ case PictFilterBilinear:
+ case PictFilterGood:
+ filter = PIXMAN_FILTER_BILINEAR;
+ break;
+
+ case PictFilterConvolution:
+ filter = PIXMAN_FILTER_CONVOLUTION;
+ break;
+ }
+
+ pixman_image_set_filter(image, filter,
+ (pixman_fixed_t *) pict->filter_params,
+ pict->filter_nparams);
+ pixman_image_set_source_clipping(image, TRUE);
+}
+
+static pixman_image_t *
+image_from_pict_internal(PicturePtr pict, Bool has_clip, int *xoff, int *yoff,
+ Bool is_alpha_map)
+{
+ pixman_image_t *image = NULL;
+
+ if (!pict)
+ return NULL;
+
+ if (pict->pDrawable) {
+ image = create_bits_picture(pict, has_clip, xoff, yoff);
+ }
+ else if (pict->pSourcePict) {
+ SourcePict *sp = pict->pSourcePict;
+
+ if (sp->type == SourcePictTypeSolidFill) {
+ image = create_solid_fill_image(pict);
+ }
+ else {
+ PictGradient *gradient = &pict->pSourcePict->gradient;
+
+ if (sp->type == SourcePictTypeLinear)
+ image = create_linear_gradient_image(gradient);
+ else if (sp->type == SourcePictTypeRadial)
+ image = create_radial_gradient_image(gradient);
+ else if (sp->type == SourcePictTypeConical)
+ image = create_conical_gradient_image(gradient);
+ }
+ *xoff = *yoff = 0;
+ }
+
+ if (image)
+ set_image_properties(image, pict, has_clip, xoff, yoff, is_alpha_map);
+
+ return image;
+}
+
+pixman_image_t *
+image_from_pict(PicturePtr pict, Bool has_clip, int *xoff, int *yoff)
+{
+ return image_from_pict_internal(pict, has_clip, xoff, yoff, FALSE);
+}
+
+void
+free_pixman_pict(PicturePtr pict, pixman_image_t * image)
+{
+ if (image)
+ pixman_image_unref(image);
+}
diff --git a/src/sna/fb/fbpict.h b/src/sna/fb/fbpict.h
new file mode 100644
index 000000000..1ce09df25
--- /dev/null
+++ b/src/sna/fb/fbpict.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef FBPICT_H
+#define FBPICT_H
+
+#include "sfb.h"
+
+extern void
+fbComposite(CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, CARD16 height);
+
+extern pixman_image_t *image_from_pict(PicturePtr pict,
+ Bool has_clip,
+ int *xoff, int *yoff);
+
+extern void free_pixman_pict(PicturePtr, pixman_image_t *);
+
+#endif /* FBPICT_H */
diff --git a/src/sna/fb/fbpoint.c b/src/sna/fb/fbpoint.c
new file mode 100644
index 000000000..3df79a261
--- /dev/null
+++ b/src/sna/fb/fbpoint.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright © 1998 Keith Packard
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "fb.h"
+#include <micoord.h>
+
+#define DOTS fbDots8
+#define DOTS__SIMPLE fbDots8__simple
+#define BITS BYTE
+#include "fbpointbits.h"
+#undef BITS
+#undef DOTS__SIMPLE
+#undef DOTS
+
+#define DOTS fbDots16
+#define DOTS__SIMPLE fbDots16__simple
+#define BITS CARD16
+#include "fbpointbits.h"
+#undef BITS
+#undef DOTS__SIMPLE
+#undef DOTS
+
+#define DOTS fbDots32
+#define DOTS__SIMPLE fbDots32__simple
+#define BITS CARD32
+#include "fbpointbits.h"
+#undef BITS
+#undef DOTS__SIMPLE
+#undef DOTS
+
+static void
+fbDots(FbBits *dstOrig, FbStride dstStride, int dstBpp,
+ RegionPtr clip,
+ xPoint *pts, int n,
+ int xorg, int yorg,
+ int xoff, int yoff,
+ FbBits andOrig, FbBits xorOrig)
+{
+ FbStip *dst = (FbStip *) dstOrig;
+ FbStip and = andOrig;
+ FbStip xor = xorOrig;
+
+ while (n--) {
+ int x = pts->x + xorg;
+ int y = pts->y + yorg;
+ pts++;
+ if (RegionContainsPoint(clip, x, y, NULL)) {
+ FbStip mask;
+ FbStip *d;
+
+ x = (x + xoff) * dstBpp;
+ d = dst + ((y + yoff) * dstStride) + (x >> FB_STIP_SHIFT);
+ x &= FB_STIP_MASK;
+
+ mask = FbStipMask(x, dstBpp);
+ WRITE(d, FbDoMaskRRop(READ(d), and, xor, mask));
+ }
+ }
+}
+
+void
+fbPolyPoint(DrawablePtr drawable, GCPtr gc,
+ int mode, int n, xPoint *pt, unsigned flags)
+{
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+ void (*dots)(FbBits *dst, FbStride dstStride, int dstBpp,
+ RegionPtr clip,
+ xPoint *pts, int n,
+ int xorg, int yorg,
+ int xoff, int yoff,
+ FbBits and, FbBits xor);
+
+ DBG(("%s x %d, clip=[(%d, %d), (%d, %d)]x%d\n", __FUNCTION__, n,
+ gc->pCompositeClip->extents.x1, gc->pCompositeClip->extents.y1,
+ gc->pCompositeClip->extents.x2, gc->pCompositeClip->extents.y2,
+ RegionNumRects(gc->pCompositeClip)));
+
+ if (mode == CoordModePrevious)
+ fbFixCoordModePrevious(n, pt);
+
+ fbGetDrawable(drawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
+ dots = fbDots;
+ if ((flags & 2) == 0 && fb_gc(gc)->and == 0) {
+ switch (dstBpp) {
+ case 8:
+ dots = fbDots8__simple;
+ break;
+ case 16:
+ dots = fbDots16__simple;
+ break;
+ case 32:
+ dots = fbDots32__simple;
+ break;
+ }
+ } else {
+ switch (dstBpp) {
+ case 8:
+ dots = fbDots8;
+ break;
+ case 16:
+ dots = fbDots16;
+ break;
+ case 32:
+ dots = fbDots32;
+ break;
+ }
+ }
+ dots(dst, dstStride, dstBpp, gc->pCompositeClip, pt, n,
+ drawable->x, drawable->y, dstXoff, dstYoff,
+ fb_gc(gc)->and, fb_gc(gc)->xor);
+}
diff --git a/src/sna/fb/fbpointbits.h b/src/sna/fb/fbpointbits.h
new file mode 100644
index 000000000..60bf4881d
--- /dev/null
+++ b/src/sna/fb/fbpointbits.h
@@ -0,0 +1,148 @@
+/*
+ * Copyright © 1998 Keith Packard
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define RROP(b,a,x) WRITE((b), FbDoRRop (READ(b), (a), (x)))
+#define isClipped(c,ul,lr) (((c) | ((c) - (ul)) | ((lr) - (c))) & 0x80008000)
+
+static void
+DOTS(FbBits * dst,
+ FbStride dstStride,
+ int dstBpp,
+ RegionPtr region,
+ xPoint * ptsOrig,
+ int npt, int xorg, int yorg, int xoff, int yoff, FbBits and, FbBits xor)
+{
+ uint32_t *pts = (uint32_t *) ptsOrig;
+ BITS *bits = (BITS *) dst;
+ BITS bxor = (BITS) xor;
+ BITS band = (BITS) and;
+ FbStride bitsStride = dstStride * (sizeof(FbBits) / sizeof(BITS));
+
+ if (region->data == NULL) {
+ INT32 ul = coordToInt(region->extents.x1 - xorg,
+ region->extents.y1 - yorg);
+ INT32 lr = coordToInt(region->extents.x2 - xorg - 1,
+ region->extents.y2 - yorg - 1);
+
+ bits += bitsStride * (yorg + yoff) + (xorg + xoff);
+ if (and == 0) {
+ while (npt >= 2) {
+ union {
+ uint32_t pt32[2];
+ uint64_t pt64;
+ } pt;
+ pt.pt64 = *(uint64_t *)pts;
+ if (!isClipped(pt.pt32[0], ul, lr)) {
+ BITS *point = bits + intToY(pt.pt32[0]) * bitsStride + intToX(pt.pt32[0]);
+ WRITE(point, bxor);
+ }
+ if (!isClipped(pt.pt32[1], ul, lr)) {
+ BITS *point = bits + intToY(pt.pt32[1]) * bitsStride + intToX(pt.pt32[1]);
+ WRITE(point, bxor);
+ }
+
+ pts += 2;
+ npt -= 2;
+ }
+ if (npt) {
+ uint32_t pt = *pts;
+ if (!isClipped(pt, ul, lr)) {
+ BITS *point = bits + intToY(pt) * bitsStride + intToX(pt);
+ WRITE(point, bxor);
+ }
+ }
+ } else {
+ while (npt--) {
+ uint32_t pt = *pts++;
+ if (!isClipped(pt, ul, lr)) {
+ BITS *point = bits + intToY(pt) * bitsStride + intToX(pt);
+ RROP(point, band, bxor);
+ }
+ }
+ }
+ } else {
+ bits += bitsStride * yoff + xoff;
+ if (and == 0) {
+ while (npt--) {
+ uint32_t pt = *pts++;
+ int x = intToX(pt) + xorg;
+ int y = intToY(pt) + yorg;
+ if (RegionContainsPoint(region, x, y, NULL)) {
+ BITS *point = bits + y * bitsStride + x;
+ WRITE(point, bxor);
+ }
+ }
+ } else {
+ while (npt--) {
+ uint32_t pt = *pts++;
+ int x = intToX(pt) + xorg;
+ int y = intToY(pt) + yorg;
+ if (RegionContainsPoint(region, x, y, NULL)) {
+ BITS *point = bits + y * bitsStride + x;
+ RROP(point, band, bxor);
+ }
+ }
+ }
+ }
+}
+
+static void
+DOTS__SIMPLE(FbBits * dst,
+ FbStride dstStride,
+ int dstBpp,
+ RegionPtr region,
+ xPoint * ptsOrig,
+ int npt, int xorg, int yorg, int xoff, int yoff,
+ FbBits and, FbBits xor)
+{
+ uint32_t *pts = (uint32_t *) ptsOrig;
+ BITS *bits = (BITS *) dst, *p;
+ BITS bxor = (BITS) xor;
+ FbStride bitsStride = dstStride * (sizeof(FbBits) / sizeof(BITS));
+
+ bits += bitsStride * (yorg + yoff) + (xorg + xoff);
+ while (npt >= 2) {
+ union {
+ uint32_t pt32[2];
+ uint64_t pt64;
+ } pt;
+ pt.pt64 = *(uint64_t *)pts;
+
+ p = bits + intToY(pt.pt32[0]) * bitsStride + intToX(pt.pt32[0]);
+ WRITE(p, bxor);
+
+ p = bits + intToY(pt.pt32[1]) * bitsStride + intToX(pt.pt32[1]);
+ WRITE(p, bxor);
+
+ pts += 2;
+ npt -= 2;
+ }
+ if (npt) {
+ uint32_t pt = *pts;
+ p = bits + intToY(pt) * bitsStride + intToX(pt);
+ WRITE(p, bxor);
+ }
+}
+
+#undef RROP
+#undef isClipped
diff --git a/src/sna/fb/fbpush.c b/src/sna/fb/fbpush.c
new file mode 100644
index 000000000..c53f0adf8
--- /dev/null
+++ b/src/sna/fb/fbpush.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright © 1998 Keith Packard
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "fb.h"
+#include "fbclip.h"
+
+static void
+fbPushPattern(DrawablePtr drawable, GCPtr gc,
+ FbStip *src, FbStride srcStride, int srcX,
+ int x, int y, int width, int height)
+{
+ FbStip *s, bitsMask, bitsMask0, bits;
+ int xspan;
+ int w;
+ int lenspan;
+
+ src += srcX >> FB_STIP_SHIFT;
+ srcX &= FB_STIP_MASK;
+
+ bitsMask0 = FbStipMask(srcX, 1);
+
+ while (height--) {
+ bitsMask = bitsMask0;
+ w = width;
+ s = src;
+ src += srcStride;
+ bits = READ(s++);
+ xspan = x;
+ while (w) {
+ if (bits & bitsMask) {
+ lenspan = 0;
+ do {
+ if (++lenspan == w)
+ break;
+
+ bitsMask = FbStipRight(bitsMask, 1);
+ if (!bitsMask) {
+ bits = READ(s++);
+ bitsMask = FbBitsMask(0, 1);
+ }
+ } while (bits & bitsMask);
+ fbFill(drawable, gc, xspan, y, lenspan, 1);
+ xspan += lenspan;
+ w -= lenspan;
+ } else {
+ do {
+ xspan++;
+ if (!--w)
+ break;
+
+ bitsMask = FbStipRight(bitsMask, 1);
+ if (!bitsMask) {
+ bits = READ(s++);
+ bitsMask = FbBitsMask(0, 1);
+ }
+ } while (!(bits & bitsMask));
+ }
+ }
+ y++;
+ }
+}
+
+static void
+fbPushFill(DrawablePtr drawable, GCPtr gc,
+ FbStip *src, FbStride srcStride, int srcX,
+ int x, int y, int width, int height)
+{
+ FbGCPrivPtr pgc = fb_gc(gc);
+
+ if (gc->fillStyle == FillSolid) {
+ FbBits *dst;
+ FbStride dstStride;
+ int dstBpp;
+ int dstXoff, dstYoff;
+ int dstX;
+ int dstWidth;
+
+ fbGetDrawable(drawable, dst,
+ dstStride, dstBpp, dstXoff, dstYoff);
+ dst = dst + (y + dstYoff) * dstStride;
+ dstX = (x + dstXoff) * dstBpp;
+ dstWidth = width * dstBpp;
+ if (dstBpp == 1) {
+ fbBltStip(src, srcStride, srcX,
+ (FbStip *)dst, dstStride, dstX,
+ dstWidth, height,
+ FbStipple1Rop(gc->alu, gc->fgPixel), pgc->pm, dstBpp);
+ } else {
+ fbBltOne(src, srcStride, srcX,
+ dst, dstStride, dstX, dstBpp,
+ dstWidth, height,
+ pgc->and, pgc->xor,
+ fbAnd(GXnoop, (FbBits) 0, FB_ALLONES),
+ fbXor(GXnoop, (FbBits) 0, FB_ALLONES));
+ }
+ } else
+ fbPushPattern(drawable, gc, src, srcStride, srcX,
+ x, y, width, height);
+}
+
+struct fbPushImage {
+ FbStip *src;
+ FbStride stride;
+ int x0, y0;
+};
+
+inline static void
+_fbPushImage(DrawablePtr drawable, GCPtr gc, const BoxRec *b, void *_data)
+{
+ struct fbPushImage *data = _data;
+
+ fbPushFill(drawable, gc,
+ data->src + (b->y1 - data->y0) * data->stride, data->stride,
+ b->x1 - data->x0,
+ b->x1, b->y1,
+ b->x2 - b->x1, b->y2 - b->y1);
+}
+
+void
+fbPushImage(DrawablePtr drawable, GCPtr gc,
+ FbStip *src, FbStride stride, int dx,
+ int x, int y, int width, int height)
+{
+ struct fbPushImage data;
+ BoxRec box;
+
+ DBG(("%s (%d, %d)x(%d, %d)", __FUNCTION__, x, y, width, height));
+
+ data.src = src;
+ data.stride = stride;
+ data.y0 = y;
+ data.x0 = x - dx;
+
+ box.x1 = x;
+ box.y1 = y;
+ box.x2 = x + width;
+ box.y2 = y + height;
+ fbDrawableRun(drawable, gc, &box, _fbPushImage, &data);
+}
+
+void
+fbPushPixels(GCPtr gc, PixmapPtr bitmap, DrawablePtr drawable,
+ int dx, int dy, int xOrg, int yOrg)
+{
+ FbStip *stip;
+ FbStride stipStride;
+ int stipBpp;
+ _X_UNUSED int stipXoff, stipYoff;
+
+ DBG(("%s bitmap=%x%d\n", __FUNCTION__,
+ bitmap->drawable.width, bitmap->drawable.height));
+
+ fbGetStipDrawable(&bitmap->drawable, stip,
+ stipStride, stipBpp, stipXoff, stipYoff);
+
+ fbPushImage(drawable, gc, stip, stipStride, 0, xOrg, yOrg, dx, dy);
+}
diff --git a/src/sna/fb/fbrop.h b/src/sna/fb/fbrop.h
new file mode 100644
index 000000000..9eb1fc380
--- /dev/null
+++ b/src/sna/fb/fbrop.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright © 1998 Keith Packard
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _FBROP_H_
+#define _FBROP_H_
+
+#define FbDestInvarientRop(alu,pm) ((pm) == FB_ALLONES && \
+ (((alu) >> 1 & 5) == ((alu) & 5)))
+
+#define FbDestInvarientMergeRop() (_ca1 == 0 && _cx1 == 0)
+
+/* AND has higher precedence than XOR */
+
+#define FbDoMergeRop(src, dst) \
+ (((dst) & (((src) & _ca1) ^ _cx1)) ^ (((src) & _ca2) ^ _cx2))
+
+#define FbDoDestInvarientMergeRop(src) (((src) & _ca2) ^ _cx2)
+
+#define FbDoMaskMergeRop(src, dst, mask) \
+ (((dst) & ((((src) & _ca1) ^ _cx1) | ~(mask))) ^ ((((src) & _ca2) ^ _cx2) & (mask)))
+
+#define FbDoLeftMaskByteMergeRop(dst, src, lb, l) { \
+ FbBits __xor = ((src) & _ca2) ^ _cx2; \
+ FbDoLeftMaskByteRRop(dst,lb,l,((src) & _ca1) ^ _cx1,__xor); \
+}
+
+#define FbDoRightMaskByteMergeRop(dst, src, rb, r) { \
+ FbBits __xor = ((src) & _ca2) ^ _cx2; \
+ FbDoRightMaskByteRRop(dst,rb,r,((src) & _ca1) ^ _cx1,__xor); \
+}
+
+#define FbDoRRop(dst, and, xor) (((dst) & (and)) ^ (xor))
+
+#define FbDoMaskRRop(dst, and, xor, mask) \
+ (((dst) & ((and) | ~(mask))) ^ (xor & mask))
+
+/*
+ * Take a single bit (0 or 1) and generate a full mask
+ */
+#define fbFillFromBit(b,t) (~((t) ((b) & 1)-1))
+
+#define fbXorT(rop,fg,pm,t) ((((fg) & fbFillFromBit((rop) >> 1,t)) | \
+ (~(fg) & fbFillFromBit((rop) >> 3,t))) & (pm))
+
+#define fbAndT(rop,fg,pm,t) ((((fg) & fbFillFromBit (rop ^ (rop>>1),t)) | \
+ (~(fg) & fbFillFromBit((rop>>2) ^ (rop>>3),t))) | \
+ ~(pm))
+
+#define fbXor(rop,fg,pm) fbXorT(rop,fg,pm,FbBits)
+
+#define fbAnd(rop,fg,pm) fbAndT(rop,fg,pm,FbBits)
+
+#define fbXorStip(rop,fg,pm) fbXorT(rop,fg,pm,FbStip)
+
+#define fbAndStip(rop,fg,pm) fbAndT(rop,fg,pm,FbStip)
+
+/*
+ * Stippling operations;
+ */
+extern const FbBits *const fbStippleTable[];
+
+#define FbStippleRRop(dst, b, fa, fx, ba, bx) \
+ (FbDoRRop(dst, fa, fx) & b) | (FbDoRRop(dst, ba, bx) & ~b)
+
+#define FbStippleRRopMask(dst, b, fa, fx, ba, bx, m) \
+ (FbDoMaskRRop(dst, fa, fx, m) & (b)) | (FbDoMaskRRop(dst, ba, bx, m) & ~(b))
+
+#define FbDoLeftMaskByteStippleRRop(dst, b, fa, fx, ba, bx, lb, l) { \
+ FbBits __xor = ((fx) & (b)) | ((bx) & ~(b)); \
+ FbDoLeftMaskByteRRop(dst, lb, l, ((fa) & (b)) | ((ba) & ~(b)), __xor); \
+}
+
+#define FbDoRightMaskByteStippleRRop(dst, b, fa, fx, ba, bx, rb, r) { \
+ FbBits __xor = ((fx) & (b)) | ((bx) & ~(b)); \
+ FbDoRightMaskByteRRop(dst, rb, r, ((fa) & (b)) | ((ba) & ~(b)), __xor); \
+}
+
+#define FbOpaqueStipple(b, fg, bg) (((fg) & (b)) | ((bg) & ~(b)))
+
+/*
+ * Compute rop for using tile code for 1-bit dest stipples; modifies
+ * existing rop to flip depending on pixel values
+ */
+#define FbStipple1RopPick(alu,b) (((alu) >> (2 - (((b) & 1) << 1))) & 3)
+
+#define FbOpaqueStipple1Rop(alu,fg,bg) (FbStipple1RopPick(alu,fg) | \
+ (FbStipple1RopPick(alu,bg) << 2))
+
+#define FbStipple1Rop(alu,fg) (FbStipple1RopPick(alu,fg) | 4)
+
+#endif
diff --git a/src/sna/fb/fbseg.c b/src/sna/fb/fbseg.c
new file mode 100644
index 000000000..5b8173f08
--- /dev/null
+++ b/src/sna/fb/fbseg.c
@@ -0,0 +1,563 @@
+/*
+ * Copyright © 1998 Keith Packard
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <stdlib.h>
+
+#include "fb.h"
+#include "fbclip.h"
+#include <mi.h>
+#include <miline.h>
+#include <scrnintstr.h>
+
+#define FbDashDeclare \
+ unsigned char *__dash, *__firstDash, *__lastDash
+
+#define FbDashInit(gc,pgc,dashOffset,dashlen,even) { \
+ (even) = TRUE; \
+ __firstDash = (gc)->dash; \
+ __lastDash = __firstDash + (gc)->numInDashList; \
+ (dashOffset) %= (pgc)->dashLength; \
+ \
+ __dash = __firstDash; \
+ while ((dashOffset) >= ((dashlen) = *__dash)) { \
+ (dashOffset) -= (dashlen); \
+ (even) = 1-(even); \
+ if (++__dash == __lastDash) \
+ __dash = __firstDash; \
+ } \
+ (dashlen) -= (dashOffset); \
+}
+
+#define FbDashNext(dashlen) { \
+ if (++__dash == __lastDash) \
+ __dash = __firstDash; \
+ (dashlen) = *__dash; \
+}
+
+/* as numInDashList is always even, this case can skip a test */
+
+#define FbDashNextEven(dashlen) { \
+ (dashlen) = *++__dash; \
+}
+
+#define FbDashNextOdd(dashlen) FbDashNext(dashlen)
+
+#define FbDashStep(dashlen,even) { \
+ if (!--(dashlen)) { \
+ FbDashNext(dashlen); \
+ (even) = 1-(even); \
+ } \
+}
+
+#define fbBresShiftMask(mask,dir,bpp) ((bpp == FB_STIP_UNIT) ? 0 : \
+ ((dir < 0) ? FbStipLeft(mask,bpp) : \
+ FbStipRight(mask,bpp)))
+
+typedef void FbBres(DrawablePtr drawable,
+ GCPtr gc,
+ int dashOffset,
+ int sdx,
+ int sdy,
+ int axis, int x, int y, int e, int e1, int e3, int len);
+
+#define BRESSOLID fbBresSolid8
+#define BRESSOLIDR fbBresSolidR8
+#define BRESDASH fbBresDash8
+#define BITS BYTE
+#define BITS2 CARD16
+#define BITS4 CARD32
+#include "fbsegbits.h"
+#undef BRESSOLID
+#undef BRESSOLIDR
+#undef BRESDASH
+#undef BITS
+#undef BITS2
+#undef BITS4
+
+#define BRESSOLID fbBresSolid16
+#define BRESSOLIDR fbBresSolidR16
+#define BRESDASH fbBresDash16
+#define BITS CARD16
+#define BITS2 CARD32
+#include "fbsegbits.h"
+#undef BRESSOLID
+#undef BRESSOLIDR
+#undef BRESDASH
+#undef BITS
+#undef BITS2
+
+#define BRESSOLID fbBresSolid32
+#define BRESSOLIDR fbBresSolidR32
+#define BRESDASH fbBresDash32
+#define BITS CARD32
+#include "fbsegbits.h"
+#undef BRESSOLID
+#undef BRESSOLIDR
+#undef BRESDASH
+#undef BITS
+
+static void
+fbBresSolid(DrawablePtr drawable, GCPtr gc, int dashOffset,
+ int sdx, int sdy, int axis,
+ int x1, int y1,
+ int e, int e1, int e3, int len)
+{
+ FbStip *dst;
+ FbStride stride;
+ int bpp;
+ int dx, dy;
+ FbGCPrivPtr pgc = fb_gc(gc);
+ FbStip and = (FbStip) pgc->and;
+ FbStip xor = (FbStip) pgc->xor;
+ FbStip mask, mask0;
+ FbStip bits;
+
+ fbGetStipDrawable(drawable, dst, stride, bpp, dx, dy);
+ dst += ((y1 + dy) * stride);
+ x1 = (x1 + dx) * bpp;
+ dst += x1 >> FB_STIP_SHIFT;
+ x1 &= FB_STIP_MASK;
+ mask0 = FbStipMask(0, bpp);
+ mask = FbStipRight(mask0, x1);
+ if (sdx < 0)
+ mask0 = FbStipRight(mask0, FB_STIP_UNIT - bpp);
+ if (sdy < 0)
+ stride = -stride;
+ if (axis == X_AXIS) {
+ bits = 0;
+ while (len--) {
+ bits |= mask;
+ mask = fbBresShiftMask(mask, sdx, bpp);
+ if (!mask) {
+ WRITE(dst, FbDoMaskRRop(READ(dst), and, xor, bits));
+ bits = 0;
+ dst += sdx;
+ mask = mask0;
+ }
+ e += e1;
+ if (e >= 0) {
+ WRITE(dst, FbDoMaskRRop(READ(dst), and, xor, bits));
+ bits = 0;
+ dst += stride;
+ e += e3;
+ }
+ }
+ if (bits)
+ WRITE(dst, FbDoMaskRRop(READ(dst), and, xor, bits));
+ } else {
+ while (len--) {
+ WRITE(dst, FbDoMaskRRop(READ(dst), and, xor, mask));
+ dst += stride;
+ e += e1;
+ if (e >= 0) {
+ e += e3;
+ mask = fbBresShiftMask(mask, sdx, bpp);
+ if (!mask) {
+ dst += sdx;
+ mask = mask0;
+ }
+ }
+ }
+ }
+}
+
+static void
+fbBresDash(DrawablePtr drawable, GCPtr gc, int dashOffset,
+ int sdx, int sdy, int axis,
+ int x1, int y1,
+ int e, int e1, int e3, int len)
+{
+ FbStip *dst;
+ FbStride stride;
+ int bpp;
+ int dx, dy;
+ FbGCPrivPtr pgc = fb_gc(gc);
+ FbStip and = (FbStip) pgc->and;
+ FbStip xor = (FbStip) pgc->xor;
+ FbStip bgand = (FbStip) pgc->bgand;
+ FbStip bgxor = (FbStip) pgc->bgxor;
+ FbStip mask, mask0;
+
+ FbDashDeclare;
+ int dashlen;
+ bool even;
+ bool doOdd;
+
+ fbGetStipDrawable(drawable, dst, stride, bpp, dx, dy);
+ doOdd = gc->lineStyle == LineDoubleDash;
+
+ FbDashInit(gc, pgc, dashOffset, dashlen, even);
+
+ dst += ((y1 + dy) * stride);
+ x1 = (x1 + dx) * bpp;
+ dst += x1 >> FB_STIP_SHIFT;
+ x1 &= FB_STIP_MASK;
+ mask0 = FbStipMask(0, bpp);
+ mask = FbStipRight(mask0, x1);
+ if (sdx < 0)
+ mask0 = FbStipRight(mask0, FB_STIP_UNIT - bpp);
+ if (sdy < 0)
+ stride = -stride;
+ while (len--) {
+ if (even)
+ WRITE(dst, FbDoMaskRRop(READ(dst), and, xor, mask));
+ else if (doOdd)
+ WRITE(dst, FbDoMaskRRop(READ(dst), bgand, bgxor, mask));
+ if (axis == X_AXIS) {
+ mask = fbBresShiftMask(mask, sdx, bpp);
+ if (!mask) {
+ dst += sdx;
+ mask = mask0;
+ }
+ e += e1;
+ if (e >= 0) {
+ dst += stride;
+ e += e3;
+ }
+ } else {
+ dst += stride;
+ e += e1;
+ if (e >= 0) {
+ e += e3;
+ mask = fbBresShiftMask(mask, sdx, bpp);
+ if (!mask) {
+ dst += sdx;
+ mask = mask0;
+ }
+ }
+ }
+ FbDashStep(dashlen, even);
+ }
+}
+
+static void
+fbBresFill(DrawablePtr drawable, GCPtr gc, int dashOffset,
+ int sdx, int sdy, int axis,
+ int x1, int y1,
+ int e, int e1, int e3, int len)
+{
+ while (len--) {
+ fbFill(drawable, gc, x1, y1, 1, 1);
+ if (axis == X_AXIS) {
+ x1 += sdx;
+ e += e1;
+ if (e >= 0) {
+ e += e3;
+ y1 += sdy;
+ }
+ } else {
+ y1 += sdy;
+ e += e1;
+ if (e >= 0) {
+ e += e3;
+ x1 += sdx;
+ }
+ }
+ }
+}
+
+static void
+fbSetFg(DrawablePtr drawable, GCPtr gc, Pixel fg)
+{
+ if (fg != gc->fgPixel) {
+ gc->fgPixel = fg;
+ fbValidateGC(gc, GCForeground, drawable);
+ }
+}
+
+static void
+fbBresFillDash(DrawablePtr drawable,
+ GCPtr gc,
+ int dashOffset,
+ int sdx,
+ int sdy,
+ int axis, int x1, int y1, int e, int e1, int e3, int len)
+{
+ FbGCPrivPtr pgc = fb_gc(gc);
+
+ FbDashDeclare;
+ int dashlen;
+ bool even;
+ bool doOdd;
+ bool doBg;
+ Pixel fg, bg;
+
+ fg = gc->fgPixel;
+ bg = gc->bgPixel;
+
+ /* whether to fill the odd dashes */
+ doOdd = gc->lineStyle == LineDoubleDash;
+ /* whether to switch fg to bg when filling odd dashes */
+ doBg = doOdd && (gc->fillStyle == FillSolid ||
+ gc->fillStyle == FillStippled);
+
+ /* compute current dash position */
+ FbDashInit(gc, pgc, dashOffset, dashlen, even);
+
+ while (len--) {
+ if (even || doOdd) {
+ if (doBg) {
+ if (even)
+ fbSetFg(drawable, gc, fg);
+ else
+ fbSetFg(drawable, gc, bg);
+ }
+ fbFill(drawable, gc, x1, y1, 1, 1);
+ }
+ if (axis == X_AXIS) {
+ x1 += sdx;
+ e += e1;
+ if (e >= 0) {
+ e += e3;
+ y1 += sdy;
+ }
+ } else {
+ y1 += sdy;
+ e += e1;
+ if (e >= 0) {
+ e += e3;
+ x1 += sdx;
+ }
+ }
+ FbDashStep(dashlen, even);
+ }
+ if (doBg)
+ fbSetFg(drawable, gc, fg);
+}
+
+static FbBres *
+fbSelectBres(DrawablePtr drawable, GCPtr gc)
+{
+ FbGCPrivPtr pgc = fb_gc(gc);
+ int bpp = drawable->bitsPerPixel;
+ FbBres *bres;
+
+ DBG(("%s: line=%d, fill=%d, and=%lx, bgand=%lx\n",
+ __FUNCTION__, gc->lineStyle, gc->fillStyle, pgc->and, pgc->bgand));
+ assert(gc->lineWidth == 0);
+
+ if (gc->lineStyle == LineSolid) {
+ bres = fbBresFill;
+ if (gc->fillStyle == FillSolid) {
+ bres = fbBresSolid;
+ if (pgc->and == 0) {
+ switch (bpp) {
+ case 8:
+ bres = fbBresSolid8;
+ break;
+ case 16:
+ bres = fbBresSolid16;
+ break;
+ case 32:
+ bres = fbBresSolid32;
+ break;
+ }
+ } else {
+ switch (bpp) {
+ case 8:
+ bres = fbBresSolidR8;
+ break;
+ case 16:
+ bres = fbBresSolidR16;
+ break;
+ case 32:
+ bres = fbBresSolidR32;
+ break;
+ }
+ }
+ }
+ } else {
+ bres = fbBresFillDash;
+ if (gc->fillStyle == FillSolid) {
+ bres = fbBresDash;
+ if (pgc->and == 0 &&
+ (gc->lineStyle == LineOnOffDash || pgc->bgand == 0)) {
+ switch (bpp) {
+ case 8:
+ bres = fbBresDash8;
+ break;
+ case 16:
+ bres = fbBresDash16;
+ break;
+ case 32:
+ bres = fbBresDash32;
+ break;
+ }
+ }
+ }
+ }
+ return bres;
+}
+
+struct fbSegment {
+ FbBres *bres;
+ bool drawLast;
+ int *dashOffset;
+ int x1, y1, x2, y2;
+};
+
+static void
+_fbSegment(DrawablePtr drawable, GCPtr gc, const BoxRec *b, void *_data)
+{
+ struct fbSegment *data = _data;
+ const unsigned int bias = miGetZeroLineBias(drawable->pScreen);
+ int adx, ady; /* abs values of dx and dy */
+ int sdx, sdy; /* sign of dx and dy */
+ int e, e1, e2, e3; /* bresenham error and increments */
+ int len, axis, octant;
+ int dashoff, doff;
+ unsigned int oc1, oc2;
+
+ DBG(("%s box=(%d, %d),(%d, %d)\n",
+ __FUNCTION__, b->x1, b->y1, b->x2, b->y2));
+
+ CalcLineDeltas(data->x1, data->y1, data->x2, data->y2,
+ adx, ady, sdx, sdy, 1, 1, octant);
+
+ if (adx > ady) {
+ axis = X_AXIS;
+ e1 = ady << 1;
+ e2 = e1 - (adx << 1);
+ e = e1 - adx;
+ len = adx;
+ } else {
+ axis = Y_AXIS;
+ e1 = adx << 1;
+ e2 = e1 - (ady << 1);
+ e = e1 - ady;
+ SetYMajorOctant(octant);
+ len = ady;
+ }
+
+ FIXUP_ERROR(e, octant, bias);
+
+ /*
+ * Adjust error terms to compare against zero
+ */
+ e3 = e2 - e1;
+ e = e - e1;
+
+ if (data->drawLast)
+ len++;
+ dashoff = *data->dashOffset;
+ *data->dashOffset = dashoff + len;
+
+ oc1 = 0;
+ oc2 = 0;
+ OUTCODES(oc1, data->x1, data->y1, b);
+ OUTCODES(oc2, data->x2, data->y2, b);
+ if ((oc1 | oc2) == 0) {
+ data->bres(drawable, gc, dashoff,
+ sdx, sdy, axis, data->x1, data->y1, e, e1, e3, len);
+ } else if (oc1 & oc2) {
+ } else {
+ int new_x1 = data->x1, new_y1 = data->y1;
+ int new_x2 = data->x2, new_y2 = data->y2;
+ int clip1 = 0, clip2 = 0;
+ int clipdx, clipdy;
+ int err;
+
+ if (miZeroClipLine(b->x1, b->y1, b->x2-1, b->y2-1,
+ &new_x1, &new_y1, &new_x2, &new_y2,
+ adx, ady, &clip1, &clip2,
+ octant, bias, oc1, oc2) == -1)
+ return;
+
+ if (axis == X_AXIS)
+ len = abs(new_x2 - new_x1);
+ else
+ len = abs(new_y2 - new_y1);
+ if (clip2 != 0 || data->drawLast)
+ len++;
+ if (len) {
+ /* unwind bresenham error term to first point */
+ doff = dashoff;
+ err = e;
+ if (clip1) {
+ clipdx = abs(new_x1 - data->x1);
+ clipdy = abs(new_y1 - data->y1);
+ if (axis == X_AXIS) {
+ doff += clipdx;
+ err += e3 * clipdy + e1 * clipdx;
+ } else {
+ doff += clipdy;
+ err += e3 * clipdx + e1 * clipdy;
+ }
+ }
+ data->bres(drawable, gc, doff,
+ sdx, sdy, axis, new_x1, new_y1,
+ err, e1, e3, len);
+ }
+ }
+}
+
+void
+fbSegment(DrawablePtr drawable, GCPtr gc,
+ int x1, int y1, int x2, int y2,
+ bool drawLast, int *dashOffset)
+{
+ struct fbSegment data;
+ BoxRec box;
+
+ DBG(("%s (%d, %d), (%d, %d), drawLast?=%d\n",
+ __FUNCTION__, x1, y1, x2, y2, drawLast));
+
+ /* simple overestimate of line extents for clipping */
+ box.x1 = x1 - 1;
+ box.y1 = y1 - 1;
+ box.x2 = x2 + 1;
+ box.y2 = y2 + 1;
+
+ data.x1 = x1;
+ data.y1 = y1;
+ data.x2 = x2;
+ data.y2 = y2;
+
+ data.dashOffset = dashOffset;
+ data.drawLast = drawLast;
+ data.bres = fbSelectBres(drawable, gc);
+
+ fbDrawableRunUnclipped(drawable, gc, &box, _fbSegment, &data);
+}
+
+void
+fbSegment1(DrawablePtr drawable, GCPtr gc, const BoxRec *b,
+ int x1, int y1, int x2, int y2,
+ bool drawLast, int *dashOffset)
+{
+ struct fbSegment data;
+
+ DBG(("%s (%d, %d), (%d, %d), drawLast?=%d\n",
+ __FUNCTION__, x1, y1, x2, y2, drawLast));
+
+ data.x1 = x1;
+ data.y1 = y1;
+ data.x2 = x2;
+ data.y2 = y2;
+
+ data.dashOffset = dashOffset;
+ data.drawLast = drawLast;
+ data.bres = fbSelectBres(drawable, gc);
+
+ _fbSegment(drawable, gc, b, &data);
+}
diff --git a/src/sna/fb/fbsegbits.h b/src/sna/fb/fbsegbits.h
new file mode 100644
index 000000000..590ad3009
--- /dev/null
+++ b/src/sna/fb/fbsegbits.h
@@ -0,0 +1,212 @@
+/*
+ * Copyright © 1998 Keith Packard
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define isClipped(c,ul,lr) (((c) | ((c) - (ul)) | ((lr) - (c))) & 0x80008000)
+#define RROP(b,a,x) WRITE((b), FbDoRRop (READ(b), (a), (x)))
+
+static void
+BRESSOLID(DrawablePtr drawable, GCPtr gc, int dashOffset,
+ int sdx, int sdy, int axis,
+ int x1, int y1, int e, int e1, int e3, int len)
+{
+ FbBits *dst;
+ FbStride stride;
+ int bpp, dx, dy;
+ BITS *bits;
+ FbStride major, minor;
+ BITS xor = fb_gc(gc)->xor;
+
+ fbGetDrawable(drawable, dst, stride, bpp, dx, dy);
+ bits = (BITS *)(dst + (y1 + dy) * stride) + (x1 + dx);
+ stride = stride * (sizeof(FbBits) / sizeof(BITS));
+ if (sdy < 0)
+ stride = -stride;
+ if (axis == X_AXIS) {
+ major = sdx;
+ minor = stride;
+ } else {
+ major = stride;
+ minor = sdx;
+ }
+ while (len--) {
+ WRITE(bits, xor);
+ bits += major;
+ e += e1;
+ if (e >= 0) {
+ bits += minor;
+ e += e3;
+ }
+ }
+}
+
+static void
+BRESSOLIDR(DrawablePtr drawable, GCPtr gc, int dashOffset,
+ int sdx, int sdy, int axis,
+ int x1, int y1, int e, int e1, int e3, int len)
+{
+ FbBits *dst;
+ FbStride stride;
+ int bpp, dx, dy;
+ BITS *bits;
+ FbStride major, minor;
+ BITS and = fb_gc(gc)->and;
+ BITS xor = fb_gc(gc)->xor;
+
+ fbGetDrawable(drawable, dst, stride, bpp, dx, dy);
+ bits = (BITS *)(dst + (y1 + dy) * stride) + (x1 + dx);
+ stride = stride * (sizeof(FbBits) / sizeof(BITS));
+ if (sdy < 0)
+ stride = -stride;
+ if (axis == X_AXIS) {
+ major = sdx;
+ minor = stride;
+ } else {
+ major = stride;
+ minor = sdx;
+ }
+ while (len--) {
+ RROP(bits, and, xor);
+ bits += major;
+ e += e1;
+ if (e >= 0) {
+ bits += minor;
+ e += e3;
+ }
+ }
+}
+
+static void
+BRESDASH(DrawablePtr drawable, GCPtr gc, int dashOffset,
+ int sdx, int sdy, int axis,
+ int x1, int y1, int e, int e1, int e3, int len)
+{
+ FbBits *dst;
+ FbStride stride;
+ int bpp, dx, dy;
+ BITS *bits;
+ FbStride major, minor;
+
+ FbDashDeclare;
+ int dashlen;
+ bool even;
+ bool doOdd = gc->lineStyle == LineDoubleDash;
+ BITS xorfg = fb_gc(gc)->xor;
+ BITS xorbg = fb_gc(gc)->bgxor;
+
+ fbGetDrawable(drawable, dst, stride, bpp, dx, dy);
+
+ FbDashInit(gc, fb_gc(gc), dashOffset, dashlen, even);
+
+ bits = ((BITS *) (dst + ((y1 + dy) * stride))) + (x1 + dx);
+ stride = stride * (sizeof(FbBits) / sizeof(BITS));
+ if (sdy < 0)
+ stride = -stride;
+ if (axis == X_AXIS) {
+ major = sdx;
+ minor = stride;
+ } else {
+ major = stride;
+ minor = sdx;
+ }
+ if (dashlen >= len)
+ dashlen = len;
+ if (doOdd) {
+ if (!even)
+ goto doubleOdd;
+ for (;;) {
+ len -= dashlen;
+ while (dashlen--) {
+ WRITE(bits, xorfg);
+ bits += major;
+ if ((e += e1) >= 0) {
+ e += e3;
+ bits += minor;
+ }
+ }
+ if (!len)
+ break;
+
+ FbDashNextEven(dashlen);
+
+ if (dashlen >= len)
+ dashlen = len;
+doubleOdd:
+ len -= dashlen;
+ while (dashlen--) {
+ WRITE(bits, xorbg);
+ bits += major;
+ if ((e += e1) >= 0) {
+ e += e3;
+ bits += minor;
+ }
+ }
+ if (!len)
+ break;
+
+ FbDashNextOdd(dashlen);
+
+ if (dashlen >= len)
+ dashlen = len;
+ }
+ } else {
+ if (!even)
+ goto onOffOdd;
+ for (;;) {
+ len -= dashlen;
+ while (dashlen--) {
+ WRITE(bits, xorfg);
+ bits += major;
+ if ((e += e1) >= 0) {
+ e += e3;
+ bits += minor;
+ }
+ }
+ if (!len)
+ break;
+
+ FbDashNextEven(dashlen);
+
+ if (dashlen >= len)
+ dashlen = len;
+onOffOdd:
+ len -= dashlen;
+ while (dashlen--) {
+ bits += major;
+ if ((e += e1) >= 0) {
+ e += e3;
+ bits += minor;
+ }
+ }
+ if (!len)
+ break;
+
+ FbDashNextOdd(dashlen);
+
+ if (dashlen >= len)
+ dashlen = len;
+ }
+ }
+}
+
+#undef RROP
+#undef isClipped
diff --git a/src/sna/fb/fbspan.c b/src/sna/fb/fbspan.c
new file mode 100644
index 000000000..45cb7cc7b
--- /dev/null
+++ b/src/sna/fb/fbspan.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright © 1998 Keith Packard
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "fb.h"
+#include "fbclip.h"
+
+inline static void
+fbFillSpan(DrawablePtr drawable, GCPtr gc, const BoxRec *b, void *data)
+{
+ DBG(("%s (%d,%d)+%d\n", __FUNCTION__, b->x1, b->y1, b->x2-b->x1));
+ fbFill(drawable, gc, b->x1, b->y1, b->x2 - b->x1, 1);
+}
+
+void
+fbFillSpans(DrawablePtr drawable, GCPtr gc,
+ int n, DDXPointPtr pt, int *width, int fSorted)
+{
+ DBG(("%s x %d\n", __FUNCTION__, n));
+ while (n--) {
+ BoxRec box;
+
+ *(DDXPointPtr)&box = *pt++;
+ box.x2 = box.x1 + *width++;
+ box.y2 = box.y1 + 1;
+
+ /* XXX fSorted */
+ fbDrawableRun(drawable, gc, &box, fbFillSpan, NULL);
+ }
+}
+
+struct fbSetSpan {
+ char *src;
+ DDXPointRec pt;
+ FbStride stride;
+ FbBits *dst;
+ int dx, dy;
+};
+
+inline static void
+fbSetSpan(DrawablePtr drawable, GCPtr gc, const BoxRec *b, void *_data)
+{
+ struct fbSetSpan *data = _data;
+ int xoff, bpp;
+
+ xoff = (int) (((long)data->src) & (FB_MASK >> 3));
+ bpp = drawable->bitsPerPixel;
+
+ fbBlt((FbBits *)(data->src - xoff), 0,
+ (b->x1 - data->pt.x) * bpp + (xoff << 3),
+ data->dst + (b->y1 + data->dy) * data->stride, data->stride,
+ (b->x1 + data->dx) * bpp,
+ (b->x2 - b->x1) * bpp, 1,
+ gc->alu, fb_gc(gc)->pm, bpp,
+ FALSE, FALSE);
+}
+
+void
+fbSetSpans(DrawablePtr drawable, GCPtr gc,
+ char *src, DDXPointPtr pt, int *width, int n, int fSorted)
+{
+ struct fbSetSpan data;
+ PixmapPtr pixmap;
+
+ DBG(("%s x %d\n", __FUNCTION__, n));
+
+ fbGetDrawablePixmap(drawable, pixmap, data.dx, data.dy);
+ data.dst = pixmap->devPrivate.ptr;
+ data.stride = pixmap->devKind / sizeof(FbStip);
+
+ data.src = src;
+ while (n--) {
+ BoxRec box;
+
+ *(DDXPointPtr)&box = data.pt = *pt;
+ box.x2 = box.x1 + *width;
+ box.y2 = box.y1 + 1;
+
+ fbDrawableRun(drawable, gc, &box, fbSetSpan, &data);
+
+ data.src += PixmapBytePad(*width, drawable->depth);
+ width++;
+ pt++;
+ }
+}
+
+void
+fbGetSpans(DrawablePtr drawable, int wMax,
+ DDXPointPtr pt, int *width, int n, char *dst)
+{
+ FbBits *src, *d;
+ FbStride srcStride;
+ int srcBpp;
+ int srcXoff, srcYoff;
+ int xoff;
+
+ fbGetDrawable(drawable, src, srcStride, srcBpp, srcXoff, srcYoff);
+
+ DBG(("%s x %d\n", __FUNCTION__, n));
+ while (n--) {
+ xoff = (int) (((long) dst) & (FB_MASK >> 3));
+ d = (FbBits *) (dst - xoff);
+ fbBlt(src + (pt->y + srcYoff) * srcStride, srcStride,
+ (pt->x + srcXoff) * srcBpp,
+ d, 1, xoff << 3, *width * srcBpp,
+ 1, GXcopy, FB_ALLONES, srcBpp,
+ FALSE, FALSE);
+ dst += PixmapBytePad(*width, drawable->depth);
+ pt++;
+ width++;
+ }
+}
diff --git a/src/sna/fb/fbstipple.c b/src/sna/fb/fbstipple.c
new file mode 100644
index 000000000..d02970a0d
--- /dev/null
+++ b/src/sna/fb/fbstipple.c
@@ -0,0 +1,223 @@
+/*
+ * Copyright © 1998 Keith Packard
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "fb.h"
+
+/*
+ * This is a slight abuse of the preprocessor to generate repetitive
+ * code, the idea is to generate code for each case of a copy-mode
+ * transparent stipple
+ */
+#define LaneCases1(c,a) \
+ case c: while (n--) { FbLaneCase(c,a); a++; } break
+#define LaneCases2(c,a) LaneCases1(c,a); LaneCases1(c+1,a)
+#define LaneCases4(c,a) LaneCases2(c,a); LaneCases2(c+2,a)
+#define LaneCases8(c,a) LaneCases4(c,a); LaneCases4(c+4,a)
+#define LaneCases16(c,a) LaneCases8(c,a); LaneCases8(c+8,a)
+
+#define LaneCases(a) LaneCases16(0,a)
+
+/*
+ * Repeat a transparent stipple across a scanline n times
+ */
+
+void
+fbTransparentSpan(FbBits * dst, FbBits stip, FbBits fgxor, int n)
+{
+ FbStip s;
+
+ s = ((FbStip) (stip) & 0x01);
+ s |= ((FbStip) (stip >> 8) & 0x02);
+ s |= ((FbStip) (stip >> 16) & 0x04);
+ s |= ((FbStip) (stip >> 24) & 0x08);
+ switch (s) {
+ LaneCases(dst);
+ }
+}
+
+static void
+fbEvenStipple(FbBits *dst, FbStride dstStride, int dstX, int dstBpp,
+ int width, int height,
+ FbStip *stip, FbStride stipStride,
+ int stipHeight,
+ FbBits fgand, FbBits fgxor, FbBits bgand, FbBits bgxor,
+ int xRot, int yRot)
+{
+ FbBits startmask, endmask;
+ FbBits mask, and, xor;
+ int nmiddle, n;
+ FbStip *s, *stipEnd, bits;
+ int rot, stipX, stipY;
+ int pixelsPerDst;
+ const FbBits *fbBits;
+ Bool transparent;
+ int startbyte, endbyte;
+
+ /*
+ * Check for a transparent stipple (stencil)
+ */
+ transparent = FALSE;
+ if (dstBpp >= 8 && fgand == 0 && bgand == FB_ALLONES && bgxor == 0)
+ transparent = TRUE;
+
+ pixelsPerDst = FB_UNIT / dstBpp;
+ /*
+ * Adjust dest pointers
+ */
+ dst += dstX >> FB_SHIFT;
+ dstX &= FB_MASK;
+ FbMaskBitsBytes(dstX, width, fgand == 0 && bgand == 0,
+ startmask, startbyte, nmiddle, endmask, endbyte);
+
+ if (startmask)
+ dstStride--;
+ dstStride -= nmiddle;
+
+ xRot *= dstBpp;
+ /*
+ * Compute stip start scanline and rotation parameters
+ */
+ stipEnd = stip + stipStride * stipHeight;
+ modulus(-yRot, stipHeight, stipY);
+ s = stip + stipStride * stipY;
+ modulus(-xRot, FB_UNIT, stipX);
+ rot = stipX;
+
+ /*
+ * Get pointer to stipple mask array for this depth
+ */
+ /* fbStippleTable covers all valid bpp (4,8,16,32) */
+ fbBits = fbStippleTable[pixelsPerDst];
+
+ while (height--) {
+ /*
+ * Extract stipple bits for this scanline;
+ */
+ bits = READ(s);
+ s += stipStride;
+ if (s == stipEnd)
+ s = stip;
+ mask = fbBits[FbLeftStipBits(bits, pixelsPerDst)];
+ /*
+ * Rotate into position and compute reduced rop values
+ */
+ mask = FbRotLeft(mask, rot);
+ and = (fgand & mask) | (bgand & ~mask);
+ xor = (fgxor & mask) | (bgxor & ~mask);
+
+ if (transparent) {
+ if (startmask) {
+ fbTransparentSpan(dst, mask & startmask, fgxor, 1);
+ dst++;
+ }
+ fbTransparentSpan(dst, mask, fgxor, nmiddle);
+ dst += nmiddle;
+ if (endmask)
+ fbTransparentSpan(dst, mask & endmask, fgxor, 1);
+ } else {
+ /*
+ * Fill scanline
+ */
+ if (startmask) {
+ FbDoLeftMaskByteRRop(dst, startbyte, startmask, and, xor);
+ dst++;
+ }
+ n = nmiddle;
+ if (!and)
+ while (n--)
+ WRITE(dst++, xor);
+ else {
+ while (n--) {
+ WRITE(dst, FbDoRRop(READ(dst), and, xor));
+ dst++;
+ }
+ }
+ if (endmask)
+ FbDoRightMaskByteRRop(dst, endbyte, endmask, and, xor);
+ }
+ dst += dstStride;
+ }
+}
+
+static void
+fbOddStipple(FbBits *dst, FbStride dstStride, int dstX, int dstBpp,
+ int width, int height,
+ FbStip *stip, FbStride stipStride,
+ int stipWidth, int stipHeight,
+ FbBits fgand, FbBits fgxor, FbBits bgand, FbBits bgxor,
+ int xRot, int yRot)
+{
+ int stipX, stipY, sx;
+ int widthTmp;
+ int h, w;
+ int x, y;
+
+ modulus(-yRot, stipHeight, stipY);
+ modulus(dstX / dstBpp - xRot, stipWidth, stipX);
+ y = 0;
+ while (height) {
+ h = stipHeight - stipY;
+ if (h > height)
+ h = height;
+ height -= h;
+ widthTmp = width;
+ x = dstX;
+ sx = stipX;
+ while (widthTmp) {
+ w = (stipWidth - sx) * dstBpp;
+ if (w > widthTmp)
+ w = widthTmp;
+ widthTmp -= w;
+ fbBltOne(stip + stipY * stipStride,
+ stipStride,
+ sx,
+ dst + y * dstStride,
+ dstStride, x, dstBpp, w, h, fgand, fgxor, bgand, bgxor);
+ x += w;
+ sx = 0;
+ }
+ y += h;
+ stipY = 0;
+ }
+}
+
+void
+fbStipple(FbBits *dst, FbStride dstStride, int dstX, int dstBpp,
+ int width, int height,
+ FbStip *stip, FbStride stipStride,
+ int stipWidth, int stipHeight, Bool even,
+ FbBits fgand, FbBits fgxor, FbBits bgand, FbBits bgxor,
+ int xRot, int yRot)
+{
+ DBG(("%s stipple=%dx%d, size=%dx%d\n",
+ __FUNCTION__, stipWidth, stipHeight, width, height));
+
+ if (even)
+ fbEvenStipple(dst, dstStride, dstX, dstBpp, width, height,
+ stip, stipStride, stipHeight,
+ fgand, fgxor, bgand, bgxor, xRot, yRot);
+ else
+ fbOddStipple(dst, dstStride, dstX, dstBpp, width, height,
+ stip, stipStride, stipWidth, stipHeight,
+ fgand, fgxor, bgand, bgxor, xRot, yRot);
+}
diff --git a/src/sna/fb/fbtile.c b/src/sna/fb/fbtile.c
new file mode 100644
index 000000000..c3506716a
--- /dev/null
+++ b/src/sna/fb/fbtile.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright © 1998 Keith Packard
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "fb.h"
+
+/*
+ * Accelerated tile fill -- tile width is a power of two not greater
+ * than FB_UNIT
+ */
+
+static void
+fbEvenTile(FbBits *dst, FbStride dstStride, int dstX, int width, int height,
+ FbBits *tile, FbStride tileStride, int tileHeight,
+ int alu, FbBits pm,
+ int xRot, int yRot)
+{
+ FbBits *t, *tileEnd, bits;
+ FbBits startmask, endmask;
+ FbBits and, xor;
+ int n, nmiddle;
+ int tileX, tileY;
+ int rot;
+ int startbyte, endbyte;
+
+ dst += dstX >> FB_SHIFT;
+ dstX &= FB_MASK;
+ FbMaskBitsBytes(dstX, width, FbDestInvarientRop(alu, pm),
+ startmask, startbyte, nmiddle, endmask, endbyte);
+ if (startmask)
+ dstStride--;
+ dstStride -= nmiddle;
+
+ /*
+ * Compute tile start scanline and rotation parameters
+ */
+ tileEnd = tile + tileHeight * tileStride;
+ modulus(-yRot, tileHeight, tileY);
+ t = tile + tileY * tileStride;
+ modulus(-xRot, FB_UNIT, tileX);
+ rot = tileX;
+
+ while (height--) {
+ /*
+ * Pick up bits for this scanline
+ */
+ bits = READ(t);
+ t += tileStride;
+ if (t >= tileEnd)
+ t = tile;
+ bits = FbRotLeft(bits, rot);
+ and = fbAnd(alu, bits, pm);
+ xor = fbXor(alu, bits, pm);
+
+ if (startmask) {
+ FbDoLeftMaskByteRRop(dst, startbyte, startmask, and, xor);
+ dst++;
+ }
+ n = nmiddle;
+ if (!and)
+ while (n--)
+ WRITE(dst++, xor);
+ else
+ while (n--) {
+ WRITE(dst, FbDoRRop(READ(dst), and, xor));
+ dst++;
+ }
+ if (endmask)
+ FbDoRightMaskByteRRop(dst, endbyte, endmask, and, xor);
+ dst += dstStride;
+ }
+}
+
+static void
+fbOddTile(FbBits *dst, FbStride dstStride, int dstX,
+ int width, int height,
+ FbBits *tile, FbStride tileStride,
+ int tileWidth, int tileHeight,
+ int alu, FbBits pm, int bpp,
+ int xRot, int yRot)
+{
+ int tileX, tileY;
+ int x, y;
+
+ DBG(("%s tile=%dx%d, size=%dx%d\n", __FUNCTION__,
+ tileWidth, tileHeight, width, height));
+
+ modulus(-yRot, tileHeight, tileY);
+ y = 0;
+ while (height) {
+ int ww = width;
+ int h = tileHeight - tileY;
+ if (h > height)
+ h = height;
+ height -= h;
+ x = dstX;
+ modulus(dstX - xRot, tileWidth, tileX);
+ while (ww) {
+ int w = tileWidth - tileX;
+ if (w > ww)
+ w = ww;
+ ww -= w;
+ fbBlt(tile + tileY * tileStride, tileStride, tileX,
+ dst + y * dstStride, dstStride,
+ x, w, h, alu, pm, bpp, FALSE, FALSE);
+ x += w;
+ tileX = 0;
+ }
+ y += h;
+ tileY = 0;
+ }
+}
+
+void
+fbTile(FbBits *dst, FbStride dstStride, int dstX,
+ int width, int height,
+ FbBits *tile, FbStride tileStride,
+ int tileWidth, int tileHeight,
+ int alu, FbBits pm, int bpp,
+ int xRot, int yRot)
+{
+ DBG(("%s tile=%dx%d, size=%dx%d\n", __FUNCTION__,
+ tileWidth, tileHeight, width, height));
+
+ if (FbEvenTile(tileWidth))
+ fbEvenTile(dst, dstStride, dstX, width, height,
+ tile, tileStride, tileHeight, alu, pm, xRot, yRot);
+ else
+ fbOddTile(dst, dstStride, dstX, width, height,
+ tile, tileStride, tileWidth, tileHeight,
+ alu, pm, bpp, xRot, yRot);
+}
diff --git a/src/sna/fb/fbutil.c b/src/sna/fb/fbutil.c
new file mode 100644
index 000000000..61b63ad58
--- /dev/null
+++ b/src/sna/fb/fbutil.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright © 1998 Keith Packard
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "fb.h"
+
+FbBits
+fbReplicatePixel(Pixel p, int bpp)
+{
+ FbBits b = p;
+
+ b &= FbFullMask(bpp);
+ while (bpp < FB_UNIT) {
+ b |= b << bpp;
+ bpp <<= 1;
+ }
+ return b;
+}
+
+/*
+ * Stipple masks are independent of bit/byte order as long
+ * as bitorder == byteorder. FB doesn't handle the case
+ * where these differ
+ */
+#define __mask(x,w) ((FB_ALLONES << ((x) & FB_MASK)) & \
+ (FB_ALLONES >> ((FB_UNIT - ((x) + (w))) & FB_MASK)))
+#define _mask(x,w) __mask((x)*(w),(w))
+#define mask(b,n,w) ((((b) >> (n)) & 1) * _mask(n,w))
+
+#define _C1(b,n,w) mask(b,n,w)
+#define _C2(b,n,w) (_C1(b,n,w) | _C1(b,n+1,w))
+#define _C4(b,n,w) (_C2(b,n,w) | _C2(b,n+2,w))
+#define C8(b,w) (_C4(b,0,w) | _C4(b,4,w))
+#define C4(b,w) _C4(b,0,w)
+#define C2(b,w) _C2(b,0,w)
+#define C1(b,w) _C1(b,0,w)
+
+static const FbBits fbStipple8Bits[256] = {
+ C8(0, 4), C8(1, 4), C8(2, 4), C8(3, 4), C8(4, 4), C8(5, 4),
+ C8(6, 4), C8(7, 4), C8(8, 4), C8(9, 4), C8(10, 4), C8(11, 4),
+ C8(12, 4), C8(13, 4), C8(14, 4), C8(15, 4), C8(16, 4), C8(17, 4),
+ C8(18, 4), C8(19, 4), C8(20, 4), C8(21, 4), C8(22, 4), C8(23, 4),
+ C8(24, 4), C8(25, 4), C8(26, 4), C8(27, 4), C8(28, 4), C8(29, 4),
+ C8(30, 4), C8(31, 4), C8(32, 4), C8(33, 4), C8(34, 4), C8(35, 4),
+ C8(36, 4), C8(37, 4), C8(38, 4), C8(39, 4), C8(40, 4), C8(41, 4),
+ C8(42, 4), C8(43, 4), C8(44, 4), C8(45, 4), C8(46, 4), C8(47, 4),
+ C8(48, 4), C8(49, 4), C8(50, 4), C8(51, 4), C8(52, 4), C8(53, 4),
+ C8(54, 4), C8(55, 4), C8(56, 4), C8(57, 4), C8(58, 4), C8(59, 4),
+ C8(60, 4), C8(61, 4), C8(62, 4), C8(63, 4), C8(64, 4), C8(65, 4),
+ C8(66, 4), C8(67, 4), C8(68, 4), C8(69, 4), C8(70, 4), C8(71, 4),
+ C8(72, 4), C8(73, 4), C8(74, 4), C8(75, 4), C8(76, 4), C8(77, 4),
+ C8(78, 4), C8(79, 4), C8(80, 4), C8(81, 4), C8(82, 4), C8(83, 4),
+ C8(84, 4), C8(85, 4), C8(86, 4), C8(87, 4), C8(88, 4), C8(89, 4),
+ C8(90, 4), C8(91, 4), C8(92, 4), C8(93, 4), C8(94, 4), C8(95, 4),
+ C8(96, 4), C8(97, 4), C8(98, 4), C8(99, 4), C8(100, 4), C8(101, 4),
+ C8(102, 4), C8(103, 4), C8(104, 4), C8(105, 4), C8(106, 4), C8(107, 4),
+ C8(108, 4), C8(109, 4), C8(110, 4), C8(111, 4), C8(112, 4), C8(113, 4),
+ C8(114, 4), C8(115, 4), C8(116, 4), C8(117, 4), C8(118, 4), C8(119, 4),
+ C8(120, 4), C8(121, 4), C8(122, 4), C8(123, 4), C8(124, 4), C8(125, 4),
+ C8(126, 4), C8(127, 4), C8(128, 4), C8(129, 4), C8(130, 4), C8(131, 4),
+ C8(132, 4), C8(133, 4), C8(134, 4), C8(135, 4), C8(136, 4), C8(137, 4),
+ C8(138, 4), C8(139, 4), C8(140, 4), C8(141, 4), C8(142, 4), C8(143, 4),
+ C8(144, 4), C8(145, 4), C8(146, 4), C8(147, 4), C8(148, 4), C8(149, 4),
+ C8(150, 4), C8(151, 4), C8(152, 4), C8(153, 4), C8(154, 4), C8(155, 4),
+ C8(156, 4), C8(157, 4), C8(158, 4), C8(159, 4), C8(160, 4), C8(161, 4),
+ C8(162, 4), C8(163, 4), C8(164, 4), C8(165, 4), C8(166, 4), C8(167, 4),
+ C8(168, 4), C8(169, 4), C8(170, 4), C8(171, 4), C8(172, 4), C8(173, 4),
+ C8(174, 4), C8(175, 4), C8(176, 4), C8(177, 4), C8(178, 4), C8(179, 4),
+ C8(180, 4), C8(181, 4), C8(182, 4), C8(183, 4), C8(184, 4), C8(185, 4),
+ C8(186, 4), C8(187, 4), C8(188, 4), C8(189, 4), C8(190, 4), C8(191, 4),
+ C8(192, 4), C8(193, 4), C8(194, 4), C8(195, 4), C8(196, 4), C8(197, 4),
+ C8(198, 4), C8(199, 4), C8(200, 4), C8(201, 4), C8(202, 4), C8(203, 4),
+ C8(204, 4), C8(205, 4), C8(206, 4), C8(207, 4), C8(208, 4), C8(209, 4),
+ C8(210, 4), C8(211, 4), C8(212, 4), C8(213, 4), C8(214, 4), C8(215, 4),
+ C8(216, 4), C8(217, 4), C8(218, 4), C8(219, 4), C8(220, 4), C8(221, 4),
+ C8(222, 4), C8(223, 4), C8(224, 4), C8(225, 4), C8(226, 4), C8(227, 4),
+ C8(228, 4), C8(229, 4), C8(230, 4), C8(231, 4), C8(232, 4), C8(233, 4),
+ C8(234, 4), C8(235, 4), C8(236, 4), C8(237, 4), C8(238, 4), C8(239, 4),
+ C8(240, 4), C8(241, 4), C8(242, 4), C8(243, 4), C8(244, 4), C8(245, 4),
+ C8(246, 4), C8(247, 4), C8(248, 4), C8(249, 4), C8(250, 4), C8(251, 4),
+ C8(252, 4), C8(253, 4), C8(254, 4), C8(255, 4),
+};
+
+static const FbBits fbStipple4Bits[16] = {
+ C4(0, 8), C4(1, 8), C4(2, 8), C4(3, 8), C4(4, 8), C4(5, 8),
+ C4(6, 8), C4(7, 8), C4(8, 8), C4(9, 8), C4(10, 8), C4(11, 8),
+ C4(12, 8), C4(13, 8), C4(14, 8), C4(15, 8),
+};
+
+static const FbBits fbStipple2Bits[4] = {
+ C2(0, 16), C2(1, 16), C2(2, 16), C2(3, 16),
+};
+
+static const FbBits fbStipple1Bits[2] = {
+ C1(0, 32), C1(1, 32),
+};
+const FbBits *const fbStippleTable[] = {
+ 0,
+ fbStipple1Bits,
+ fbStipple2Bits,
+ 0,
+ fbStipple4Bits,
+ 0,
+ 0,
+ 0,
+ fbStipple8Bits,
+};
diff --git a/src/sna/fb/sfb.h b/src/sna/fb/sfb.h
new file mode 100644
index 000000000..a4d9d1711
--- /dev/null
+++ b/src/sna/fb/sfb.h
@@ -0,0 +1,40 @@
+/* And rename to avoid symbol clashes with UXA */
+#define fbPolyArc sfbPolyArc
+#define fbBlt sfbBlt
+#define fbBltOne sfbBltOne
+#define fbBltPlane sfbBltPlane
+#define fbCopyNtoN sfbCopyNtoN
+#define fbCopy1toN sfbCopy1toN
+#define fbCopyNto1 sfbCopyNto1
+#define fbCopyArea sfbCopyArea
+#define fbCopyPlane sfbCopyPlane
+#define fbFill sfbFill
+#define fbSolidBoxClipped sfbSolidBoxClipped
+#define fbPolyFillRect sfbPolyFillRect
+#define fbFillSpans sfbFillSpans
+#define fbPadPixmap sfbPadPixmap
+#define fbValidateGC sfbValidateGC
+#define fbGetSpans sfbGetSpans
+#define fbPolyGlyphBlt sfbPolyGlyphBlt
+#define fbImageGlyphBlt sfbImageGlyphBlt
+#define fbPutImage sfbPutImage
+#define fbPuXYtImage sfbPutXYImage
+#define fbGetImage sfbGetImage
+#define fbPolyLine sfbPolyLine
+#define fbFixCoordModePrevious sfbFixCoordModePrevious
+#define fbPolySegment sfbPolySegment
+#define fbBitmapToRegion sfbBitmapToRegion
+#define fbPolyPoint sfbPolyPoint
+#define fbPushImage sfbPushImage
+#define fbPushPixels sfbPushPixels
+#define fbSetSpans sfbSetSpans
+#define fbSegment sfbSegment
+#define fbSegment1 sfbSegment1
+#define fbTransparentSpan sfbTransparentSpan
+#define fbStipple sfbStipple
+#define fbTile sfbTile
+#define fbReplicatePixel sfbReplicatePixel
+
+#define fbComposite sfbComposite
+#define image_from_pict simage_from_pict
+#define free_pixmap_pict sfree_pixmap_pict