diff options
Diffstat (limited to 'src/sna/fb')
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 = ®ion->extents + 1; + return ®ion->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(¢er, 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 |