diff options
91 files changed, 3670 insertions, 2366 deletions
diff --git a/fontconfig/configure.in b/fontconfig/configure.in index 9c9de30e7..9bb0988ec 100644 --- a/fontconfig/configure.in +++ b/fontconfig/configure.in @@ -150,7 +150,11 @@ AC_DEFINE_UNQUOTED(USE_REGEX,$use_regex,[Use regex.]) AC_ARG_WITH(libiconv, [AC_HELP_STRING([--with-libiconv=DIR], [Use libiconv in DIR])], - [libiconv_prefix=$withval], + [if test "x$withval" = "xyes"; then + libiconv_prefix=$prefix + else + libiconv_prefix=$withval + fi], [libiconv_prefix=auto]) AC_ARG_WITH(libiconv-includes, [AC_HELP_STRING([--with-libiconv-includes=DIR], @@ -163,33 +167,33 @@ AC_ARG_WITH(libiconv-lib, [libiconv_lib=$withval], [libiconv_lib=auto]) -# if none of libiconv,libiconv-includes,libiconv-libs are specified -if test "$libiconv_prefix" != "auto" -o "$libiconv_includes" != "auto" -o "$libiconv_lib" != "auto"; then - if test "$libiconv_includes" != "auto" -a -r ${libiconv_includes}/iconv.h; then - libiconv_cflags="-I${libiconv_includes}" - elif test "$libiconv_prefix" != "auto" -a -r ${libiconv_prefix}/include/iconv.h; then - libiconv_cflags="-I${libiconv_prefix}/include" - else - libiconv_cflags="" - fi - if test "$libiconv_lib" != "auto"; then - libiconv_lib="-L${libiconv_lib} -liconv" - elif test "$libiconv_prefix" != "auto"; then - libiconv_lib="-L${libiconv_prefix}/lib -liconv" - elif test "x$libiconv_cflags" != "x"; then - libiconv_lib="-liconv" +# if no libiconv,libiconv-includes,libiconv-lib are specified, +# libc's iconv has a priority. +if test "$libiconv_includes" != "auto" -a -r ${libiconv_includes}/iconv.h; then + libiconv_cflags="-I${libiconv_includes}" +elif test "$libiconv_prefix" != "auto" -a -r ${libiconv_prefix}/include/iconv.h; then + libiconv_cflags="-I${libiconv_prefix}/include" +else + libiconv_cflags="" +fi +libiconv_libs="" +if test "x$libiconv_cflags" != "x"; then + if test "$libiconv_lib" != "auto" -a -d ${libiconv_lib}; then + libiconv_libs="-L${libiconv_lib} -liconv" + elif test "$libiconv_prefix" != "auto" -a -d ${libiconv_prefix}/lib; then + libiconv_libs="-L${libiconv_prefix}/lib -liconv" else - libiconv_lib="" + libiconv_libs="-liconv" fi fi use_iconv=0 AC_MSG_CHECKING([for a usable iconv]) -if test "x$libiconv_cflags" != "x" -o "x$libiconv_lib" != "x"; then +if test "x$libiconv_cflags" != "x" -o "x$libiconv_libs" != "x"; then iconvsaved_CFLAGS="$CFLAGS" iconvsaved_LIBS="$LIBS" CFLAGS="$CFLAGS $libiconv_cflags" - LIBS="$LIBS $libiconv_lib" + LIBS="$LIBS $libiconv_libs" AC_TRY_LINK([#include <iconv.h>], [iconv_open ("from", "to");], @@ -200,7 +204,7 @@ if test "x$libiconv_cflags" != "x" -o "x$libiconv_lib" != "x"; then CFLAGS="$iconvsaved_CFLAGS" LIBS="$iconvsaved_LIBS" ICONV_CFLAGS="$libiconv_cflags" - ICONV_LIBS="$libiconv_lib" + ICONV_LIBS="$libiconv_libs" fi if test "x$use_iconv" = "x0"; then AC_TRY_LINK([#include <iconv.h>], diff --git a/fontconfig/doc/fccache.fncs b/fontconfig/doc/fccache.fncs index f35c5d7cb..2f5fa4766 100644 --- a/fontconfig/doc/fccache.fncs +++ b/fontconfig/doc/fccache.fncs @@ -66,3 +66,12 @@ This returns the total number of subdirectories in the cache. This returns the number of fonts which would be included in the return from FcCacheCopySet. @@ + +@RET@ FcBool +@FUNC@ FcDirCacheClean +@TYPE1@ const FcChar8 * @ARG1@ cache_dir +@TYPE2@ FcBool @ARG2@ verbose +@PURPOSE@ +This tries to clean up the cache directory of <parameter>cache_dir</parameter>. +This returns FcTrue if the operation is successfully complete. otherwise FcFalse. +@@ diff --git a/fontconfig/fc-cache/fc-cache.c b/fontconfig/fc-cache/fc-cache.c index 24bb2ec9f..b42fd3545 100644 --- a/fontconfig/fc-cache/fc-cache.c +++ b/fontconfig/fc-cache/fc-cache.c @@ -32,7 +32,6 @@ #endif #include <fontconfig/fontconfig.h> -#include "../src/fcarch.h" #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -319,96 +318,6 @@ scanDirs (FcStrList *list, FcConfig *config, FcBool force, FcBool really_force, } static FcBool -cleanCacheDirectory (FcConfig *config, FcChar8 *dir, FcBool verbose) -{ - DIR *d; - struct dirent *ent; - FcChar8 *dir_base; - FcBool ret = FcTrue; - FcBool remove; - FcCache *cache; - struct stat target_stat; - - dir_base = FcStrPlus (dir, (FcChar8 *) "/"); - if (!dir_base) - { - fprintf (stderr, "%s: out of memory\n", dir); - return FcFalse; - } - if (access ((char *) dir, W_OK) != 0) - { - if (verbose) - printf ("%s: not cleaning %s cache directory\n", dir, - access ((char *) dir, F_OK) == 0 ? "unwritable" : "non-existent"); - FcStrFree (dir_base); - return FcTrue; - } - if (verbose) - printf ("%s: cleaning cache directory\n", dir); - d = opendir ((char *) dir); - if (!d) - { - perror ((char *) dir); - FcStrFree (dir_base); - return FcFalse; - } - while ((ent = readdir (d))) - { - FcChar8 *file_name; - const FcChar8 *target_dir; - - if (ent->d_name[0] == '.') - continue; - /* skip cache files for different architectures and */ - /* files which are not cache files at all */ - if (strlen(ent->d_name) != 32 + strlen ("-" FC_ARCHITECTURE FC_CACHE_SUFFIX) || - strcmp(ent->d_name + 32, "-" FC_ARCHITECTURE FC_CACHE_SUFFIX)) - continue; - - file_name = FcStrPlus (dir_base, (FcChar8 *) ent->d_name); - if (!file_name) - { - fprintf (stderr, "%s: allocation failure\n", dir); - ret = FcFalse; - break; - } - remove = FcFalse; - cache = FcDirCacheLoadFile (file_name, NULL); - if (!cache) - { - if (verbose) - printf ("%s: invalid cache file: %s\n", dir, ent->d_name); - remove = FcTrue; - } - else - { - target_dir = FcCacheDir (cache); - if (stat ((char *) target_dir, &target_stat) < 0) - { - if (verbose) - printf ("%s: %s: missing directory: %s \n", - dir, ent->d_name, target_dir); - remove = FcTrue; - } - } - if (remove) - { - if (unlink ((char *) file_name) < 0) - { - perror ((char *) file_name); - ret = FcFalse; - } - } - FcDirCacheUnload (cache); - FcStrFree (file_name); - } - - closedir (d); - FcStrFree (dir_base); - return ret; -} - -static FcBool cleanCacheDirectories (FcConfig *config, FcBool verbose) { FcStrList *cache_dirs = FcConfigGetCacheDirs (config); @@ -419,7 +328,7 @@ cleanCacheDirectories (FcConfig *config, FcBool verbose) return FcFalse; while ((cache_dir = FcStrListNext (cache_dirs))) { - if (!cleanCacheDirectory (config, cache_dir, verbose)) + if (!FcDirCacheClean (cache_dir, verbose)) { ret = FcFalse; break; diff --git a/fontconfig/fontconfig/fontconfig.h b/fontconfig/fontconfig/fontconfig.h index 8936d8337..0e2ca509d 100644 --- a/fontconfig/fontconfig/fontconfig.h +++ b/fontconfig/fontconfig/fontconfig.h @@ -328,6 +328,9 @@ FcDirCacheUnlink (const FcChar8 *dir, FcConfig *config); FcPublic FcBool FcDirCacheValid (const FcChar8 *cache_file); +FcPublic FcBool +FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose); + /* fccfg.c */ FcPublic FcChar8 * FcConfigHome (void); diff --git a/fontconfig/src/fccache.c b/fontconfig/src/fccache.c index 0fc599583..d3842ddff 100644 --- a/fontconfig/src/fccache.c +++ b/fontconfig/src/fccache.c @@ -1021,6 +1021,97 @@ FcDirCacheWrite (FcCache *cache, FcConfig *config) return FcFalse; } +FcBool +FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose) +{ + DIR *d; + struct dirent *ent; + FcChar8 *dir_base; + FcBool ret = FcTrue; + FcBool remove; + FcCache *cache; + struct stat target_stat; + + dir_base = FcStrPlus (cache_dir, (FcChar8 *) FC_DIR_SEPARATOR_S); + if (!dir_base) + { + fprintf (stderr, "Fontconfig error: %s: out of memory\n", cache_dir); + return FcFalse; + } + if (access ((char *) cache_dir, W_OK) != 0) + { + if (verbose || FcDebug () & FC_DBG_CACHE) + printf ("%s: not cleaning %s cache directory\n", cache_dir, + access ((char *) cache_dir, F_OK) == 0 ? "unwritable" : "non-existent"); + goto bail0; + } + if (verbose || FcDebug () & FC_DBG_CACHE) + printf ("%s: cleaning cache directory\n", cache_dir); + d = opendir ((char *) cache_dir); + if (!d) + { + perror ((char *) cache_dir); + ret = FcFalse; + goto bail0; + } + while ((ent = readdir (d))) + { + FcChar8 *file_name; + const FcChar8 *target_dir; + + if (ent->d_name[0] == '.') + continue; + /* skip cache files for different architectures and */ + /* files which are not cache files at all */ + if (strlen(ent->d_name) != 32 + strlen ("-" FC_ARCHITECTURE FC_CACHE_SUFFIX) || + strcmp(ent->d_name + 32, "-" FC_ARCHITECTURE FC_CACHE_SUFFIX)) + continue; + + file_name = FcStrPlus (dir_base, (FcChar8 *) ent->d_name); + if (!file_name) + { + fprintf (stderr, "Fontconfig error: %s: allocation failure\n", cache_dir); + ret = FcFalse; + break; + } + remove = FcFalse; + cache = FcDirCacheLoadFile (file_name, NULL); + if (!cache) + { + if (verbose || FcDebug () & FC_DBG_CACHE) + printf ("%s: invalid cache file: %s\n", cache_dir, ent->d_name); + remove = FcTrue; + } + else + { + target_dir = FcCacheDir (cache); + if (stat ((char *) target_dir, &target_stat) < 0) + { + if (verbose || FcDebug () & FC_DBG_CACHE) + printf ("%s: %s: missing directory: %s \n", + cache_dir, ent->d_name, target_dir); + remove = FcTrue; + } + } + if (remove) + { + if (unlink ((char *) file_name) < 0) + { + perror ((char *) file_name); + ret = FcFalse; + } + } + FcDirCacheUnload (cache); + FcStrFree (file_name); + } + + closedir (d); + bail0: + FcStrFree (dir_base); + + return ret; +} + /* * Hokey little macro trick to permit the definitions of C functions * with the same name as CPP macros diff --git a/fontconfig/src/fcint.h b/fontconfig/src/fcint.h index 6afd6456c..1e39fecd1 100644 --- a/fontconfig/src/fcint.h +++ b/fontconfig/src/fcint.h @@ -66,8 +66,10 @@ typedef HRESULT (WINAPI *pfnSHGetFolderPathA)(HWND, int, HANDLE, DWORD, LPSTR); extern pfnGetSystemWindowsDirectory pGetSystemWindowsDirectory; extern pfnSHGetFolderPathA pSHGetFolderPathA; # define FC_SEARCH_PATH_SEPARATOR ';' +# define FC_DIR_SEPARATOR_S "\\" #else # define FC_SEARCH_PATH_SEPARATOR ':' +# define FC_DIR_SEPARATOR_S "/" #endif #define FC_DBG_MATCH 1 diff --git a/libX11/specs/libX11/AppC.xml b/libX11/specs/libX11/AppC.xml index c2e7f54fb..df250275e 100644 --- a/libX11/specs/libX11/AppC.xml +++ b/libX11/specs/libX11/AppC.xml @@ -37,9 +37,9 @@ and should use minor opcodes to distinguish the requests. <!-- .LP --> The symbols and macros used for writing stubs to Xlib are listed in <filename class="headerfile"><X11/Xlibint.h></filename>. -<!-- .SH --> -Basic Protocol Support Routines </para> +<sect1 id="Basic_Protocol_Support_Routines"> +<title>Basic Protocol Support Routines</title> <para> The basic protocol requests for extensions are <xref linkend='XQueryExtension' xrefstyle='select: title'/> @@ -202,9 +202,10 @@ The <xref linkend='XFreeExtensionList' xrefstyle='select: title'/> function frees the memory allocated by <xref linkend='XListExtensions' xrefstyle='select: title'/>. -<!-- .SH --> -Hooking into Xlib </para> +</sect1> +<sect1 id="Hooking_into_Xlib"> +<title>Hooking into Xlib</title> <para> <!-- .LP --> These functions allow you to hook into the library. @@ -350,9 +351,9 @@ function allocates the structure, bumps the extension number count, and chains the extension onto the extension list. (This permits extensions to Xlib without requiring server extensions.) -<!-- .SH --> -Hooks into the Library </para> +<sect2 id="Hooks_into_the_Library"> +<title>Hooks into the Library</title> <para> <!-- .LP --> These functions allow you to define procedures that are to be @@ -1536,9 +1537,10 @@ The data argument specifies a portion of the outgoing data buffer, and its length in bytes is specified by the len argument. Your procedure must not alter the contents of the data and must not do additional protocol requests to the same display. -<!-- .SH --> -Hooks onto Xlib Data Structures </para> +</sect2> +<sect2 id="Hooks_onto_Xlib_Data_Structures"> +<title>Hooks onto Xlib Data Structures</title> <para> <!-- .LP --> Various Xlib data structures have provisions for extension procedures @@ -1817,9 +1819,11 @@ To correctly handle automatic reuse of resource IDs, you must call <xref linkend='XAllocIDs' xrefstyle='select: title'/> when requesting multiple resource IDs. This call might generate protocol requests. -<!-- .SH --> -GC Caching </para> +</sect2> +</sect1> +<sect1 id="GC_Caching"> +<title>GC Caching</title> <para> <!-- .LP --> GCs are cached by the library to allow merging of independent change @@ -1922,12 +1926,11 @@ Specifies the GC. </listitem> </varlistentry> </variablelist> -<para> <!-- .LP --> <!-- .eM --> -<!-- .SH --> -Graphics Batching -</para> +</sect1> +<sect1 id="Graphics_Batching"> +<title>Graphics Batching</title> <para> <!-- .LP --> If you extend X to add more poly graphics primitives, you may be able to @@ -2010,9 +2013,10 @@ Note that <xref linkend='FlushGC' xrefstyle='select: title'/> is called <emphasis remap='I'>before</emphasis> picking up the value of last_req, because it may modify this field. -<!-- .SH --> -Writing Extension Stubs </para> +</sect1> +<sect1 id="Writing_Extension_Stubs"> +<title>Writing Extension Stubs</title> <para> <!-- .LP --> All X requests always contain the length of the request, @@ -2023,10 +2027,11 @@ Some servers may not support single requests of such a length. The value of dpy->max_request_size contains the maximum length as defined by the server implementation. For further information, -see ``X Window System Protocol.'' -<!-- .SH --> -Requests, Replies, and Xproto.h +see <olink targetdoc='x11protocol' targetptr='Maximum-request-length' +><citetitle>X Window System Protocol</citetitle></olink>. </para> +<sect2 id="Requests_Replies_and_Xproto.h"> +<title>Requests, Replies, and Xproto.h</title> <para> <!-- .LP --> The @@ -2068,9 +2073,10 @@ that looks similar to this: In your extension header file, this will be a minor opcode, instead of a major opcode. -<!-- .SH --> -Request Format </para> +</sect2> +<sect2 id="Request_Format"> +<title>Request Format</title> <para> <!-- .LP --> Every request contains an 8-bit major opcode and a 16-bit length field @@ -2269,9 +2275,10 @@ Instead, they use the <structname>xGenericReply</structname> structure, which contains only a type, length, and sequence number (and sufficient padding to make it 32 bytes long). -<!-- .SH --> -Starting to Write a Stub Procedure </para> +</sect2> +<sect2 id="Starting_to_Write_a_Stub_Procedure"> +<title>Starting to Write a Stub Procedure</title> <para> <!-- .LP --> An Xlib stub procedure should start like this: @@ -2299,9 +2306,10 @@ The following is an example: <programlisting> xDoSomethingReply rep; </programlisting> -<!-- .SH --> -Locking Data Structures </para> +</sect2> +<sect2 id="Locking_Data_Structures"> +<title>Locking Data Structures</title> <para> <!-- .LP --> To lock the display structure for systems that @@ -2343,12 +2351,11 @@ Specifies the connection to the X server. </listitem> </varlistentry> </variablelist> -<para> <!-- .LP --> <!-- .eM --> -<!-- .SH --> -Sending the Protocol Request and Arguments -</para> +</sect2> +<sect2 id="Sending_the_Protocol_Request_and_Arguments"> +<title>Sending the Protocol Request and Arguments</title> <para> <!-- .LP --> After the variable declarations, @@ -2462,9 +2469,10 @@ which is the same as except that it takes an additional argument (the number of extra bytes to allocate in the output buffer after the request structure). This number should always be a multiple of four. -<!-- .SH --> -Variable Length Arguments </para> +</sect2> +<sect2 id="Variable_Length_Arguments"> +<title>Variable Length Arguments</title> <para> <!-- .LP --> Some protocol requests take additional variable-length data that @@ -2544,9 +2552,10 @@ copying it into the output buffer (which would later be flushed anyway by the following call on <xref linkend='_XReply' xrefstyle='select: title'/>), it is faster. -<!-- .SH --> -Replies </para> +</sect2> +<sect2 id="Replies"> +<title>Replies</title> <para> <!-- .LP --> If the protocol request has a reply, @@ -2995,9 +3004,10 @@ reads and discards up to three additional pad bytes. Each protocol request is a little different. For further information, see the Xlib sources for examples. -<!-- .SH --> -Synchronous Calling </para> +</sect2> +<sect2 id="Synchronous_Calling"> +<title>Synchronous Calling</title> <para> <!-- .LP --> Each procedure should have a call, just before returning to the user, @@ -3008,9 +3018,10 @@ If synchronous mode is enabled (see the request is sent immediately. The library, however, waits until any error the procedure could generate at the server has been handled. -<!-- .SH --> -Allocating and Deallocating Memory </para> +</sect2> +<sect2 id="Allocating_and_Deallocating_Memory"> +<title>Allocating and Deallocating Memory</title> <para> <!-- .LP --> To support the possible reentry of these procedures, @@ -3181,9 +3192,10 @@ Specifies the size of the buffer. <!-- .eM --> You must pass back the same pointer and size that were returned by <xref linkend='_XAllocTemp' xrefstyle='select: title'/>. -<!-- .SH --> -Portability Considerations </para> +</sect2> +<sect2 id="Portability_Considerations"> +<title>Portability Considerations</title> <para> <!-- .LP --> Many machine architectures, @@ -3252,9 +3264,10 @@ The <function>PackData</function> macro is a half-hearted attempt to deal with the possibility of 32 bit shorts. However, much more work is needed to make this work properly. -<!-- .SH --> -Deriving the Correct Extension Opcode </para> +</sect2> +<sect2 id="Deriving_the_Correct_Extension_Opcode"> +<title>Deriving the Correct Extension Opcode</title> <para> <!-- .LP --> The remaining problem a writer of an extension stub procedure faces that @@ -3310,4 +3323,6 @@ structure. </para> </listitem> </itemizedlist> +</sect2> +</sect1> </appendix> diff --git a/libX11/specs/libX11/CH01.xml b/libX11/specs/libX11/CH01.xml index 8d2092420..081e80c46 100644 --- a/libX11/specs/libX11/CH01.xml +++ b/libX11/specs/libX11/CH01.xml @@ -26,7 +26,8 @@ programming language. Other higher-level abstractions (for example, those provided by the toolkits for X) are built on top of the Xlib library. For further information about these higher-level libraries, see the appropriate toolkit documentation. -The <citetitle>X Window System Protocol</citetitle> provides the +The <olink targetdoc='x11protocol' targetptr='x11protocol' +><citetitle>X Window System Protocol</citetitle></olink> provides the definitive word on the behavior of X. Although additional information appears here, the protocol document is the ruling document. diff --git a/libX11/specs/libX11/CH09.xml b/libX11/specs/libX11/CH09.xml index e239db2e9..5636df149 100644 --- a/libX11/specs/libX11/CH09.xml +++ b/libX11/specs/libX11/CH09.xml @@ -1434,7 +1434,8 @@ setup. Servers also can implement other access control policies in addition to or in place of this host access facility. For further information about other access control implementations, -see ``X Window System Protocol.'' +see <olink targetdoc='x11protocol' targetptr='Connection_Setup' +><citetitle>X Window System Protocol</citetitle></olink>. </para> <sect2 id="Adding_Getting_or_Removing_Hosts"> <title>Adding, Getting, or Removing Hosts</title> diff --git a/mesalib/Makefile b/mesalib/Makefile index 1368b44ea..0f88071aa 100644 --- a/mesalib/Makefile +++ b/mesalib/Makefile @@ -22,7 +22,7 @@ doxygen: cd doxygen && $(MAKE) check: - cd src/glsl/tests/ && ./optimization-test + make -C src/glsl/tests check make -C tests check clean: diff --git a/mesalib/configure.ac b/mesalib/configure.ac index 9d6cbeb96..1b571b95c 100644 --- a/mesalib/configure.ac +++ b/mesalib/configure.ac @@ -708,7 +708,7 @@ default_driver="xlib" case "$host_os" in linux*) case "$host_cpu" in - i*86|x86_64|powerpc*|sparc*) default_driver="dri";; + i*86|x86_64|powerpc*|sparc*|ia64*) default_driver="dri";; esac ;; *freebsd* | dragonfly* | *netbsd*) @@ -1993,6 +1993,7 @@ dnl Substitute the config AC_CONFIG_FILES([configs/autoconf src/gallium/drivers/Makefile src/gallium/drivers/r300/Makefile + src/gallium/drivers/r600/Makefile src/gbm/Makefile src/gbm/main/gbm.pc src/egl/drivers/Makefile @@ -2004,6 +2005,7 @@ AC_CONFIG_FILES([configs/autoconf src/egl/wayland/wayland-egl/Makefile src/egl/wayland/wayland-egl/wayland-egl.pc src/egl/wayland/wayland-drm/Makefile + src/glsl/tests/Makefile src/glx/Makefile src/mapi/shared-glapi/Makefile src/gtest/Makefile diff --git a/mesalib/docs/download.html b/mesalib/docs/download.html index 4e8fc2f02..6a9533aae 100644 --- a/mesalib/docs/download.html +++ b/mesalib/docs/download.html @@ -20,26 +20,12 @@ When a new release is coming, release candidates (betas) may be found </p> +<H1>Unpacking</H1> + <p> -The Mesa package is named MesaLib-x.y.z.{tar.bz2, tar.gz, zip} where x.y.z -is the version. There are three types of compressed archives. -</p> -<p> -In the past, there was also MesaGLUT-x.y.z.{tar.bz2, tar.gz, zip} packages which -contained Mark Kilgard's GLUT library. -Most Linux distributions include an implementation of GLUT (such as freeglut). -</p> -<p> -In the past, the Mesa demos collection was distributed as -MesaDemos-x.y.z.{tar.bz2, tar.gz, zip}. -Now, the -<a href="ftp://ftp.freedesktop.org/pub/mesa/demos/" target="_parent"> -Mesa demos</a> are distributed separately. +Mesa releases are available in three formats: .tar.bz2, .tar.gz, and .zip </p> - -<H1>Unpacking</H1> - <p> To unpack .tar.gz files: </p> @@ -86,10 +72,6 @@ src/glu - libGLU source code src/glx - sources for building libGL with full GLX and DRI support </pre> -If you downloaded and unpacked the MesaGLUT.x.y.z package: -<pre> -src/glut - GLUT library source code -</pre> <p> Proceed to the <a href="install.html">compilation and installation @@ -97,5 +79,24 @@ instructions</a>. </p> +<H1>Demos and GLUT</H2> + +<p> +A package of Mark Kilgard's GLUT library is available +<a href="ftp://ftp.freedesktop.org/pub/mesa/glut/" target="_parent">here</a> +</p> + +<p> +The Mesa demos collection is available +<a href="ftp://ftp.freedesktop.org/pub/mesa/demos/" target="_parent">here</a> +</p> + +<p> +In the past, GLUT and the Mesa demos were released in conjunction with +Mesa releases. But since GLUT and the demos change infrequently, they +were split off some time ago. +</p> + + </BODY> </HTML> diff --git a/mesalib/docs/install.html b/mesalib/docs/install.html index 46d0b4c7b..2ba7cb867 100644 --- a/mesalib/docs/install.html +++ b/mesalib/docs/install.html @@ -10,30 +10,24 @@ <H1>Compiling and Installing</H1> <ol> -<li><a href="#unix-x11">Unix / X11</a> +<li><a href="#prereq-general">Prerequisites for building</a> <ul> - <li><a href="#prereq-general">General prerequisites for building</a> - <li><a href="#prereq-dri">Prerequisites for DRI and hardware acceleration</a> - <li><a href="#autoconf">Building with autoconf</a> - <li><a href="#traditional">Building with traditional Makefiles</a> - <li><a href="#libs">The Libraries</a> - <li><a href="#install">Installing the header and library files - <li><a href="#pkg-config">Building OpenGL programs with pkg-config + <li><a href="#prereq-general">General prerequisites</a> + <li><a href="#prereq-dri">For DRI and hardware acceleration</a> </ul> -<li><a href="#windows">Windows</a> -<li><a href="#scons">Building with SCons</a> -<li><a href="#other">Other</a> +<li><a href="#autoconf">Building with autoconf (Linux/Unix/X11)</a> +<li><a href="#scons">Building with SCons (Windows)</a> +<li><a href="#legacy">Building with legacy Makefiles (deprecated)</a> +<li><a href="#other">Building for other systems</a> +<li><a href="#libs">Library Information</a> +<li><a href="#pkg-config">Building OpenGL programs with pkg-config </ol> -<br> - - -<a name="unix-x11"> -<H2>1. Unix/X11 Compilation and Installation</H1> <a name="prereq-general"> -<h3>1.1 General prerequisites for building</h3> +<h1>1. Prerequisites for building</h1> +<h2>1.1 General</h2> <ul> <li>lex / yacc - for building the GLSL compiler. On Linux systems, flex and bison are used. @@ -54,18 +48,19 @@ To build OpenGL ES 1.1 and 2.0 you'll also need <a name="prereq-dri"> -<h3>1.2 Prerequisites for DRI and hardware acceleration</h3> +<h3>1.2 For DRI and hardware acceleration</h3> <p> The following are required for DRI-based hardware acceleration with Mesa: </p> <ul> -<li><a href="http://xorg.freedesktop.org/releases/individual/proto/">dri2proto</a> version 1.99.3 or later -<li>Linux 2.6.28 +<li><a href="http://xorg.freedesktop.org/releases/individual/proto/" +target="_parent">dri2proto</a> version 2.6 or later <li><a href="http://dri.freedesktop.org/libdrm/" target="_parent">libDRM</a> -version 2.4.15 or later +version 2.4.33 or later <li>Xorg server version 1.5 or later +<li>Linux 2.6.28 or later </ul> </p> <p> @@ -78,22 +73,69 @@ the needed dependencies: </pre> + <a name="autoconf"> -<h3>1.3 Building with Autoconf</h3> +<H1>2. Building with autoconf (Linux/Unix/X11)</H1> + +<p> +The primary method to build Mesa on Unix systems is with autoconf. +</p> <p> -Mesa may be <a href="autoconf.html">built using autoconf</a>. -This should work well on most GNU-based systems. -If that fails the traditional Mesa build system is available. +The general approach is the standard: +<pre> + ./configure + make + sudo make install +</pre> +But please read the <a href="autoconf.html">detailed autoconf instructions</a> +for more details. +</p> -<a name="traditional"> -<h3>1.4 Building with traditional Makefiles</h3> +<a name="scons"> +<H1>3. Building with SCons (Windows)</H1> <p> -The traditional Mesa build system is based on a collection of pre-defined +To build Mesa with SCons on Linux or Windows do +</p> +<pre> + scons +</pre> +<p> +The build output will be placed in +build/<i>platform</i>-<i>machine</i>-<i>debug</i>/..., where <i>platform</i> is for +example linux or windows, <i>machine</i> is x86 or x86_64, optionally followed +by -debug for debug builds. +</p> + +<p> +To build Mesa with SCons for Windows on Linux using the MinGW crosscompiler toolchain do +</p> +<pre> + scons platform=windows toolchain=crossmingw machine=x86 mesagdi libgl-gdi +</pre> +<p> +This will create: +</p> +<ul> +<li>build/windows-x86-debug/mesa/drivers/windows/gdi/opengl32.dll — Mesa + swrast, binary compatible with Windows's opengl32.dll +<li>build/windows-x86-debug/gallium/targets/libgl-gdi/opengl32.dll — Mesa + Gallium + softpipe, binary compatible with Windows's opengl32.dll +</ul> +<p> +Put them all in the same directory to test them. +</p> + + + +<a name="legacy"> +<h1>4. Building with legacy Makefiles (deprecated)</h1> + +<p> +The legacy Mesa build system is based on a collection of pre-defined system configurations. +Some of these might work for older systems not supported by autoconf. </p> <p> To see the list of configurations, just type <code>make</code>. @@ -144,8 +186,6 @@ Make sure you have the prerequisite versions of DRM and Xserver mentioned above. </p> -</li> - </ul> @@ -155,58 +195,9 @@ Later, if you want to rebuild for a different configuration run </p> -<a name="libs"> -<h3>1.5 The libraries</h3> - -<p> -When compilation has finished, look in the top-level <code>lib/</code> -(or <code>lib64/</code>) directory. -You'll see a set of library files similar to this: -</p> -<pre> -lrwxrwxrwx 1 brian users 10 Mar 26 07:53 libGL.so -> libGL.so.1* -lrwxrwxrwx 1 brian users 19 Mar 26 07:53 libGL.so.1 -> libGL.so.1.5.060100* --rwxr-xr-x 1 brian users 3375861 Mar 26 07:53 libGL.so.1.5.060100* -lrwxrwxrwx 1 brian users 11 Mar 26 07:53 libGLU.so -> libGLU.so.1* -lrwxrwxrwx 1 brian users 20 Mar 26 07:53 libGLU.so.1 -> libGLU.so.1.3.060100* --rwxr-xr-x 1 brian users 549269 Mar 26 07:53 libGLU.so.1.3.060100* -lrwxrwxrwx 1 brian users 12 Mar 26 07:53 libglut.so -> libglut.so.3* -lrwxrwxrwx 1 brian users 16 Mar 26 07:53 libglut.so.3 -> libglut.so.3.7.1* --rwxr-xr-x 1 brian users 597754 Mar 26 07:53 libglut.so.3.7.1* -lrwxrwxrwx 1 brian users 14 Mar 26 07:53 libOSMesa.so -> libOSMesa.so.6* -lrwxrwxrwx 1 brian users 23 Mar 26 07:53 libOSMesa.so.6 -> libOSMesa.so.6.1.060100* --rwxr-xr-x 1 brian users 23871 Mar 26 07:53 libOSMesa.so.6.1.060100* -</pre> - -<p> -<b>libGL</b> is the main OpenGL library (i.e. Mesa). -<br> -<b>libGLU</b> is the OpenGL Utility library. -<br> -<b>libglut</b> is the GLUT library. -<br> -<b>libOSMesa</b> is the OSMesa (Off-Screen) interface library. -</p> - -<p> -If you built the DRI hardware drivers, you'll also see the DRI drivers: -</p> -<pre> --rwxr-xr-x 1 brian users 16895413 Jul 21 12:11 i915_dri.so --rwxr-xr-x 1 brian users 11849858 Jul 21 12:12 r200_dri.so --rwxr-xr-x 1 brian users 16050488 Jul 21 12:11 r300_dri.so --rwxr-xr-x 1 brian users 11757388 Jul 21 12:12 radeon_dri.so -</pre> - -<p> -If you built with Gallium support, look in lib/gallium/ for Gallium-based -versions of libGL and device drivers. -</p> - - <a name="install"> -<H3>1.6 Installing the header and library files</H3> +<H2>Installing the header and library files</H2> <p> The standard location for the OpenGL header files on Unix-type systems is @@ -246,85 +237,89 @@ This is a handy way to compare multiple OpenGL implementations. </p> -<a name="pkg-config"> -<H3>1.7 Building OpenGL programs with pkg-config</H3> -<p> -Running <code>make install</code> will install package configuration files -for the pkg-config utility. -</p> -<p> -When compiling your OpenGL application you can use pkg-config to determine -the proper compiler and linker flags. -</p> +<a name="other"> +<H1>5. Building for other systems</H1> <p> -For example, compiling and linking a GLUT application can be done with: +Documentation for other environments (some may be very out of date): </p> -<pre> - gcc `pkg-config --cflags --libs glut` mydemo.c -o mydemo -</pre> - -<br> - -<a name="windows"> -<H2>2. Windows Compilation and Installation</H1> -<p> -Please see the <a href="#scons">instructions on building with SCons</a>. -</p> +<UL> +<li><A HREF="README.VMS">README.VMS</A> - VMS +<LI><A HREF="README.CYGWIN">README.CYGWIN</A> - Cygwin +<LI><A HREF="README.WIN32">README.WIN32</A> - Win32 +</UL> -<a name="scons"> -<H2>3. Building with SCons</H1> +<a name="libs"> +<H1>6. Library Information</H1> <p> -To build Mesa with SCons on Linux or Windows do +When compilation has finished, look in the top-level <code>lib/</code> +(or <code>lib64/</code>) directory. +You'll see a set of library files similar to this: </p> <pre> - scons +lrwxrwxrwx 1 brian users 10 Mar 26 07:53 libGL.so -> libGL.so.1* +lrwxrwxrwx 1 brian users 19 Mar 26 07:53 libGL.so.1 -> libGL.so.1.5.060100* +-rwxr-xr-x 1 brian users 3375861 Mar 26 07:53 libGL.so.1.5.060100* +lrwxrwxrwx 1 brian users 11 Mar 26 07:53 libGLU.so -> libGLU.so.1* +lrwxrwxrwx 1 brian users 20 Mar 26 07:53 libGLU.so.1 -> libGLU.so.1.3.060100* +-rwxr-xr-x 1 brian users 549269 Mar 26 07:53 libGLU.so.1.3.060100* +lrwxrwxrwx 1 brian users 14 Mar 26 07:53 libOSMesa.so -> libOSMesa.so.6* +lrwxrwxrwx 1 brian users 23 Mar 26 07:53 libOSMesa.so.6 -> libOSMesa.so.6.1.060100* +-rwxr-xr-x 1 brian users 23871 Mar 26 07:53 libOSMesa.so.6.1.060100* </pre> + <p> -The build output will be placed in -build/<i>platform</i>-<i>machine</i>-<i>debug</i>/..., where <i>platform</i> is for -example linux or windows, <i>machine</i> is x86 or x86_64, optionally followed -by -debug for debug builds. +<b>libGL</b> is the main OpenGL library (i.e. Mesa). +<br> +<b>libGLU</b> is the OpenGL Utility library. +<br> +<b>libOSMesa</b> is the OSMesa (Off-Screen) interface library. </p> <p> -To build Mesa with SCons for Windows on Linux using the MinGW crosscompiler toolchain do +If you built the DRI hardware drivers, you'll also see the DRI drivers: </p> <pre> - scons platform=windows toolchain=crossmingw machine=x86 mesagdi libgl-gdi +-rwxr-xr-x 1 brian users 16895413 Jul 21 12:11 i915_dri.so +-rwxr-xr-x 1 brian users 16895413 Jul 21 12:11 i965_dri.so +-rwxr-xr-x 1 brian users 11849858 Jul 21 12:12 r200_dri.so +-rwxr-xr-x 1 brian users 16050488 Jul 21 12:11 r300_dri.so +-rwxr-xr-x 1 brian users 11757388 Jul 21 12:12 radeon_dri.so </pre> + <p> -This will create: -</p> -<ul> -<li>build/windows-x86-debug/mesa/drivers/windows/gdi/opengl32.dll — Mesa + swrast, binary compatible with Windows's opengl32.dll -<li>build/windows-x86-debug/gallium/targets/libgl-gdi/opengl32.dll — Mesa + Gallium + softpipe, binary compatible with Windows's opengl32.dll -</ul> -<p> -Put them all in the same directory to test them. +If you built with Gallium support, look in lib/gallium/ for Gallium-based +versions of libGL and device drivers. </p> -<a name="other"> -<H2>4. Other systems</H1> +<a name="pkg-config"> +<H1>7. Building OpenGL programs with pkg-config</H1> <p> -Documentation for other environments (some may be very out of date): +Running <code>make install</code> will install package configuration files +for the pkg-config utility. </p> -<UL> -<li><A HREF="README.VMS">README.VMS</A> - VMS -<LI><A HREF="README.CYGWIN">README.CYGWIN</A> - Cygwin -<LI><A HREF="README.WIN32">README.WIN32</A> - Win32 -</UL> +<p> +When compiling your OpenGL application you can use pkg-config to determine +the proper compiler and linker flags. +</p> +<p> +For example, compiling and linking a GLUT application can be done with: +</p> +<pre> + gcc `pkg-config --cflags --libs glut` mydemo.c -o mydemo +</pre> +<br> </body> diff --git a/mesalib/src/gallium/auxiliary/util/u_blit.c b/mesalib/src/gallium/auxiliary/util/u_blit.c index 127973388..e5b97f720 100644 --- a/mesalib/src/gallium/auxiliary/util/u_blit.c +++ b/mesalib/src/gallium/auxiliary/util/u_blit.c @@ -232,8 +232,10 @@ get_next_slot( struct blit_state *ctx ) { const unsigned max_slots = 4096 / sizeof ctx->vertices; - if (ctx->vbuf_slot >= max_slots) - util_blit_flush( ctx ); + if (ctx->vbuf_slot >= max_slots) { + pipe_resource_reference(&ctx->vbuf, NULL); + ctx->vbuf_slot = 0; + } if (!ctx->vbuf) { ctx->vbuf = pipe_buffer_create(ctx->pipe->screen, @@ -674,17 +676,6 @@ util_blit_pixels(struct blit_state *ctx, } -/* Release vertex buffer at end of frame to avoid synchronous - * rendering. - */ -void util_blit_flush( struct blit_state *ctx ) -{ - pipe_resource_reference(&ctx->vbuf, NULL); - ctx->vbuf_slot = 0; -} - - - /** * Copy pixel block from src texture to dst surface. * The sampler view's first_level field indicates the source diff --git a/mesalib/src/gallium/auxiliary/util/u_blit.h b/mesalib/src/gallium/auxiliary/util/u_blit.h index 23a427d34..810d01b04 100644 --- a/mesalib/src/gallium/auxiliary/util/u_blit.h +++ b/mesalib/src/gallium/auxiliary/util/u_blit.h @@ -1,98 +1,93 @@ -/**************************************************************************
- *
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * 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, sub license, 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 NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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.
- *
- **************************************************************************/
-
-
-#ifndef U_BLIT_H
-#define U_BLIT_H
-
-
-#include "pipe/p_compiler.h"
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-struct cso_context;
-struct pipe_context;
-struct pipe_resource;
-struct pipe_sampler_view;
-struct pipe_surface;
-
-
-extern struct blit_state *
-util_create_blit(struct pipe_context *pipe, struct cso_context *cso);
-
-extern void
-util_destroy_blit(struct blit_state *ctx);
-
-extern void
-util_blit_pixels(struct blit_state *ctx,
- struct pipe_resource *src_tex,
- unsigned src_level,
- int srcX0, int srcY0,
- int srcX1, int srcY1,
- int srcZ0,
- struct pipe_surface *dst,
- int dstX0, int dstY0,
- int dstX1, int dstY1,
- float z, uint filter);
-
-void
-util_blit_pixels_writemask(struct blit_state *ctx,
- struct pipe_resource *src_tex,
- unsigned src_level,
- int srcX0, int srcY0,
- int srcX1, int srcY1,
- int srcZ0,
- struct pipe_surface *dst,
- int dstX0, int dstY0,
- int dstX1, int dstY1,
- float z, uint filter,
- uint writemask);
-
-extern void
-util_blit_pixels_tex(struct blit_state *ctx,
- struct pipe_sampler_view *src_sampler_view,
- int srcX0, int srcY0,
- int srcX1, int srcY1,
- struct pipe_surface *dst,
- int dstX0, int dstY0,
- int dstX1, int dstY1,
- float z, uint filter);
-
-/* Call at end of frame to avoid synchronous rendering.
- */
-extern void
-util_blit_flush( struct blit_state *ctx );
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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. + * + **************************************************************************/ + + +#ifndef U_BLIT_H +#define U_BLIT_H + + +#include "pipe/p_compiler.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +struct cso_context; +struct pipe_context; +struct pipe_resource; +struct pipe_sampler_view; +struct pipe_surface; + + +extern struct blit_state * +util_create_blit(struct pipe_context *pipe, struct cso_context *cso); + +extern void +util_destroy_blit(struct blit_state *ctx); + +extern void +util_blit_pixels(struct blit_state *ctx, + struct pipe_resource *src_tex, + unsigned src_level, + int srcX0, int srcY0, + int srcX1, int srcY1, + int srcZ0, + struct pipe_surface *dst, + int dstX0, int dstY0, + int dstX1, int dstY1, + float z, uint filter); + +void +util_blit_pixels_writemask(struct blit_state *ctx, + struct pipe_resource *src_tex, + unsigned src_level, + int srcX0, int srcY0, + int srcX1, int srcY1, + int srcZ0, + struct pipe_surface *dst, + int dstX0, int dstY0, + int dstX1, int dstY1, + float z, uint filter, + uint writemask); + +extern void +util_blit_pixels_tex(struct blit_state *ctx, + struct pipe_sampler_view *src_sampler_view, + int srcX0, int srcY0, + int srcX1, int srcY1, + struct pipe_surface *dst, + int dstX0, int dstY0, + int dstX1, int dstY1, + float z, uint filter); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mesalib/src/gallium/auxiliary/util/u_gen_mipmap.c b/mesalib/src/gallium/auxiliary/util/u_gen_mipmap.c index a28d41825..82474cd7b 100644 --- a/mesalib/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/mesalib/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -1361,8 +1361,10 @@ get_next_slot(struct gen_mipmap_state *ctx) { const unsigned max_slots = 4096 / sizeof ctx->vertices; - if (ctx->vbuf_slot >= max_slots) - util_gen_mipmap_flush( ctx ); + if (ctx->vbuf_slot >= max_slots) { + pipe_resource_reference(&ctx->vbuf, NULL); + ctx->vbuf_slot = 0; + } if (!ctx->vbuf) { ctx->vbuf = pipe_buffer_create(ctx->pipe->screen, @@ -1475,17 +1477,6 @@ util_destroy_gen_mipmap(struct gen_mipmap_state *ctx) } - -/* Release vertex buffer at end of frame to avoid synchronous - * rendering. - */ -void util_gen_mipmap_flush( struct gen_mipmap_state *ctx ) -{ - pipe_resource_reference(&ctx->vbuf, NULL); - ctx->vbuf_slot = 0; -} - - /** * Generate mipmap images. It's assumed all needed texture memory is * already allocated. diff --git a/mesalib/src/gallium/auxiliary/util/u_gen_mipmap.h b/mesalib/src/gallium/auxiliary/util/u_gen_mipmap.h index e4670a43c..1bcc50f51 100644 --- a/mesalib/src/gallium/auxiliary/util/u_gen_mipmap.h +++ b/mesalib/src/gallium/auxiliary/util/u_gen_mipmap.h @@ -1,70 +1,64 @@ -/**************************************************************************
- *
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * 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, sub license, 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 NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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.
- *
- **************************************************************************/
-
-#ifndef U_GENMIPMAP_H
-#define U_GENMIPMAP_H
-
-#include "pipe/p_state.h"
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-struct pipe_context;
-struct pipe_resource;
-struct cso_context;
-
-struct gen_mipmap_state;
-
-
-extern struct gen_mipmap_state *
-util_create_gen_mipmap(struct pipe_context *pipe, struct cso_context *cso);
-
-
-extern void
-util_destroy_gen_mipmap(struct gen_mipmap_state *ctx);
-
-/* Release vertex buffer at end of frame to avoid synchronous
- * rendering.
- */
-extern void
-util_gen_mipmap_flush( struct gen_mipmap_state *ctx );
-
-
-extern void
-util_gen_mipmap(struct gen_mipmap_state *ctx,
- struct pipe_sampler_view *psv,
- uint layer, uint baseLevel, uint lastLevel, uint filter);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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. + * + **************************************************************************/ + +#ifndef U_GENMIPMAP_H +#define U_GENMIPMAP_H + +#include "pipe/p_state.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +struct pipe_context; +struct pipe_resource; +struct cso_context; + +struct gen_mipmap_state; + + +extern struct gen_mipmap_state * +util_create_gen_mipmap(struct pipe_context *pipe, struct cso_context *cso); + + +extern void +util_destroy_gen_mipmap(struct gen_mipmap_state *ctx); + + +extern void +util_gen_mipmap(struct gen_mipmap_state *ctx, + struct pipe_sampler_view *psv, + uint layer, uint baseLevel, uint lastLevel, uint filter); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mesalib/src/gallium/auxiliary/util/u_inlines.h b/mesalib/src/gallium/auxiliary/util/u_inlines.h index 23658bc88..49b4531db 100644 --- a/mesalib/src/gallium/auxiliary/util/u_inlines.h +++ b/mesalib/src/gallium/auxiliary/util/u_inlines.h @@ -370,7 +370,7 @@ pipe_buffer_write_nooverlap(struct pipe_context *pipe, buf, 0, (PIPE_TRANSFER_WRITE | - PIPE_TRANSFER_NOOVERWRITE), + PIPE_TRANSFER_UNSYNCHRONIZED), &box, data, 0, 0); diff --git a/mesalib/src/glsl/ast_function.cpp b/mesalib/src/glsl/ast_function.cpp index 39401017b..8bf0ba2a8 100644 --- a/mesalib/src/glsl/ast_function.cpp +++ b/mesalib/src/glsl/ast_function.cpp @@ -152,19 +152,22 @@ verify_parameter_modes(_mesa_glsl_parse_state *state, return false; } - if (actual->variable_referenced() - && actual->variable_referenced()->read_only) { - _mesa_glsl_error(&loc, state, - "function parameter '%s %s' references the " - "read-only variable '%s'", - mode, formal->name, - actual->variable_referenced()->name); - return false; - } else if (!actual->is_lvalue()) { - _mesa_glsl_error(&loc, state, - "function parameter '%s %s' is not an lvalue", - mode, formal->name); - return false; + ir_variable *var = actual->variable_referenced(); + if (var) { + if (var->read_only) { + _mesa_glsl_error(&loc, state, + "function parameter '%s %s' references the " + "read-only variable '%s'", + mode, formal->name, + actual->variable_referenced()->name); + return false; + } else if (!actual->is_lvalue()) { + _mesa_glsl_error(&loc, state, + "function parameter '%s %s' is not an lvalue", + mode, formal->name); + return false; + } + var->assigned = true; } } diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp index 820c86c5e..e24914b83 100644 --- a/mesalib/src/glsl/ast_to_hir.cpp +++ b/mesalib/src/glsl/ast_to_hir.cpp @@ -57,6 +57,10 @@ #include "program/hash_table.h" #include "ir.h" +static void +detect_conflicting_assignments(struct _mesa_glsl_parse_state *state, + exec_list *instructions); + void _mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) { @@ -87,6 +91,7 @@ _mesa_ast_to_hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) ast->hir(instructions, state); detect_recursion_unlinked(state, instructions); + detect_conflicting_assignments(state, instructions); state->toplevel_ir = NULL; } @@ -672,6 +677,10 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state, void *ctx = state; bool error_emitted = (lhs->type->is_error() || rhs->type->is_error()); + ir_variable *lhs_var = lhs->variable_referenced(); + if (lhs_var) + lhs_var->assigned = true; + if (!error_emitted) { if (non_lvalue_description != NULL) { _mesa_glsl_error(&lhs_loc, state, @@ -4013,3 +4022,64 @@ ast_struct_specifier::hir(exec_list *instructions, */ return NULL; } + +static void +detect_conflicting_assignments(struct _mesa_glsl_parse_state *state, + exec_list *instructions) +{ + bool gl_FragColor_assigned = false; + bool gl_FragData_assigned = false; + bool user_defined_fs_output_assigned = false; + ir_variable *user_defined_fs_output = NULL; + + /* It would be nice to have proper location information. */ + YYLTYPE loc; + memset(&loc, 0, sizeof(loc)); + + foreach_list(node, instructions) { + ir_variable *var = ((ir_instruction *)node)->as_variable(); + + if (!var) + continue; + + if (strcmp(var->name, "gl_FragColor") == 0) + gl_FragColor_assigned = var->assigned; + else if (strcmp(var->name, "gl_FragData") == 0) + gl_FragData_assigned = var->assigned; + else if (strncmp(var->name, "gl_", 3) != 0) { + if (state->target == fragment_shader && + (var->mode == ir_var_out || var->mode == ir_var_inout)) { + user_defined_fs_output_assigned = true; + user_defined_fs_output = var; + } + } + } + + /* From the GLSL 1.30 spec: + * + * "If a shader statically assigns a value to gl_FragColor, it + * may not assign a value to any element of gl_FragData. If a + * shader statically writes a value to any element of + * gl_FragData, it may not assign a value to + * gl_FragColor. That is, a shader may assign values to either + * gl_FragColor or gl_FragData, but not both. Multiple shaders + * linked together must also consistently write just one of + * these variables. Similarly, if user declared output + * variables are in use (statically assigned to), then the + * built-in variables gl_FragColor and gl_FragData may not be + * assigned to. These incorrect usages all generate compile + * time errors." + */ + if (gl_FragColor_assigned && gl_FragData_assigned) { + _mesa_glsl_error(&loc, state, "fragment shader writes to both " + "`gl_FragColor' and `gl_FragData'\n"); + } else if (gl_FragColor_assigned && user_defined_fs_output_assigned) { + _mesa_glsl_error(&loc, state, "fragment shader writes to both " + "`gl_FragColor' and `%s'\n", + user_defined_fs_output->name); + } else if (gl_FragData_assigned && user_defined_fs_output_assigned) { + _mesa_glsl_error(&loc, state, "fragment shader writes to both " + "`gl_FragData' and `%s'\n", + user_defined_fs_output->name); + } +} diff --git a/mesalib/src/glsl/ir.h b/mesalib/src/glsl/ir.h index d6c6a607a..ddfaf3614 100644 --- a/mesalib/src/glsl/ir.h +++ b/mesalib/src/glsl/ir.h @@ -353,10 +353,23 @@ public: * Several GLSL semantic checks require knowledge of whether or not a * variable has been used. For example, it is an error to redeclare a * variable as invariant after it has been used. + * + * This is only maintained in the ast_to_hir.cpp path, not in + * Mesa's fixed function or ARB program paths. */ unsigned used:1; /** + * Has this variable been statically assigned? + * + * This answers whether the variable was assigned in any path of + * the shader during ast_to_hir. This doesn't answer whether it is + * still written after dead code removal, nor is it maintained in + * non-ast_to_hir.cpp (GLSL parsing) paths. + */ + unsigned assigned:1; + + /** * Storage class of the variable. * * \sa ir_variable_mode diff --git a/mesalib/src/glsl/main.cpp b/mesalib/src/glsl/main.cpp index f04a146e8..8c651b8c0 100644 --- a/mesalib/src/glsl/main.cpp +++ b/mesalib/src/glsl/main.cpp @@ -249,7 +249,7 @@ main(int argc, char **argv) usage_fail(argv[0]); const char *const ext = & argv[optind][len - 5]; - if (strncmp(".vert", ext, 5) == 0) + if (strncmp(".vert", ext, 5) == 0 || strncmp(".glsl", ext, 5) == 0) shader->Type = GL_VERTEX_SHADER; else if (strncmp(".geom", ext, 5) == 0) shader->Type = GL_GEOMETRY_SHADER; diff --git a/mesalib/src/glsl/opt_array_splitting.cpp b/mesalib/src/glsl/opt_array_splitting.cpp index f11b51631..67733ca6b 100644 --- a/mesalib/src/glsl/opt_array_splitting.cpp +++ b/mesalib/src/glsl/opt_array_splitting.cpp @@ -49,7 +49,7 @@ public: variable_entry(ir_variable *var) { this->var = var; - this->whole_array_access = 0; + this->split = true; this->declaration = false; this->components = NULL; this->mem_ctx = NULL; @@ -62,10 +62,14 @@ public: ir_variable *var; /* The key: the variable's pointer. */ unsigned size; /* array length or matrix columns */ - /** Number of times the variable is referenced, including assignments. */ - unsigned whole_array_access; + /** Whether this array should be split or not. */ + bool split; - bool declaration; /* If the variable had a decl in the instruction stream */ + /* If the variable had a decl we can work with in the instruction + * stream. We can't do splitting on function arguments, which + * don't get this variable set. + */ + bool declaration; ir_variable **components; @@ -99,6 +103,7 @@ public: virtual ir_visitor_status visit(ir_variable *); virtual ir_visitor_status visit(ir_dereference_variable *); virtual ir_visitor_status visit_enter(ir_dereference_array *); + virtual ir_visitor_status visit_enter(ir_function_signature *); variable_entry *get_variable_entry(ir_variable *var); @@ -154,12 +159,13 @@ ir_array_reference_visitor::visit(ir_dereference_variable *ir) { variable_entry *entry = this->get_variable_entry(ir->var); - /* If we made it to here, then the dereference of this array didn't - * have a constant index (see the visit_continue_with_parent - * below), so we can't split the variable. + /* If we made it to here without seeing an ir_dereference_array, + * then the dereference of this array didn't have a constant index + * (see the visit_continue_with_parent below), so we can't split + * the variable. */ if (entry) - entry->whole_array_access++; + entry->split = false; return visit_continue; } @@ -173,12 +179,26 @@ ir_array_reference_visitor::visit_enter(ir_dereference_array *ir) variable_entry *entry = this->get_variable_entry(deref->var); + /* If the access to the array has a variable index, we wouldn't + * know which split variable this dereference should go to. + */ if (entry && !ir->array_index->as_constant()) - entry->whole_array_access++; + entry->split = false; return visit_continue_with_parent; } +ir_visitor_status +ir_array_reference_visitor::visit_enter(ir_function_signature *ir) +{ + /* We don't have logic for array-splitting function arguments, + * so just look at the body instructions and not the parameter + * declarations. + */ + visit_list_elements(this, &ir->body); + return visit_continue_with_parent; +} + bool ir_array_reference_visitor::get_split_list(exec_list *instructions, bool linked) @@ -204,12 +224,12 @@ ir_array_reference_visitor::get_split_list(exec_list *instructions, variable_entry *entry = (variable_entry *)iter.get(); if (debug) { - printf("array %s@%p: decl %d, whole_access %d\n", + printf("array %s@%p: decl %d, split %d\n", entry->var->name, (void *) entry->var, entry->declaration, - entry->whole_array_access); + entry->split); } - if (!entry->declaration || entry->whole_array_access) { + if (!(entry->declaration && entry->split)) { entry->remove(); } } @@ -217,7 +237,10 @@ ir_array_reference_visitor::get_split_list(exec_list *instructions, return !variable_list.is_empty(); } -/** This is the class that does the actual work of splitting. */ +/** + * This class rewrites the dereferences of arrays that have been split + * to use the newly created ir_variables for each component. + */ class ir_array_splitting_visitor : public ir_rvalue_visitor { public: ir_array_splitting_visitor(exec_list *vars) @@ -236,7 +259,6 @@ public: variable_entry *get_splitting_entry(ir_variable *var); exec_list *variable_list; - void *mem_ctx; }; variable_entry * @@ -348,8 +370,7 @@ optimize_split_arrays(exec_list *instructions, bool linked) const struct glsl_type *subtype; if (type->is_matrix()) - subtype = glsl_type::get_instance(GLSL_TYPE_FLOAT, - type->vector_elements, 1); + subtype = type->column_type(); else subtype = type->fields.array; diff --git a/mesalib/src/glsl/opt_structure_splitting.cpp b/mesalib/src/glsl/opt_structure_splitting.cpp index d08a5cee1..6dd228e4e 100644 --- a/mesalib/src/glsl/opt_structure_splitting.cpp +++ b/mesalib/src/glsl/opt_structure_splitting.cpp @@ -1,367 +1,372 @@ -/*
- * Copyright © 2010 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.
- */
-
-/**
- * \file opt_structure_splitting.cpp
- *
- * If a structure is only ever referenced by its components, then
- * split those components out to individual variables so they can be
- * handled normally by other optimization passes.
- *
- * This skips structures like uniforms, which need to be accessible as
- * structures for their access by the GL.
- */
-
-#include "ir.h"
-#include "ir_visitor.h"
-#include "ir_print_visitor.h"
-#include "ir_rvalue_visitor.h"
-#include "glsl_types.h"
-
-static bool debug = false;
-
-// XXX using variable_entry2 here to avoid collision (MSVC multiply-defined
-// function) with the variable_entry class seen in ir_variable_refcount.h
-// Perhaps we can use the one in ir_variable_refcount.h and make this class
-// here go away?
-class variable_entry2 : public exec_node
-{
-public:
- variable_entry2(ir_variable *var)
- {
- this->var = var;
- this->whole_structure_access = 0;
- this->declaration = false;
- this->components = NULL;
- this->mem_ctx = NULL;
- }
-
- ir_variable *var; /* The key: the variable's pointer. */
-
- /** Number of times the variable is referenced, including assignments. */
- unsigned whole_structure_access;
-
- bool declaration; /* If the variable had a decl in the instruction stream */
-
- ir_variable **components;
-
- /** ralloc_parent(this->var) -- the shader's ralloc context. */
- void *mem_ctx;
-};
-
-
-class ir_structure_reference_visitor : public ir_hierarchical_visitor {
-public:
- ir_structure_reference_visitor(void)
- {
- this->mem_ctx = ralloc_context(NULL);
- this->variable_list.make_empty();
- }
-
- ~ir_structure_reference_visitor(void)
- {
- ralloc_free(mem_ctx);
- }
-
- virtual ir_visitor_status visit(ir_variable *);
- virtual ir_visitor_status visit(ir_dereference_variable *);
- virtual ir_visitor_status visit_enter(ir_dereference_record *);
- virtual ir_visitor_status visit_enter(ir_assignment *);
- virtual ir_visitor_status visit_enter(ir_function_signature *);
-
- variable_entry2 *get_variable_entry2(ir_variable *var);
-
- /* List of variable_entry */
- exec_list variable_list;
-
- void *mem_ctx;
-};
-
-variable_entry2 *
-ir_structure_reference_visitor::get_variable_entry2(ir_variable *var)
-{
- assert(var);
-
- if (!var->type->is_record() || var->mode == ir_var_uniform)
- return NULL;
-
- foreach_iter(exec_list_iterator, iter, this->variable_list) {
- variable_entry2 *entry = (variable_entry2 *)iter.get();
- if (entry->var == var)
- return entry;
- }
-
- variable_entry2 *entry = new(mem_ctx) variable_entry2(var);
- this->variable_list.push_tail(entry);
- return entry;
-}
-
-
-ir_visitor_status
-ir_structure_reference_visitor::visit(ir_variable *ir)
-{
- variable_entry2 *entry = this->get_variable_entry2(ir);
-
- if (entry)
- entry->declaration = true;
-
- return visit_continue;
-}
-
-ir_visitor_status
-ir_structure_reference_visitor::visit(ir_dereference_variable *ir)
-{
- ir_variable *const var = ir->variable_referenced();
- variable_entry2 *entry = this->get_variable_entry2(var);
-
- if (entry)
- entry->whole_structure_access++;
-
- return visit_continue;
-}
-
-ir_visitor_status
-ir_structure_reference_visitor::visit_enter(ir_dereference_record *ir)
-{
- (void) ir;
- /* Don't descend into the ir_dereference_variable below. */
- return visit_continue_with_parent;
-}
-
-ir_visitor_status
-ir_structure_reference_visitor::visit_enter(ir_assignment *ir)
-{
- /* If there are no structure references yet, no need to bother with
- * processing the expression tree.
- */
- if (this->variable_list.is_empty())
- return visit_continue_with_parent;
-
- if (ir->lhs->as_dereference_variable() &&
- ir->rhs->as_dereference_variable() &&
- !ir->condition) {
- /* We'll split copies of a structure to copies of components, so don't
- * descend to the ir_dereference_variables.
- */
- return visit_continue_with_parent;
- }
- return visit_continue;
-}
-
-ir_visitor_status
-ir_structure_reference_visitor::visit_enter(ir_function_signature *ir)
-{
- /* We don't want to descend into the function parameters and
- * dead-code eliminate them, so just accept the body here.
- */
- visit_list_elements(this, &ir->body);
- return visit_continue_with_parent;
-}
-
-class ir_structure_splitting_visitor : public ir_rvalue_visitor {
-public:
- ir_structure_splitting_visitor(exec_list *vars)
- {
- this->variable_list = vars;
- }
-
- virtual ~ir_structure_splitting_visitor()
- {
- }
-
- virtual ir_visitor_status visit_leave(ir_assignment *);
-
- void split_deref(ir_dereference **deref);
- void handle_rvalue(ir_rvalue **rvalue);
- variable_entry2 *get_splitting_entry(ir_variable *var);
-
- exec_list *variable_list;
- void *mem_ctx;
-};
-
-variable_entry2 *
-ir_structure_splitting_visitor::get_splitting_entry(ir_variable *var)
-{
- assert(var);
-
- if (!var->type->is_record())
- return NULL;
-
- foreach_iter(exec_list_iterator, iter, *this->variable_list) {
- variable_entry2 *entry = (variable_entry2 *)iter.get();
- if (entry->var == var) {
- return entry;
- }
- }
-
- return NULL;
-}
-
-void
-ir_structure_splitting_visitor::split_deref(ir_dereference **deref)
-{
- if ((*deref)->ir_type != ir_type_dereference_record)
- return;
-
- ir_dereference_record *deref_record = (ir_dereference_record *)*deref;
- ir_dereference_variable *deref_var = deref_record->record->as_dereference_variable();
- if (!deref_var)
- return;
-
- variable_entry2 *entry = get_splitting_entry(deref_var->var);
- if (!entry)
- return;
-
- unsigned int i;
- for (i = 0; i < entry->var->type->length; i++) {
- if (strcmp(deref_record->field,
- entry->var->type->fields.structure[i].name) == 0)
- break;
- }
- assert(i != entry->var->type->length);
-
- *deref = new(entry->mem_ctx) ir_dereference_variable(entry->components[i]);
-}
-
-void
-ir_structure_splitting_visitor::handle_rvalue(ir_rvalue **rvalue)
-{
- if (!*rvalue)
- return;
-
- ir_dereference *deref = (*rvalue)->as_dereference();
-
- if (!deref)
- return;
-
- split_deref(&deref);
- *rvalue = deref;
-}
-
-ir_visitor_status
-ir_structure_splitting_visitor::visit_leave(ir_assignment *ir)
-{
- ir_dereference_variable *lhs_deref = ir->lhs->as_dereference_variable();
- ir_dereference_variable *rhs_deref = ir->rhs->as_dereference_variable();
- variable_entry2 *lhs_entry = lhs_deref ? get_splitting_entry(lhs_deref->var) : NULL;
- variable_entry2 *rhs_entry = rhs_deref ? get_splitting_entry(rhs_deref->var) : NULL;
- const glsl_type *type = ir->rhs->type;
-
- if ((lhs_entry || rhs_entry) && !ir->condition) {
- for (unsigned int i = 0; i < type->length; i++) {
- ir_dereference *new_lhs, *new_rhs;
- void *mem_ctx = lhs_entry ? lhs_entry->mem_ctx : rhs_entry->mem_ctx;
-
- if (lhs_entry) {
- new_lhs = new(mem_ctx) ir_dereference_variable(lhs_entry->components[i]);
- } else {
- new_lhs = new(mem_ctx)
- ir_dereference_record(ir->lhs->clone(mem_ctx, NULL),
- type->fields.structure[i].name);
- }
-
- if (rhs_entry) {
- new_rhs = new(mem_ctx) ir_dereference_variable(rhs_entry->components[i]);
- } else {
- new_rhs = new(mem_ctx)
- ir_dereference_record(ir->rhs->clone(mem_ctx, NULL),
- type->fields.structure[i].name);
- }
-
- ir->insert_before(new(mem_ctx) ir_assignment(new_lhs,
- new_rhs,
- NULL));
- }
- ir->remove();
- } else {
- handle_rvalue(&ir->rhs);
- split_deref(&ir->lhs);
- }
-
- handle_rvalue(&ir->condition);
-
- return visit_continue;
-}
-
-bool
-do_structure_splitting(exec_list *instructions)
-{
- ir_structure_reference_visitor refs;
-
- visit_list_elements(&refs, instructions);
-
- /* Trim out variables we can't split. */
- foreach_iter(exec_list_iterator, iter, refs.variable_list) {
- variable_entry2 *entry = (variable_entry2 *)iter.get();
-
- if (debug) {
- printf("structure %s@%p: decl %d, whole_access %d\n",
- entry->var->name, (void *) entry->var, entry->declaration,
- entry->whole_structure_access);
- }
-
- if (!entry->declaration || entry->whole_structure_access) {
- entry->remove();
- }
- }
-
- if (refs.variable_list.is_empty())
- return false;
-
- void *mem_ctx = ralloc_context(NULL);
-
- /* Replace the decls of the structures to be split with their split
- * components.
- */
- foreach_iter(exec_list_iterator, iter, refs.variable_list) {
- variable_entry2 *entry = (variable_entry2 *)iter.get();
- const struct glsl_type *type = entry->var->type;
-
- entry->mem_ctx = ralloc_parent(entry->var);
-
- entry->components = ralloc_array(mem_ctx,
- ir_variable *,
- type->length);
-
- for (unsigned int i = 0; i < entry->var->type->length; i++) {
- const char *name = ralloc_asprintf(mem_ctx, "%s_%s",
- entry->var->name,
- type->fields.structure[i].name);
-
- entry->components[i] =
- new(entry->mem_ctx) ir_variable(type->fields.structure[i].type,
- name,
- ir_var_temporary);
- entry->var->insert_before(entry->components[i]);
- }
-
- entry->var->remove();
- }
-
- ir_structure_splitting_visitor split(&refs.variable_list);
- visit_list_elements(&split, instructions);
-
- ralloc_free(mem_ctx);
-
- return true;
-}
+/* + * Copyright © 2010 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. + */ + +/** + * \file opt_structure_splitting.cpp + * + * If a structure is only ever referenced by its components, then + * split those components out to individual variables so they can be + * handled normally by other optimization passes. + * + * This skips structures like uniforms, which need to be accessible as + * structures for their access by the GL. + */ + +#include "ir.h" +#include "ir_visitor.h" +#include "ir_print_visitor.h" +#include "ir_rvalue_visitor.h" +#include "glsl_types.h" + +static bool debug = false; + +// XXX using variable_entry2 here to avoid collision (MSVC multiply-defined +// function) with the variable_entry class seen in ir_variable_refcount.h +// Perhaps we can use the one in ir_variable_refcount.h and make this class +// here go away? +class variable_entry2 : public exec_node +{ +public: + variable_entry2(ir_variable *var) + { + this->var = var; + this->whole_structure_access = 0; + this->declaration = false; + this->components = NULL; + this->mem_ctx = NULL; + } + + ir_variable *var; /* The key: the variable's pointer. */ + + /** Number of times the variable is referenced, including assignments. */ + unsigned whole_structure_access; + + /* If the variable had a decl we can work with in the instruction + * stream. We can't do splitting on function arguments, which + * don't get this variable set. + */ + bool declaration; + + ir_variable **components; + + /** ralloc_parent(this->var) -- the shader's ralloc context. */ + void *mem_ctx; +}; + + +class ir_structure_reference_visitor : public ir_hierarchical_visitor { +public: + ir_structure_reference_visitor(void) + { + this->mem_ctx = ralloc_context(NULL); + this->variable_list.make_empty(); + } + + ~ir_structure_reference_visitor(void) + { + ralloc_free(mem_ctx); + } + + virtual ir_visitor_status visit(ir_variable *); + virtual ir_visitor_status visit(ir_dereference_variable *); + virtual ir_visitor_status visit_enter(ir_dereference_record *); + virtual ir_visitor_status visit_enter(ir_assignment *); + virtual ir_visitor_status visit_enter(ir_function_signature *); + + variable_entry2 *get_variable_entry2(ir_variable *var); + + /* List of variable_entry */ + exec_list variable_list; + + void *mem_ctx; +}; + +variable_entry2 * +ir_structure_reference_visitor::get_variable_entry2(ir_variable *var) +{ + assert(var); + + if (!var->type->is_record() || var->mode == ir_var_uniform) + return NULL; + + foreach_iter(exec_list_iterator, iter, this->variable_list) { + variable_entry2 *entry = (variable_entry2 *)iter.get(); + if (entry->var == var) + return entry; + } + + variable_entry2 *entry = new(mem_ctx) variable_entry2(var); + this->variable_list.push_tail(entry); + return entry; +} + + +ir_visitor_status +ir_structure_reference_visitor::visit(ir_variable *ir) +{ + variable_entry2 *entry = this->get_variable_entry2(ir); + + if (entry) + entry->declaration = true; + + return visit_continue; +} + +ir_visitor_status +ir_structure_reference_visitor::visit(ir_dereference_variable *ir) +{ + ir_variable *const var = ir->variable_referenced(); + variable_entry2 *entry = this->get_variable_entry2(var); + + if (entry) + entry->whole_structure_access++; + + return visit_continue; +} + +ir_visitor_status +ir_structure_reference_visitor::visit_enter(ir_dereference_record *ir) +{ + (void) ir; + /* Don't descend into the ir_dereference_variable below. */ + return visit_continue_with_parent; +} + +ir_visitor_status +ir_structure_reference_visitor::visit_enter(ir_assignment *ir) +{ + /* If there are no structure references yet, no need to bother with + * processing the expression tree. + */ + if (this->variable_list.is_empty()) + return visit_continue_with_parent; + + if (ir->lhs->as_dereference_variable() && + ir->rhs->as_dereference_variable() && + !ir->condition) { + /* We'll split copies of a structure to copies of components, so don't + * descend to the ir_dereference_variables. + */ + return visit_continue_with_parent; + } + return visit_continue; +} + +ir_visitor_status +ir_structure_reference_visitor::visit_enter(ir_function_signature *ir) +{ + /* We don't have logic for structure-splitting function arguments, + * so just look at the body instructions and not the parameter + * declarations. + */ + visit_list_elements(this, &ir->body); + return visit_continue_with_parent; +} + +class ir_structure_splitting_visitor : public ir_rvalue_visitor { +public: + ir_structure_splitting_visitor(exec_list *vars) + { + this->variable_list = vars; + } + + virtual ~ir_structure_splitting_visitor() + { + } + + virtual ir_visitor_status visit_leave(ir_assignment *); + + void split_deref(ir_dereference **deref); + void handle_rvalue(ir_rvalue **rvalue); + variable_entry2 *get_splitting_entry(ir_variable *var); + + exec_list *variable_list; + void *mem_ctx; +}; + +variable_entry2 * +ir_structure_splitting_visitor::get_splitting_entry(ir_variable *var) +{ + assert(var); + + if (!var->type->is_record()) + return NULL; + + foreach_iter(exec_list_iterator, iter, *this->variable_list) { + variable_entry2 *entry = (variable_entry2 *)iter.get(); + if (entry->var == var) { + return entry; + } + } + + return NULL; +} + +void +ir_structure_splitting_visitor::split_deref(ir_dereference **deref) +{ + if ((*deref)->ir_type != ir_type_dereference_record) + return; + + ir_dereference_record *deref_record = (ir_dereference_record *)*deref; + ir_dereference_variable *deref_var = deref_record->record->as_dereference_variable(); + if (!deref_var) + return; + + variable_entry2 *entry = get_splitting_entry(deref_var->var); + if (!entry) + return; + + unsigned int i; + for (i = 0; i < entry->var->type->length; i++) { + if (strcmp(deref_record->field, + entry->var->type->fields.structure[i].name) == 0) + break; + } + assert(i != entry->var->type->length); + + *deref = new(entry->mem_ctx) ir_dereference_variable(entry->components[i]); +} + +void +ir_structure_splitting_visitor::handle_rvalue(ir_rvalue **rvalue) +{ + if (!*rvalue) + return; + + ir_dereference *deref = (*rvalue)->as_dereference(); + + if (!deref) + return; + + split_deref(&deref); + *rvalue = deref; +} + +ir_visitor_status +ir_structure_splitting_visitor::visit_leave(ir_assignment *ir) +{ + ir_dereference_variable *lhs_deref = ir->lhs->as_dereference_variable(); + ir_dereference_variable *rhs_deref = ir->rhs->as_dereference_variable(); + variable_entry2 *lhs_entry = lhs_deref ? get_splitting_entry(lhs_deref->var) : NULL; + variable_entry2 *rhs_entry = rhs_deref ? get_splitting_entry(rhs_deref->var) : NULL; + const glsl_type *type = ir->rhs->type; + + if ((lhs_entry || rhs_entry) && !ir->condition) { + for (unsigned int i = 0; i < type->length; i++) { + ir_dereference *new_lhs, *new_rhs; + void *mem_ctx = lhs_entry ? lhs_entry->mem_ctx : rhs_entry->mem_ctx; + + if (lhs_entry) { + new_lhs = new(mem_ctx) ir_dereference_variable(lhs_entry->components[i]); + } else { + new_lhs = new(mem_ctx) + ir_dereference_record(ir->lhs->clone(mem_ctx, NULL), + type->fields.structure[i].name); + } + + if (rhs_entry) { + new_rhs = new(mem_ctx) ir_dereference_variable(rhs_entry->components[i]); + } else { + new_rhs = new(mem_ctx) + ir_dereference_record(ir->rhs->clone(mem_ctx, NULL), + type->fields.structure[i].name); + } + + ir->insert_before(new(mem_ctx) ir_assignment(new_lhs, + new_rhs, + NULL)); + } + ir->remove(); + } else { + handle_rvalue(&ir->rhs); + split_deref(&ir->lhs); + } + + handle_rvalue(&ir->condition); + + return visit_continue; +} + +bool +do_structure_splitting(exec_list *instructions) +{ + ir_structure_reference_visitor refs; + + visit_list_elements(&refs, instructions); + + /* Trim out variables we can't split. */ + foreach_iter(exec_list_iterator, iter, refs.variable_list) { + variable_entry2 *entry = (variable_entry2 *)iter.get(); + + if (debug) { + printf("structure %s@%p: decl %d, whole_access %d\n", + entry->var->name, (void *) entry->var, entry->declaration, + entry->whole_structure_access); + } + + if (!entry->declaration || entry->whole_structure_access) { + entry->remove(); + } + } + + if (refs.variable_list.is_empty()) + return false; + + void *mem_ctx = ralloc_context(NULL); + + /* Replace the decls of the structures to be split with their split + * components. + */ + foreach_iter(exec_list_iterator, iter, refs.variable_list) { + variable_entry2 *entry = (variable_entry2 *)iter.get(); + const struct glsl_type *type = entry->var->type; + + entry->mem_ctx = ralloc_parent(entry->var); + + entry->components = ralloc_array(mem_ctx, + ir_variable *, + type->length); + + for (unsigned int i = 0; i < entry->var->type->length; i++) { + const char *name = ralloc_asprintf(mem_ctx, "%s_%s", + entry->var->name, + type->fields.structure[i].name); + + entry->components[i] = + new(entry->mem_ctx) ir_variable(type->fields.structure[i].type, + name, + ir_var_temporary); + entry->var->insert_before(entry->components[i]); + } + + entry->var->remove(); + } + + ir_structure_splitting_visitor split(&refs.variable_list); + visit_list_elements(&split, instructions); + + ralloc_free(mem_ctx); + + return true; +} diff --git a/mesalib/src/mesa/main/attrib.c b/mesalib/src/mesa/main/attrib.c index 7042312a8..9b90b05f7 100644 --- a/mesalib/src/mesa/main/attrib.c +++ b/mesalib/src/mesa/main/attrib.c @@ -1448,9 +1448,6 @@ restore_array_attrib(struct gl_context *ctx, _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, src->ArrayObj->ElementArrayBufferObj->Name); - /* Better safe than sorry?! */ - dest->RebindArrays = GL_TRUE; - /* FIXME: Should some bits in ctx->Array->NewState also be set * FIXME: here? It seems like it should be set to inclusive-or * FIXME: of the old ArrayObj->_Enabled and the new _Enabled. diff --git a/mesalib/src/mesa/main/context.c b/mesalib/src/mesa/main/context.c index 51b024143..d75351c85 100644 --- a/mesalib/src/mesa/main/context.c +++ b/mesalib/src/mesa/main/context.c @@ -1104,6 +1104,9 @@ _mesa_free_context_data( struct gl_context *ctx ) _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL); _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, NULL); + _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, NULL); + _mesa_reference_array_object(ctx, &ctx->Array.DefaultArrayObj, NULL); + _mesa_free_attrib_data(ctx); _mesa_free_buffer_objects(ctx); _mesa_free_lighting_data( ctx ); @@ -1118,8 +1121,6 @@ _mesa_free_context_data( struct gl_context *ctx ) _mesa_free_varray_data(ctx); _mesa_free_transform_feedback(ctx); - _mesa_delete_array_object(ctx, ctx->Array.DefaultArrayObj); - #if FEATURE_ARB_pixel_buffer_object _mesa_reference_buffer_object(ctx, &ctx->Pack.BufferObj, NULL); _mesa_reference_buffer_object(ctx, &ctx->Unpack.BufferObj, NULL); diff --git a/mesalib/src/mesa/main/ff_fragment_shader.cpp b/mesalib/src/mesa/main/ff_fragment_shader.cpp index 3c91b1a42..8a42281db 100644 --- a/mesalib/src/mesa/main/ff_fragment_shader.cpp +++ b/mesalib/src/mesa/main/ff_fragment_shader.cpp @@ -337,7 +337,7 @@ static GLbitfield get_fp_input_mask( struct gl_context *ctx ) } else if (!(vertexProgram || vertexShader)) { /* Fixed function vertex logic */ - /* _NEW_ARRAY */ + /* _NEW_VARYING_VP_INPUTS */ GLbitfield64 varying_inputs = ctx->varying_vp_inputs; /* These get generated in the setup routine regardless of the diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h index bfa320a52..f277307a8 100644 --- a/mesalib/src/mesa/main/mtypes.h +++ b/mesalib/src/mesa/main/mtypes.h @@ -1632,7 +1632,6 @@ struct gl_array_attrib GLuint RestartIndex; GLbitfield64 NewState; /**< mask of VERT_BIT_* values */ - GLboolean RebindArrays; /**< whether the VBO module should rebind arrays */ /* GL_ARB_vertex_buffer_object */ struct gl_buffer_object *ArrayBufferObj; @@ -3063,6 +3062,7 @@ struct gl_matrix_stack #define _NEW_BUFFER_OBJECT (1 << 28) #define _NEW_FRAG_CLAMP (1 << 29) #define _NEW_TRANSFORM_FEEDBACK (1 << 30) /**< gl_context::TransformFeedback */ +#define _NEW_VARYING_VP_INPUTS (1 << 31) /**< gl_context::varying_vp_inputs */ #define _NEW_ALL ~0 /** diff --git a/mesalib/src/mesa/main/readpix.c b/mesalib/src/mesa/main/readpix.c index 491854955..31acfcbf1 100644 --- a/mesalib/src/mesa/main/readpix.c +++ b/mesalib/src/mesa/main/readpix.c @@ -208,6 +208,11 @@ read_stencil_pixels( struct gl_context *ctx, ctx->Driver.UnmapRenderbuffer(ctx, rb); } + +/** + * Try to do glReadPixels of RGBA data using a simple memcpy or swizzle. + * \return GL_TRUE if successful, GL_FALSE otherwise (use the slow path) + */ static GLboolean fast_read_rgba_pixels_memcpy( struct gl_context *ctx, GLint x, GLint y, @@ -220,9 +225,23 @@ fast_read_rgba_pixels_memcpy( struct gl_context *ctx, struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer; GLubyte *dst, *map; int dstStride, stride, j, texelBytes; - - if (!_mesa_format_matches_format_and_type(rb->Format, format, type, - ctx->Pack.SwapBytes)) + GLboolean swizzle_rb = GL_FALSE, copy_xrgb = GL_FALSE; + + /* XXX we could check for other swizzle/special cases here as needed */ + if (rb->Format == MESA_FORMAT_RGBA8888_REV && + format == GL_BGRA && + type == GL_UNSIGNED_INT_8_8_8_8_REV && + !ctx->Pack.SwapBytes) { + swizzle_rb = GL_TRUE; + } + else if (rb->Format == MESA_FORMAT_XRGB8888 && + format == GL_BGRA && + type == GL_UNSIGNED_INT_8_8_8_8_REV && + !ctx->Pack.SwapBytes) { + copy_xrgb = GL_TRUE; + } + else if (!_mesa_format_matches_format_and_type(rb->Format, format, type, + ctx->Pack.SwapBytes)) return GL_FALSE; /* If the format is unsigned normalized then we can ignore clamping @@ -247,10 +266,39 @@ fast_read_rgba_pixels_memcpy( struct gl_context *ctx, } texelBytes = _mesa_get_format_bytes(rb->Format); - for (j = 0; j < height; j++) { - memcpy(dst, map, width * texelBytes); - dst += dstStride; - map += stride; + + if (swizzle_rb) { + /* swap R/B */ + for (j = 0; j < height; j++) { + int i; + for (i = 0; i < width; i++) { + GLuint *dst4 = (GLuint *) dst, *map4 = (GLuint *) map; + GLuint pixel = map4[i]; + dst4[i] = (pixel & 0xff00ff00) + | ((pixel & 0x00ff0000) >> 16) + | ((pixel & 0x000000ff) << 16); + } + dst += dstStride; + map += stride; + } + } else if (copy_xrgb) { + /* convert xrgb -> argb */ + for (j = 0; j < height; j++) { + GLuint *dst4 = (GLuint *) dst, *map4 = (GLuint *) map; + int i; + for (i = 0; i < width; i++) { + dst4[i] = map4[i] | 0xff000000; /* set A=0xff */ + } + dst += dstStride; + map += stride; + } + } else { + /* just memcpy */ + for (j = 0; j < height; j++) { + memcpy(dst, map, width * texelBytes); + dst += dstStride; + map += stride; + } } ctx->Driver.UnmapRenderbuffer(ctx, rb); diff --git a/mesalib/src/mesa/main/state.c b/mesalib/src/mesa/main/state.c index b01926622..f82e4a25e 100644 --- a/mesalib/src/mesa/main/state.c +++ b/mesalib/src/mesa/main/state.c @@ -473,12 +473,13 @@ _mesa_update_state_locked( struct gl_context *ctx ) /* Determine which state flags effect vertex/fragment program state */ if (ctx->FragmentProgram._MaintainTexEnvProgram) { prog_flags |= (_NEW_BUFFERS | _NEW_TEXTURE | _NEW_FOG | - _NEW_ARRAY | _NEW_LIGHT | _NEW_POINT | _NEW_RENDERMODE | - _NEW_PROGRAM | _NEW_FRAG_CLAMP | _NEW_COLOR); + _NEW_VARYING_VP_INPUTS | _NEW_LIGHT | _NEW_POINT | + _NEW_RENDERMODE | _NEW_PROGRAM | _NEW_FRAG_CLAMP | + _NEW_COLOR); } if (ctx->VertexProgram._MaintainTnlProgram) { - prog_flags |= (_NEW_ARRAY | _NEW_TEXTURE | _NEW_TEXTURE_MATRIX | - _NEW_TRANSFORM | _NEW_POINT | + prog_flags |= (_NEW_VARYING_VP_INPUTS | _NEW_TEXTURE | + _NEW_TEXTURE_MATRIX | _NEW_TRANSFORM | _NEW_POINT | _NEW_FOG | _NEW_LIGHT | _MESA_NEW_NEED_EYE_COORDS); } @@ -580,8 +581,6 @@ _mesa_update_state_locked( struct gl_context *ctx ) ctx->NewState = 0; ctx->Driver.UpdateState(ctx, new_state); ctx->Array.NewState = 0; - if (!ctx->Array.RebindArrays) - ctx->Array.RebindArrays = (new_state & (_NEW_ARRAY | _NEW_PROGRAM)) != 0; } @@ -626,7 +625,16 @@ _mesa_set_varying_vp_inputs( struct gl_context *ctx, { if (ctx->varying_vp_inputs != varying_inputs) { ctx->varying_vp_inputs = varying_inputs; - ctx->NewState |= _NEW_ARRAY; + + /* Only the fixed-func generated programs need to use the flag + * and the fixed-func fragment program uses it only if there is also + * a fixed-func vertex program, so this only depends on the latter. + * + * It's okay to check the VP pointer here, because this is called after + * _mesa_update_state in the vbo module. */ + if (ctx->VertexProgram._TnlProgram) { + ctx->NewState |= _NEW_VARYING_VP_INPUTS; + } /*printf("%s %x\n", __FUNCTION__, varying_inputs);*/ } } diff --git a/mesalib/src/mesa/main/varray.c b/mesalib/src/mesa/main/varray.c index a402c7b22..1c1484323 100644 --- a/mesalib/src/mesa/main/varray.c +++ b/mesalib/src/mesa/main/varray.c @@ -1221,7 +1221,7 @@ _mesa_print_arrays(struct gl_context *ctx) void _mesa_init_varray(struct gl_context *ctx) { - ctx->Array.DefaultArrayObj = _mesa_new_array_object(ctx, 0); + ctx->Array.DefaultArrayObj = ctx->Driver.NewArrayObject(ctx, 0); _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, ctx->Array.DefaultArrayObj); ctx->Array.ActiveTexture = 0; /* GL_ARB_multitexture */ diff --git a/mesalib/src/mesa/state_tracker/st_cb_bitmap.c b/mesalib/src/mesa/state_tracker/st_cb_bitmap.c index 7c0254d8d..09152c79a 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_bitmap.c +++ b/mesalib/src/mesa/state_tracker/st_cb_bitmap.c @@ -52,6 +52,7 @@ #include "util/u_inlines.h" #include "util/u_draw_quad.h" #include "util/u_simple_shaders.h" +#include "util/u_upload_mgr.h" #include "program/prog_instruction.h" #include "cso_cache/cso_context.h" @@ -327,12 +328,13 @@ make_bitmap_texture(struct gl_context *ctx, GLsizei width, GLsizei height, return pt; } -static GLuint +static void setup_bitmap_vertex_data(struct st_context *st, bool normalized, int x, int y, int width, int height, - float z, const float color[4]) + float z, const float color[4], + struct pipe_resource **vbuf, + unsigned *vbuf_offset) { - struct pipe_context *pipe = st->pipe; const struct gl_framebuffer *fb = st->ctx->DrawBuffer; const GLfloat fb_width = (GLfloat)fb->Width; const GLfloat fb_height = (GLfloat)fb->Height; @@ -346,8 +348,8 @@ setup_bitmap_vertex_data(struct st_context *st, bool normalized, const GLfloat clip_y0 = (GLfloat)(y0 / fb_height * 2.0 - 1.0); const GLfloat clip_x1 = (GLfloat)(x1 / fb_width * 2.0 - 1.0); const GLfloat clip_y1 = (GLfloat)(y1 / fb_height * 2.0 - 1.0); - const GLuint max_slots = 1; /* 4096 / sizeof(st->bitmap.vertices); */ GLuint i; + float (*vertices)[3][4]; /**< vertex pos + color + texcoord */ if(!normalized) { @@ -355,77 +357,48 @@ setup_bitmap_vertex_data(struct st_context *st, bool normalized, tBot = (GLfloat) height; } - /* XXX: Need to improve buffer_write to allow NO_WAIT (as well as - * no_flush) updates to buffers where we know there is no conflict - * with previous data. Currently using max_slots > 1 will cause - * synchronous rendering if the driver flushes its command buffers - * between one bitmap and the next. Our flush hook below isn't - * sufficient to catch this as the driver doesn't tell us when it - * flushes its own command buffers. Until this gets fixed, pay the - * price of allocating a new buffer for each bitmap cache-flush to - * avoid synchronous rendering. - */ - if (st->bitmap.vbuf_slot >= max_slots) { - pipe_resource_reference(&st->bitmap.vbuf, NULL); - st->bitmap.vbuf_slot = 0; - } - - if (!st->bitmap.vbuf) { - st->bitmap.vbuf = pipe_buffer_create(pipe->screen, - PIPE_BIND_VERTEX_BUFFER, - PIPE_USAGE_STREAM, - max_slots * - sizeof(st->bitmap.vertices)); - if (!st->bitmap.vbuf) { - /* out of memory */ - return 0; - } + u_upload_alloc(st->uploader, 0, 4 * sizeof(vertices[0]), vbuf_offset, vbuf, + (void**)&vertices); + if (!vbuf) { + return; } /* Positions are in clip coords since we need to do clipping in case * the bitmap quad goes beyond the window bounds. */ - st->bitmap.vertices[0][0][0] = clip_x0; - st->bitmap.vertices[0][0][1] = clip_y0; - st->bitmap.vertices[0][2][0] = sLeft; - st->bitmap.vertices[0][2][1] = tTop; - - st->bitmap.vertices[1][0][0] = clip_x1; - st->bitmap.vertices[1][0][1] = clip_y0; - st->bitmap.vertices[1][2][0] = sRight; - st->bitmap.vertices[1][2][1] = tTop; + vertices[0][0][0] = clip_x0; + vertices[0][0][1] = clip_y0; + vertices[0][2][0] = sLeft; + vertices[0][2][1] = tTop; + + vertices[1][0][0] = clip_x1; + vertices[1][0][1] = clip_y0; + vertices[1][2][0] = sRight; + vertices[1][2][1] = tTop; - st->bitmap.vertices[2][0][0] = clip_x1; - st->bitmap.vertices[2][0][1] = clip_y1; - st->bitmap.vertices[2][2][0] = sRight; - st->bitmap.vertices[2][2][1] = tBot; + vertices[2][0][0] = clip_x1; + vertices[2][0][1] = clip_y1; + vertices[2][2][0] = sRight; + vertices[2][2][1] = tBot; - st->bitmap.vertices[3][0][0] = clip_x0; - st->bitmap.vertices[3][0][1] = clip_y1; - st->bitmap.vertices[3][2][0] = sLeft; - st->bitmap.vertices[3][2][1] = tBot; + vertices[3][0][0] = clip_x0; + vertices[3][0][1] = clip_y1; + vertices[3][2][0] = sLeft; + vertices[3][2][1] = tBot; /* same for all verts: */ for (i = 0; i < 4; i++) { - st->bitmap.vertices[i][0][2] = z; - st->bitmap.vertices[i][0][3] = 1.0f; - st->bitmap.vertices[i][1][0] = color[0]; - st->bitmap.vertices[i][1][1] = color[1]; - st->bitmap.vertices[i][1][2] = color[2]; - st->bitmap.vertices[i][1][3] = color[3]; - st->bitmap.vertices[i][2][2] = 0.0; /*R*/ - st->bitmap.vertices[i][2][3] = 1.0; /*Q*/ + vertices[i][0][2] = z; + vertices[i][0][3] = 1.0f; + vertices[i][1][0] = color[0]; + vertices[i][1][1] = color[1]; + vertices[i][1][2] = color[2]; + vertices[i][1][3] = color[3]; + vertices[i][2][2] = 0.0; /*R*/ + vertices[i][2][3] = 1.0; /*Q*/ } - /* put vertex data into vbuf */ - pipe_buffer_write_nooverlap(st->pipe, - st->bitmap.vbuf, - st->bitmap.vbuf_slot - * sizeof(st->bitmap.vertices), - sizeof st->bitmap.vertices, - st->bitmap.vertices); - - return st->bitmap.vbuf_slot++ * sizeof st->bitmap.vertices; + u_upload_unmap(st->uploader); } @@ -446,6 +419,7 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z, struct st_fp_variant_key key; GLuint maxSize; GLuint offset; + struct pipe_resource *vbuf = NULL; memset(&key, 0, sizeof(key)); key.st = st; @@ -551,12 +525,11 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z, z = z * 2.0f - 1.0f; /* draw textured quad */ - offset = setup_bitmap_vertex_data(st, - sv->texture->target != PIPE_TEXTURE_RECT, - x, y, width, height, z, color); + setup_bitmap_vertex_data(st, sv->texture->target != PIPE_TEXTURE_RECT, + x, y, width, height, z, color, &vbuf, &offset); - if (st->bitmap.vbuf) { - util_draw_vertex_buffer(pipe, st->cso_context, st->bitmap.vbuf, offset, + if (vbuf) { + util_draw_vertex_buffer(pipe, st->cso_context, vbuf, offset, PIPE_PRIM_TRIANGLE_FAN, 4, /* verts */ 3); /* attribs/vert */ @@ -573,6 +546,8 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z, cso_restore_vertex_elements(cso); cso_restore_vertex_buffers(cso); cso_restore_stream_outputs(cso); + + pipe_resource_reference(&vbuf, NULL); } @@ -709,18 +684,12 @@ st_flush_bitmap_cache(struct st_context *st) /** - * Flush bitmap cache and release vertex buffer. + * Flush bitmap cache. */ void st_flush_bitmap( struct st_context *st ) { st_flush_bitmap_cache(st); - - /* Release vertex buffer to avoid synchronous rendering if we were - * to map it in the next frame. - */ - pipe_resource_reference(&st->bitmap.vbuf, NULL); - st->bitmap.vbuf_slot = 0; } @@ -914,11 +883,6 @@ st_destroy_bitmap(struct st_context *st) st->bitmap.vs = NULL; } - if (st->bitmap.vbuf) { - pipe_resource_reference(&st->bitmap.vbuf, NULL); - st->bitmap.vbuf = NULL; - } - if (cache) { if (cache->trans) { pipe_transfer_unmap(pipe, cache->trans); diff --git a/mesalib/src/mesa/state_tracker/st_cb_clear.c b/mesalib/src/mesa/state_tracker/st_cb_clear.c index 193583372..3cd8756f2 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_clear.c +++ b/mesalib/src/mesa/state_tracker/st_cb_clear.c @@ -53,6 +53,7 @@ #include "util/u_inlines.h" #include "util/u_simple_shaders.h" #include "util/u_draw_quad.h" +#include "util/u_upload_mgr.h" #include "cso_cache/cso_context.h" @@ -87,10 +88,6 @@ st_destroy_clear(struct st_context *st) cso_delete_vertex_shader(st->cso_context, st->clear.vs); st->clear.vs = NULL; } - if (st->clear.vbuf) { - pipe_resource_reference(&st->clear.vbuf, NULL); - st->clear.vbuf = NULL; - } } @@ -140,78 +137,50 @@ draw_quad(struct st_context *st, const union pipe_color_union *color) { struct pipe_context *pipe = st->pipe; + struct pipe_resource *vbuf = NULL; + GLuint i, offset; + float (*vertices)[2][4]; /**< vertex pos + color */ - /* XXX: Need to improve buffer_write to allow NO_WAIT (as well as - * no_flush) updates to buffers where we know there is no conflict - * with previous data. Currently using max_slots > 1 will cause - * synchronous rendering if the driver flushes its command buffers - * between one bitmap and the next. Our flush hook below isn't - * sufficient to catch this as the driver doesn't tell us when it - * flushes its own command buffers. Until this gets fixed, pay the - * price of allocating a new buffer for each bitmap cache-flush to - * avoid synchronous rendering. - */ - const GLuint max_slots = 1; /* 1024 / sizeof(st->clear.vertices); */ - GLuint i; - - if (st->clear.vbuf_slot >= max_slots) { - pipe_resource_reference(&st->clear.vbuf, NULL); - st->clear.vbuf_slot = 0; - } - - if (!st->clear.vbuf) { - st->clear.vbuf = pipe_buffer_create(pipe->screen, - PIPE_BIND_VERTEX_BUFFER, - PIPE_USAGE_STREAM, - max_slots * sizeof(st->clear.vertices)); - } - - if (!st->clear.vbuf) { - /* ran out of memory */ + u_upload_alloc(st->uploader, 0, 4 * sizeof(vertices[0]), &offset, &vbuf, + (void**)&vertices); + if (!vbuf) { return; } /* positions */ - st->clear.vertices[0][0][0] = x0; - st->clear.vertices[0][0][1] = y0; + vertices[0][0][0] = x0; + vertices[0][0][1] = y0; - st->clear.vertices[1][0][0] = x1; - st->clear.vertices[1][0][1] = y0; + vertices[1][0][0] = x1; + vertices[1][0][1] = y0; - st->clear.vertices[2][0][0] = x1; - st->clear.vertices[2][0][1] = y1; + vertices[2][0][0] = x1; + vertices[2][0][1] = y1; - st->clear.vertices[3][0][0] = x0; - st->clear.vertices[3][0][1] = y1; + vertices[3][0][0] = x0; + vertices[3][0][1] = y1; /* same for all verts: */ for (i = 0; i < 4; i++) { - st->clear.vertices[i][0][2] = z; - st->clear.vertices[i][0][3] = 1.0; - st->clear.vertices[i][1][0] = color->f[0]; - st->clear.vertices[i][1][1] = color->f[1]; - st->clear.vertices[i][1][2] = color->f[2]; - st->clear.vertices[i][1][3] = color->f[3]; + vertices[i][0][2] = z; + vertices[i][0][3] = 1.0; + vertices[i][1][0] = color->f[0]; + vertices[i][1][1] = color->f[1]; + vertices[i][1][2] = color->f[2]; + vertices[i][1][3] = color->f[3]; } - /* put vertex data into vbuf */ - pipe_buffer_write_nooverlap(st->pipe, st->clear.vbuf, - st->clear.vbuf_slot - * sizeof(st->clear.vertices), - sizeof(st->clear.vertices), - st->clear.vertices); + u_upload_unmap(st->uploader); /* draw */ util_draw_vertex_buffer(pipe, st->cso_context, - st->clear.vbuf, - st->clear.vbuf_slot * sizeof(st->clear.vertices), + vbuf, offset, PIPE_PRIM_TRIANGLE_FAN, 4, /* verts */ 2); /* attribs/vert */ - /* Increment slot */ - st->clear.vbuf_slot++; + pipe_resource_reference(&vbuf, NULL); } @@ -465,22 +434,6 @@ check_clear_stencil_with_quad(struct gl_context *ctx, struct gl_renderbuffer *rb } - -/** - * Called when we need to flush. - */ -void -st_flush_clear(struct st_context *st) -{ - /* Release vertex buffer to avoid synchronous rendering if we were - * to map it in the next frame. - */ - pipe_resource_reference(&st->clear.vbuf, NULL); - st->clear.vbuf_slot = 0; -} - - - /** * Called via ctx->Driver.Clear() */ diff --git a/mesalib/src/mesa/state_tracker/st_cb_clear.h b/mesalib/src/mesa/state_tracker/st_cb_clear.h index 8eafae5a4..e9297de9c 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_clear.h +++ b/mesalib/src/mesa/state_tracker/st_cb_clear.h @@ -1,52 +1,49 @@ -/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * 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, sub license, 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 NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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.
- *
- **************************************************************************/
-
-
-#ifndef ST_CB_CLEAR_H
-#define ST_CB_CLEAR_H
-
-
-struct dd_function_table;
-struct st_context;
-
-extern void
-st_init_clear(struct st_context *st);
-
-
-extern void
-st_destroy_clear(struct st_context *st);
-
-extern void
-st_flush_clear(struct st_context *st);
-
-
-extern void
-st_init_clear_functions(struct dd_function_table *functions);
-
-
-#endif /* ST_CB_CLEAR_H */
-
+/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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. + * + **************************************************************************/ + + +#ifndef ST_CB_CLEAR_H +#define ST_CB_CLEAR_H + + +struct dd_function_table; +struct st_context; + +extern void +st_init_clear(struct st_context *st); + + +extern void +st_destroy_clear(struct st_context *st); + + +extern void +st_init_clear_functions(struct dd_function_table *functions); + + +#endif /* ST_CB_CLEAR_H */ + diff --git a/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c b/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c index 18d0e53d4..5e078a85e 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c @@ -66,6 +66,7 @@ #include "util/u_inlines.h" #include "util/u_math.h" #include "util/u_tile.h" +#include "util/u_upload_mgr.h" #include "cso_cache/cso_context.h" @@ -554,7 +555,15 @@ draw_quad(struct gl_context *ctx, GLfloat x0, GLfloat y0, GLfloat z, { struct st_context *st = st_context(ctx); struct pipe_context *pipe = st->pipe; - GLfloat verts[4][3][4]; /* four verts, three attribs, XYZW */ + GLfloat (*verts)[3][4]; /* four verts, three attribs, XYZW */ + struct pipe_resource *buf = NULL; + unsigned offset; + + u_upload_alloc(st->uploader, 0, 4 * sizeof(verts[0]), &offset, &buf, + (void**)&verts); + if (!buf) { + return; + } /* setup vertex data */ { @@ -618,22 +627,12 @@ draw_quad(struct gl_context *ctx, GLfloat x0, GLfloat y0, GLfloat z, } } - { - struct pipe_resource *buf; - - /* allocate/load buffer object with vertex data */ - buf = pipe_buffer_create(pipe->screen, - PIPE_BIND_VERTEX_BUFFER, - PIPE_USAGE_STATIC, - sizeof(verts)); - pipe_buffer_write(st->pipe, buf, 0, sizeof(verts), verts); - - util_draw_vertex_buffer(pipe, st->cso_context, buf, 0, - PIPE_PRIM_QUADS, - 4, /* verts */ - 3); /* attribs/vert */ - pipe_resource_reference(&buf, NULL); - } + u_upload_unmap(st->uploader); + util_draw_vertex_buffer(pipe, st->cso_context, buf, offset, + PIPE_PRIM_QUADS, + 4, /* verts */ + 3); /* attribs/vert */ + pipe_resource_reference(&buf, NULL); } diff --git a/mesalib/src/mesa/state_tracker/st_cb_drawtex.c b/mesalib/src/mesa/state_tracker/st_cb_drawtex.c index 6144eb99c..d57e629f1 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_drawtex.c +++ b/mesalib/src/mesa/state_tracker/st_cb_drawtex.c @@ -29,6 +29,7 @@ #include "pipe/p_shader_tokens.h" #include "util/u_draw_quad.h" #include "util/u_simple_shaders.h" +#include "util/u_upload_mgr.h" #include "cso_cache/cso_context.h" @@ -107,13 +108,13 @@ st_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z, struct st_context *st = ctx->st; struct pipe_context *pipe = st->pipe; struct cso_context *cso = ctx->st->cso_context; - struct pipe_resource *vbuffer; - struct pipe_transfer *vbuffer_transfer; + struct pipe_resource *vbuffer = NULL; GLuint i, numTexCoords, numAttribs; GLboolean emitColor; uint semantic_names[2 + MAX_TEXTURE_UNITS]; uint semantic_indexes[2 + MAX_TEXTURE_UNITS]; struct pipe_vertex_element velements[2 + MAX_TEXTURE_UNITS]; + unsigned offset; st_validate_state(st); @@ -134,12 +135,6 @@ st_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z, /* total number of attributes per vertex */ numAttribs = 1 + emitColor + numTexCoords; - - /* create the vertex buffer */ - vbuffer = pipe_buffer_create(pipe->screen, PIPE_BIND_VERTEX_BUFFER, - PIPE_USAGE_STREAM, - numAttribs * 4 * 4 * sizeof(GLfloat)); - /* load vertex buffer */ { #define SET_ATTRIB(VERT, ATTR, X, Y, Z, W) \ @@ -153,10 +148,15 @@ st_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z, } while (0) const GLfloat x0 = x, y0 = y, x1 = x + width, y1 = y + height; - GLfloat *vbuf = (GLfloat *) pipe_buffer_map(pipe, vbuffer, - PIPE_TRANSFER_WRITE, - &vbuffer_transfer); + GLfloat *vbuf = NULL; GLuint attr; + + u_upload_alloc(st->uploader, 0, + numAttribs * 4 * 4 * sizeof(GLfloat), + &offset, &vbuffer, (void**)&vbuf); + if (!vbuffer) { + return; + } z = CLAMP(z, 0.0f, 1.0f); @@ -220,7 +220,7 @@ st_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z, } } - pipe_buffer_unmap(pipe, vbuffer_transfer); + u_upload_unmap(st->uploader); #undef SET_ATTRIB } @@ -269,7 +269,7 @@ st_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z, util_draw_vertex_buffer(pipe, cso, vbuffer, - 0, /* offset */ + offset, /* offset */ PIPE_PRIM_TRIANGLE_FAN, 4, /* verts */ numAttribs); /* attribs/vert */ diff --git a/mesalib/src/mesa/state_tracker/st_cb_flush.c b/mesalib/src/mesa/state_tracker/st_cb_flush.c index c029fad48..4e40a93f5 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_flush.c +++ b/mesalib/src/mesa/state_tracker/st_cb_flush.c @@ -1,165 +1,159 @@ -/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * 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, sub license, 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 NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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:
- * Keith Whitwell <keith@tungstengraphics.com>
- * Brian Paul
- */
-
-#include "main/glheader.h"
-#include "main/macros.h"
-#include "main/context.h"
-#include "st_context.h"
-#include "st_cb_bitmap.h"
-#include "st_cb_flush.h"
-#include "st_cb_clear.h"
-#include "st_cb_fbo.h"
-#include "st_manager.h"
-#include "pipe/p_context.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_screen.h"
-#include "util/u_gen_mipmap.h"
-#include "util/u_blit.h"
-
-
-/** Check if we have a front color buffer and if it's been drawn to. */
-static INLINE GLboolean
-is_front_buffer_dirty(struct st_context *st)
-{
- struct gl_framebuffer *fb = st->ctx->DrawBuffer;
- struct st_renderbuffer *strb
- = st_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
- return strb && strb->defined;
-}
-
-
-/**
- * Tell the screen to display the front color buffer on-screen.
- */
-static void
-display_front_buffer(struct st_context *st)
-{
- struct gl_framebuffer *fb = st->ctx->DrawBuffer;
- struct st_renderbuffer *strb
- = st_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
-
- if (strb) {
- /* Hook for copying "fake" frontbuffer if necessary:
- */
- st_manager_flush_frontbuffer(st);
- }
-}
-
-
-void st_flush( struct st_context *st,
- struct pipe_fence_handle **fence )
-{
- FLUSH_CURRENT(st->ctx, 0);
-
- /* Release any vertex buffers that might potentially be accessed in
- * successive frames:
- */
- st_flush_bitmap(st);
- st_flush_clear(st);
- util_blit_flush(st->blit);
- util_gen_mipmap_flush(st->gen_mipmap);
-
- st->pipe->flush( st->pipe, fence );
-}
-
-
-/**
- * Flush, and wait for completion.
- */
-void st_finish( struct st_context *st )
-{
- struct pipe_fence_handle *fence = NULL;
-
- st_flush(st, &fence);
-
- if(fence) {
- st->pipe->screen->fence_finish(st->pipe->screen, fence,
- PIPE_TIMEOUT_INFINITE);
- st->pipe->screen->fence_reference(st->pipe->screen, &fence, NULL);
- }
-}
-
-
-
-/**
- * Called via ctx->Driver.Flush()
- */
-static void st_glFlush(struct gl_context *ctx)
-{
- struct st_context *st = st_context(ctx);
-
- /* Don't call st_finish() here. It is not the state tracker's
- * responsibilty to inject sleeps in the hope of avoiding buffer
- * synchronization issues. Calling finish() here will just hide
- * problems that need to be fixed elsewhere.
- */
- st_flush(st, NULL);
-
- if (is_front_buffer_dirty(st)) {
- display_front_buffer(st);
- }
-}
-
-
-/**
- * Called via ctx->Driver.Finish()
- */
-static void st_glFinish(struct gl_context *ctx)
-{
- struct st_context *st = st_context(ctx);
-
- st_finish(st);
-
- if (is_front_buffer_dirty(st)) {
- display_front_buffer(st);
- }
-}
-
-
-void st_init_flush_functions(struct dd_function_table *functions)
-{
- functions->Flush = st_glFlush;
- functions->Finish = st_glFinish;
-
- /* Windows opengl32.dll calls glFinish prior to every swapbuffers.
- * This is unnecessary and degrades performance. Luckily we have some
- * scope to work around this, as the externally-visible behaviour of
- * Finish() is identical to Flush() in all cases - no differences in
- * rendering or ReadPixels are visible if we opt not to wait here.
- *
- * Only set this up on windows to avoid suprise elsewhere.
- */
-#ifdef PIPE_OS_WINDOWS
- functions->Finish = st_glFlush;
-#endif
-}
+/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * 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, sub license, 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 NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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: + * Keith Whitwell <keith@tungstengraphics.com> + * Brian Paul + */ + +#include "main/glheader.h" +#include "main/macros.h" +#include "main/context.h" +#include "st_context.h" +#include "st_cb_bitmap.h" +#include "st_cb_flush.h" +#include "st_cb_clear.h" +#include "st_cb_fbo.h" +#include "st_manager.h" +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_screen.h" +#include "util/u_gen_mipmap.h" +#include "util/u_blit.h" + + +/** Check if we have a front color buffer and if it's been drawn to. */ +static INLINE GLboolean +is_front_buffer_dirty(struct st_context *st) +{ + struct gl_framebuffer *fb = st->ctx->DrawBuffer; + struct st_renderbuffer *strb + = st_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer); + return strb && strb->defined; +} + + +/** + * Tell the screen to display the front color buffer on-screen. + */ +static void +display_front_buffer(struct st_context *st) +{ + struct gl_framebuffer *fb = st->ctx->DrawBuffer; + struct st_renderbuffer *strb + = st_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer); + + if (strb) { + /* Hook for copying "fake" frontbuffer if necessary: + */ + st_manager_flush_frontbuffer(st); + } +} + + +void st_flush( struct st_context *st, + struct pipe_fence_handle **fence ) +{ + FLUSH_CURRENT(st->ctx, 0); + + st_flush_bitmap(st); + + st->pipe->flush( st->pipe, fence ); +} + + +/** + * Flush, and wait for completion. + */ +void st_finish( struct st_context *st ) +{ + struct pipe_fence_handle *fence = NULL; + + st_flush(st, &fence); + + if(fence) { + st->pipe->screen->fence_finish(st->pipe->screen, fence, + PIPE_TIMEOUT_INFINITE); + st->pipe->screen->fence_reference(st->pipe->screen, &fence, NULL); + } +} + + + +/** + * Called via ctx->Driver.Flush() + */ +static void st_glFlush(struct gl_context *ctx) +{ + struct st_context *st = st_context(ctx); + + /* Don't call st_finish() here. It is not the state tracker's + * responsibilty to inject sleeps in the hope of avoiding buffer + * synchronization issues. Calling finish() here will just hide + * problems that need to be fixed elsewhere. + */ + st_flush(st, NULL); + + if (is_front_buffer_dirty(st)) { + display_front_buffer(st); + } +} + + +/** + * Called via ctx->Driver.Finish() + */ +static void st_glFinish(struct gl_context *ctx) +{ + struct st_context *st = st_context(ctx); + + st_finish(st); + + if (is_front_buffer_dirty(st)) { + display_front_buffer(st); + } +} + + +void st_init_flush_functions(struct dd_function_table *functions) +{ + functions->Flush = st_glFlush; + functions->Finish = st_glFinish; + + /* Windows opengl32.dll calls glFinish prior to every swapbuffers. + * This is unnecessary and degrades performance. Luckily we have some + * scope to work around this, as the externally-visible behaviour of + * Finish() is identical to Flush() in all cases - no differences in + * rendering or ReadPixels are visible if we opt not to wait here. + * + * Only set this up on windows to avoid suprise elsewhere. + */ +#ifdef PIPE_OS_WINDOWS + functions->Finish = st_glFlush; +#endif +} diff --git a/mesalib/src/mesa/state_tracker/st_context.c b/mesalib/src/mesa/state_tracker/st_context.c index a3fd4dbcb..0245fd92b 100644 --- a/mesalib/src/mesa/state_tracker/st_context.c +++ b/mesalib/src/mesa/state_tracker/st_context.c @@ -63,6 +63,7 @@ #include "st_program.h" #include "pipe/p_context.h" #include "util/u_inlines.h" +#include "util/u_upload_mgr.h" #include "cso_cache/cso_context.h" @@ -130,6 +131,7 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe ) st->dirty.mesa = ~0; st->dirty.st = ~0; + st->uploader = u_upload_create(st->pipe, 65536, 4, PIPE_BIND_VERTEX_BUFFER); st->cso_context = cso_create_context(pipe); st_init_atoms( st ); @@ -235,6 +237,7 @@ static void st_destroy_context_priv( struct st_context *st ) st->default_texture = NULL; } + u_upload_destroy(st->uploader); free( st ); } diff --git a/mesalib/src/mesa/state_tracker/st_context.h b/mesalib/src/mesa/state_tracker/st_context.h index da03719fd..e3d65d97a 100644 --- a/mesalib/src/mesa/state_tracker/st_context.h +++ b/mesalib/src/mesa/state_tracker/st_context.h @@ -40,14 +40,15 @@ struct draw_stage; struct gen_mipmap_state; struct st_context; struct st_fragment_program; +struct u_upload_mgr; -#define ST_NEW_MESA 0x1 /* Mesa state has changed */ -#define ST_NEW_FRAGMENT_PROGRAM 0x2 -#define ST_NEW_VERTEX_PROGRAM 0x4 -#define ST_NEW_FRAMEBUFFER 0x8 -#define ST_NEW_EDGEFLAGS_DATA 0x10 -#define ST_NEW_GEOMETRY_PROGRAM 0x20 +#define ST_NEW_MESA (1 << 0) /* Mesa state has changed */ +#define ST_NEW_FRAGMENT_PROGRAM (1 << 1) +#define ST_NEW_VERTEX_PROGRAM (1 << 2) +#define ST_NEW_FRAMEBUFFER (1 << 3) +#define ST_NEW_EDGEFLAGS_DATA (1 << 4) +#define ST_NEW_GEOMETRY_PROGRAM (1 << 5) struct st_state_flags { @@ -71,6 +72,7 @@ struct st_context struct pipe_context *pipe; + struct u_upload_mgr *uploader; struct draw_context *draw; /**< For selection/feedback/rastpos only */ struct draw_stage *feedback_stage; /**< For GL_FEEDBACK rendermode */ struct draw_stage *selection_stage; /**< For GL_SELECT rendermode */ @@ -153,9 +155,6 @@ struct st_context struct pipe_sampler_state samplers[2]; enum pipe_format tex_format; void *vs; - float vertices[4][3][4]; /**< vertex pos + color + texcoord */ - struct pipe_resource *vbuf; - unsigned vbuf_slot; /* next free slot in vbuf */ struct bitmap_cache *cache; } bitmap; @@ -171,9 +170,6 @@ struct st_context struct pipe_viewport_state viewport; void *vs; void *fs; - float vertices[4][2][4]; /**< vertex pos + color */ - struct pipe_resource *vbuf; - unsigned vbuf_slot; boolean enable_ds_separate; } clear; diff --git a/mesalib/src/mesa/vbo/vbo_context.c b/mesalib/src/mesa/vbo/vbo_context.c index d83f2fd23..5f1c72bc1 100644 --- a/mesalib/src/mesa/vbo/vbo_context.c +++ b/mesalib/src/mesa/vbo/vbo_context.c @@ -47,7 +47,7 @@ static GLuint check_size( const GLfloat *attr ) static void init_legacy_currval(struct gl_context *ctx) { struct vbo_context *vbo = vbo_context(ctx); - struct gl_client_array *arrays = vbo->legacy_currval; + struct gl_client_array *arrays = &vbo->currval[VBO_ATTRIB_POS]; GLuint i; memset(arrays, 0, sizeof(*arrays) * VERT_ATTRIB_FF_MAX); @@ -77,7 +77,7 @@ static void init_legacy_currval(struct gl_context *ctx) static void init_generic_currval(struct gl_context *ctx) { struct vbo_context *vbo = vbo_context(ctx); - struct gl_client_array *arrays = vbo->generic_currval; + struct gl_client_array *arrays = &vbo->currval[VBO_ATTRIB_GENERIC0]; GLuint i; memset(arrays, 0, sizeof(*arrays) * VERT_ATTRIB_GENERIC_MAX); @@ -104,7 +104,8 @@ static void init_generic_currval(struct gl_context *ctx) static void init_mat_currval(struct gl_context *ctx) { struct vbo_context *vbo = vbo_context(ctx); - struct gl_client_array *arrays = vbo->mat_currval; + struct gl_client_array *arrays = + &vbo->currval[VBO_ATTRIB_MAT_FRONT_AMBIENT]; GLuint i; ASSERT(NR_MAT_ATTRIBS == MAT_ATTRIB_MAX); @@ -160,12 +161,6 @@ GLboolean _vbo_CreateContext( struct gl_context *ctx ) return GL_FALSE; } - /* TODO: remove these pointers. - */ - vbo->legacy_currval = &vbo->currval[VBO_ATTRIB_POS]; - vbo->generic_currval = &vbo->currval[VBO_ATTRIB_GENERIC0]; - vbo->mat_currval = &vbo->currval[VBO_ATTRIB_MAT_FRONT_AMBIENT]; - init_legacy_currval( ctx ); init_generic_currval( ctx ); init_mat_currval( ctx ); diff --git a/mesalib/src/mesa/vbo/vbo_context.h b/mesalib/src/mesa/vbo/vbo_context.h index 1a1cc928b..b9a8affa5 100644 --- a/mesalib/src/mesa/vbo/vbo_context.h +++ b/mesalib/src/mesa/vbo/vbo_context.h @@ -61,20 +61,10 @@ struct vbo_context { struct gl_client_array currval[VBO_ATTRIB_MAX]; - /* These point into the above. TODO: remove. - */ - struct gl_client_array *legacy_currval; - struct gl_client_array *generic_currval; - struct gl_client_array *mat_currval; - /** Map VERT_ATTRIB_x to VBO_ATTRIB_y */ GLuint map_vp_none[VERT_ATTRIB_MAX]; GLuint map_vp_arb[VERT_ATTRIB_MAX]; - GLfloat *current[VBO_ATTRIB_MAX]; /* points into ctx->Current, ctx->Light.Material */ - GLfloat CurrentFloatEdgeFlag; - - struct vbo_exec_context exec; #if FEATURE_dlist struct vbo_save_context save; diff --git a/mesalib/src/mesa/vbo/vbo_exec.c b/mesalib/src/mesa/vbo/vbo_exec.c index 05c3ec1ae..fd5e0f891 100644 --- a/mesalib/src/mesa/vbo/vbo_exec.c +++ b/mesalib/src/mesa/vbo/vbo_exec.c @@ -85,6 +85,10 @@ void vbo_exec_invalidate_state( struct gl_context *ctx, GLuint new_state ) { struct vbo_exec_context *exec = &vbo_context(ctx)->exec; + if (new_state & (_NEW_PROGRAM|_NEW_ARRAY)) { + exec->array.recalculate_inputs = GL_TRUE; + } + if (new_state & (_NEW_PROGRAM|_NEW_EVAL)) exec->eval.recalculate_maps = 1; diff --git a/mesalib/src/mesa/vbo/vbo_exec.h b/mesalib/src/mesa/vbo/vbo_exec.h index f6ede99cd..5cdf5ced9 100644 --- a/mesalib/src/mesa/vbo/vbo_exec.h +++ b/mesalib/src/mesa/vbo/vbo_exec.h @@ -141,6 +141,7 @@ struct vbo_exec_context * programs: */ const struct gl_client_array *inputs[VERT_ATTRIB_MAX]; + GLboolean recalculate_inputs; } array; /* Which flags to set in vbo_exec_BeginVertices() */ diff --git a/mesalib/src/mesa/vbo/vbo_exec_api.c b/mesalib/src/mesa/vbo/vbo_exec_api.c index 306199067..3f9541089 100644 --- a/mesalib/src/mesa/vbo/vbo_exec_api.c +++ b/mesalib/src/mesa/vbo/vbo_exec_api.c @@ -1089,24 +1089,26 @@ void vbo_exec_vtx_init( struct vbo_exec_context *exec ) struct gl_client_array *arrays = exec->vtx.arrays; unsigned i; - memcpy(arrays, vbo->legacy_currval, + memcpy(arrays, &vbo->currval[VBO_ATTRIB_POS], VERT_ATTRIB_FF_MAX * sizeof(arrays[0])); for (i = 0; i < VERT_ATTRIB_FF_MAX; ++i) { struct gl_client_array *array; array = &arrays[VERT_ATTRIB_FF(i)]; array->BufferObj = NULL; _mesa_reference_buffer_object(ctx, &arrays->BufferObj, - vbo->legacy_currval[i].BufferObj); + vbo->currval[VBO_ATTRIB_POS+i].BufferObj); } - memcpy(arrays + VERT_ATTRIB_GENERIC(0), vbo->generic_currval, + memcpy(arrays + VERT_ATTRIB_GENERIC(0), + &vbo->currval[VBO_ATTRIB_GENERIC0], VERT_ATTRIB_GENERIC_MAX * sizeof(arrays[0])); + for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; ++i) { struct gl_client_array *array; array = &arrays[VERT_ATTRIB_GENERIC(i)]; array->BufferObj = NULL; _mesa_reference_buffer_object(ctx, &array->BufferObj, - vbo->generic_currval[i].BufferObj); + vbo->currval[VBO_ATTRIB_GENERIC0+i].BufferObj); } } diff --git a/mesalib/src/mesa/vbo/vbo_exec_array.c b/mesalib/src/mesa/vbo/vbo_exec_array.c index b0a4261e7..f95e062fb 100644 --- a/mesalib/src/mesa/vbo/vbo_exec_array.c +++ b/mesalib/src/mesa/vbo/vbo_exec_array.c @@ -420,13 +420,14 @@ recalculate_input_bindings(struct gl_context *ctx) if (vertexAttrib[VERT_ATTRIB_FF(i)].Enabled) inputs[i] = &vertexAttrib[VERT_ATTRIB_FF(i)]; else { - inputs[i] = &vbo->legacy_currval[i]; + inputs[i] = &vbo->currval[VBO_ATTRIB_POS+i]; const_inputs |= VERT_BIT(i); } } for (i = 0; i < MAT_ATTRIB_MAX; i++) { - inputs[VERT_ATTRIB_GENERIC(i)] = &vbo->mat_currval[i]; + inputs[VERT_ATTRIB_GENERIC(i)] = + &vbo->currval[VBO_ATTRIB_MAT_FRONT_AMBIENT+i]; const_inputs |= VERT_BIT_GENERIC(i); } @@ -434,7 +435,7 @@ recalculate_input_bindings(struct gl_context *ctx) * slots: */ for (i = MAT_ATTRIB_MAX; i < VERT_ATTRIB_GENERIC_MAX; i++) { - inputs[VERT_ATTRIB_GENERIC(i)] = &vbo->generic_currval[i]; + inputs[VERT_ATTRIB_GENERIC(i)] = &vbo->currval[VBO_ATTRIB_GENERIC0+i]; const_inputs |= VERT_BIT_GENERIC(i); } @@ -459,7 +460,7 @@ recalculate_input_bindings(struct gl_context *ctx) else if (vertexAttrib[VERT_ATTRIB_FF(i)].Enabled) inputs[i] = &vertexAttrib[VERT_ATTRIB_FF(i)]; else { - inputs[i] = &vbo->legacy_currval[i]; + inputs[i] = &vbo->currval[VBO_ATTRIB_POS+i]; const_inputs |= VERT_BIT_FF(i); } } @@ -468,7 +469,7 @@ recalculate_input_bindings(struct gl_context *ctx) * slots: */ for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; i++) { - inputs[VERT_ATTRIB_GENERIC(i)] = &vbo->generic_currval[i]; + inputs[VERT_ATTRIB_GENERIC(i)] = &vbo->currval[VBO_ATTRIB_GENERIC0+i]; const_inputs |= VERT_BIT_GENERIC(i); } @@ -488,7 +489,7 @@ recalculate_input_bindings(struct gl_context *ctx) else if (vertexAttrib[VERT_ATTRIB_POS].Enabled) inputs[0] = &vertexAttrib[VERT_ATTRIB_POS]; else { - inputs[0] = &vbo->legacy_currval[0]; + inputs[0] = &vbo->currval[VBO_ATTRIB_POS]; const_inputs |= VERT_BIT_POS; } @@ -496,7 +497,7 @@ recalculate_input_bindings(struct gl_context *ctx) if (vertexAttrib[VERT_ATTRIB_FF(i)].Enabled) inputs[i] = &vertexAttrib[VERT_ATTRIB_FF(i)]; else { - inputs[i] = &vbo->legacy_currval[i]; + inputs[i] = &vbo->currval[VBO_ATTRIB_POS+i]; const_inputs |= VERT_BIT_FF(i); } } @@ -505,7 +506,7 @@ recalculate_input_bindings(struct gl_context *ctx) if (vertexAttrib[VERT_ATTRIB_GENERIC(i)].Enabled) inputs[VERT_ATTRIB_GENERIC(i)] = &vertexAttrib[VERT_ATTRIB_GENERIC(i)]; else { - inputs[VERT_ATTRIB_GENERIC(i)] = &vbo->generic_currval[i]; + inputs[VERT_ATTRIB_GENERIC(i)] = &vbo->currval[VBO_ATTRIB_GENERIC0+i]; const_inputs |= VERT_BIT_GENERIC(i); } } @@ -523,18 +524,31 @@ recalculate_input_bindings(struct gl_context *ctx) * Examine the enabled vertex arrays to set the exec->array.inputs[] values. * These will point to the arrays to actually use for drawing. Some will * be user-provided arrays, other will be zero-stride const-valued arrays. - * Note that this might set the _NEW_ARRAY dirty flag so state validation - * must be done after this call. + * Note that this might set the _NEW_VARYING_VP_INPUTS dirty flag so state + * validation must be done after this call. */ void vbo_bind_arrays(struct gl_context *ctx) { - if (!ctx->Array.RebindArrays) { - return; - } + struct vbo_context *vbo = vbo_context(ctx); + struct vbo_exec_context *exec = &vbo->exec; + + vbo_draw_method(exec, DRAW_ARRAYS); + + if (exec->array.recalculate_inputs) { + recalculate_input_bindings(ctx); + + /* Again... because we may have changed the bitmask of per-vertex varying + * attributes. If we regenerate the fixed-function vertex program now + * we may be able to prune down the number of vertex attributes which we + * need in the shader. + */ + if (ctx->NewState) { + _mesa_update_state(ctx); + } - recalculate_input_bindings(ctx); - ctx->Array.RebindArrays = GL_FALSE; + exec->array.recalculate_inputs = GL_FALSE; + } } @@ -554,16 +568,6 @@ vbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start, vbo_bind_arrays(ctx); - vbo_draw_method(exec, DRAW_ARRAYS); - - /* Again... because we may have changed the bitmask of per-vertex varying - * attributes. If we regenerate the fixed-function vertex program now - * we may be able to prune down the number of vertex attributes which we - * need in the shader. - */ - if (ctx->NewState) - _mesa_update_state(ctx); - /* init most fields to zero */ memset(prim, 0, sizeof(prim)); prim[0].begin = 1; @@ -641,10 +645,6 @@ vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count) FLUSH_CURRENT( ctx, 0 ); - if (!_mesa_valid_to_render(ctx, "glDrawArrays")) { - return; - } - if (0) check_draw_arrays_data(ctx, start, count); @@ -674,10 +674,6 @@ vbo_exec_DrawArraysInstanced(GLenum mode, GLint start, GLsizei count, FLUSH_CURRENT( ctx, 0 ); - if (!_mesa_valid_to_render(ctx, "glDrawArraysInstanced")) { - return; - } - if (0) check_draw_arrays_data(ctx, start, count); @@ -767,17 +763,7 @@ vbo_validated_drawrangeelements(struct gl_context *ctx, GLenum mode, FLUSH_CURRENT( ctx, 0 ); - if (!_mesa_valid_to_render(ctx, "glDraw[Range]Elements")) { - return; - } - - vbo_bind_arrays( ctx ); - - vbo_draw_method(exec, DRAW_ARRAYS); - - /* check for dirty state again */ - if (ctx->NewState) - _mesa_update_state( ctx ); + vbo_bind_arrays(ctx); ib.count = count; ib.type = type; @@ -1053,25 +1039,13 @@ vbo_validated_multidrawelements(struct gl_context *ctx, GLenum mode, FLUSH_CURRENT( ctx, 0 ); - if (!_mesa_valid_to_render(ctx, "glMultiDrawElements")) { - return; - } - prim = calloc(1, primcount * sizeof(*prim)); if (prim == NULL) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMultiDrawElements"); return; } - /* Decide if we can do this all as one set of primitives sharing the - * same index buffer, or if we have to reset the index pointer per - * primitive. - */ - vbo_bind_arrays( ctx ); - - /* check for dirty state again */ - if (ctx->NewState) - _mesa_update_state( ctx ); + vbo_bind_arrays(ctx); min_index_ptr = (uintptr_t)indices[0]; max_index_ptr = 0; @@ -1217,14 +1191,6 @@ vbo_draw_transform_feedback(struct gl_context *ctx, GLenum mode, vbo_bind_arrays(ctx); - /* Again... because we may have changed the bitmask of per-vertex varying - * attributes. If we regenerate the fixed-function vertex program now - * we may be able to prune down the number of vertex attributes which we - * need in the shader. - */ - if (ctx->NewState) - _mesa_update_state(ctx); - /* init most fields to zero */ memset(prim, 0, sizeof(prim)); prim[0].begin = 1; @@ -1266,10 +1232,6 @@ vbo_exec_DrawTransformFeedback(GLenum mode, GLuint name) FLUSH_CURRENT(ctx, 0); - if (!_mesa_valid_to_render(ctx, "glDrawTransformFeedback")) { - return; - } - vbo_draw_transform_feedback(ctx, mode, obj, 1); } diff --git a/mesalib/src/mesa/vbo/vbo_exec_draw.c b/mesalib/src/mesa/vbo/vbo_exec_draw.c index dd5363beb..5cc6586b3 100644 --- a/mesalib/src/mesa/vbo/vbo_exec_draw.c +++ b/mesalib/src/mesa/vbo/vbo_exec_draw.c @@ -174,11 +174,12 @@ vbo_exec_bind_arrays( struct gl_context *ctx ) switch (get_program_mode(exec->ctx)) { case VP_NONE: for (attr = 0; attr < VERT_ATTRIB_FF_MAX; attr++) { - exec->vtx.inputs[attr] = &vbo->legacy_currval[attr]; + exec->vtx.inputs[attr] = &vbo->currval[VBO_ATTRIB_POS+attr]; } for (attr = 0; attr < MAT_ATTRIB_MAX; attr++) { ASSERT(VERT_ATTRIB_GENERIC(attr) < Elements(exec->vtx.inputs)); - exec->vtx.inputs[VERT_ATTRIB_GENERIC(attr)] = &vbo->mat_currval[attr]; + exec->vtx.inputs[VERT_ATTRIB_GENERIC(attr)] = + &vbo->currval[VBO_ATTRIB_MAT_FRONT_AMBIENT+attr]; } map = vbo->map_vp_none; break; @@ -189,11 +190,12 @@ vbo_exec_bind_arrays( struct gl_context *ctx ) * nor attributes greater than VERT_ATTRIB_TEX7. */ for (attr = 0; attr < VERT_ATTRIB_FF_MAX; attr++) { - exec->vtx.inputs[attr] = &vbo->legacy_currval[attr]; + exec->vtx.inputs[attr] = &vbo->currval[VBO_ATTRIB_POS+attr]; } for (attr = 0; attr < VERT_ATTRIB_GENERIC_MAX; attr++) { ASSERT(VERT_ATTRIB_GENERIC(attr) < Elements(exec->vtx.inputs)); - exec->vtx.inputs[VERT_ATTRIB_GENERIC(attr)] = &vbo->generic_currval[attr]; + exec->vtx.inputs[VERT_ATTRIB_GENERIC(attr)] = + &vbo->currval[VBO_ATTRIB_GENERIC0+attr]; } map = vbo->map_vp_arb; @@ -388,7 +390,7 @@ vbo_exec_vtx_flush(struct vbo_exec_context *exec, GLboolean keepUnmapped) if (exec->vtx.copied.nr != exec->vtx.vert_count) { struct gl_context *ctx = exec->ctx; - /* Before the update_state() as this may raise _NEW_ARRAY + /* Before the update_state() as this may raise _NEW_VARYING_VP_INPUTS * from _mesa_set_varying_vp_inputs(). */ vbo_exec_bind_arrays( ctx ); diff --git a/mesalib/src/mesa/vbo/vbo_save.c b/mesalib/src/mesa/vbo/vbo_save.c index e02706191..040c9b7a9 100644 --- a/mesalib/src/mesa/vbo/vbo_save.c +++ b/mesalib/src/mesa/vbo/vbo_save.c @@ -63,24 +63,26 @@ void vbo_save_init( struct gl_context *ctx ) struct gl_client_array *arrays = save->arrays; unsigned i; - memcpy(arrays, vbo->legacy_currval, + memcpy(arrays, &vbo->currval[VBO_ATTRIB_POS], VERT_ATTRIB_FF_MAX * sizeof(arrays[0])); for (i = 0; i < VERT_ATTRIB_FF_MAX; ++i) { struct gl_client_array *array; array = &arrays[VERT_ATTRIB_FF(i)]; array->BufferObj = NULL; _mesa_reference_buffer_object(ctx, &arrays->BufferObj, - vbo->legacy_currval[i].BufferObj); + vbo->currval[VBO_ATTRIB_POS+i].BufferObj); } - memcpy(arrays + VERT_ATTRIB_GENERIC(0), vbo->generic_currval, + memcpy(arrays + VERT_ATTRIB_GENERIC(0), + &vbo->currval[VBO_ATTRIB_GENERIC0], VERT_ATTRIB_GENERIC_MAX * sizeof(arrays[0])); + for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; ++i) { struct gl_client_array *array; array = &arrays[VERT_ATTRIB_GENERIC(i)]; array->BufferObj = NULL; _mesa_reference_buffer_object(ctx, &array->BufferObj, - vbo->generic_currval[i].BufferObj); + vbo->currval[VBO_ATTRIB_GENERIC0+i].BufferObj); } } diff --git a/mesalib/src/mesa/vbo/vbo_save_draw.c b/mesalib/src/mesa/vbo/vbo_save_draw.c index b8e1e7883..57186de64 100644 --- a/mesalib/src/mesa/vbo/vbo_save_draw.c +++ b/mesalib/src/mesa/vbo/vbo_save_draw.c @@ -147,10 +147,11 @@ static void vbo_bind_vertex_list(struct gl_context *ctx, switch (get_program_mode(ctx)) { case VP_NONE: for (attr = 0; attr < VERT_ATTRIB_FF_MAX; attr++) { - save->inputs[attr] = &vbo->legacy_currval[attr]; + save->inputs[attr] = &vbo->currval[VBO_ATTRIB_POS+attr]; } for (attr = 0; attr < MAT_ATTRIB_MAX; attr++) { - save->inputs[VERT_ATTRIB_GENERIC(attr)] = &vbo->mat_currval[attr]; + save->inputs[VERT_ATTRIB_GENERIC(attr)] = + &vbo->currval[VBO_ATTRIB_MAT_FRONT_AMBIENT+attr]; } map = vbo->map_vp_none; break; @@ -161,10 +162,11 @@ static void vbo_bind_vertex_list(struct gl_context *ctx, * nor attributes greater than VERT_ATTRIB_TEX7. */ for (attr = 0; attr < VERT_ATTRIB_FF_MAX; attr++) { - save->inputs[attr] = &vbo->legacy_currval[attr]; + save->inputs[attr] = &vbo->currval[VBO_ATTRIB_POS+attr]; } for (attr = 0; attr < VERT_ATTRIB_GENERIC_MAX; attr++) { - save->inputs[VERT_ATTRIB_GENERIC(attr)] = &vbo->generic_currval[attr]; + save->inputs[VERT_ATTRIB_GENERIC(attr)] = + &vbo->currval[VBO_ATTRIB_GENERIC0+attr]; } map = vbo->map_vp_arb; diff --git a/pixman/configure.ac b/pixman/configure.ac index 56ef10ebf..b8d59f625 100644 --- a/pixman/configure.ac +++ b/pixman/configure.ac @@ -566,7 +566,7 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ #error "IWMMXT is only available on ARM" #endif #if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5)) -#error "Need GCC >= 4.6 for IWMMXT intrinsics" +#error "Need GCC >= 4.5 for IWMMXT intrinsics" #endif #include <mmintrin.h> int main () { diff --git a/xorg-server/Xext/Makefile.am b/xorg-server/Xext/Makefile.am index cb432e00e..5929a3e49 100644 --- a/xorg-server/Xext/Makefile.am +++ b/xorg-server/Xext/Makefile.am @@ -50,7 +50,7 @@ MODULE_SRCS += $(XV_SRCS) endif # XResource extension: lets clients get data about per-client resource usage -RES_SRCS = xres.c +RES_SRCS = hashtable.c xres.c if RES MODULE_SRCS += $(RES_SRCS) endif diff --git a/xorg-server/Xext/hashtable.c b/xorg-server/Xext/hashtable.c new file mode 100644 index 000000000..2adf92e56 --- /dev/null +++ b/xorg-server/Xext/hashtable.c @@ -0,0 +1,291 @@ +#include <stdlib.h> +#include "misc.h" +#include "hashtable.h" + +/* HashResourceID */ +#include "resource.h" + +#define INITHASHSIZE 6 +#define MAXHASHSIZE 11 + +struct HashTableRec { + int keySize; + int dataSize; + + int elements; /* number of elements inserted */ + int bucketBits; /* number of buckets is 1 << bucketBits */ + struct xorg_list *buckets; /* array of bucket list heads */ + + HashFunc hash; + HashCompareFunc compare; + + pointer cdata; +}; + +typedef struct { + struct xorg_list l; + void *key; + void *data; +} BucketRec, *BucketPtr; + +HashTable +ht_create(int keySize, + int dataSize, + HashFunc hash, + HashCompareFunc compare, + pointer cdata) +{ + int c; + int numBuckets; + HashTable ht = malloc(sizeof(struct HashTableRec)); + + if (!ht) { + return NULL; + } + + ht->keySize = keySize; + ht->dataSize = dataSize; + ht->hash = hash; + ht->compare = compare; + ht->elements = 0; + ht->bucketBits = INITHASHSIZE; + numBuckets = 1 << ht->bucketBits; + ht->buckets = malloc(numBuckets * sizeof(*ht->buckets)); + ht->cdata = cdata; + + if (ht->buckets) { + for (c = 0; c < numBuckets; ++c) { + xorg_list_init(&ht->buckets[c]); + } + return ht; + } else { + free(ht); + return NULL; + } +} + +void +ht_destroy(HashTable ht) +{ + int c; + BucketPtr it, tmp; + int numBuckets = 1 << ht->bucketBits; + for (c = 0; c < numBuckets; ++c) { + xorg_list_for_each_entry_safe(it, tmp, &ht->buckets[c], l) { + xorg_list_del(&it->l); + free(it); + } + } + free(ht->buckets); +} + +static Bool +double_size(HashTable ht) +{ + struct xorg_list *newBuckets; + int numBuckets = 1 << ht->bucketBits; + int newBucketBits = ht->bucketBits + 1; + int newNumBuckets = 1 << newBucketBits; + int c; + + newBuckets = malloc(newNumBuckets * sizeof(*ht->buckets)); + if (newBuckets) { + for (c = 0; c < newNumBuckets; ++c) { + xorg_list_init(&newBuckets[c]); + } + + for (c = 0; c < numBuckets; ++c) { + BucketPtr it, tmp; + xorg_list_for_each_entry_safe(it, tmp, &ht->buckets[c], l) { + struct xorg_list *newBucket = + &newBuckets[ht->hash(ht->cdata, it->key, newBucketBits)]; + xorg_list_del(&it->l); + xorg_list_add(&it->l, newBucket); + } + } + free(ht->buckets); + + ht->buckets = newBuckets; + ht->bucketBits = newBucketBits; + return TRUE; + } else { + return FALSE; + } +} + +pointer +ht_add(HashTable ht, pointer key) +{ + unsigned index = ht->hash(ht->cdata, key, ht->bucketBits); + struct xorg_list *bucket = &ht->buckets[index]; + BucketRec *elem = calloc(1, sizeof(BucketRec)); + if (!elem) { + goto outOfMemory; + } + elem->key = malloc(ht->keySize); + if (!elem->key) { + goto outOfMemory; + } + /* we avoid signaling an out-of-memory error if dataSize is 0 */ + elem->data = calloc(1, ht->dataSize); + if (ht->dataSize && !elem->data) { + goto outOfMemory; + } + xorg_list_add(&elem->l, bucket); + ++ht->elements; + + memcpy(elem->key, key, ht->keySize); + + if (ht->elements > 4 * (1 << ht->bucketBits) && + ht->bucketBits < MAXHASHSIZE) { + if (!double_size(ht)) { + --ht->elements; + xorg_list_del(&elem->l); + goto outOfMemory; + } + } + + /* if memory allocation has failed due to dataSize being 0, return + a "dummy" pointer pointing at the of the key */ + return elem->data ? elem->data : ((char*) elem->key + ht->keySize); + + outOfMemory: + if (elem) { + free(elem->key); + free(elem->data); + free(elem); + } + + return NULL; +} + +void +ht_remove(HashTable ht, pointer key) +{ + unsigned index = ht->hash(ht->cdata, key, ht->bucketBits); + struct xorg_list *bucket = &ht->buckets[index]; + BucketPtr it; + + xorg_list_for_each_entry(it, bucket, l) { + if (ht->compare(ht->cdata, key, it->key) == 0) { + xorg_list_del(&it->l); + --ht->elements; + free(it->key); + free(it->data); + free(it); + return; + } + } +} + +pointer +ht_find(HashTable ht, pointer key) +{ + unsigned index = ht->hash(ht->cdata, key, ht->bucketBits); + struct xorg_list *bucket = &ht->buckets[index]; + BucketPtr it; + + xorg_list_for_each_entry(it, bucket, l) { + if (ht->compare(ht->cdata, key, it->key) == 0) { + return it->data ? it->data : ((char*) it->key + ht->keySize); + } + } + + return NULL; +} + +void +ht_dump_distribution(HashTable ht) +{ + int c; + int numBuckets = 1 << ht->bucketBits; + for (c = 0; c < numBuckets; ++c) { + BucketPtr it; + int n = 0; + + xorg_list_for_each_entry(it, &ht->buckets[c], l) { + ++n; + } + printf("%d: %d\n", c, n); + } +} + +/* Picked the function from http://burtleburtle.net/bob/hash/doobs.html by + Bob Jenkins, which is released in public domain */ +static CARD32 +one_at_a_time_hash(const void *data, int len) +{ + CARD32 hash; + int i; + const char *key = data; + for (hash=0, i=0; i<len; ++i) { + hash += key[i]; + hash += (hash << 10); + hash ^= (hash >> 6); + } + hash += (hash << 3); + hash ^= (hash >> 11); + hash += (hash << 15); + return hash; +} + +unsigned +ht_generic_hash(void *cdata, const void *ptr, int numBits) +{ + HtGenericHashSetupPtr setup = cdata; + return one_at_a_time_hash(ptr, setup->keySize) & ~((~0) << numBits); +} + +int +ht_generic_compare(void *cdata, const void *l, const void *r) +{ + HtGenericHashSetupPtr setup = cdata; + return memcmp(l, r, setup->keySize); +} + +unsigned +ht_resourceid_hash(void * cdata, const void * data, int numBits) +{ + const XID* idPtr = data; + XID id = *idPtr & RESOURCE_ID_MASK; + (void) cdata; + return HashResourceID(id, numBits); +} + +int +ht_resourceid_compare(void* cdata, const void* a, const void* b) +{ + const XID* xa = a; + const XID* xb = b; + (void) cdata; + return + *xa < *xb ? -1 : + *xa > *xb ? 1 : + 0; +} + +void +ht_dump_contents(HashTable ht, + void (*print_key)(void *opaque, void *key), + void (*print_value)(void *opaque, void *value), + void* opaque) +{ + int c; + int numBuckets = 1 << ht->bucketBits; + for (c = 0; c < numBuckets; ++c) { + BucketPtr it; + int n = 0; + + printf("%d: ", c); + xorg_list_for_each_entry(it, &ht->buckets[c], l) { + if (n > 0) { + printf(", "); + } + print_key(opaque, it->key); + printf("->"); + print_value(opaque, it->data); + ++n; + } + printf("\n"); + } +} diff --git a/xorg-server/Xext/hashtable.h b/xorg-server/Xext/hashtable.h new file mode 100644 index 000000000..5d1598425 --- /dev/null +++ b/xorg-server/Xext/hashtable.h @@ -0,0 +1,137 @@ +#ifndef HASHTABLE_H +#define HASHTABLE_H 1 + +#include <dix-config.h> +#include <X11/Xfuncproto.h> +#include <X11/Xdefs.h> +#include "list.h" + +/** @brief A hashing function. + + @param[in/out] cdata Opaque data that can be passed to HtInit that will + eventually end up here + @param[in] ptr The data to be hashed. The size of the data, if + needed, can be configured via a record that can be + passed via cdata. + @param[in] numBits The number of bits this hash needs to have in the + resulting hash + + @return A numBits-bit hash of the data +*/ +typedef unsigned (*HashFunc)(void * cdata, const void * ptr, int numBits); + +/** @brief A comparison function for hashed keys. + + @param[in/out] cdata Opaque data that ca be passed to Htinit that will + eventually end up here + @param[in] l The left side data to be compared + @param[in] r The right side data to be compared + + @return -1 if l < r, 0 if l == r, 1 if l > r +*/ +typedef int (*HashCompareFunc)(void * cdata, const void * l, const void * r); + +struct HashTableRec; + +typedef struct HashTableRec *HashTable; + +/** @brief A configuration for HtGenericHash */ +typedef struct { + int keySize; +} HtGenericHashSetupRec, *HtGenericHashSetupPtr; + +/** @brief ht_create initalizes a hash table for a certain hash table + configuration + + @param[out] ht The hash table structure to initialize + @param[in] keySize The key size in bytes + @param[in] dataSize The data size in bytes + @param[in] hash The hash function to use for hashing keys + @param[in] compare The comparison function for hashing keys + @param[in] cdata Opaque data that will be passed to hash and + comparison functions +*/ +extern _X_EXPORT HashTable ht_create(int keySize, + int dataSize, + HashFunc hash, + HashCompareFunc compare, + pointer cdata); +/** @brief HtDestruct deinitializes the structure. It does not free the + memory allocated to HashTableRec +*/ +extern _X_EXPORT void ht_destroy(HashTable ht); + +/** @brief Adds a new key to the hash table. The key will be copied + and a pointer to the value will be returned. The data will + be initialized with zeroes. + + @param[in/out] ht The hash table + @param[key] key The key. The contents of the key will be copied. + + @return On error NULL is returned, otherwise a pointer to the data + associated with the newly inserted key. + + @note If dataSize is 0, a pointer to the end of the key may be returned + to avoid returning NULL. Obviously the data pointed cannot be + modified, as implied by dataSize being 0. +*/ +extern _X_EXPORT pointer ht_add(HashTable ht, pointer key); + +/** @brief Removes a key from the hash table along with its + associated data, which will be free'd. +*/ +extern _X_EXPORT void ht_remove(HashTable ht, pointer key); + +/** @brief Finds the associated data of a key from the hash table. + + @return If the key cannot be found, the function returns NULL. + Otherwise it returns a pointer to the data associated + with the key. + + @note If dataSize == 0, this function may return NULL + even if the key has been inserted! If dataSize == NULL, + use HtMember instead to determine if a key has been + inserted. +*/ +extern _X_EXPORT pointer ht_find(HashTable ht, pointer key); + +/** @brief A generic hash function */ +extern _X_EXPORT unsigned ht_generic_hash(void *cdata, + const void *ptr, + int numBits); + +/** @brief A generic comparison function. It compares data byte-wise. */ +extern _X_EXPORT int ht_generic_compare(void *cdata, + const void *l, + const void *r); + +/** @brief A debugging function that dumps the distribution of the + hash table: for each bucket, list the number of elements + contained within. */ +extern _X_EXPORT void ht_dump_distribution(HashTable ht); + +/** @brief A debugging function that dumps the contents of the hash + table: for each bucket, list the elements contained + within. */ +extern _X_EXPORT void ht_dump_contents(HashTable ht, + void (*print_key)(void *opaque, void *key), + void (*print_value)(void *opaque, void *value), + void* opaque); + +/** @brief A hashing function to be used for hashing resource IDs when + used with HashTables. It makes no use of cdata, so that can + be NULL. It uses HashXID underneath, and should HashXID be + unable to hash the value, it switches into using the generic + hash function. */ +extern _X_EXPORT unsigned ht_resourceid_hash(void *cdata, + const void * data, + int numBits); + +/** @brief A comparison function to be used for comparing resource + IDs when used with HashTables. It makes no use of cdata, + so that can be NULL. */ +extern _X_EXPORT int ht_resourceid_compare(void *cdata, + const void *a, + const void *b); + +#endif // HASHTABLE_H diff --git a/xorg-server/Xext/xres.c b/xorg-server/Xext/xres.c index 9d89b6550..ecef0c032 100644 --- a/xorg-server/Xext/xres.c +++ b/xorg-server/Xext/xres.c @@ -10,6 +10,7 @@ #include <string.h> #include <X11/X.h> #include <X11/Xproto.h> +#include <assert.h> #include "misc.h" #include "os.h" #include "dixstruct.h" @@ -22,6 +23,169 @@ #include "gcstruct.h" #include "modinit.h" #include "protocol-versions.h" +#include "client.h" +#include "list.h" +#include "misc.h" +#include <string.h> +#include "hashtable.h" +#include "picturestr.h" +#include "compint.h" + +/** @brief Holds fragments of responses for ConstructClientIds. + * + * note: there is no consideration for data alignment */ +typedef struct { + struct xorg_list l; + int bytes; + /* data follows */ +} FragmentList; + +#define FRAGMENT_DATA(ptr) ((void*) ((char*) (ptr) + sizeof(FragmentList))) + +/** @brief Holds structure for the generated response to + ProcXResQueryClientIds; used by ConstructClientId* -functions */ +typedef struct { + int numIds; + int resultBytes; + struct xorg_list response; + int sentClientMasks[MAXCLIENTS]; +} ConstructClientIdCtx; + +/** @brief Holds the structure for information required to + generate the response to XResQueryResourceBytes. In addition + to response it contains information on the query as well, + as well as some volatile information required by a few + functions that cannot take that information directly + via a parameter, as they are called via already-existing + higher order functions. */ +typedef struct { + ClientPtr sendClient; + int numSizes; + int resultBytes; + struct xorg_list response; + int status; + long numSpecs; + xXResResourceIdSpec *specs; + HashTable visitedResources; + + /* Used by AddSubResourceSizeSpec when AddResourceSizeValue is + handling crossreferences */ + HashTable visitedSubResources; + + /* used when ConstructResourceBytesCtx is passed to + AddResourceSizeValue2 via FindClientResourcesByType */ + RESTYPE resType; + + /* used when ConstructResourceBytesCtx is passed to + AddResourceSizeValueByResource from ConstructResourceBytesByResource */ + xXResResourceIdSpec *curSpec; + + /** Used when iterating through a single resource's subresources + + @see AddSubResourceSizeSpec */ + xXResResourceSizeValue *sizeValue; +} ConstructResourceBytesCtx; + +/** @brief Allocate and add a sequence of bytes at the end of a fragment list. + Call DestroyFragments to release the list. + + @param frags A pointer to head of an initialized linked list + @param bytes Number of bytes to allocate + @return Returns a pointer to the allocated non-zeroed region + that is to be filled by the caller. On error (out of memory) + returns NULL and makes no changes to the list. +*/ +static void * +AddFragment(struct xorg_list *frags, int bytes) +{ + FragmentList *f = malloc(sizeof(FragmentList) + bytes); + if (!f) { + return NULL; + } else { + f->bytes = bytes; + xorg_list_add(&f->l, frags->prev); + return (char*) f + sizeof(*f); + } +} + +/** @brief Sends all fragments in the list to the client. Does not + free anything. + + @param client The client to send the fragments to + @param frags The head of the list of fragments +*/ +static void +WriteFragmentsToClient(ClientPtr client, struct xorg_list *frags) +{ + FragmentList *it; + xorg_list_for_each_entry(it, frags, l) { + WriteToClient(client, it->bytes, (char*) it + sizeof(*it)); + } +} + +/** @brief Frees a list of fragments. Does not free() root node. + + @param frags The head of the list of fragments +*/ +static void +DestroyFragments(struct xorg_list *frags) +{ + FragmentList *it, *tmp; + xorg_list_for_each_entry_safe(it, tmp, frags, l) { + xorg_list_del(&it->l); + free(it); + } +} + +/** @brief Constructs a context record for ConstructClientId* functions + to use */ +static void +InitConstructClientIdCtx(ConstructClientIdCtx *ctx) +{ + ctx->numIds = 0; + ctx->resultBytes = 0; + xorg_list_init(&ctx->response); + memset(ctx->sentClientMasks, 0, sizeof(ctx->sentClientMasks)); +} + +/** @brief Destroys a context record, releases all memory (except the storage + for *ctx itself) */ +static void +DestroyConstructClientIdCtx(ConstructClientIdCtx *ctx) +{ + DestroyFragments(&ctx->response); +} + +static Bool +InitConstructResourceBytesCtx(ConstructResourceBytesCtx *ctx, + ClientPtr sendClient, + long numSpecs, + xXResResourceIdSpec *specs) +{ + ctx->sendClient = sendClient; + ctx->numSizes = 0; + ctx->resultBytes = 0; + xorg_list_init(&ctx->response); + ctx->status = Success; + ctx->numSpecs = numSpecs; + ctx->specs = specs; + ctx->visitedResources = ht_create(sizeof(XID), 0, + ht_resourceid_hash, ht_resourceid_compare, + NULL); + + if (!ctx->visitedResources) { + return FALSE; + } else { + return TRUE; + } +} + +static void +DestroyConstructResourceBytesCtx(ConstructResourceBytesCtx *ctx) +{ + DestroyFragments(&ctx->response); + ht_destroy(ctx->visitedResources); +} static int ProcXResQueryVersion(ClientPtr client) @@ -195,6 +359,17 @@ ResGetApproxPixmapBytes(PixmapPtr pix) } static void +ResFindResourcePixmaps(pointer value, XID id, RESTYPE type, pointer cdata) +{ + SizeType sizeFunc = GetResourceTypeSizeFunc(type); + ResourceSizeRec size = { 0, 0, 0 }; + unsigned long *bytes = cdata; + + sizeFunc(value, id, &size); + *bytes += size.pixmapRefSize; +} + +static void ResFindPixmaps(pointer value, XID id, pointer cdata) { unsigned long *bytes = (unsigned long *) cdata; @@ -229,6 +404,22 @@ ResFindGCPixmaps(pointer value, XID id, pointer cdata) *bytes += ResGetApproxPixmapBytes(pGC->tile.pixmap); } +static void +ResFindPicturePixmaps(pointer value, XID id, pointer cdata) +{ +#ifdef RENDER + ResFindResourcePixmaps(value, id, PictureType, cdata); +#endif +} + +static void +ResFindCompositeClientWindowPixmaps (pointer value, XID id, pointer cdata) +{ +#ifdef COMPOSITE + ResFindResourcePixmaps(value, id, CompositeClientWindowType, cdata); +#endif +} + static int ProcXResQueryClientPixmapBytes(ClientPtr client) { @@ -263,8 +454,18 @@ ProcXResQueryClientPixmapBytes(ClientPtr client) FindClientResourcesByType(clients[clientID], RT_GC, ResFindGCPixmaps, (pointer) (&bytes)); +#ifdef RENDER + /* Render extension picture pixmaps. */ + FindClientResourcesByType(clients[clientID], PictureType, + ResFindPicturePixmaps, + (pointer)(&bytes)); +#endif + #ifdef COMPOSITE - /* FIXME: include composite pixmaps too */ + /* Composite extension client window pixmaps. */ + FindClientResourcesByType(clients[clientID], CompositeClientWindowType, + ResFindCompositeClientWindowPixmaps, + (pointer)(&bytes)); #endif rep.type = X_Reply; @@ -288,6 +489,584 @@ ProcXResQueryClientPixmapBytes(ClientPtr client) return Success; } +/** @brief Finds out if a client's information need to be put into the + response; marks client having been handled, if that is the case. + + @param client The client to send information about + @param mask The request mask (0 to send everything, otherwise a + bitmask of X_XRes*Mask) + @param ctx The context record that tells which clients and id types + have been already handled + @param sendMask Which id type are we now considering. One of X_XRes*Mask. + + @return Returns TRUE if the client information needs to be on the + response, otherwise FALSE. +*/ +static Bool +WillConstructMask(ClientPtr client, CARD32 mask, + ConstructClientIdCtx *ctx, int sendMask) +{ + if ((!mask || (mask & sendMask)) + && !(ctx->sentClientMasks[client->index] & sendMask)) { + ctx->sentClientMasks[client->index] |= sendMask; + return TRUE; + } else { + return FALSE; + } +} + +/** @brief Constructs a response about a single client, based on a certain + client id spec + + @param sendClient Which client wishes to receive this answer. Used for + byte endianess. + @param client Which client are we considering. + @param mask The client id spec mask indicating which information + we want about this client. + @param ctx The context record containing the constructed response + and information on which clients and masks have been + already handled. + + @return Return TRUE if everything went OK, otherwise FALSE which indicates + a memory allocation problem. +*/ +static Bool +ConstructClientIdValue(ClientPtr sendClient, ClientPtr client, CARD32 mask, + ConstructClientIdCtx *ctx) +{ + xXResClientIdValue rep; + + rep.spec.client = client->clientAsMask; + if (client->swapped) { + swapl (&rep.spec.client); + } + + if (WillConstructMask(client, mask, ctx, X_XResClientXIDMask)) { + void *ptr = AddFragment(&ctx->response, sizeof(rep)); + if (!ptr) { + return FALSE; + } + + rep.spec.mask = X_XResClientXIDMask; + rep.length = 0; + if (sendClient->swapped) { + swapl (&rep.spec.mask); + /* swapl (&rep.length, n); - not required for rep.length = 0 */ + } + + memcpy(ptr, &rep, sizeof(rep)); + + ctx->resultBytes += sizeof(rep); + ++ctx->numIds; + } + if (WillConstructMask(client, mask, ctx, X_XResLocalClientPIDMask)) { + pid_t pid = GetClientPid(client); + + if (pid != -1) { + void *ptr = AddFragment(&ctx->response, + sizeof(rep) + sizeof(CARD32)); + CARD32 *value = (void*) ((char*) ptr + sizeof(rep)); + + if (!ptr) { + return FALSE; + } + + rep.spec.mask = X_XResLocalClientPIDMask; + rep.length = 4; + + if (sendClient->swapped) { + swapl (&rep.spec.mask); + swapl (&rep.length); + } + + if (sendClient->swapped) { + swapl (value); + } + memcpy(ptr, &rep, sizeof(rep)); + *value = pid; + + ctx->resultBytes += sizeof(rep) + sizeof(CARD32); + ++ctx->numIds; + } + } + + /* memory allocation errors earlier may return with FALSE */ + return TRUE; +} + +/** @brief Constructs a response about all clients, based on a client id specs + + @param client Which client which we are constructing the response for. + @param numSpecs Number of client id specs in specs + @param specs Client id specs + + @return Return Success if everything went OK, otherwise a Bad* (currently + BadAlloc or BadValue) +*/ +static int +ConstructClientIds(ClientPtr client, + int numSpecs, xXResClientIdSpec* specs, + ConstructClientIdCtx *ctx) +{ + int specIdx; + + for (specIdx = 0; specIdx < numSpecs; ++specIdx) { + if (specs[specIdx].client == 0) { + int c; + for (c = 0; c < currentMaxClients; ++c) { + if (clients[c]) { + if (!ConstructClientIdValue(client, clients[c], + specs[specIdx].mask, ctx)) { + return BadAlloc; + } + } + } + } else { + int clientID = CLIENT_ID(specs[specIdx].client); + + if ((clientID < currentMaxClients) && clients[clientID]) { + if (!ConstructClientIdValue(client, clients[clientID], + specs[specIdx].mask, ctx)) { + return BadAlloc; + } + } + } + } + + /* memory allocation errors earlier may return with BadAlloc */ + return Success; +} + +/** @brief Response to XResQueryClientIds request introduced in XResProto v1.2 + + @param client Which client which we are constructing the response for. + + @return Returns the value returned from ConstructClientIds with the same + semantics +*/ +static int +ProcXResQueryClientIds (ClientPtr client) +{ + REQUEST(xXResQueryClientIdsReq); + + xXResQueryClientIdsReply rep; + xXResClientIdSpec *specs = (void*) ((char*) stuff + sizeof(*stuff)); + int rc; + ConstructClientIdCtx ctx; + + InitConstructClientIdCtx(&ctx); + + REQUEST_AT_LEAST_SIZE(xXResQueryClientIdsReq); + REQUEST_FIXED_SIZE(xXResQueryClientIdsReq, + stuff->numSpecs * sizeof(specs[0])); + + rc = ConstructClientIds(client, stuff->numSpecs, specs, &ctx); + + if (rc == Success) { + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + + assert((ctx.resultBytes & 3) == 0); + rep.length = bytes_to_int32(ctx.resultBytes); + rep.numIds = ctx.numIds; + + if (client->swapped) { + swaps (&rep.sequenceNumber); + swapl (&rep.length); + swapl (&rep.numIds); + } + + WriteToClient(client,sizeof(rep),(char*)&rep); + WriteFragmentsToClient(client, &ctx.response); + } + + DestroyConstructClientIdCtx(&ctx); + + return rc; +} + +/** @brief Swaps xXResResourceIdSpec endianess */ +static void +SwapXResResourceIdSpec(xXResResourceIdSpec *spec) +{ + swapl(&spec->resource); + swapl(&spec->type); +} + +/** @brief Swaps xXResResourceSizeSpec endianess */ +static void +SwapXResResourceSizeSpec(xXResResourceSizeSpec *size) +{ + SwapXResResourceIdSpec(&size->spec); + swapl(&size->bytes); + swapl(&size->refCount); + swapl(&size->useCount); +} + +/** @brief Swaps xXResResourceSizeValue endianess */ +static void +SwapXResResourceSizeValue(xXResResourceSizeValue *rep) +{ + SwapXResResourceSizeSpec(&rep->size); + swapl(&rep->numCrossReferences); +} + +/** @brief Swaps the response bytes */ +static void +SwapXResQueryResourceBytes(struct xorg_list *response) +{ + struct xorg_list *it = response->next; + int c; + + while (it != response) { + xXResResourceSizeValue *value = FRAGMENT_DATA(it); + it = it->next; + for (c = 0; c < value->numCrossReferences; ++c) { + xXResResourceSizeSpec *spec = FRAGMENT_DATA(it); + SwapXResResourceSizeSpec(spec); + it = it->next; + } + SwapXResResourceSizeValue(value); + } +} + +/** @brief Adds xXResResourceSizeSpec describing a resource's size into + the buffer contained in the context. The resource is considered + to be a subresource. + + @see AddResourceSizeValue + + @param[in] value The X resource object on which to add information + about to the buffer + @param[in] id The ID of the X resource + @param[in] type The type of the X resource + @param[in/out] cdata The context object of type ConstructResourceBytesCtx. + Void pointer type is used here to satisfy the type + FindRes +*/ +static void +AddSubResourceSizeSpec(pointer value, + XID id, + RESTYPE type, + pointer cdata) +{ + ConstructResourceBytesCtx *ctx = cdata; + + if (ctx->status == Success) { + xXResResourceSizeSpec **prevCrossRef = + ht_find(ctx->visitedSubResources, &value); + if (!prevCrossRef) { + Bool ok = TRUE; + xXResResourceSizeSpec *crossRef = + AddFragment(&ctx->response, sizeof(xXResResourceSizeSpec)); + ok = ok && crossRef != NULL; + if (ok) { + xXResResourceSizeSpec **p; + p = ht_add(ctx->visitedSubResources, &value); + if (!p) { + ok = FALSE; + } else { + *p = crossRef; + } + } + if (!ok) { + ctx->status = BadAlloc; + } else { + SizeType sizeFunc = GetResourceTypeSizeFunc(type); + ResourceSizeRec size = { 0, 0, 0 }; + sizeFunc(value, id, &size); + + crossRef->spec.resource = id; + crossRef->spec.type = type; + crossRef->bytes = size.resourceSize; + crossRef->refCount = size.refCnt; + crossRef->useCount = 1; + + ++ctx->sizeValue->numCrossReferences; + + ctx->resultBytes += sizeof(*crossRef); + } + } else { + /* if we have visited the subresource earlier (from current parent + resource), just increase its use count by one */ + ++(*prevCrossRef)->useCount; + } + } +} + +/** @brief Adds xXResResourceSizeValue describing a resource's size into + the buffer contained in the context. In addition, the + subresources are iterated and added as xXResResourceSizeSpec's + by using AddSubResourceSizeSpec + + @see AddSubResourceSizeSpec + + @param[in] value The X resource object on which to add information + about to the buffer + @param[in] id The ID of the X resource + @param[in] type The type of the X resource + @param[in/out] cdata The context object of type ConstructResourceBytesCtx. + Void pointer type is used here to satisfy the type + FindRes +*/ +static void +AddResourceSizeValue(pointer ptr, XID id, RESTYPE type, pointer cdata) +{ + ConstructResourceBytesCtx *ctx = cdata; + if (ctx->status == Success && + !ht_find(ctx->visitedResources, &id)) { + Bool ok = TRUE; + HashTable ht; + HtGenericHashSetupRec htSetup = { + .keySize = sizeof(void*) + }; + + /* it doesn't matter that we don't undo the work done here + * immediately. All but ht_init will be undone at the end + * of the request and there can happen no failure after + * ht_init, so we don't need to clean it up here in any + * special way */ + + xXResResourceSizeValue *value = + AddFragment(&ctx->response, sizeof(xXResResourceSizeValue)); + if (!value) { + ok = FALSE; + } + ok = ok && ht_add(ctx->visitedResources, &id); + if (ok) { + ht = ht_create(htSetup.keySize, + sizeof(xXResResourceSizeSpec*), + ht_generic_hash, ht_generic_compare, + &htSetup); + ok = ok && ht; + } + + if (!ok) { + ctx->status = BadAlloc; + } else { + SizeType sizeFunc = GetResourceTypeSizeFunc(type); + ResourceSizeRec size = { 0, 0, 0 }; + + sizeFunc(ptr, id, &size); + + value->size.spec.resource = id; + value->size.spec.type = type; + value->size.bytes = size.resourceSize; + value->size.refCount = size.refCnt; + value->size.useCount = 1; + value->numCrossReferences = 0; + + ctx->sizeValue = value; + ctx->visitedSubResources = ht; + FindSubResources(ptr, type, AddSubResourceSizeSpec, ctx); + ctx->visitedSubResources = NULL; + ctx->sizeValue = NULL; + + ctx->resultBytes += sizeof(*value); + ++ctx->numSizes; + + ht_destroy(ht); + } + } +} + +/** @brief A variant of AddResourceSizeValue that passes the resource type + through the context object to satisfy the type FindResType + + @see AddResourceSizeValue + + @param[in] ptr The resource + @param[in] id The resource ID + @param[in/out] cdata The context object that contains the resource type +*/ +static void +AddResourceSizeValueWithResType(pointer ptr, XID id, pointer cdata) +{ + ConstructResourceBytesCtx *ctx = cdata; + AddResourceSizeValue(ptr, id, ctx->resType, cdata); +} + +/** @brief Adds the information of a resource into the buffer if it matches + the match condition. + + @see AddResourceSizeValue + + @param[in] ptr The resource + @param[in] id The resource ID + @param[in] type The resource type + @param[in/out] cdata The context object as a void pointer to satisfy the + type FindAllRes +*/ +static void +AddResourceSizeValueByResource(pointer ptr, XID id, RESTYPE type, pointer cdata) +{ + ConstructResourceBytesCtx *ctx = cdata; + xXResResourceIdSpec *spec = ctx->curSpec; + + if ((!spec->type || spec->type == type) && + (!spec->resource || spec->resource == id)) { + AddResourceSizeValue(ptr, id, type, ctx); + } +} + +/** @brief Add all resources of the client into the result buffer + disregarding all those specifications that specify the + resource by its ID. Those are handled by + ConstructResourceBytesByResource + + @see ConstructResourceBytesByResource + + @param[in] aboutClient Which client is being considered + @param[in/out] ctx The context that contains the resource id + specifications as well as the result buffer +*/ +static void +ConstructClientResourceBytes(ClientPtr aboutClient, + ConstructResourceBytesCtx *ctx) +{ + int specIdx; + for (specIdx = 0; specIdx < ctx->numSpecs; ++specIdx) { + xXResResourceIdSpec* spec = ctx->specs + specIdx; + if (spec->resource) { + /* these specs are handled elsewhere */ + } else if (spec->type) { + ctx->resType = spec->type; + FindClientResourcesByType(aboutClient, spec->type, + AddResourceSizeValueWithResType, ctx); + } else { + FindAllClientResources(aboutClient, AddResourceSizeValue, ctx); + } + } +} + +/** @brief Add the sizes of all such resources that can are specified by + their ID in the resource id specification. The scan can + by limited to a client with the aboutClient parameter + + @see ConstructResourceBytesByResource + + @param[in] aboutClient Which client is being considered. This may be None + to mean all clients. + @param[in/out] ctx The context that contains the resource id + specifications as well as the result buffer. In + addition this function uses the curSpec field to + keep a pointer to the current resource id + specification in it, which can be used by + AddResourceSizeValueByResource . +*/ +static void +ConstructResourceBytesByResource(XID aboutClient, ConstructResourceBytesCtx *ctx) +{ + int specIdx; + for (specIdx = 0; specIdx < ctx->numSpecs; ++specIdx) { + xXResResourceIdSpec *spec = ctx->specs + specIdx; + if (spec->resource) { + int cid = CLIENT_ID(spec->resource); + if (cid < currentMaxClients && + (aboutClient == None || cid == aboutClient)) { + ClientPtr client = clients[cid]; + if (client) { + ctx->curSpec = spec; + FindAllClientResources(client, + AddResourceSizeValueByResource, + ctx); + } + } + } + } +} + +/** @brief Build the resource size response for the given client + (or all if not specified) per the parameters set up + in the context object. + + @param[in] aboutClient Which client to consider or None for all clients + @param[in/out] ctx The context object that contains the request as well + as the response buffer. +*/ +static int +ConstructResourceBytes(XID aboutClient, + ConstructResourceBytesCtx *ctx) +{ + if (aboutClient) { + int clientIdx = CLIENT_ID(aboutClient); + ClientPtr client = NullClient; + + if ((clientIdx >= currentMaxClients) || !clients[clientIdx]) { + ctx->sendClient->errorValue = aboutClient; + return BadValue; + } + + client = clients[clientIdx]; + + ConstructClientResourceBytes(client, ctx); + ConstructResourceBytesByResource(aboutClient, ctx); + } else { + int clientIdx; + + ConstructClientResourceBytes(NULL, ctx); + + for (clientIdx = 0; clientIdx < currentMaxClients; ++clientIdx) { + ClientPtr client = clients[clientIdx]; + + if (client) { + ConstructClientResourceBytes(client, ctx); + } + } + + ConstructResourceBytesByResource(None, ctx); + } + + + return ctx->status; +} + +/** @brief Implements the XResQueryResourceBytes of XResProto v1.2 */ +static int +ProcXResQueryResourceBytes (ClientPtr client) +{ + REQUEST(xXResQueryResourceBytesReq); + + xXResQueryResourceBytesReply rep; + int rc; + ConstructResourceBytesCtx ctx; + + REQUEST_AT_LEAST_SIZE(xXResQueryResourceBytesReq); + REQUEST_FIXED_SIZE(xXResQueryResourceBytesReq, + stuff->numSpecs * sizeof(ctx.specs[0])); + + if (!InitConstructResourceBytesCtx(&ctx, client, + stuff->numSpecs, + (void*) ((char*) stuff + + sz_xXResQueryResourceBytesReq))) { + return BadAlloc; + } + + rc = ConstructResourceBytes(stuff->client, &ctx); + + if (rc == Success) { + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.numSizes = ctx.numSizes; + rep.length = bytes_to_int32(ctx.resultBytes); + + if (client->swapped) { + swaps (&rep.sequenceNumber); + swapl (&rep.length); + swapl (&rep.numSizes); + + SwapXResQueryResourceBytes(&ctx.response); + } + + WriteToClient(client,sizeof(rep),(char*)&rep); + WriteFragmentsToClient(client, &ctx.response); + } + + DestroyConstructResourceBytesCtx(&ctx); + + return rc; +} + static int ProcResDispatch(ClientPtr client) { @@ -301,8 +1080,11 @@ ProcResDispatch(ClientPtr client) return ProcXResQueryClientResources(client); case X_XResQueryClientPixmapBytes: return ProcXResQueryClientPixmapBytes(client); - default: - break; + case X_XResQueryClientIds: + return ProcXResQueryClientIds(client); + case X_XResQueryResourceBytes: + return ProcXResQueryResourceBytes(client); + default: break; } return BadRequest; @@ -335,7 +1117,39 @@ SProcXResQueryClientPixmapBytes(ClientPtr client) } static int -SProcResDispatch(ClientPtr client) +SProcXResQueryClientIds (ClientPtr client) +{ + REQUEST(xXResQueryClientIdsReq); + + REQUEST_AT_LEAST_SIZE (xXResQueryClientIdsReq); + swapl(&stuff->numSpecs); + return ProcXResQueryClientIds(client); +} + +/** @brief Implements the XResQueryResourceBytes of XResProto v1.2. + This variant byteswaps request contents before issuing the + rest of the work to ProcXResQueryResourceBytes */ +static int +SProcXResQueryResourceBytes (ClientPtr client) +{ + REQUEST(xXResQueryResourceBytesReq); + int c; + xXResResourceIdSpec *specs = (void*) ((char*) stuff + sizeof(*stuff)); + + swapl(&stuff->numSpecs); + REQUEST_AT_LEAST_SIZE(xXResQueryResourceBytesReq); + REQUEST_FIXED_SIZE(xXResQueryResourceBytesReq, + stuff->numSpecs * sizeof(specs[0])); + + for (c = 0; c < stuff->numSpecs; ++c) { + SwapXResResourceIdSpec(specs + c); + } + + return ProcXResQueryResourceBytes(client); +} + +static int +SProcResDispatch (ClientPtr client) { REQUEST(xReq); swaps(&stuff->length); @@ -349,8 +1163,11 @@ SProcResDispatch(ClientPtr client) return SProcXResQueryClientResources(client); case X_XResQueryClientPixmapBytes: return SProcXResQueryClientPixmapBytes(client); - default: - break; + case X_XResQueryClientIds: + return SProcXResQueryClientIds(client); + case X_XResQueryResourceBytes: + return SProcXResQueryResourceBytes(client); + default: break; } return BadRequest; diff --git a/xorg-server/Xi/exevents.c b/xorg-server/Xi/exevents.c index d6575c597..f11e09f38 100644 --- a/xorg-server/Xi/exevents.c +++ b/xorg-server/Xi/exevents.c @@ -1236,14 +1236,6 @@ TouchRejected(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, XID resource, } } - /* If there are no other listeners left, and the touchpoint is pending - * finish, then we can just kill it now. */ - if (ti->num_listeners == 1 && ti->pending_finish) { - TouchEndTouch(sourcedev, ti); - CheckOldestTouch(sourcedev); - return; - } - /* Remove the resource from the listener list, updating * ti->num_listeners, as well as ti->num_grabs if it was a grab. */ if (TouchRemoveListener(ti, resource)) { @@ -1256,6 +1248,8 @@ TouchRejected(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, XID resource, * the TouchOwnership or TouchBegin event to the new owner. */ if (ev && ti->num_listeners > 0 && was_owner) TouchPuntToNextOwner(sourcedev, ti, ev); + else if (ti->num_listeners == 0) + TouchEndTouch(sourcedev, ti); CheckOldestTouch(sourcedev); } @@ -1275,9 +1269,18 @@ ProcessTouchOwnershipEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, if (ev->reason == XIRejectTouch) TouchRejected(dev, ti, ev->resource, ev); else if (ev->reason == XIAcceptTouch) { + int i; + + /* Go through the motions of ending the touch if the listener has + * already seen the end. This ensures that the touch record is ended in + * the server. */ + if (ti->listeners[0].state == LISTENER_HAS_END) + EmitTouchEnd(dev, ti, TOUCH_ACCEPT, ti->listeners[0].listener); + /* The touch owner has accepted the touch. Send TouchEnd events to * everyone else, and truncate the list of listeners. */ - EmitTouchEnd(dev, ti, TOUCH_ACCEPT, 0); + for (i = 1; i < ti->num_listeners; i++) + EmitTouchEnd(dev, ti, TOUCH_ACCEPT, ti->listeners[i].listener); while (ti->num_listeners > 1) TouchRemoveListener(ti, ti->listeners[1].listener); @@ -1329,6 +1332,7 @@ RetrieveTouchDeliveryData(DeviceIntPtr dev, TouchPointInfoPtr ti, { int rc; InputClients *iclients = NULL; + *mask = NULL; if (listener->type == LISTENER_GRAB || listener->type == LISTENER_POINTER_GRAB) { @@ -1379,6 +1383,9 @@ RetrieveTouchDeliveryData(DeviceIntPtr dev, TouchPointInfoPtr ti, BUG_WARN(!iclients); if (!iclients) return FALSE; + + *mask = iclients->xi2mask; + *client = rClient(iclients); } else if (listener->level == XI) { int xi_type = GetXIType(TouchGetPointerEventType(ev)); @@ -1391,21 +1398,24 @@ RetrieveTouchDeliveryData(DeviceIntPtr dev, TouchPointInfoPtr ti, BUG_WARN(!iclients); if (!iclients) return FALSE; + + *client = rClient(iclients); } else { int coretype = GetCoreType(TouchGetPointerEventType(ev)); Mask core_filter = event_get_filter_from_type(dev, coretype); + OtherClients *oclients; /* all others */ - nt_list_for_each_entry(iclients, - (InputClients *) wOtherClients(*win), next) - if (iclients->mask[XIAllDevices] & core_filter) - break; - /* if owner selected, iclients is NULL */ + nt_list_for_each_entry(oclients, + (OtherClients *) wOtherClients(*win), next) + if (oclients->mask & core_filter) + break; + + /* if owner selected, oclients is NULL */ + *client = oclients ? rClient(oclients) : wClient(*win); } - *client = iclients ? rClient(iclients) : wClient(*win); - *mask = iclients ? iclients->xi2mask : NULL; *grab = NULL; } @@ -1461,7 +1471,14 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, if (!deliveries) DeliverOneGrabbedEvent(ptrev, dev, grab->grabtype); + /* We must accept the touch sequence once a pointer listener has + * received one event past ButtonPress. */ + if (deliveries && ev->any.type != ET_TouchBegin && + !(ev->device_event.flags & TOUCH_CLIENT_ID)) + TouchListenerAcceptReject(dev, ti, 0, XIAcceptTouch); + if (ev->any.type == ET_TouchEnd && + !(ev->device_event.flags & TOUCH_CLIENT_ID) && !dev->button->buttonsDown && dev->deviceGrab.fromPassiveGrab && GrabIsPointerGrab(grab)) { (*dev->deviceGrab.DeactivateGrab) (dev); @@ -1582,6 +1599,9 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev) else touchid = ev->device_event.touchid; + if (emulate_pointer) + UpdateDeviceState(dev, &ev->device_event); + if (type == ET_TouchBegin) { ti = TouchBeginTouch(dev, ev->device_event.sourceid, touchid, emulate_pointer); @@ -1589,6 +1609,34 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev) else ti = TouchFindByClientID(dev, touchid); + /* Under the following circumstances we create a new touch record for an + * existing touch: + * + * - The touch may be pointer emulated + * - An explicit grab is active on the device + * - The grab is a pointer grab + * + * This allows for an explicit grab to receive pointer events for an already + * active touch. + */ + if (!ti && type != ET_TouchBegin && emulate_pointer && + dev->deviceGrab.grab && !dev->deviceGrab.fromPassiveGrab && + (dev->deviceGrab.grab->grabtype == CORE || + dev->deviceGrab.grab->grabtype == XI || + !xi2mask_isset(dev->deviceGrab.grab->xi2mask, dev, XI_TouchBegin))) { + ti = TouchBeginTouch(dev, ev->device_event.sourceid, touchid, + emulate_pointer); + if (!ti) { + DebugF("[Xi] %s: Failed to create new dix record for explicitly " + "grabbed touchpoint %d\n", + dev->name, type, touchid); + return; + } + + TouchBuildSprite(dev, ti, ev); + TouchSetupListeners(dev, ti, ev); + } + if (!ti) { DebugF("[Xi] %s: Failed to get event %d for touchpoint %d\n", dev->name, type, touchid); @@ -1604,9 +1652,11 @@ ProcessTouchEvent(InternalEvent *ev, DeviceIntPtr dev) CheckMotion(&ev->device_event, dev); /* Make sure we have a valid window trace for event delivery; must be - * called after event type mutation. */ + * called after event type mutation. Touch end events are always processed + * in order to end touch records. */ /* FIXME: check this */ - if (!TouchEnsureSprite(dev, ti, ev)) + if ((type == ET_TouchBegin && !TouchBuildSprite(dev, ti, ev)) || + (type != ET_TouchEnd && ti->sprite.spriteTraceGood == 0)) return; /* TouchOwnership events are handled separately from the rest, as they @@ -1838,7 +1888,8 @@ DeliverTouchEndEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev, if (ti->num_listeners > 1) { ev->any.type = ET_TouchUpdate; ev->device_event.flags |= TOUCH_PENDING_END; - ti->pending_finish = TRUE; + if (!(ev->device_event.flags & TOUCH_CLIENT_ID)) + ti->pending_finish = TRUE; } goto out; @@ -1952,9 +2003,6 @@ DeliverTouchEvents(DeviceIntPtr dev, TouchPointInfoPtr ti, DeliverTouchEvent(dev, ti, ev, listener, client, win, grab, mask); } - - if (ti->emulate_pointer) - UpdateDeviceState(dev, &ev->device_event); } int diff --git a/xorg-server/composite/compext.c b/xorg-server/composite/compext.c index 940eed1fc..1d4d8bf97 100644 --- a/xorg-server/composite/compext.c +++ b/xorg-server/composite/compext.c @@ -497,6 +497,28 @@ SProcCompositeDispatch(ClientPtr client) return BadRequest; } +/** @see GetDefaultBytes */ +static void +GetCompositeClientWindowBytes(pointer value, XID id, ResourceSizePtr size) +{ + WindowPtr window = value; + + /* Currently only pixmap bytes are reported to clients. */ + size->resourceSize = 0; + + /* Calculate pixmap reference sizes. */ + size->pixmapRefSize = 0; + if (window->redirectDraw != RedirectDrawNone) + { + SizeType pixmapSizeFunc = GetResourceTypeSizeFunc(RT_PIXMAP); + ResourceSizeRec pixmapSize = { 0, 0 }; + ScreenPtr screen = window->drawable.pScreen; + PixmapPtr pixmap = screen->GetWindowPixmap(window); + pixmapSizeFunc(pixmap, pixmap->drawable.id, &pixmapSize); + size->pixmapRefSize += pixmapSize.pixmapRefSize; + } +} + void CompositeExtensionInit(void) { @@ -529,6 +551,9 @@ CompositeExtensionInit(void) if (!CompositeClientWindowType) return; + SetResourceTypeSizeFunc(CompositeClientWindowType, + GetCompositeClientWindowBytes); + CompositeClientSubwindowsType = CreateNewResourceType (FreeCompositeClientSubwindows, "CompositeClientSubwindows"); if (!CompositeClientSubwindowsType) diff --git a/xorg-server/composite/compint.h b/xorg-server/composite/compint.h index 6c4272e5b..9e2713e93 100644 --- a/xorg-server/composite/compint.h +++ b/xorg-server/composite/compint.h @@ -71,6 +71,7 @@ #include "damageextint.h" #include "xfixes.h" #include <X11/extensions/compositeproto.h> +#include "compositeext.h" #include <assert.h> /* @@ -182,7 +183,6 @@ extern DevPrivateKeyRec CompSubwindowsPrivateKeyRec; #define GetCompSubwindows(w) ((CompSubwindowsPtr) \ dixLookupPrivate(&(w)->devPrivates, CompSubwindowsPrivateKey)) -extern RESTYPE CompositeClientWindowType; extern RESTYPE CompositeClientSubwindowsType; extern RESTYPE CompositeClientOverlayType; diff --git a/xorg-server/composite/compositeext.h b/xorg-server/composite/compositeext.h index 600604d8d..0b148f029 100644 --- a/xorg-server/composite/compositeext.h +++ b/xorg-server/composite/compositeext.h @@ -35,4 +35,6 @@ extern _X_EXPORT Bool CompositeRegisterAlternateVisuals(ScreenPtr pScreen, VisualID * vids, int nVisuals); +extern _X_EXPORT RESTYPE CompositeClientWindowType; + #endif /* _COMPOSITEEXT_H_ */ diff --git a/xorg-server/configure.ac b/xorg-server/configure.ac index 65d29f206..4afac8268 100644 --- a/xorg-server/configure.ac +++ b/xorg-server/configure.ac @@ -699,11 +699,21 @@ dnl DDX Detection... Yes, it's ugly to have it here... but we need to dnl handle this early on so that we don't require unsupported extensions case $host_os in cygwin*) + CONFIG_DBUS_API=no + CONFIG_HAL=no + CONFIG_UDEV=no DGA=no DRI2=no + INT10MODULE=no + PCI=no + VGAHW=no + VBE=no + XAA=no + XF86UTILS=no XF86VIDMODE=no XSELINUX=no XV=no + SYMBOL_VISIBILITY=no ;; darwin*) PCI=no @@ -759,7 +769,7 @@ VIDEOPROTO="videoproto" COMPOSITEPROTO="compositeproto >= 0.4" RECORDPROTO="recordproto >= 1.13.99.1" SCRNSAVERPROTO="scrnsaverproto >= 1.1" -RESOURCEPROTO="resourceproto" +RESOURCEPROTO="resourceproto >= 1.2.0" DRIPROTO="xf86driproto >= 2.1.0" DRI2PROTO="dri2proto >= 2.6" XINERAMAPROTO="xineramaproto" @@ -1060,6 +1070,7 @@ if test "x$GLX_USE_TLS" = xyes ; then GLX_SYS_LIBS="$GLX_SYS_LIBS -lpthread" fi AC_SUBST([GLX_DEFINES]) +AC_SUBST([GLX_SYS_LIBS]) AM_CONDITIONAL(DRI, test "x$DRI" = xyes) if test "x$DRI" = xyes; then @@ -1461,7 +1472,21 @@ AC_SUBST([UTILS_SYS_LIBS]) # Some platforms require extra flags to do this. libtool should set the # necessary flags for each platform when -export-dynamic is passed to it. LD_EXPORT_SYMBOLS_FLAG="-export-dynamic" +LD_NO_UNDEFINED_FLAG= +XORG_DRIVER_LIBS= +case "$host_os" in + cygwin*) + LD_EXPORT_SYMBOLS_FLAG="-Wl,--export-all,--out-implib,lib\$@.a" + LD_NO_UNDEFINED_FLAG="-no-undefined -Wl,\$(top_builddir)/hw/xfree86/libXorg.exe.a" + XORG_DRIVER_LIBS="-lXorg.exe -L\${moduledir} -lshadow -lfb -no-undefined" + CYGWIN=yes + ;; +esac AC_SUBST([LD_EXPORT_SYMBOLS_FLAG]) +AC_SUBST([LD_NO_UNDEFINED_FLAG]) +AC_SUBST([XORG_DRIVER_LIBS]) +AM_CONDITIONAL([CYGWIN], [test x"$CYGWIN" = xyes]) +AM_CONDITIONAL([NO_UNDEFINED], [test x"$LD_NO_UNDEFINED_FLAG" != x]) dnl Imake defines SVR4 on SVR4 systems, and many files check for it, so dnl we need to replicate that here until those can all be fixed diff --git a/xorg-server/dix/dispatch.c b/xorg-server/dix/dispatch.c index 14f1af18a..60d57a352 100644 --- a/xorg-server/dix/dispatch.c +++ b/xorg-server/dix/dispatch.c @@ -218,7 +218,7 @@ UpdateCurrentTimeIf(void) systime.milliseconds = GetTimeInMillis();
if (systime.milliseconds < currentTime.milliseconds)
systime.months++;
- if (*checkForInput[0] == *checkForInput[1])
+ if (CompareTimeStamps(systime, currentTime) == LATER)
currentTime = systime;
}
@@ -400,6 +400,9 @@ Dispatch(void) }
/* now, finally, deal with client requests */
+ /* Update currentTime so request time checks, such as for input
+ * device grabs, are calculated correctly */
+ UpdateCurrentTimeIf();
result = ReadRequestFromClient(client);
if (result <= 0) {
if (result < 0)
@@ -422,8 +425,9 @@ Dispatch(void) StartMajorOp=client->majorOp;
XSERVER_REQUEST_START(LookupMajorName(client->majorOp),
client->majorOp,
- ((xReq *)client->requestBuffer)->length,
- client->index, client->requestBuffer);
+ ((xReq *) client->requestBuffer)->length,
+ client->index,
+ client->requestBuffer);
}
#endif
if (result > (maxBigRequestSize << 2))
diff --git a/xorg-server/dix/events.c b/xorg-server/dix/events.c index 1a2126884..6d5f67586 100644 --- a/xorg-server/dix/events.c +++ b/xorg-server/dix/events.c @@ -1276,18 +1276,11 @@ ComputeFreezes(void) event->root_x, event->root_y); if (!CheckDeviceGrabs(replayDev, event, syncEvents.replayWin)) { if (IsTouchEvent((InternalEvent *) event)) { - InternalEvent *events = InitEventList(GetMaximumEventsNum()); - int i, nev; TouchPointInfoPtr ti = TouchFindByClientID(replayDev, event->touchid); BUG_WARN(!ti); - nev = - GetTouchOwnershipEvents(events, replayDev, ti, - XIRejectTouch, - ti->listeners[0].listener, 0); - for (i = 0; i < nev; i++) - mieqProcessDeviceEvent(replayDev, events + i, NULL); - ProcessInputEvents(); + + TouchListenerAcceptReject(replayDev, ti, 0, XIRejectTouch); } else if (replayDev->focus && !IsPointerEvent((InternalEvent *) event)) @@ -1419,6 +1412,38 @@ ReattachToOldMaster(DeviceIntPtr dev) } /** + * Update touch records when an explicit grab is activated. Any touches owned by + * the grabbing client are updated so the listener state reflects the new grab. + */ +static void +UpdateTouchesForGrab(DeviceIntPtr mouse) +{ + int i; + + if (!mouse->touch || mouse->deviceGrab.fromPassiveGrab) + return; + + for (i = 0; i < mouse->touch->num_touches; i++) { + TouchPointInfoPtr ti = mouse->touch->touches + i; + GrabPtr grab = mouse->deviceGrab.grab; + + if (ti->active && + CLIENT_BITS(ti->listeners[0].listener) == grab->resource) { + ti->listeners[0].listener = grab->resource; + ti->listeners[0].level = grab->grabtype; + ti->listeners[0].state = LISTENER_IS_OWNER; + ti->listeners[0].window = grab->window; + + if (grab->grabtype == CORE || grab->grabtype == XI || + !xi2mask_isset(grab->xi2mask, mouse, XI_TouchBegin)) + ti->listeners[0].type = LISTENER_POINTER_GRAB; + else + ti->listeners[0].type = LISTENER_GRAB; + } + } +} + +/** * Activate a pointer grab on the given device. A pointer grab will cause all * core pointer events of this device to be delivered to the grabbing client only. * No other device will send core events to the grab client while the grab is @@ -1467,6 +1492,7 @@ ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab, grabinfo->fromPassiveGrab = isPassive; grabinfo->implicitGrab = autoGrab & ImplicitGrabMask; PostNewCursor(mouse); + UpdateTouchesForGrab(mouse); CheckGrabForSyncs(mouse, (Bool) grab->pointerMode, (Bool) grab->keyboardMode); } @@ -1483,6 +1509,8 @@ DeactivatePointerGrab(DeviceIntPtr mouse) DeviceIntPtr dev; Bool wasImplicit = (mouse->deviceGrab.fromPassiveGrab && mouse->deviceGrab.implicitGrab); + XID grab_resource = grab->resource; + int i; TouchRemovePointerGrab(mouse); @@ -1507,6 +1535,15 @@ DeactivatePointerGrab(DeviceIntPtr mouse) ReattachToOldMaster(mouse); ComputeFreezes(); + + /* If an explicit grab was deactivated, we must remove it from the head of + * all the touches' listener lists. */ + for (i = 0; mouse->touch && i < mouse->touch->num_touches; i++) { + TouchPointInfoPtr ti = mouse->touch->touches + i; + + if (ti->active && TouchResourceIsOwner(ti, grab_resource)) + TouchListenerAcceptReject(mouse, ti, 0, XIRejectTouch); + } } /** diff --git a/xorg-server/dix/resource.c b/xorg-server/dix/resource.c index 865b5b219..1ab06d51d 100644 --- a/xorg-server/dix/resource.c +++ b/xorg-server/dix/resource.c @@ -141,6 +141,7 @@ Equipment Corporation. #include "xace.h" #include <assert.h> #include "registry.h" +#include "gcstruct.h" #ifdef XSERVER_DTRACE #include <sys/types.h> @@ -182,50 +183,313 @@ RESTYPE TypeMask; struct ResourceType { DeleteType deleteFunc; + SizeType sizeFunc; + FindTypeSubResources findSubResFunc; int errorValue; }; +/** + * Used by all resources that don't specify a function to calculate + * resource size. Currently this is used for all resources with + * insignificant memory usage. + * + * @see GetResourceTypeSizeFunc, SetResourceTypeSizeFunc + * + * @param[in] value Pointer to resource object. + * + * @param[in] id Resource ID for the object. + * + * @param[out] size Fill all fields to zero to indicate that size of + * resource can't be determined. + */ +static void +GetDefaultBytes(pointer value, XID id, ResourceSizePtr size) +{ + size->resourceSize = 0; + size->pixmapRefSize = 0; + size->refCnt = 1; +} + +/** + * Used by all resources that don't specify a function to iterate + * through subresources. Currently this is used for all resources with + * insignificant memory usage. + * + * @see FindSubResources, SetResourceTypeFindSubResFunc + * + * @param[in] value Pointer to resource object. + * + * @param[in] func Function to call for each subresource. + + * @param[out] cdata Pointer to opaque data. + */ +static void +DefaultFindSubRes(pointer value, FindAllRes func, pointer cdata) +{ + /* do nothing */ +} + +/** + * Calculate drawable size in bytes. Reference counting is not taken + * into account. + * + * @param[in] drawable Pointer to a drawable. + * + * @return Estimate of total memory usage for the drawable. + */ +static unsigned long +GetDrawableBytes(DrawablePtr drawable) +{ + int bytes = 0; + + if (drawable) + { + int bytesPerPixel = drawable->bitsPerPixel >> 3; + int numberOfPixels = drawable->width * drawable->height; + bytes = numberOfPixels * bytesPerPixel; + } + + return bytes; +} + +/** + * Calculate pixmap size in bytes. Reference counting is taken into + * account. Any extra data attached by extensions and drivers is not + * taken into account. The purpose of this function is to estimate + * memory usage that can be attributed to single reference of the + * pixmap. + * + * @param[in] value Pointer to a pixmap. + * + * @param[in] id Resource ID of pixmap. If the pixmap hasn't been + * added as resource, just pass value->drawable.id. + * + * @param[out] size Estimate of memory usage attributed to a single + * pixmap reference. + */ +static void +GetPixmapBytes(pointer value, XID id, ResourceSizePtr size) +{ + PixmapPtr pixmap = value; + + size->resourceSize = 0; + size->pixmapRefSize = 0; + size->refCnt = pixmap->refcnt; + + if (pixmap && pixmap->refcnt) + { + DrawablePtr drawable = &pixmap->drawable; + size->resourceSize = GetDrawableBytes(drawable); + size->pixmapRefSize = size->resourceSize / pixmap->refcnt; + } +} + +/** + * Calculate window size in bytes. The purpose of this function is to + * estimate memory usage that can be attributed to all pixmap + * references of the window. + * + * @param[in] value Pointer to a window. + * + * @param[in] id Resource ID of window. + * + * @param[out] size Estimate of memory usage attributed to a all + * pixmap references of a window. + */ +static void +GetWindowBytes(pointer value, XID id, ResourceSizePtr size) +{ + SizeType pixmapSizeFunc = GetResourceTypeSizeFunc(RT_PIXMAP); + ResourceSizeRec pixmapSize = { 0, 0, 0 }; + WindowPtr window = value; + + /* Currently only pixmap bytes are reported to clients. */ + size->resourceSize = 0; + + /* Calculate pixmap reference sizes. */ + size->pixmapRefSize = 0; + + size->refCnt = 1; + + if (window->backgroundState == BackgroundPixmap) + { + PixmapPtr pixmap = window->background.pixmap; + pixmapSizeFunc(pixmap, pixmap->drawable.id, &pixmapSize); + size->pixmapRefSize += pixmapSize.pixmapRefSize; + } + if (window->border.pixmap && !window->borderIsPixel) + { + PixmapPtr pixmap = window->border.pixmap; + pixmapSizeFunc(pixmap, pixmap->drawable.id, &pixmapSize); + size->pixmapRefSize += pixmapSize.pixmapRefSize; + } +} + +/** + * Iterate through subresources of a window. The purpose of this + * function is to gather accurate information on what resources + * a resource uses. + * + * @note Currently only sub-pixmaps are iterated + * + * @param[in] value Pointer to a window + * + * @param[in] func Function to call with each subresource + * + * @param[out] cdata Pointer to opaque data + */ +static void +FindWindowSubRes(pointer value, FindAllRes func, pointer cdata) +{ + WindowPtr window = value; + + /* Currently only pixmap subresources are reported to clients. */ + + if (window->backgroundState == BackgroundPixmap) + { + PixmapPtr pixmap = window->background.pixmap; + func(window->background.pixmap, pixmap->drawable.id, RT_PIXMAP, cdata); + } + if (window->border.pixmap && !window->borderIsPixel) + { + PixmapPtr pixmap = window->border.pixmap; + func(window->background.pixmap, pixmap->drawable.id, RT_PIXMAP, cdata); + } +} + +/** + * Calculate graphics context size in bytes. The purpose of this + * function is to estimate memory usage that can be attributed to all + * pixmap references of the graphics context. + * + * @param[in] value Pointer to a graphics context. + * + * @param[in] id Resource ID of graphics context. + * + * @param[out] size Estimate of memory usage attributed to a all + * pixmap references of a graphics context. + */ +static void +GetGcBytes(pointer value, XID id, ResourceSizePtr size) +{ + SizeType pixmapSizeFunc = GetResourceTypeSizeFunc(RT_PIXMAP); + ResourceSizeRec pixmapSize = { 0, 0, 0 }; + GCPtr gc = value; + + /* Currently only pixmap bytes are reported to clients. */ + size->resourceSize = 0; + + /* Calculate pixmap reference sizes. */ + size->pixmapRefSize = 0; + + size->refCnt = 1; + if (gc->stipple) + { + PixmapPtr pixmap = gc->stipple; + pixmapSizeFunc(pixmap, pixmap->drawable.id, &pixmapSize); + size->pixmapRefSize += pixmapSize.pixmapRefSize; + } + if (gc->tile.pixmap && !gc->tileIsPixel) + { + PixmapPtr pixmap = gc->tile.pixmap; + pixmapSizeFunc(pixmap, pixmap->drawable.id, &pixmapSize); + size->pixmapRefSize += pixmapSize.pixmapRefSize; + } +} + +/** + * Iterate through subresources of a graphics context. The purpose of + * this function is to gather accurate information on what resources a + * resource uses. + * + * @note Currently only sub-pixmaps are iterated + * + * @param[in] value Pointer to a window + * + * @param[in] func Function to call with each subresource + * + * @param[out] cdata Pointer to opaque data + */ +static void +FindGCSubRes(pointer value, FindAllRes func, pointer cdata) +{ + GCPtr gc = value; + + /* Currently only pixmap subresources are reported to clients. */ + + if (gc->stipple) + { + PixmapPtr pixmap = gc->stipple; + func(pixmap, pixmap->drawable.id, RT_PIXMAP, cdata); + } + if (gc->tile.pixmap && !gc->tileIsPixel) + { + PixmapPtr pixmap = gc->tile.pixmap; + func(pixmap, pixmap->drawable.id, RT_PIXMAP, cdata); + } +} + static struct ResourceType *resourceTypes; static const struct ResourceType predefTypes[] = { /* [RT_NONE & (RC_LASTPREDEF - 1)] = */ { /*.deleteFunc = */(DeleteType)NoopDDA, + /*.sizeFunc = */GetDefaultBytes, + /*.findSubResFunc = */DefaultFindSubRes, /*.errorValue = */BadValue, }, /* [RT_WINDOW & (RC_LASTPREDEF - 1)] = */ { /*.deleteFunc = */DeleteWindow, + /*.sizeFunc = */GetWindowBytes, + /*.findSubResFunc = */FindWindowSubRes, /*.errorValue = */BadWindow, }, /* [RT_PIXMAP & (RC_LASTPREDEF - 1)] = */ { /*.deleteFunc = */dixDestroyPixmap, + /*.sizeFunc = */GetPixmapBytes, + /*.findSubResFunc = */DefaultFindSubRes, /*.errorValue = */BadPixmap, }, /* [RT_GC & (RC_LASTPREDEF - 1)] = */ { /*.deleteFunc = */FreeGC, + /*.sizeFunc = */GetGcBytes, + /*.findSubResFunc = */FindGCSubRes, /*.errorValue = */BadGC, }, /* [RT_FONT & (RC_LASTPREDEF - 1)] = */ { /*.deleteFunc = */CloseFont, + /*.sizeFunc = */GetDefaultBytes, + /*.findSubResFunc = */DefaultFindSubRes, /*.errorValue = */BadFont, }, /* [RT_CURSOR & (RC_LASTPREDEF - 1)] = */ { /*.deleteFunc = */FreeCursor, + /*.sizeFunc = */GetDefaultBytes, + /*.findSubResFunc = */DefaultFindSubRes, /*.errorValue = */BadCursor, }, /* [RT_COLORMAP & (RC_LASTPREDEF - 1)] = */ { /*.deleteFunc = */FreeColormap, + /*.sizeFunc = */GetDefaultBytes, + /*.findSubResFunc = */DefaultFindSubRes, /*.errorValue = */BadColor, }, /* [RT_CMAPENTRY & (RC_LASTPREDEF - 1)] = */ { /*.deleteFunc = */FreeClientPixels, + /*.sizeFunc = */GetDefaultBytes, + /*.findSubResFunc = */DefaultFindSubRes, /*.errorValue = */BadColor, }, /* [RT_OTHERCLIENT & (RC_LASTPREDEF - 1)] = */ { /*.deleteFunc = */OtherClientGone, + /*.sizeFunc = */GetDefaultBytes, + /*.findSubResFunc = */DefaultFindSubRes, /*.errorValue = */BadValue, }, /* [RT_PASSIVEGRAB & (RC_LASTPREDEF - 1)] = */ { /*.deleteFunc = */DeletePassiveGrab, + /*.deleteFunc = */DeletePassiveGrab, + /*.sizeFunc = */GetDefaultBytes, /*.errorValue = */BadValue, }, }; @@ -256,6 +520,8 @@ CreateNewResourceType(DeleteType deleteFunc, const char *name) lastResourceType = next; resourceTypes = types; resourceTypes[next].deleteFunc = deleteFunc; + resourceTypes[next].sizeFunc = GetDefaultBytes; + resourceTypes[next].findSubResFunc = DefaultFindSubRes; resourceTypes[next].errorValue = BadValue; /* Called even if name is NULL, to remove any previous entry */ @@ -264,6 +530,57 @@ CreateNewResourceType(DeleteType deleteFunc, const char *name) return next; } +/** + * Get the function used to calculate resource size. Extensions and + * drivers need to be able to determine the current size calculation + * function if they want to wrap or override it. + * + * @param[in] type Resource type used in size calculations. + * + * @return Function to calculate the size of a single + * resource. + */ +SizeType +GetResourceTypeSizeFunc(RESTYPE type) +{ + return resourceTypes[type & TypeMask].sizeFunc; +} + +/** + * Override the default function that calculates resource size. For + * example, video driver knows better how to calculate pixmap memory + * usage and can therefore wrap or override size calculation for + * RT_PIXMAP. + * + * @param[in] type Resource type used in size calculations. + * + * @param[in] sizeFunc Function to calculate the size of a single + * resource. + */ +void +SetResourceTypeSizeFunc(RESTYPE type, SizeType sizeFunc) +{ + resourceTypes[type & TypeMask].sizeFunc = sizeFunc; +} + +/** + * Provide a function for iterating the subresources of a resource. + * This allows for example more accurate accounting of the (memory) + * resources consumed by a resource. + * + * @see FindSubResources + * + * @param[in] type Resource type used in size calculations. + * + * @param[in] sizeFunc Function to calculate the size of a single + * resource. + */ +void +SetResourceTypeFindSubResFunc(RESTYPE type, FindTypeSubResources findFunc) +{ + resourceTypes[type & TypeMask].findSubResFunc = findFunc; +} + void SetResourceTypeErrorValue(RESTYPE type, int errorValue) { @@ -326,25 +643,32 @@ InitClientResources(ClientPtr client) return TRUE; } -static int -Hash(int client, XID id) +int +HashResourceID(XID id, int numBits) { id &= RESOURCE_ID_MASK; - switch (clientTable[client].hashsize) { - case 6: - return ((int) (0x03F & (id ^ (id >> 6) ^ (id >> 12)))); - case 7: - return ((int) (0x07F & (id ^ (id >> 7) ^ (id >> 13)))); - case 8: - return ((int) (0x0FF & (id ^ (id >> 8) ^ (id >> 16)))); - case 9: - return ((int) (0x1FF & (id ^ (id >> 9)))); - case 10: - return ((int) (0x3FF & (id ^ (id >> 10)))); - case 11: - return ((int) (0x7FF & (id ^ (id >> 11)))); - } - return -1; + switch (numBits) + { + case 6: + return ((int)(0x03F & (id ^ (id>>6) ^ (id>>12)))); + case 7: + return ((int)(0x07F & (id ^ (id>>7) ^ (id>>13)))); + case 8: + return ((int)(0x0FF & (id ^ (id>>8) ^ (id>>16)))); + case 9: + return ((int)(0x1FF & (id ^ (id>>9)))); + case 10: + return ((int)(0x3FF & (id ^ (id>>10)))); + case 11: + return ((int)(0x7FF & (id ^ (id>>11)))); + } + if (numBits >= 11) + return ((int)(0x7FF & (id ^ (id>>11)))); + else + { + assert(numBits >= 0); + return id & ~((~0) << numBits); + } } static XID @@ -355,7 +679,7 @@ AvailableID(int client, XID id, XID maxid, XID goodid) if ((goodid >= id) && (goodid <= maxid)) return goodid; for (; id <= maxid; id++) { - res = clientTable[client].resources[Hash(client, id)]; + res = clientTable[client].resources[HashResourceID(id, clientTable[client].hashsize)]; while (res && (res->id != id)) res = res->next; if (!res) @@ -481,7 +805,7 @@ AddResource(XID id, RESTYPE type, pointer value) } if ((rrec->elements >= 4 * rrec->buckets) && (rrec->hashsize < MAXHASHSIZE)) RebuildTable(client); - head = &rrec->resources[Hash(client, id)]; + head = &rrec->resources[HashResourceID(id, clientTable[client].hashsize)]; res = malloc(sizeof(ResourceRec)); if (!res) { (*resourceTypes[type & TypeMask].deleteFunc) (value, id); @@ -529,7 +853,7 @@ RebuildTable(int client) for (res = *rptr; res; res = next) { next = res->next; res->next = NULL; - tptr = &tails[Hash(client, res->id)]; + tptr = &tails[HashResourceID(res->id, clientTable[client].hashsize)]; **tptr = res; *tptr = &res->next; } @@ -561,7 +885,7 @@ FreeResource(XID id, RESTYPE skipDeleteFuncType) int elements; if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets) { - head = &clientTable[cid].resources[Hash(cid, id)]; + head = &clientTable[cid].resources[HashResourceID(id, clientTable[cid].hashsize)]; eltptr = &clientTable[cid].elements; prev = head; @@ -595,7 +919,7 @@ FreeResourceByType(XID id, RESTYPE type, Bool skipFree) ResourcePtr *prev, *head; if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets) { - head = &clientTable[cid].resources[Hash(cid, id)]; + head = &clientTable[cid].resources[HashResourceID(id, clientTable[cid].hashsize)]; prev = head; while ((res = *prev)) { @@ -630,7 +954,7 @@ ChangeResourceValue(XID id, RESTYPE rtype, pointer value) ResourcePtr res; if (((cid = CLIENT_ID(id)) < MAXCLIENTS) && clientTable[cid].buckets) { - res = clientTable[cid].resources[Hash(cid, id)]; + res = clientTable[cid].resources[HashResourceID(id, clientTable[cid].hashsize)]; for (; res; res = res->next) if ((res->id == id) && (res->type == rtype)) { @@ -674,6 +998,15 @@ FindClientResourcesByType(ClientPtr client, } } +void FindSubResources(pointer resource, + RESTYPE type, + FindAllRes func, + pointer cdata) +{ + struct ResourceType rtype = resourceTypes[type & TypeMask]; + rtype.findSubResFunc(resource, func, cdata); +} + void FindAllClientResources(ClientPtr client, FindAllRes func, pointer cdata) { @@ -859,7 +1192,7 @@ dixLookupResourceByType(pointer *result, XID id, RESTYPE rtype, return BadImplementation; if ((cid < MAXCLIENTS) && clientTable[cid].buckets) { - res = clientTable[cid].resources[Hash(cid, id)]; + res = clientTable[cid].resources[HashResourceID(id, clientTable[cid].hashsize)]; for (; res; res = res->next) if (res->id == id && res->type == rtype) @@ -892,7 +1225,7 @@ dixLookupResourceByClass(pointer *result, XID id, RESTYPE rclass, *result = NULL; if ((cid < MAXCLIENTS) && clientTable[cid].buckets) { - res = clientTable[cid].resources[Hash(cid, id)]; + res = clientTable[cid].resources[HashResourceID(id, clientTable[cid].hashsize)]; for (; res; res = res->next) if (res->id == id && (res->type & rclass)) diff --git a/xorg-server/dix/touch.c b/xorg-server/dix/touch.c index 0829b6545..dd16367d0 100644 --- a/xorg-server/dix/touch.c +++ b/xorg-server/dix/touch.c @@ -364,14 +364,6 @@ TouchEndTouch(DeviceIntPtr dev, TouchPointInfoPtr ti) { if (ti->emulate_pointer) { GrabPtr grab; - DeviceEvent ev; - - memset(&ev, 0, sizeof(ev)); - ev.type = ET_TouchEnd; - ev.detail.button = 1; - ev.touchid = ti->client_id; - ev.flags = TOUCH_POINTER_EMULATED | TOUCH_END; - UpdateDeviceState(dev, &ev); if ((grab = dev->deviceGrab.grab)) { if (dev->deviceGrab.fromPassiveGrab && @@ -482,10 +474,22 @@ TouchEventHistoryReplay(TouchPointInfoPtr ti, DeviceIntPtr dev, XID resource) flags = TOUCH_CLIENT_ID | TOUCH_REPLAYING; if (ti->emulate_pointer) flags |= TOUCH_POINTER_EMULATED; - /* send fake begin event to next owner */ + /* Generate events based on a fake touch begin event to get DCCE events if + * needed */ + /* FIXME: This needs to be cleaned up */ nev = GetTouchEvents(tel, dev, ti->client_id, XI_TouchBegin, flags, mask); - for (i = 0; i < nev; i++) - DeliverTouchEvents(dev, ti, tel + i, resource); + for (i = 0; i < nev; i++) { + /* Send saved touch begin event */ + if (tel[i].any.type == ET_TouchBegin) { + DeviceEvent *ev = &ti->history[0]; + ev->flags |= TOUCH_REPLAYING; + DeliverTouchEvents(dev, ti, (InternalEvent*)ev, resource); + } + else {/* Send DCCE event */ + tel[i].any.time = ti->history[0].time; + DeliverTouchEvents(dev, ti, tel + i, resource); + } + } valuator_mask_free(&mask); FreeEventList(tel, GetMaximumEventsNum()); @@ -542,22 +546,12 @@ TouchBuildDependentSpriteTrace(DeviceIntPtr dev, SpritePtr sprite) * TouchBegin events. */ Bool -TouchEnsureSprite(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, - InternalEvent *ev) +TouchBuildSprite(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, + InternalEvent *ev) { TouchClassPtr t = sourcedev->touch; SpritePtr sprite = &ti->sprite; - /* We may not have a sprite if there are no applicable grabs or - * event selections, or if they've disappeared, or if all the grab - * owners have rejected the touch. Don't bother delivering motion - * events if not, but TouchEnd events still need to be processed so - * we can call FinishTouchPoint and release it for later use. */ - if (ev->any.type == ET_TouchEnd) - return TRUE; - else if (ev->any.type != ET_TouchBegin) - return (sprite->spriteTraceGood > 0); - if (t->mode == XIDirectTouch) { /* Focus immediately under the touchpoint in direct touch mode. * XXX: Do we need to handle crossing screens here? */ @@ -821,6 +815,7 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti, if (mask & EVENT_CORE_MASK) { int coretype = GetCoreType(TouchGetPointerEventType(ev)); Mask core_filter = event_get_filter_from_type(dev, coretype); + OtherClients *oclients; /* window owner */ if (IsMaster(dev) && (win->eventMask & core_filter)) { @@ -832,13 +827,12 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti, } /* all others */ - nt_list_for_each_entry(iclients, (InputClients *) wOtherClients(win), - next) { - if (!(iclients->mask[XIAllDevices] & core_filter)) + nt_list_for_each_entry(oclients, wOtherClients(win), next) { + if (!(oclients->mask & core_filter)) continue; TouchEventHistoryAllocate(ti); - TouchAddListener(ti, iclients->resource, CORE, + TouchAddListener(ti, oclients->resource, CORE, type, LISTENER_AWAITING_BEGIN, win); return TRUE; } @@ -874,6 +868,11 @@ TouchSetupListeners(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev) if (dev->deviceGrab.grab) TouchAddActiveGrabListener(dev, ti, ev, dev->deviceGrab.grab); + /* We set up an active touch listener for existing touches, but not any + * passive grab or regular listeners. */ + if (ev->any.type != ET_TouchBegin) + return; + /* First, find all grabbing clients from the root window down * to the deepest child window. */ for (i = 0; i < sprite->spriteTraceGood; i++) { @@ -960,15 +959,48 @@ TouchListenerGone(XID resource) } int +TouchListenerAcceptReject(DeviceIntPtr dev, TouchPointInfoPtr ti, int listener, + int mode) +{ + InternalEvent *events; + int nev; + int i; + + if (listener > 0) { + if (mode == XIRejectTouch) + TouchRejected(dev, ti, ti->listeners[listener].listener, NULL); + else + ti->listeners[listener].state = LISTENER_EARLY_ACCEPT; + + return Success; + } + + events = InitEventList(GetMaximumEventsNum()); + if (!events) { + BUG_WARN_MSG(TRUE, "Failed to allocate touch ownership events\n"); + return BadAlloc; + } + + nev = GetTouchOwnershipEvents(events, dev, ti, mode, + ti->listeners[0].listener, 0); + BUG_WARN_MSG(nev == 0, "Failed to get touch ownership events\n"); + + for (i = 0; i < nev; i++) + mieqProcessDeviceEvent(dev, events + i, NULL); + + ProcessInputEvents(); + + FreeEventList(events, GetMaximumEventsNum()); + + return nev ? Success : BadMatch; +} + +int TouchAcceptReject(ClientPtr client, DeviceIntPtr dev, int mode, uint32_t touchid, Window grab_window, XID *error) { TouchPointInfoPtr ti; - int nev, i; - InternalEvent *events = InitEventList(GetMaximumEventsNum()); - - if (!events) - return BadAlloc; + int i; if (!dev->touch) { *error = dev->id; @@ -989,24 +1021,5 @@ TouchAcceptReject(ClientPtr client, DeviceIntPtr dev, int mode, if (i == ti->num_listeners) return BadAccess; - if (i > 0) { - if (mode == XIRejectTouch) - TouchRejected(dev, ti, ti->listeners[i].listener, NULL); - else - ti->listeners[i].state = LISTENER_EARLY_ACCEPT; - - return Success; - } - - nev = GetTouchOwnershipEvents(events, dev, ti, mode, - ti->listeners[0].listener, 0); - if (nev == 0) - return BadAlloc; - for (i = 0; i < nev; i++) - mieqProcessDeviceEvent(dev, events + i, NULL); - - ProcessInputEvents(); - - FreeEventList(events, GetMaximumEventsNum()); - return Success; + return TouchListenerAcceptReject(dev, ti, i, mode); } diff --git a/xorg-server/hw/xfree86/Makefile.am b/xorg-server/hw/xfree86/Makefile.am index 72be8891c..d61c6401b 100644 --- a/xorg-server/hw/xfree86/Makefile.am +++ b/xorg-server/hw/xfree86/Makefile.am @@ -25,9 +25,9 @@ if INT10MODULE INT10_SUBDIR = int10 endif -SUBDIRS = common ddc i2c x86emu $(INT10_SUBDIR) fbdevhw os-support parser \ - ramdac shadowfb $(VBE_SUBDIR) $(VGAHW_SUBDIR) $(XAA_SUBDIR) \ - loader dixmods exa modes \ +SUBDIRS = common ddc x86emu $(INT10_SUBDIR) os-support parser \ + ramdac $(VBE_SUBDIR) $(VGAHW_SUBDIR) $(XAA_SUBDIR) \ + loader modes . i2c dixmods fbdevhw shadowfb exa \ $(DRI_SUBDIR) $(DRI2_SUBDIR) $(XF86UTILS_SUBDIR) doc man DIST_SUBDIRS = common ddc i2c x86emu int10 fbdevhw os-support \ @@ -92,6 +92,9 @@ if INSTALL_SETUID chown root $(DESTDIR)$(bindir)/Xorg chmod u+s $(DESTDIR)$(bindir)/Xorg endif +if CYGWIN + $(INSTALL_DATA) libXorg.exe.a $(DESTDIR)$(libdir)/libXorg.exe.a +endif # Use variables from XORG_MANPAGE_SECTIONS and X Server configuration # Do not include manpages.am as values are not appropriate for rc files @@ -113,3 +116,12 @@ sdksyms.dep sdksyms.c: sdksyms.sh SDKSYMS_DEP = sdksyms.dep include $(SDKSYMS_DEP) + +i2c/libi2c.la: + $(AM_V_at)cd i2c && $(MAKE) libi2c.la + +dixmods/libdixmods.la: + $(AM_V_at)cd dixmods && $(MAKE) libdixmods.la + +dixmods/libxorgxkb.la: + $(AM_V_at)cd dixmods && $(MAKE) libxorgxkb.la diff --git a/xorg-server/hw/xfree86/common/xf86Config.c b/xorg-server/hw/xfree86/common/xf86Config.c index ec679df16..b22b617a4 100644 --- a/xorg-server/hw/xfree86/common/xf86Config.c +++ b/xorg-server/hw/xfree86/common/xf86Config.c @@ -125,6 +125,11 @@ static ModuleDefault ModuleDefaults[] = { #ifdef DRI2 {.name = "dri2",.toLoad = TRUE,.load_opt = NULL}, #endif +#ifdef __CYGWIN__ + /* load DIX modules used by drivers first */ + {.name = "fb",.toLoad = TRUE,.load_opt = NULL}, + {.name = "shadow",.toLoad = TRUE,.load_opt = NULL}, +#endif {.name = NULL,.toLoad = FALSE,.load_opt = NULL} }; diff --git a/xorg-server/hw/xfree86/common/xf86Init.c b/xorg-server/hw/xfree86/common/xf86Init.c index 2a7d0a37e..f42dd1083 100644 --- a/xorg-server/hw/xfree86/common/xf86Init.c +++ b/xorg-server/hw/xfree86/common/xf86Init.c @@ -1580,3 +1580,10 @@ xf86GetBppFromDepth(ScrnInfoPtr pScrn, int depth) else return 0; } + +#ifdef DDXBEFORERESET +void +ddxBeforeReset(void) +{ +} +#endif diff --git a/xorg-server/hw/xfree86/dixmods/Makefile.am b/xorg-server/hw/xfree86/dixmods/Makefile.am index a5be3ae00..6f4af6c2c 100644 --- a/xorg-server/hw/xfree86/dixmods/Makefile.am +++ b/xorg-server/hw/xfree86/dixmods/Makefile.am @@ -30,35 +30,39 @@ INCLUDES = @XORG_INCS@ \ -I$(top_srcdir)/miext/shadow \ -I$(top_srcdir)/glx -libdbe_la_LDFLAGS = -module -avoid-version +libdbe_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) libdbe_la_LIBADD = $(top_builddir)/dbe/libdbe.la libdbe_la_SOURCES = dbemodule.c -libfb_la_LDFLAGS = -module -avoid-version +libfb_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) libfb_la_LIBADD = $(top_builddir)/fb/libfb.la libfb_la_SOURCES = $(top_builddir)/fb/fbcmap_mi.c fbmodule.c libfb_la_CFLAGS = $(AM_CFLAGS) -libwfb_la_LDFLAGS = -module -avoid-version +libwfb_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) libwfb_la_LIBADD = $(top_builddir)/fb/libwfb.la libwfb_la_SOURCES = $(top_builddir)/fb/fbcmap_mi.c fbmodule.c libwfb_la_CFLAGS = $(AM_CFLAGS) -DFB_ACCESS_WRAPPER -libglx_la_LDFLAGS = -module -avoid-version +libglx_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) +libglx_la_LIBADD = $(top_builddir)/glx/libglx.la $(GLX_SYS_LIBS) if AIGLX_DRI_LOADER -GLXDRI_LIBRARY = $(top_builddir)/glx/libglxdri.la +libglx_la_LIBADD += $(top_builddir)/glx/libglxdri.la +if NO_UNDEFINED +libglx_la_LIBADD += ../dri/libdri.la ../dri2/libdri2.la +endif endif -libglx_la_LIBADD = \ - $(top_builddir)/glx/libglx.la \ - $(GLXDRI_LIBRARY) libglx_la_SOURCES = glxmodule.c -librecord_la_LDFLAGS = -module -avoid-version +librecord_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) librecord_la_LIBADD = $(top_builddir)/record/librecord.la librecord_la_SOURCES = recordmod.c -libshadow_la_LDFLAGS = -module -avoid-version +libshadow_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) libshadow_la_LIBADD = $(top_builddir)/miext/shadow/libshadow.la +if NO_UNDEFINED +libshadow_la_LIBADD += libfb.la +endif libshadow_la_SOURCES = shmodule.c libdixmods_la_SOURCES = $(top_srcdir)/mi/miinitext.c diff --git a/xorg-server/hw/xfree86/dixmods/extmod/Makefile.am b/xorg-server/hw/xfree86/dixmods/extmod/Makefile.am index 87c28a421..d08e9ad15 100644 --- a/xorg-server/hw/xfree86/dixmods/extmod/Makefile.am +++ b/xorg-server/hw/xfree86/dixmods/extmod/Makefile.am @@ -21,7 +21,7 @@ INCLUDES = @XORG_INCS@ \ -I$(top_srcdir)/hw/xfree86/loader \ -I$(top_srcdir)/miext/shadow -libextmod_la_LDFLAGS = -module -avoid-version +libextmod_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) libextmod_la_SOURCES = modinit.c \ modinit.h \ $(DGA_SRCS) \ diff --git a/xorg-server/hw/xfree86/dri/Makefile.am b/xorg-server/hw/xfree86/dri/Makefile.am index a7b491c6e..194cf8e3f 100644 --- a/xorg-server/hw/xfree86/dri/Makefile.am +++ b/xorg-server/hw/xfree86/dri/Makefile.am @@ -12,7 +12,8 @@ libdri_la_CFLAGS = -I$(top_srcdir)/hw/xfree86/common \ @DIX_CFLAGS@ @XORG_CFLAGS@ @DRIPROTO_CFLAGS@ \ @LIBDRM_CFLAGS@ \ @DRI_CFLAGS@ -libdri_la_LDFLAGS = -module -avoid-version @LIBDRM_LIBS@ +libdri_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) +libdri_la_LIBADD = @LIBDRM_LIBS@ libdri_ladir = $(moduledir)/extensions libdri_la_SOURCES = \ dri.c \ diff --git a/xorg-server/hw/xfree86/dri2/Makefile.am b/xorg-server/hw/xfree86/dri2/Makefile.am index c9fdde2f8..0e40fbcf2 100644 --- a/xorg-server/hw/xfree86/dri2/Makefile.am +++ b/xorg-server/hw/xfree86/dri2/Makefile.am @@ -6,7 +6,8 @@ libdri2_la_CFLAGS = \ -I$(top_srcdir)/hw/xfree86/common \ -I$(top_srcdir)/hw/xfree86/os-support/bus -libdri2_la_LDFLAGS = -module -avoid-version @LIBDRM_LIBS@ +libdri2_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) +libdri2_la_LIBADD = @LIBDRM_LIBS@ libdri2_ladir = $(moduledir)/extensions libdri2_la_SOURCES = \ dri2.c \ diff --git a/xorg-server/hw/xfree86/exa/Makefile.am b/xorg-server/hw/xfree86/exa/Makefile.am index 3ced531fa..433908411 100644 --- a/xorg-server/hw/xfree86/exa/Makefile.am +++ b/xorg-server/hw/xfree86/exa/Makefile.am @@ -2,7 +2,7 @@ SUBDIRS = man module_LTLIBRARIES = libexa.la -libexa_la_LDFLAGS = -module -avoid-version +libexa_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) INCLUDES = \ $(XORG_INCS) \ @@ -15,4 +15,4 @@ libexa_la_SOURCES = \ examodule.c libexa_la_LIBADD = \ - ../../../exa/libexa.la + ../../../exa/libexa.la $(PIXMAN_LIBS) diff --git a/xorg-server/hw/xfree86/fbdevhw/Makefile.am b/xorg-server/hw/xfree86/fbdevhw/Makefile.am index 4472acd91..1fa9321cb 100644 --- a/xorg-server/hw/xfree86/fbdevhw/Makefile.am +++ b/xorg-server/hw/xfree86/fbdevhw/Makefile.am @@ -2,7 +2,7 @@ SUBDIRS = man module_LTLIBRARIES = libfbdevhw.la -libfbdevhw_la_LDFLAGS = -module -avoid-version +libfbdevhw_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) if FBDEVHW libfbdevhw_la_SOURCES = fbdevhw.c diff --git a/xorg-server/hw/xfree86/i2c/Makefile.am b/xorg-server/hw/xfree86/i2c/Makefile.am index 0b80cc8a6..f08541cf0 100644 --- a/xorg-server/hw/xfree86/i2c/Makefile.am +++ b/xorg-server/hw/xfree86/i2c/Makefile.am @@ -21,23 +21,26 @@ sdk_HEADERS = xf86i2c.h bt829.h fi1236.h msp3430.h tda8425.h tda9850.h tda9885.h # # i2c drivers # -bt829_drv_la_LDFLAGS = -module -avoid-version +bt829_drv_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) bt829_drv_la_SOURCES = bt829.c bt829.h bt829_module.c -fi1236_drv_la_LDFLAGS = -module -avoid-version +fi1236_drv_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) fi1236_drv_la_SOURCES = fi1236.c fi1236.h fi1236_module.c +if NO_UNDEFINED +fi1236_drv_la_LIBADD = tda9885_drv.la +endif -msp3430_drv_la_LDFLAGS = -module -avoid-version +msp3430_drv_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) msp3430_drv_la_SOURCES = msp3430.c msp3430.h msp3430_module.c -tda8425_drv_la_LDFLAGS = -module -avoid-version +tda8425_drv_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) tda8425_drv_la_SOURCES = tda8425.c tda8425.h tda8425_module.c -tda9850_drv_la_LDFLAGS = -module -avoid-version +tda9850_drv_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) tda9850_drv_la_SOURCES = tda9850.c tda9850.h tda9850_module.c -tda9885_drv_la_LDFLAGS = -module -avoid-version +tda9885_drv_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) tda9885_drv_la_SOURCES = tda9885.c tda9885.h tda9885_module.c -uda1380_drv_la_LDFLAGS = -module -avoid-version +uda1380_drv_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) uda1380_drv_la_SOURCES = uda1380.c uda1380.h uda1380_module.c diff --git a/xorg-server/hw/xfree86/loader/loadmod.c b/xorg-server/hw/xfree86/loader/loadmod.c index c6b559072..706b9b3e8 100644 --- a/xorg-server/hw/xfree86/loader/loadmod.c +++ b/xorg-server/hw/xfree86/loader/loadmod.c @@ -212,9 +212,15 @@ static const char *stdSubdirs[] = { * to port this DDX to, say, Darwin, we'll need to fix this. */ static PatternRec stdPatterns[] = { +#ifdef __CYGWIN__ + {"^cyg(.*)\\.dll$",}, + {"(.*)_drv\\.dll$",}, + {"(.*)\\.dll$",}, +#else {"^lib(.*)\\.so$",}, {"(.*)_drv\\.so$",}, {"(.*)\\.so$",}, +#endif {NULL,} }; @@ -408,21 +414,33 @@ FindModuleInSubdir(const char *dirpath, const char *module) continue; } +#ifdef __CYGWIN__ + snprintf(tmpBuf, PATH_MAX, "cyg%s.dll", module); +#else snprintf(tmpBuf, PATH_MAX, "lib%s.so", module); +#endif if (strcmp(direntry->d_name, tmpBuf) == 0) { if (asprintf(&ret, "%s%s", dirpath, tmpBuf) == -1) ret = NULL; break; } +#ifdef __CYGWIN__ + snprintf(tmpBuf, PATH_MAX, "%s_drv.dll", module); +#else snprintf(tmpBuf, PATH_MAX, "%s_drv.so", module); +#endif if (strcmp(direntry->d_name, tmpBuf) == 0) { if (asprintf(&ret, "%s%s", dirpath, tmpBuf) == -1) ret = NULL; break; } +#ifdef __CYGWIN__ + snprintf(tmpBuf, PATH_MAX, "%s.dll", module); +#else snprintf(tmpBuf, PATH_MAX, "%s.so", module); +#endif if (strcmp(direntry->d_name, tmpBuf) == 0) { if (asprintf(&ret, "%s%s", dirpath, tmpBuf) == -1) ret = NULL; diff --git a/xorg-server/hw/xfree86/man/xorg.conf.man b/xorg-server/hw/xfree86/man/xorg.conf.man index 72e57136c..da67f59c9 100644 --- a/xorg-server/hw/xfree86/man/xorg.conf.man +++ b/xorg-server/hw/xfree86/man/xorg.conf.man @@ -701,7 +701,7 @@ This instructs the server to load the module called The module name given should be the module's standard name, not the module file name. The standard name is case\-sensitive, and does not include the \(lqlib\(rq -prefix, or the \(lq.a\(rq, \(lq.o\(rq, or \(lq.so\(rq suffixes. +or \(lqcyg\(rq prefixes, or the \(lq.so\(rq or \(lq.dll\(rq suffixes. .PP .RS 7 Example: the DRI extension module can be loaded with the following entry: diff --git a/xorg-server/hw/xfree86/modes/xf86Crtc.c b/xorg-server/hw/xfree86/modes/xf86Crtc.c index 6d5e92f12..fee1ae774 100644 --- a/xorg-server/hw/xfree86/modes/xf86Crtc.c +++ b/xorg-server/hw/xfree86/modes/xf86Crtc.c @@ -44,7 +44,9 @@ #include "X11/Xatom.h" #include "picturestr.h" +#ifdef XV #include "xf86xv.h" +#endif #define NO_OUTPUT_DEFAULT_WIDTH 1024 #define NO_OUTPUT_DEFAULT_HEIGHT 768 diff --git a/xorg-server/hw/xfree86/os-support/xf86_OSlib.h b/xorg-server/hw/xfree86/os-support/xf86_OSlib.h index 9161e181e..e931b09a1 100644 --- a/xorg-server/hw/xfree86/os-support/xf86_OSlib.h +++ b/xorg-server/hw/xfree86/os-support/xf86_OSlib.h @@ -171,7 +171,7 @@ /**************************************************************************/ /* Linux or Glibc-based system */ /**************************************************************************/ -#if defined(__linux__) || defined(__GLIBC__) +#if defined(__linux__) || defined(__GLIBC__) || defined(__CYGWIN__) #include <sys/ioctl.h> #include <signal.h> #include <stdlib.h> diff --git a/xorg-server/hw/xfree86/sdksyms.sh b/xorg-server/hw/xfree86/sdksyms.sh index 40ea7c8da..3815525fa 100644 --- a/xorg-server/hw/xfree86/sdksyms.sh +++ b/xorg-server/hw/xfree86/sdksyms.sh @@ -252,6 +252,8 @@ cat > sdksyms.c << EOF */ +#include "compositeext.h" + /* xfixes/Makefile.am */ #include "xfixes.h" diff --git a/xorg-server/hw/xfree86/shadowfb/Makefile.am b/xorg-server/hw/xfree86/shadowfb/Makefile.am index 39c66109e..5756fca3b 100644 --- a/xorg-server/hw/xfree86/shadowfb/Makefile.am +++ b/xorg-server/hw/xfree86/shadowfb/Makefile.am @@ -1,6 +1,7 @@ module_LTLIBRARIES = libshadowfb.la -libshadowfb_la_LDFLAGS = -module -avoid-version +libshadowfb_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) libshadowfb_la_SOURCES = sfbmodule.c shadow.c +libshadowfb_la_LIBADD = $(PIXMAN_LIBS) sdk_HEADERS = shadowfb.h diff --git a/xorg-server/hw/xfree86/vbe/Makefile.am b/xorg-server/hw/xfree86/vbe/Makefile.am index 4b794e647..0b24faf1f 100644 --- a/xorg-server/hw/xfree86/vbe/Makefile.am +++ b/xorg-server/hw/xfree86/vbe/Makefile.am @@ -1,6 +1,9 @@ module_LTLIBRARIES = libvbe.la -libvbe_la_LDFLAGS = -module -avoid-version +libvbe_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) libvbe_la_SOURCES = vbe.c vbeModes.c vbe_module.c +if NO_UNDEFINED +libvbe_la_LIBADD = ../int10/libint10.la +endif sdk_HEADERS = vbe.h vbeModes.h diff --git a/xorg-server/hw/xfree86/xaa/Makefile.am b/xorg-server/hw/xfree86/xaa/Makefile.am index 78d934876..f6480a713 100644 --- a/xorg-server/hw/xfree86/xaa/Makefile.am +++ b/xorg-server/hw/xfree86/xaa/Makefile.am @@ -10,7 +10,7 @@ POLYSEG = s-xaaLine.c s-xaaDashLine.c if XAA -libxaa_la_LDFLAGS = -module -avoid-version +libxaa_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) if COMPOSITE libxaa_la_LIBADD = $(top_builddir)/miext/cw/libcw.la endif diff --git a/xorg-server/include/input.h b/xorg-server/include/input.h index d891fe5db..991d64813 100644 --- a/xorg-server/include/input.h +++ b/xorg-server/include/input.h @@ -563,8 +563,8 @@ extern void TouchAddListener(TouchPointInfoPtr ti, XID resource, extern Bool TouchRemoveListener(TouchPointInfoPtr ti, XID resource); extern void TouchSetupListeners(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev); -extern Bool TouchEnsureSprite(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, - InternalEvent *ev); +extern Bool TouchBuildSprite(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, + InternalEvent *ev); extern Bool TouchBuildDependentSpriteTrace(DeviceIntPtr dev, SpritePtr sprite); extern int TouchConvertToPointerEvent(const InternalEvent *ev, InternalEvent *motion, @@ -572,6 +572,8 @@ extern int TouchConvertToPointerEvent(const InternalEvent *ev, extern int TouchGetPointerEventType(const InternalEvent *ev); extern void TouchRemovePointerGrab(DeviceIntPtr dev); extern void TouchListenerGone(XID resource); +extern int TouchListenerAcceptReject(DeviceIntPtr dev, TouchPointInfoPtr ti, + int listener, int mode); extern int TouchAcceptReject(ClientPtr client, DeviceIntPtr dev, int mode, uint32_t touchid, Window grab_window, XID *error); diff --git a/xorg-server/include/protocol-versions.h b/xorg-server/include/protocol-versions.h index 479ac2f77..cb8e213bb 100644 --- a/xorg-server/include/protocol-versions.h +++ b/xorg-server/include/protocol-versions.h @@ -135,7 +135,7 @@ /* Resource */ #define SERVER_XRES_MAJOR_VERSION 1 -#define SERVER_XRES_MINOR_VERSION 0 +#define SERVER_XRES_MINOR_VERSION 2 /* XvMC */ #define SERVER_XVMC_MAJOR_VERSION 1 diff --git a/xorg-server/include/resource.h b/xorg-server/include/resource.h index f2f23768b..224e9bb18 100644 --- a/xorg-server/include/resource.h +++ b/xorg-server/include/resource.h @@ -152,12 +152,46 @@ typedef Bool (*FindComplexResType) (pointer /*value */ , XID /*id */ , pointer /*cdata */ ); +/* Structure for estimating resource memory usage. Memory usage + * consists of space allocated for the resource itself and of + * references to other resources. Currently the most important use for + * this structure is to estimate pixmap usage of different resources + * more accurately. */ +typedef struct { + /* Size of resource itself. Zero if not implemented. */ + unsigned long resourceSize; + /* Size attributed to pixmap references from the resource. */ + unsigned long pixmapRefSize; + /* Number of references to this resource; typically 1 */ + unsigned long refCnt; +} ResourceSizeRec, *ResourceSizePtr; + +typedef void (*SizeType)(pointer /*value*/, + XID /*id*/, + ResourceSizePtr /*size*/); + extern _X_EXPORT RESTYPE CreateNewResourceType(DeleteType /*deleteFunc */ , const char * /*name */ ); +typedef void (*FindTypeSubResources)(pointer /* value */, + FindAllRes /* func */, + pointer /* cdata */); + extern _X_EXPORT void SetResourceTypeErrorValue(RESTYPE /*type */ , int /*errorValue */ ); +extern _X_EXPORT SizeType GetResourceTypeSizeFunc( + RESTYPE /*type*/); + +extern _X_EXPORT void SetResourceTypeFindSubResFunc( + RESTYPE /*type*/, FindTypeSubResources /*findFunc*/); + +extern _X_EXPORT void SetResourceTypeSizeFunc( + RESTYPE /*type*/, SizeType /*sizeFunc*/); + +extern _X_EXPORT void SetResourceTypeErrorValue( + RESTYPE /*type*/, int /*errorValue*/); + extern _X_EXPORT RESTYPE CreateNewResourceClass(void); extern _X_EXPORT Bool InitClientResources(ClientPtr /*client */ ); @@ -193,6 +227,15 @@ extern _X_EXPORT void FindAllClientResources(ClientPtr /*client */ , FindAllRes /*func */ , pointer /*cdata */ ); +/** @brief Iterate through all subresources of a resource. + + @note The XID argument provided to the FindAllRes function + may be 0 for subresources that don't have an XID */ +extern _X_EXPORT void FindSubResources(pointer /*resource*/, + RESTYPE /*type*/, + FindAllRes /*func*/, + pointer /*cdata*/); + extern _X_EXPORT void FreeClientNeverRetainResources(ClientPtr /*client */ ); extern _X_EXPORT void FreeClientResources(ClientPtr /*client */ ); @@ -231,4 +274,17 @@ extern _X_EXPORT unsigned int GetXIDList(ClientPtr /*client */ , extern _X_EXPORT RESTYPE lastResourceType; extern _X_EXPORT RESTYPE TypeMask; -#endif /* RESOURCE_H */ +/** @brief A hashing function to be used for hashing resource IDs + + @param id The resource ID to hash + @param numBits The number of bits in the resulting hash. Must be >=0. + + @note This function is really only for handling + INITHASHSIZE..MAXHASHSIZE bit hashes, but will handle any number + of bits by either masking numBits lower bits of the ID or by + providing at most MAXHASHSIZE hashes. +*/ +extern _X_EXPORT int HashResourceID(XID id, + int numBits); + +#endif /* RESOURCE_H */ diff --git a/xorg-server/render/picture.c b/xorg-server/render/picture.c index 2fd13fc37..da3e49936 100644 --- a/xorg-server/render/picture.c +++ b/xorg-server/render/picture.c @@ -591,6 +591,29 @@ PictureParseCmapPolicy(const char *name) return PictureCmapPolicyInvalid; } +/** @see GetDefaultBytes */ +static void +GetPictureBytes(pointer value, XID id, ResourceSizePtr size) +{ + PicturePtr picture = value; + + /* Currently only pixmap bytes are reported to clients. */ + size->resourceSize = 0; + + size->refCnt = picture->refcnt; + + /* Calculate pixmap reference sizes. */ + size->pixmapRefSize = 0; + if (picture->pDrawable && (picture->pDrawable->type == DRAWABLE_PIXMAP)) + { + SizeType pixmapSizeFunc = GetResourceTypeSizeFunc(RT_PIXMAP); + ResourceSizeRec pixmapSize = { 0, 0, 0 }; + PixmapPtr pixmap = (PixmapPtr)picture->pDrawable; + pixmapSizeFunc(pixmap, pixmap->drawable.id, &pixmapSize); + size->pixmapRefSize += pixmapSize.pixmapRefSize; + } +} + Bool PictureInit(ScreenPtr pScreen, PictFormatPtr formats, int nformats) { @@ -602,6 +625,7 @@ PictureInit(ScreenPtr pScreen, PictFormatPtr formats, int nformats) PictureType = CreateNewResourceType(FreePicture, "PICTURE"); if (!PictureType) return FALSE; + SetResourceTypeSizeFunc(PictureType, GetPictureBytes); PictFormatType = CreateNewResourceType(FreePictFormat, "PICTFORMAT"); if (!PictFormatType) return FALSE; diff --git a/xorg-server/test/Makefile.am b/xorg-server/test/Makefile.am index eb6147021..8c7e412c3 100644 --- a/xorg-server/test/Makefile.am +++ b/xorg-server/test/Makefile.am @@ -5,7 +5,7 @@ if XORG # Tests that require at least some DDX functions in order to fully link # For now, requires xf86 ddx, could be adjusted to use another SUBDIRS += xi2 -noinst_PROGRAMS += xkb input xtest misc fixes xfree86 +noinst_PROGRAMS += xkb input xtest misc fixes xfree86 hashtabletest endif check_LTLIBRARIES = libxservertest.la @@ -36,6 +36,7 @@ misc_LDADD=$(TEST_LDADD) fixes_LDADD=$(TEST_LDADD) xfree86_LDADD=$(TEST_LDADD) touch_LDADD=$(TEST_LDADD) +hashtabletest_LDADD=$(TEST_LDADD) ../Xext/hashtable.c libxservertest_la_LIBADD = $(XSERVER_LIBS) if XORG diff --git a/xorg-server/test/hashtabletest.c b/xorg-server/test/hashtabletest.c new file mode 100644 index 000000000..64c7091fc --- /dev/null +++ b/xorg-server/test/hashtabletest.c @@ -0,0 +1,162 @@ +#include <misc.h> +#include <stdlib.h> +#include <stdio.h> +#include "hashtable.h" +#include "resource.h" + +static void +print_xid(void* ptr, void* v) +{ + XID *x = v; + printf("%ld", *x); +} + +static void +print_int(void* ptr, void* v) +{ + int *x = v; + printf("%d", *x); +} + +static int +test1(void) +{ + HashTable h; + XID id; + int c; + int ok = 1; + const int numKeys = 420; + + printf("test1\n"); + h = ht_create(sizeof(XID), sizeof(int), ht_resourceid_hash, ht_resourceid_compare, NULL); + + for (c = 0; c < numKeys; ++c) { + int *dest; + id = c; + dest = ht_add(h, &id); + if (dest) { + *dest = 2 * c; + } + } + + printf("Distribution after insertion\n"); + ht_dump_distribution(h); + ht_dump_contents(h, print_xid, print_int, NULL); + + for (c = 0; c < numKeys; ++c) { + XID id = c; + int* v = ht_find(h, &id); + if (v) { + if (*v == 2 * c) { + // ok + } else { + printf("Key %d doesn't have expected value %d but has %d instead\n", + c, 2 * c, *v); + ok = 0; + } + } else { + ok = 0; + printf("Cannot find key %d\n", c); + } + } + + if (ok) { + printf("%d keys inserted and found\n", c); + + for (c = 0; c < numKeys; ++c) { + XID id = c; + ht_remove(h, &id); + } + + printf("Distribution after deletion\n"); + ht_dump_distribution(h); + } + + ht_destroy(h); + + return ok; +} + +static int +test2(void) +{ + HashTable h; + XID id; + int c; + int ok = 1; + const int numKeys = 420; + + printf("test2\n"); + h = ht_create(sizeof(XID), 0, ht_resourceid_hash, ht_resourceid_compare, NULL); + + for (c = 0; c < numKeys; ++c) { + id = c; + ht_add(h, &id); + } + + for (c = 0; c < numKeys; ++c) { + XID id = c; + if (!ht_find(h, &id)) { + ok = 0; + printf("Cannot find key %d\n", c); + } + } + + { + XID id = c + 1; + if (ht_find(h, &id)) { + ok = 0; + printf("Could find a key that shouldn't be there\n"); + } + } + + ht_destroy(h); + + if (ok) { + printf("Test with empty keys OK\n"); + } else { + printf("Test with empty keys FAILED\n"); + } + + return ok; +} + +static int +test3(void) +{ + int ok = 1; + HtGenericHashSetupRec hashSetup = { + .keySize = 4 + }; + HashTable h; + printf("test3\n"); + h = ht_create(4, 0, ht_generic_hash, ht_generic_compare, &hashSetup); + + if (!ht_add(h, "helo") || + !ht_add(h, "wrld")) { + printf("Could not insert keys\n"); + } + + if (!ht_find(h, "helo") || + !ht_find(h, "wrld")) { + ok = 0; + printf("Could not find inserted keys\n"); + } + + printf("Hash distribution with two strings\n"); + ht_dump_distribution(h); + + ht_destroy(h); + + return ok; +} + +int +main(void) +{ + int ok = test1(); + ok = ok && test2(); + ok = ok && test3(); + + return ok ? 0 : 1; +} diff --git a/xorg-server/xkeyboard-config/ABOUT-NLS b/xorg-server/xkeyboard-config/ABOUT-NLS deleted file mode 100644 index 2f50c6693..000000000 --- a/xorg-server/xkeyboard-config/ABOUT-NLS +++ /dev/null @@ -1,768 +0,0 @@ -Notes on the Free Translation Project -************************************* - -Free software is going international! The Free Translation Project is -a way to get maintainers of free software, translators, and users all -together, so that will gradually become able to speak many languages. -A few packages already provide translations for their messages. - - If you found this `ABOUT-NLS' file inside a distribution, you may -assume that the distributed package does use GNU `gettext' internally, -itself available at your nearest GNU archive site. But you do _not_ -need to install GNU `gettext' prior to configuring, installing or using -this package with messages translated. - - Installers will find here some useful hints. These notes also -explain how users should proceed for getting the programs to use the -available translations. They tell how people wanting to contribute and -work at translations should contact the appropriate team. - - When reporting bugs in the `intl/' directory or bugs which may be -related to internationalization, you should tell about the version of -`gettext' which is used. The information can be found in the -`intl/VERSION' file, in internationalized packages. - -Quick configuration advice -========================== - -If you want to exploit the full power of internationalization, you -should configure it using - - ./configure --with-included-gettext - -to force usage of internationalizing routines provided within this -package, despite the existence of internationalizing capabilities in the -operating system where this package is being installed. So far, only -the `gettext' implementation in the GNU C library version 2 provides as -many features (such as locale alias, message inheritance, automatic -charset conversion or plural form handling) as the implementation here. -It is also not possible to offer this additional functionality on top -of a `catgets' implementation. Future versions of GNU `gettext' will -very likely convey even more functionality. So it might be a good idea -to change to GNU `gettext' as soon as possible. - - So you need _not_ provide this option if you are using GNU libc 2 or -you have installed a recent copy of the GNU gettext package with the -included `libintl'. - -INSTALL Matters -=============== - -Some packages are "localizable" when properly installed; the programs -they contain can be made to speak your own native language. Most such -packages use GNU `gettext'. Other packages have their own ways to -internationalization, predating GNU `gettext'. - - By default, this package will be installed to allow translation of -messages. It will automatically detect whether the system already -provides the GNU `gettext' functions. If not, the GNU `gettext' own -library will be used. This library is wholly contained within this -package, usually in the `intl/' subdirectory, so prior installation of -the GNU `gettext' package is _not_ required. Installers may use -special options at configuration time for changing the default -behaviour. The commands: - - ./configure --with-included-gettext - ./configure --disable-nls - -will respectively bypass any pre-existing `gettext' to use the -internationalizing routines provided within this package, or else, -_totally_ disable translation of messages. - - When you already have GNU `gettext' installed on your system and run -configure without an option for your new package, `configure' will -probably detect the previously built and installed `libintl.a' file and -will decide to use this. This might be not what is desirable. You -should use the more recent version of the GNU `gettext' library. I.e. -if the file `intl/VERSION' shows that the library which comes with this -package is more recent, you should use - - ./configure --with-included-gettext - -to prevent auto-detection. - - The configuration process will not test for the `catgets' function -and therefore it will not be used. The reason is that even an -emulation of `gettext' on top of `catgets' could not provide all the -extensions of the GNU `gettext' library. - - Internationalized packages have usually many `po/LL.po' files, where -LL gives an ISO 639 two-letter code identifying the language. Unless -translations have been forbidden at `configure' time by using the -`--disable-nls' switch, all available translations are installed -together with the package. However, the environment variable `LINGUAS' -may be set, prior to configuration, to limit the installed set. -`LINGUAS' should then contain a space separated list of two-letter -codes, stating which languages are allowed. - -Using This Package -================== - -As a user, if your language has been installed for this package, you -only have to set the `LANG' environment variable to the appropriate -`LL_CC' combination. Here `LL' is an ISO 639 two-letter language code, -and `CC' is an ISO 3166 two-letter country code. For example, let's -suppose that you speak German and live in Germany. At the shell -prompt, merely execute `setenv LANG de_DE' (in `csh'), -`export LANG; LANG=de_DE' (in `sh') or `export LANG=de_DE' (in `bash'). -This can be done from your `.login' or `.profile' file, once and for -all. - - You might think that the country code specification is redundant. -But in fact, some languages have dialects in different countries. For -example, `de_AT' is used for Austria, and `pt_BR' for Brazil. The -country code serves to distinguish the dialects. - - The locale naming convention of `LL_CC', with `LL' denoting the -language and `CC' denoting the country, is the one use on systems based -on GNU libc. On other systems, some variations of this scheme are -used, such as `LL' or `LL_CC.ENCODING'. You can get the list of -locales supported by your system for your country by running the command -`locale -a | grep '^LL''. - - Not all programs have translations for all languages. By default, an -English message is shown in place of a nonexistent translation. If you -understand other languages, you can set up a priority list of languages. -This is done through a different environment variable, called -`LANGUAGE'. GNU `gettext' gives preference to `LANGUAGE' over `LANG' -for the purpose of message handling, but you still need to have `LANG' -set to the primary language; this is required by other parts of the -system libraries. For example, some Swedish users who would rather -read translations in German than English for when Swedish is not -available, set `LANGUAGE' to `sv:de' while leaving `LANG' to `sv_SE'. - - Special advice for Norwegian users: The language code for Norwegian -bokma*l changed from `no' to `nb' recently (in 2003). During the -transition period, while some message catalogs for this language are -installed under `nb' and some older ones under `no', it's recommended -for Norwegian users to set `LANGUAGE' to `nb:no' so that both newer and -older translations are used. - - In the `LANGUAGE' environment variable, but not in the `LANG' -environment variable, `LL_CC' combinations can be abbreviated as `LL' -to denote the language's main dialect. For example, `de' is equivalent -to `de_DE' (German as spoken in Germany), and `pt' to `pt_PT' -(Portuguese as spoken in Portugal) in this context. - -Translating Teams -================= - -For the Free Translation Project to be a success, we need interested -people who like their own language and write it well, and who are also -able to synergize with other translators speaking the same language. -Each translation team has its own mailing list. The up-to-date list of -teams can be found at the Free Translation Project's homepage, -`http://www.iro.umontreal.ca/contrib/po/HTML/', in the "National teams" -area. - - If you'd like to volunteer to _work_ at translating messages, you -should become a member of the translating team for your own language. -The subscribing address is _not_ the same as the list itself, it has -`-request' appended. For example, speakers of Swedish can send a -message to `sv-request@li.org', having this message body: - - subscribe - - Keep in mind that team members are expected to participate -_actively_ in translations, or at solving translational difficulties, -rather than merely lurking around. If your team does not exist yet and -you want to start one, or if you are unsure about what to do or how to -get started, please write to `translation@iro.umontreal.ca' to reach the -coordinator for all translator teams. - - The English team is special. It works at improving and uniformizing -the terminology in use. Proven linguistic skill are praised more than -programming skill, here. - -Available Packages -================== - -Languages are not equally supported in all packages. The following -matrix shows the current state of internationalization, as of January -2004. The matrix shows, in regard of each package, for which languages -PO files have been submitted to translation coordination, with a -translation percentage of at least 50%. - - Ready PO files af am ar az be bg bs ca cs da de el en en_GB eo es - +----------------------------------------------------+ - a2ps | [] [] [] [] | - aegis | () | - ant-phone | () | - anubis | | - ap-utils | | - aspell | [] | - bash | [] [] [] [] | - batchelor | | - bfd | [] [] | - binutils | [] [] | - bison | [] [] [] | - bluez-pin | [] [] [] | - clisp | | - clisp | [] [] [] | - console-tools | [] [] | - coreutils | [] [] [] [] | - cpio | [] [] [] | - darkstat | [] () [] | - diffutils | [] [] [] [] [] [] [] | - e2fsprogs | [] [] [] | - enscript | [] [] [] [] | - error | [] [] [] [] [] | - fetchmail | [] () [] [] [] [] | - fileutils | [] [] [] | - findutils | [] [] [] [] [] [] [] | - flex | [] [] [] [] | - fslint | | - gas | [] | - gawk | [] [] [] [] | - gbiff | [] | - gcal | [] | - gcc | [] [] | - gettext | [] [] [] [] [] | - gettext-examples | [] [] [] [] | - gettext-runtime | [] [] [] [] [] | - gettext-tools | [] [] [] | - gimp-print | [] [] [] [] [] | - gliv | | - glunarclock | [] [] | - gnubiff | [] | - gnucash | [] () [] [] | - gnucash-glossary | [] () [] | - gnupg | [] () [] [] [] [] | - gpe-aerial | [] | - gpe-beam | [] [] | - gpe-calendar | [] [] | - gpe-clock | [] [] | - gpe-conf | [] [] | - gpe-contacts | [] [] | - gpe-edit | [] | - gpe-go | [] | - gpe-login | [] [] | - gpe-ownerinfo | [] [] | - gpe-sketchbook | [] [] | - gpe-su | [] [] | - gpe-taskmanager | [] [] | - gpe-timesheet | [] | - gpe-today | [] [] | - gpe-todo | [] [] | - gphoto2 | [] [] [] [] | - gprof | [] [] [] | - gpsdrive | () () () | - gramadoir | [] | - grep | [] [] [] [] [] [] | - gretl | [] | - gtick | [] () | - hello | [] [] [] [] [] [] | - id-utils | [] [] | - indent | [] [] [] [] | - iso_3166 | [] [] [] [] [] [] [] [] [] [] | - iso_3166_1 | [] [] [] [] [] [] | - iso_3166_2 | | - iso_3166_3 | [] | - iso_4217 | [] [] [] [] | - iso_639 | | - jpilot | [] [] [] | - jtag | | - jwhois | [] | - kbd | [] [] [] [] [] | - latrine | () | - ld | [] [] | - libc | [] [] [] [] [] [] | - libgpewidget | [] [] | - libiconv | [] [] [] [] [] | - lifelines | [] () | - lilypond | [] | - lingoteach | | - lingoteach_lessons | () () | - lynx | [] [] [] [] | - m4 | [] [] [] [] | - mailutils | [] [] | - make | [] [] [] | - man-db | [] () [] [] () | - minicom | [] [] [] | - mysecretdiary | [] [] [] | - nano | [] () [] [] [] | - nano_1_0 | [] () [] [] [] | - opcodes | [] | - parted | [] [] [] [] [] | - ptx | [] [] [] [] [] | - python | | - radius | [] | - recode | [] [] [] [] [] [] [] | - rpm | [] [] | - screem | | - scrollkeeper | [] [] [] [] [] [] | - sed | [] [] [] [] [] [] | - sh-utils | [] [] [] | - shared-mime-info | | - sharutils | [] [] [] [] [] [] | - silky | () | - skencil | [] () [] | - sketch | [] () [] | - soundtracker | [] [] [] | - sp | [] | - tar | [] [] [] [] | - texinfo | [] [] [] | - textutils | [] [] [] [] | - tin | () () | - tp-robot | | - tuxpaint | [] [] [] [] [] [] [] | - unicode-han-tra... | | - unicode-transla... | | - util-linux | [] [] [] [] [] | - vorbis-tools | [] [] [] [] | - wastesedge | () | - wdiff | [] [] [] [] | - wget | [] [] [] [] [] [] | - xchat | [] [] [] [] | - xfree86_xkb_xml | [] [] | - xpad | [] | - +----------------------------------------------------+ - af am ar az be bg bs ca cs da de el en en_GB eo es - 4 0 0 1 9 4 1 40 41 60 78 17 1 5 13 68 - - et eu fa fi fr ga gl he hr hu id is it ja ko lg - +-------------------------------------------------+ - a2ps | [] [] [] () () | - aegis | | - ant-phone | [] | - anubis | [] | - ap-utils | [] | - aspell | [] [] | - bash | [] [] | - batchelor | [] [] | - bfd | [] | - binutils | [] [] | - bison | [] [] [] [] | - bluez-pin | [] [] [] [] [] | - clisp | | - clisp | [] | - console-tools | | - coreutils | [] [] [] [] [] [] | - cpio | [] [] [] [] | - darkstat | () [] [] [] | - diffutils | [] [] [] [] [] [] [] | - e2fsprogs | | - enscript | [] [] | - error | [] [] [] [] | - fetchmail | [] | - fileutils | [] [] [] [] [] [] | - findutils | [] [] [] [] [] [] [] [] [] [] [] | - flex | [] [] [] | - fslint | [] | - gas | [] | - gawk | [] [] [] | - gbiff | [] | - gcal | [] | - gcc | [] | - gettext | [] [] [] | - gettext-examples | [] [] | - gettext-runtime | [] [] [] [] [] | - gettext-tools | [] [] [] | - gimp-print | [] [] | - gliv | () | - glunarclock | [] [] [] [] | - gnubiff | [] | - gnucash | () [] | - gnucash-glossary | [] | - gnupg | [] [] [] [] [] [] [] | - gpe-aerial | [] | - gpe-beam | [] | - gpe-calendar | [] [] [] | - gpe-clock | [] | - gpe-conf | [] | - gpe-contacts | [] [] | - gpe-edit | [] [] | - gpe-go | [] | - gpe-login | [] [] | - gpe-ownerinfo | [] [] [] | - gpe-sketchbook | [] | - gpe-su | [] | - gpe-taskmanager | [] | - gpe-timesheet | [] [] [] | - gpe-today | [] [] | - gpe-todo | [] [] | - gphoto2 | [] [] [] | - gprof | [] [] | - gpsdrive | () () () | - gramadoir | [] [] | - grep | [] [] [] [] [] [] [] [] [] [] [] | - gretl | [] [] | - gtick | [] [] [] | - hello | [] [] [] [] [] [] [] [] [] [] [] [] [] | - id-utils | [] [] [] [] | - indent | [] [] [] [] [] [] [] [] [] | - iso_3166 | [] [] [] [] [] [] [] | - iso_3166_1 | [] [] [] [] [] | - iso_3166_2 | | - iso_3166_3 | | - iso_4217 | [] [] [] [] [] [] | - iso_639 | | - jpilot | [] () | - jtag | [] | - jwhois | [] [] [] [] | - kbd | [] | - latrine | [] | - ld | [] | - libc | [] [] [] [] [] [] | - libgpewidget | [] [] [] [] | - libiconv | [] [] [] [] [] [] [] [] [] | - lifelines | () | - lilypond | [] | - lingoteach | [] [] | - lingoteach_lessons | | - lynx | [] [] [] [] | - m4 | [] [] [] [] | - mailutils | | - make | [] [] [] [] [] [] | - man-db | () () | - minicom | [] [] [] [] | - mysecretdiary | [] [] | - nano | [] [] [] [] | - nano_1_0 | [] [] [] [] | - opcodes | [] | - parted | [] [] [] | - ptx | [] [] [] [] [] [] [] | - python | | - radius | [] | - recode | [] [] [] [] [] [] | - rpm | [] [] | - screem | | - scrollkeeper | [] | - sed | [] [] [] [] [] [] [] [] [] | - sh-utils | [] [] [] [] [] [] [] | - shared-mime-info | [] [] [] | - sharutils | [] [] [] [] [] | - silky | () [] () () | - skencil | [] | - sketch | [] | - soundtracker | [] [] | - sp | [] () | - tar | [] [] [] [] [] [] [] [] [] | - texinfo | [] [] [] [] | - textutils | [] [] [] [] [] [] | - tin | [] () | - tp-robot | [] | - tuxpaint | [] [] [] [] [] [] [] [] [] | - unicode-han-tra... | | - unicode-transla... | [] [] | - util-linux | [] [] [] [] () [] | - vorbis-tools | [] | - wastesedge | () | - wdiff | [] [] [] [] [] [] | - wget | [] [] [] [] [] [] [] | - xchat | [] [] [] | - xfree86_xkb_xml | [] [] | - xpad | [] [] | - +-------------------------------------------------+ - et eu fa fi fr ga gl he hr hu id is it ja ko lg - 22 2 1 26 106 28 24 8 10 41 33 1 26 33 12 0 - - lt lv mk mn ms mt nb nl nn no nso pl pt pt_BR ro ru - +-----------------------------------------------------+ - a2ps | [] [] () () [] [] [] | - aegis | () () () | - ant-phone | [] [] | - anubis | [] [] [] [] [] [] | - ap-utils | [] () [] | - aspell | [] | - bash | [] [] [] | - batchelor | [] | - bfd | [] | - binutils | [] | - bison | [] [] [] [] [] | - bluez-pin | [] [] [] | - clisp | | - clisp | [] | - console-tools | [] | - coreutils | [] [] | - cpio | [] [] [] [] [] | - darkstat | [] [] [] [] | - diffutils | [] [] [] [] [] [] | - e2fsprogs | [] | - enscript | [] [] [] [] | - error | [] [] [] | - fetchmail | [] [] () [] | - fileutils | [] [] [] | - findutils | [] [] [] [] [] | - flex | [] [] [] [] | - fslint | [] [] | - gas | | - gawk | [] [] [] | - gbiff | [] [] | - gcal | | - gcc | | - gettext | [] [] [] | - gettext-examples | [] [] [] | - gettext-runtime | [] [] [] [] | - gettext-tools | [] [] | - gimp-print | [] | - gliv | [] [] [] | - glunarclock | [] [] [] [] | - gnubiff | [] | - gnucash | [] [] () [] | - gnucash-glossary | [] [] | - gnupg | [] | - gpe-aerial | [] [] [] [] | - gpe-beam | [] [] [] [] | - gpe-calendar | [] [] [] [] | - gpe-clock | [] [] [] [] | - gpe-conf | [] [] [] [] | - gpe-contacts | [] [] [] [] | - gpe-edit | [] [] [] [] | - gpe-go | [] [] [] | - gpe-login | [] [] [] [] | - gpe-ownerinfo | [] [] [] [] | - gpe-sketchbook | [] [] [] [] | - gpe-su | [] [] [] [] | - gpe-taskmanager | [] [] [] [] | - gpe-timesheet | [] [] [] [] | - gpe-today | [] [] [] [] | - gpe-todo | [] [] [] [] | - gphoto2 | [] | - gprof | [] [] | - gpsdrive | () () [] | - gramadoir | () [] | - grep | [] [] [] [] [] | - gretl | | - gtick | [] [] [] | - hello | [] [] [] [] [] [] [] [] [] [] | - id-utils | [] [] [] [] | - indent | [] [] [] [] | - iso_3166 | [] [] [] | - iso_3166_1 | [] [] | - iso_3166_2 | | - iso_3166_3 | [] | - iso_4217 | [] [] [] [] [] [] [] [] | - iso_639 | [] | - jpilot | () () | - jtag | | - jwhois | [] [] [] [] () | - kbd | [] [] [] | - latrine | [] | - ld | | - libc | [] [] [] [] | - libgpewidget | [] [] [] | - libiconv | [] [] [] [] [] | - lifelines | | - lilypond | | - lingoteach | | - lingoteach_lessons | | - lynx | [] [] [] | - m4 | [] [] [] [] [] | - mailutils | [] [] [] | - make | [] [] [] [] | - man-db | [] | - minicom | [] [] [] [] | - mysecretdiary | [] [] [] | - nano | [] [] [] [] [] | - nano_1_0 | [] [] [] [] [] [] | - opcodes | [] [] | - parted | [] [] [] [] | - ptx | [] [] [] [] [] [] [] [] | - python | | - radius | [] [] | - recode | [] [] [] [] | - rpm | [] [] [] | - screem | | - scrollkeeper | [] [] [] [] [] | - sed | [] [] [] | - sh-utils | [] [] | - shared-mime-info | [] [] | - sharutils | [] [] | - silky | () | - skencil | [] [] | - sketch | [] [] | - soundtracker | | - sp | | - tar | [] [] [] [] [] [] | - texinfo | [] [] [] [] | - textutils | [] [] | - tin | | - tp-robot | [] | - tuxpaint | [] [] [] [] [] [] [] [] | - unicode-han-tra... | | - unicode-transla... | | - util-linux | [] [] [] | - vorbis-tools | [] [] [] | - wastesedge | | - wdiff | [] [] [] [] [] | - wget | [] [] [] | - xchat | [] [] [] | - xfree86_xkb_xml | [] [] | - xpad | [] [] | - +-----------------------------------------------------+ - lt lv mk mn ms mt nb nl nn no nso pl pt pt_BR ro ru - 1 2 0 3 12 0 10 69 6 7 1 40 26 36 76 63 - - sk sl sr sv ta th tr uk ven vi wa xh zh_CN zh_TW zu - +-----------------------------------------------------+ - a2ps | [] [] [] [] | 16 - aegis | | 0 - ant-phone | | 3 - anubis | [] [] | 9 - ap-utils | () | 3 - aspell | | 4 - bash | | 9 - batchelor | | 3 - bfd | [] [] | 6 - binutils | [] [] [] | 8 - bison | [] [] | 14 - bluez-pin | [] [] [] | 14 - clisp | | 0 - clisp | | 5 - console-tools | | 3 - coreutils | [] [] [] [] | 16 - cpio | [] [] | 14 - darkstat | [] [] [] () () | 12 - diffutils | [] [] [] | 23 - e2fsprogs | [] [] | 6 - enscript | [] [] | 12 - error | [] [] [] | 15 - fetchmail | [] [] | 11 - fileutils | [] [] [] [] [] | 17 - findutils | [] [] [] [] [] [] | 29 - flex | [] [] | 13 - fslint | | 3 - gas | [] | 3 - gawk | [] [] | 12 - gbiff | | 4 - gcal | [] [] | 4 - gcc | [] | 4 - gettext | [] [] [] [] [] | 16 - gettext-examples | [] [] [] [] [] | 14 - gettext-runtime | [] [] [] [] [] [] [] [] | 22 - gettext-tools | [] [] [] [] [] [] | 14 - gimp-print | [] [] | 10 - gliv | | 3 - glunarclock | [] [] [] | 13 - gnubiff | | 3 - gnucash | [] [] | 9 - gnucash-glossary | [] [] [] | 8 - gnupg | [] [] [] [] | 17 - gpe-aerial | [] | 7 - gpe-beam | [] | 8 - gpe-calendar | [] [] [] [] | 13 - gpe-clock | [] [] [] | 10 - gpe-conf | [] [] | 9 - gpe-contacts | [] [] [] | 11 - gpe-edit | [] [] [] [] [] | 12 - gpe-go | | 5 - gpe-login | [] [] [] [] [] | 13 - gpe-ownerinfo | [] [] [] [] | 13 - gpe-sketchbook | [] [] | 9 - gpe-su | [] [] [] | 10 - gpe-taskmanager | [] [] [] | 10 - gpe-timesheet | [] [] [] [] | 12 - gpe-today | [] [] [] [] [] | 13 - gpe-todo | [] [] [] [] | 12 - gphoto2 | [] [] [] | 11 - gprof | [] [] | 9 - gpsdrive | [] [] | 3 - gramadoir | [] | 5 - grep | [] [] [] [] | 26 - gretl | | 3 - gtick | | 7 - hello | [] [] [] [] [] | 34 - id-utils | [] [] | 12 - indent | [] [] [] [] | 21 - iso_3166 | [] [] [] [] [] [] [] | 27 - iso_3166_1 | [] [] [] | 16 - iso_3166_2 | | 0 - iso_3166_3 | | 2 - iso_4217 | [] [] [] [] [] [] | 24 - iso_639 | | 1 - jpilot | [] [] [] [] [] | 9 - jtag | [] | 2 - jwhois | () [] [] | 11 - kbd | [] [] | 11 - latrine | | 2 - ld | [] [] | 5 - libc | [] [] [] [] | 20 - libgpewidget | [] [] [] [] | 13 - libiconv | [] [] [] [] [] [] [] [] | 27 - lifelines | [] | 2 - lilypond | [] | 3 - lingoteach | | 2 - lingoteach_lessons | () | 0 - lynx | [] [] [] | 14 - m4 | [] [] | 15 - mailutils | | 5 - make | [] [] [] | 16 - man-db | [] | 5 - minicom | | 11 - mysecretdiary | [] [] | 10 - nano | [] [] [] [] | 17 - nano_1_0 | [] [] [] | 17 - opcodes | [] [] | 6 - parted | [] [] [] | 15 - ptx | [] [] | 22 - python | | 0 - radius | | 4 - recode | [] [] [] | 20 - rpm | [] [] | 9 - screem | [] [] | 2 - scrollkeeper | [] [] [] | 15 - sed | [] [] [] [] [] [] | 24 - sh-utils | [] [] | 14 - shared-mime-info | [] [] | 7 - sharutils | [] [] [] [] | 17 - silky | () | 3 - skencil | [] | 6 - sketch | [] | 6 - soundtracker | [] [] | 7 - sp | [] | 3 - tar | [] [] [] [] [] | 24 - texinfo | [] [] [] | 14 - textutils | [] [] [] [] | 16 - tin | | 1 - tp-robot | | 2 - tuxpaint | [] [] [] [] [] | 29 - unicode-han-tra... | | 0 - unicode-transla... | | 2 - util-linux | [] [] | 15 - vorbis-tools | | 8 - wastesedge | | 0 - wdiff | [] [] [] | 18 - wget | [] [] [] [] [] [] [] [] | 24 - xchat | [] [] [] [] [] | 15 - xfree86_xkb_xml | [] [] [] [] [] | 11 - xpad | | 5 - +-----------------------------------------------------+ - 63 teams sk sl sr sv ta th tr uk ven vi wa xh zh_CN zh_TW zu - 131 domains 47 19 28 83 0 0 59 13 1 1 11 0 22 22 0 1373 - - Some counters in the preceding matrix are higher than the number of -visible blocks let us expect. This is because a few extra PO files are -used for implementing regional variants of languages, or language -dialects. - - For a PO file in the matrix above to be effective, the package to -which it applies should also have been internationalized and -distributed as such by its maintainer. There might be an observable -lag between the mere existence a PO file and its wide availability in a -distribution. - - If January 2004 seems to be old, you may fetch a more recent copy of -this `ABOUT-NLS' file on most GNU archive sites. The most up-to-date -matrix with full percentage details can be found at -`http://www.iro.umontreal.ca/contrib/po/HTML/matrix.html'. - -Using `gettext' in new packages -=============================== - -If you are writing a freely available program and want to -internationalize it you are welcome to use GNU `gettext' in your -package. Of course you have to respect the GNU Library General Public -License which covers the use of the GNU `gettext' library. This means -in particular that even non-free programs can use `libintl' as a shared -library, whereas only free software can use `libintl' as a static -library or use modified versions of `libintl'. - - Once the sources are changed appropriately and the setup can handle -the use of `gettext' the only thing missing are the translations. The -Free Translation Project is also available for packages which are not -developed inside the GNU project. Therefore the information given above -applies also for every other Free Software Project. Contact -`translation@iro.umontreal.ca' to make the `.pot' files available to -the translation teams. - diff --git a/xorg-server/xkeyboard-config/autogen.sh b/xorg-server/xkeyboard-config/autogen.sh index f9cd42b58..f9c238482 100644 --- a/xorg-server/xkeyboard-config/autogen.sh +++ b/xorg-server/xkeyboard-config/autogen.sh @@ -6,9 +6,8 @@ test -z "$srcdir" && srcdir=. ORIGDIR=`pwd` cd $srcdir -intltoolize +autopoint --force +AUTOPOINT='intltoolize --automake --copy' autoreconf -v --install --force || exit 1 -autoreconf -v --install || exit 1 cd $ORIGDIR || exit $? - $srcdir/configure --enable-maintainer-mode "$@" diff --git a/xorg-server/xkeyboard-config/config.rpath b/xorg-server/xkeyboard-config/config.rpath deleted file mode 100644 index e69de29bb..000000000 --- a/xorg-server/xkeyboard-config/config.rpath +++ /dev/null diff --git a/xorg-server/xkeyboard-config/configure.in b/xorg-server/xkeyboard-config/configure.in index 3b9fac2e0..6748cad68 100644 --- a/xorg-server/xkeyboard-config/configure.in +++ b/xorg-server/xkeyboard-config/configure.in @@ -70,12 +70,13 @@ AM_CONDITIONAL(USE_COMPAT_RULES, test "x$enable_compat_rules" = "xyes") # **** AC_PROG_INTLTOOL(0.30) +AM_GNU_GETTEXT_VERSION([0.18.1]) +AM_GNU_GETTEXT([external]) + GETTEXT_PACKAGE=xkeyboard-config AC_SUBST(GETTEXT_PACKAGE) AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE", [Gettext package]) -AM_GLIB_GNU_GETTEXT - ALL_LINGUAS="af az bg ca crh cs da de el en_GB eo es fi fr gl hu id it ja ka ko ky lt nb nl pl ro ru rw sk sl sq sr sv tr uk vi zh_CN zh_TW" AC_SUBST(xkb_base) diff --git a/xorg-server/xorg-server.pc.in b/xorg-server/xorg-server.pc.in index a98eca8f9..1de1c6c50 100644 --- a/xorg-server/xorg-server.pc.in +++ b/xorg-server/xorg-server.pc.in @@ -17,4 +17,4 @@ Description: Modular X.Org X Server Version: @PACKAGE_VERSION@ Requires.private: @SDK_REQUIRED_MODULES@ Cflags: -I${sdkdir} @symbol_visibility@ -Libs: -L${libdir} +Libs: -L${libdir} @XORG_DRIVER_LIBS@ |