diff options
66 files changed, 2000 insertions, 1179 deletions
diff --git a/fontconfig/conf.d/50-user.conf b/fontconfig/conf.d/50-user.conf index 3f8901296..2f1040898 100644 --- a/fontconfig/conf.d/50-user.conf +++ b/fontconfig/conf.d/50-user.conf @@ -2,6 +2,9 @@ <!DOCTYPE fontconfig SYSTEM "fonts.dtd"> <fontconfig> <!-- Load per-user customization file --> - <include ignore_missing="yes">~/.fonts.conf.d</include> - <include ignore_missing="yes">~/.fonts.conf</include> + <include ignore_missing="yes" prefix="xdg">fontconfig/conf.d</include> + <include ignore_missing="yes" prefix="xdg">fontconfig/fonts.conf</include> + <!-- the following elements will be removed in the future --> + <include ignore_missing="yes" deprecated="yes">~/.fonts.conf.d</include> + <include ignore_missing="yes" deprecated="yes">~/.fonts.conf</include> </fontconfig> diff --git a/fontconfig/doc/fontconfig-user.sgml b/fontconfig/doc/fontconfig-user.sgml index 22d2ad355..c6ab856bb 100644 --- a/fontconfig/doc/fontconfig-user.sgml +++ b/fontconfig/doc/fontconfig-user.sgml @@ -37,6 +37,8 @@ &confdir;/fonts.conf &confdir;/fonts.dtd &confdir;/conf.d + $XDG_CONFIG_HOME/fontconfig/conf.d + $XDG_CONFIG_HOME/fontconfig/fonts.conf ~/.fonts.conf.d ~/.fonts.conf </synopsis> @@ -299,21 +301,22 @@ following structure: This is the top level element for a font configuration and can contain <literal><dir></literal>, <literal><cachedir></literal>, <literal><include></literal>, <literal><match></literal> and <literal><alias></literal> elements in any order. </para></refsect2> - <refsect2><title><literal><dir></literal></title><para> + <refsect2><title><literal><dir prefix="default"></literal></title><para> This element contains a directory name which will be scanned for font files -to include in the set of available fonts. +to include in the set of available fonts. If 'prefix' is set to "xdg", the value in the XDG_DATA_HOME environment variable will be added as the path prefix. please see XDG Base Directory Specification for more details. </para></refsect2> - <refsect2><title><literal><cachedir></literal></title><para> + <refsect2><title><literal><cachedir prefix="default"></literal></title><para> This element contains a directory name that is supposed to be stored or read the cache of font information. If multiple elements are specified in the configuration file, the directory that can be accessed first in the list will be used to store the cache files. If it starts with '~', it refers to -a directory in the users home directory. The default directory is ``~/.fontconfig'' -and it contains the cache files named ``<literal><hash value></literal>-<literal><architecture></literal>.cache-<literal><version</literal>'', +a directory in the users home directory. If 'prefix' is set to "xdg", the value in the XDG_CACHE_HOME environment variable will be added as the path prefix. please see XDG Base Directory Specification for more details. +The default directory is ``$XDG_CACHE_HOME/fontconfig'' and it contains the cache files +named ``<literal><hash value></literal>-<literal><architecture></literal>.cache-<literal><version</literal>'', where <literal><version></literal> is the font configureation file version number (currently 3). </para></refsect2> - <refsect2><title><literal><include ignore_missing="no"></literal></title><para> + <refsect2><title><literal><include ignore_missing="no" prefix="default"></literal></title><para> This element contains the name of an additional configuration file or directory. If a directory, every file within that directory starting with an ASCII digit (U+0030 - U+0039) and ending with the string ``.conf'' will be processed in sorted order. When @@ -321,7 +324,7 @@ the XML datatype is traversed by FcConfigParse, the contents of the file(s) will also be incorporated into the configuration by passing the filename(s) to FcConfigLoadAndParse. If 'ignore_missing' is set to "yes" instead of the default "no", a missing file or directory will elicit no warning message from -the library. +the library. If 'prefix' is set to "xdg", the value in the XDG_CONFIG_HOME environment variable will be added as the path prefix. please see XDG Base Directory Specification for more details. </para></refsect2> <refsect2><title><literal><config></literal></title><para> This element provides a place to consolidate additional configuration @@ -564,20 +567,20 @@ This is an example of a system-wide configuration file </match> <!-- - Names not including any well known alias are given 'sans' + Names not including any well known alias are given 'sans-serif' --> <match target="pattern"> - <test qual="all" name="family" mode="not_eq">sans</test> - <test qual="all" name="family" mode="not_eq">serif</test> - <test qual="all" name="family" mode="not_eq">monospace</test> - <edit name="family" mode="append_last"><string>sans</string></edit> + <test qual="all" name="family" mode="not_eq"><string>sans-serif</string></test> + <test qual="all" name="family" mode="not_eq"><string>serif</string></test> + <test qual="all" name="family" mode="not_eq"><string>monospace</string></test> + <edit name="family" mode="append_last"><string>sans-serif</string></edit> </match> <!-- Load per-user customization file, but don't complain if it doesn't exist --> -<include ignore_missing="yes">~/.fonts.conf</include> +<include ignore_missing="yes" prefix="xdg">fontconfig/fonts.conf</include> <!-- Load local customization files, but don't complain @@ -630,18 +633,18 @@ This is an example of a system-wide configuration file <refsect2><title>User configuration file</title> <para> This is an example of a per-user configuration file that lives in -~/.fonts.conf +$XDG_CONFIG_HOME/fontconfig/fonts.conf </para> <programlisting> <?xml version="1.0"?> <!DOCTYPE fontconfig SYSTEM "fonts.dtd"> -<!-- ~/.fonts.conf for per-user font configuration --> +<!-- $XDG_CONFIG_HOME/fontconfig/fonts.conf for per-user font configuration --> <fontconfig> <!-- Private font directory --> -<dir>~/.fonts</dir> +<dir prefix="xdg">fonts</dir> <!-- use rgb sub-pixel ordering to improve glyph appearance on @@ -677,20 +680,20 @@ format. The master fonts.conf file references this directory in an is a DTD that describes the format of the configuration files. </para> <para> -<emphasis>~/.fonts.conf.d</emphasis> +<emphasis>$XDG_CONFIG_HOME/fontconfig/conf.d</emphasis> and <emphasis>~/.fonts.conf.d</emphasis> is the conventional name for a per-user directory of (typically auto-generated) configuration files, although the -actual location is specified in the global fonts.conf file. +actual location is specified in the global fonts.conf file. please note that ~/.fonts.conf.d is deprecated now. it will not be read by default in the future version. </para> <para> -<emphasis>~/.fonts.conf</emphasis> +<emphasis>$XDG_CONFIG_HOME/fontconfig/fonts.conf</emphasis> and <emphasis>~/.fonts.conf</emphasis> is the conventional location for per-user font configuration, although the -actual location is specified in the global fonts.conf file. +actual location is specified in the global fonts.conf file. please note that ~/.fonts.conf is deprecated now. it will not be read by default in the future version. </para> <para> -<emphasis> ~/.fontconfig/*.cache-*</emphasis> +<emphasis>$XDG_CACHE_HOME/fontconfig/*.cache-*</emphasis> and <emphasis> ~/.fontconfig/*.cache-*</emphasis> is the conventional repository of font information that isn't found in the -per-directory caches. This file is automatically maintained by fontconfig. +per-directory caches. This file is automatically maintained by fontconfig. please note that ~/.fontconfig/*.cache-* is deprecated now. it will not be read by default in the future version. </para> </refsect1> <refsect1><title>Environment variables</title> diff --git a/fontconfig/fonts.conf.in b/fontconfig/fonts.conf.in index 8f9fb8823..6a8753d01 100644 --- a/fontconfig/fonts.conf.in +++ b/fontconfig/fonts.conf.in @@ -25,6 +25,8 @@ <dir>@FC_DEFAULT_FONTS@</dir> @FC_FONTPATH@ + <dir prefix="xdg">fonts</dir> + <!-- the following element will be removed in the future --> <dir>~/.fonts</dir> <!-- @@ -71,6 +73,8 @@ <!-- Font cache directory list --> <cachedir>@FC_CACHEDIR@</cachedir> + <cachedir prefix="xdg">fontconfig</cachedir> + <!-- the following element will be removed in the future --> <cachedir>~/.fontconfig</cachedir> <config> diff --git a/fontconfig/fonts.dtd b/fontconfig/fonts.dtd index 255367cf5..782e59244 100644 --- a/fontconfig/fonts.dtd +++ b/fontconfig/fonts.dtd @@ -12,7 +12,9 @@ Add a directory that provides fonts --> <!ELEMENT dir (#PCDATA)> -<!ATTLIST dir xml:space (default|preserve) 'preserve'> +<!ATTLIST dir + prefix (#PCDATA) "default" + xml:space (default|preserve) 'preserve'> <!-- Define the per-user file that holds cache font information. @@ -33,7 +35,9 @@ home directory path. --> <!ELEMENT cachedir (#PCDATA)> -<!ATTLIST cachedir xml:space (default|preserve) 'preserve'> +<!ATTLIST cachedir + prefix (#PCDATA) "default" + xml:space (default|preserve) 'preserve'> <!-- Reference another configuration file; note that this @@ -48,6 +52,8 @@ <!ELEMENT include (#PCDATA)> <!ATTLIST include ignore_missing (no|yes) "no" + prefix (#PCDATA) "default" + deprecated (#PCDATA) "no" xml:space (default|preserve) "preserve"> <!-- diff --git a/fontconfig/src/fccfg.c b/fontconfig/src/fccfg.c index 31c427636..5b7249201 100644 --- a/fontconfig/src/fccfg.c +++ b/fontconfig/src/fccfg.c @@ -1837,6 +1837,81 @@ FcConfigHome (void) return 0; } +FcChar8 * +FcConfigXdgCacheHome (void) +{ + const char *env = getenv ("XDG_CACHE_HOME"); + FcChar8 *ret = NULL; + + if (env) + ret = FcStrCopy ((const FcChar8 *)env); + else + { + const FcChar8 *home = FcConfigHome (); + size_t len = home ? strlen ((const char *)home) : 0; + + ret = malloc (len + 7 + 1); + if (ret) + { + memcpy (ret, home, len); + memcpy (&ret[len], FC_DIR_SEPARATOR_S ".cache", 7); + ret[len + 7] = 0; + } + } + + return ret; +} + +FcChar8 * +FcConfigXdgConfigHome (void) +{ + const char *env = getenv ("XDG_CONFIG_HOME"); + FcChar8 *ret = NULL; + + if (env) + ret = FcStrCopy ((const FcChar8 *)env); + else + { + const FcChar8 *home = FcConfigHome (); + size_t len = home ? strlen ((const char *)home) : 0; + + ret = malloc (len + 8 + 1); + if (ret) + { + memcpy (ret, home, len); + memcpy (&ret[len], FC_DIR_SEPARATOR_S ".config", 8); + ret[len + 8] = 0; + } + } + + return ret; +} + +FcChar8 * +FcConfigXdgDataHome (void) +{ + const char *env = getenv ("XDG_DATA_HOME"); + FcChar8 *ret = NULL; + + if (env) + ret = FcStrCopy ((const FcChar8 *)env); + else + { + const FcChar8 *home = FcConfigHome (); + size_t len = home ? strlen ((const char *)home) : 0; + + ret = malloc (len + 13 + 1); + if (ret) + { + memcpy (ret, home, len); + memcpy (&ret[len], FC_DIR_SEPARATOR_S ".local" FC_DIR_SEPARATOR_S "share", 13); + ret[len + 13] = 0; + } + } + + return ret; +} + FcBool FcConfigEnableHome (FcBool enable) { @@ -1883,7 +1958,7 @@ FcConfigFilename (const FcChar8 *url) default: path = FcConfigGetPath (); if (!path) - return 0; + return NULL; for (p = path; *p; p++) { file = FcConfigFileExists (*p, url); @@ -1893,6 +1968,7 @@ FcConfigFilename (const FcChar8 *url) FcConfigFreePath (path); break; } + return file; } diff --git a/fontconfig/src/fcinit.c b/fontconfig/src/fcinit.c index abf64b57f..ab6401215 100644 --- a/fontconfig/src/fcinit.c +++ b/fontconfig/src/fcinit.c @@ -72,21 +72,37 @@ FcInitLoadConfig (void) if (config->cacheDirs && config->cacheDirs->num == 0) { + FcChar8 *prefix; + size_t plen; + fprintf (stderr, "Fontconfig warning: no <cachedir> elements found. Check configuration.\n"); fprintf (stderr, "Fontconfig warning: adding <cachedir>%s</cachedir>\n", FC_CACHEDIR); + prefix = FcConfigXdgCacheHome (); + plen = prefix ? strlen ((const char *)prefix) : 0; + if (!prefix) + goto bail; + prefix = realloc (prefix, plen + 12); + if (!prefix) + goto bail; + memcpy (&prefix[plen], FC_DIR_SEPARATOR_S "fontconfig", 11); + prefix[plen + 11] = 0; fprintf (stderr, - "Fontconfig warning: adding <cachedir>~/.fontconfig</cachedir>\n"); + "Fontconfig warning: adding <cachedir prefix=\"xdg\">fontconfig</cachedir>\n"); + if (!FcConfigAddCacheDir (config, (FcChar8 *) FC_CACHEDIR) || - !FcConfigAddCacheDir (config, (FcChar8 *) "~/.fontconfig")) + !FcConfigAddCacheDir (config, (FcChar8 *) prefix)) { + bail: fprintf (stderr, "Fontconfig error: out of memory"); + free (prefix); FcConfigDestroy (config); return FcInitFallbackConfig (); } + free (prefix); } return config; diff --git a/fontconfig/src/fcint.h b/fontconfig/src/fcint.h index defbd7acb..46562c4ca 100644 --- a/fontconfig/src/fcint.h +++ b/fontconfig/src/fcint.h @@ -66,9 +66,11 @@ typedef HRESULT (WINAPI *pfnSHGetFolderPathA)(HWND, int, HANDLE, DWORD, LPSTR); extern pfnGetSystemWindowsDirectory pGetSystemWindowsDirectory; extern pfnSHGetFolderPathA pSHGetFolderPathA; # define FC_SEARCH_PATH_SEPARATOR ';' +# define FC_DIR_SEPARATOR '\\' # define FC_DIR_SEPARATOR_S "\\" #else # define FC_SEARCH_PATH_SEPARATOR ':' +# define FC_DIR_SEPARATOR '/' # define FC_DIR_SEPARATOR_S "/" #endif @@ -572,6 +574,15 @@ FcStat (const FcChar8 *file, struct stat *statb); /* fccfg.c */ +FcPrivate FcChar8 * +FcConfigXdgCacheHome (void); + +FcPrivate FcChar8 * +FcConfigXdgConfigHome (void); + +FcPrivate FcChar8 * +FcConfigXdgDataHome (void); + FcPrivate FcExpr * FcConfigAllocExpr (FcConfig *config); diff --git a/fontconfig/src/fcstr.c b/fontconfig/src/fcstr.c index ae37ff00a..f20d05e7d 100644 --- a/fontconfig/src/fcstr.c +++ b/fontconfig/src/fcstr.c @@ -896,11 +896,11 @@ FcStrCopyFilename (const FcChar8 *s) FcChar8 *full; int size; if (!home) - return 0; + return NULL; size = strlen ((char *) home) + strlen ((char *) s); full = (FcChar8 *) malloc (size); if (!full) - return 0; + return NULL; strcpy ((char *) full, (char *) home); strcat ((char *) full, (char *) s + 1); new = FcStrCanonFilename (full); @@ -908,6 +908,7 @@ FcStrCopyFilename (const FcChar8 *s) } else new = FcStrCanonFilename (s); + return new; } diff --git a/fontconfig/src/fcxml.c b/fontconfig/src/fcxml.c index c49529a81..f0272705d 100644 --- a/fontconfig/src/fcxml.c +++ b/fontconfig/src/fcxml.c @@ -1844,24 +1844,238 @@ FcParseUnary (FcConfigParse *parse, FcOp op) } static void +FcParseDir (FcConfigParse *parse) +{ + const FcChar8 *attr, *data; + FcChar8 *prefix = NULL; + + attr = FcConfigGetAttribute (parse, "prefix"); + if (attr && FcStrCmp (attr, (const FcChar8 *)"xdg") == 0) + prefix = FcConfigXdgDataHome (); + data = FcStrBufDoneStatic (&parse->pstack->str); + if (!data) + { + FcConfigMessage (parse, FcSevereError, "out of memory"); + goto bail; + } + if (prefix) + { + size_t plen = strlen ((const char *)prefix); + size_t dlen = strlen ((const char *)data); + + prefix = realloc (prefix, plen + 1 + dlen + 1); + if (!prefix) + { + FcConfigMessage (parse, FcSevereError, "out of memory"); + goto bail; + } + prefix[plen] = FC_DIR_SEPARATOR; + memcpy (&prefix[plen + 1], data, dlen); + prefix[plen + 1 + dlen] = 0; + data = prefix; + } +#ifdef _WIN32 + if (strcmp (data, "CUSTOMFONTDIR") == 0) + { + char *p; + data = buffer; + if (!GetModuleFileName (NULL, buffer, sizeof (buffer) - 20)) + { + FcConfigMessage (parse, FcSevereError, "GetModuleFileName failed"); + break; + } + /* + * Must use the multi-byte aware function to search + * for backslash because East Asian double-byte code + * pages have characters with backslash as the second + * byte. + */ + p = _mbsrchr (data, '\\'); + if (p) *p = '\0'; + strcat (data, "\\fonts"); + } + else if (strcmp (data, "APPSHAREFONTDIR") == 0) + { + char *p; + data = buffer; + if (!GetModuleFileName (NULL, buffer, sizeof (buffer) - 20)) + { + FcConfigMessage (parse, FcSevereError, "GetModuleFileName failed"); + break; + } + p = _mbsrchr (data, '\\'); + if (p) *p = '\0'; + strcat (data, "\\..\\share\\fonts"); + } + else if (strcmp (data, "WINDOWSFONTDIR") == 0) + { + int rc; + data = buffer; + rc = pGetSystemWindowsDirectory (buffer, sizeof (buffer) - 20); + if (rc == 0 || rc > sizeof (buffer) - 20) + { + FcConfigMessage (parse, FcSevereError, "GetSystemWindowsDirectory failed"); + break; + } + if (data [strlen (data) - 1] != '\\') + strcat (data, "\\"); + strcat (data, "fonts"); + } +#endif + if (strlen ((char *) data) == 0) + FcConfigMessage (parse, FcSevereWarning, "empty font directory name ignored"); + else if (!FcStrUsesHome (data) || FcConfigHome ()) + { + if (!FcConfigAddDir (parse->config, data)) + FcConfigMessage (parse, FcSevereError, "out of memory; cannot add directory %s", data); + } + FcStrBufDestroy (&parse->pstack->str); + + bail: + if (prefix) + free (prefix); +} + +static void +FcParseCacheDir (FcConfigParse *parse) +{ + const FcChar8 *attr; + FcChar8 *prefix = NULL, *data; + + attr = FcConfigGetAttribute (parse, "prefix"); + if (attr && FcStrCmp (attr, (const FcChar8 *)"xdg") == 0) + prefix = FcConfigXdgCacheHome (); + data = FcStrBufDone (&parse->pstack->str); + if (!data) + { + FcConfigMessage (parse, FcSevereError, "out of memory"); + goto bail; + } + if (prefix) + { + size_t plen = strlen ((const char *)prefix); + size_t dlen = strlen ((const char *)data); + + prefix = realloc (prefix, plen + 1 + dlen + 1); + if (!prefix) + { + FcConfigMessage (parse, FcSevereError, "out of memory"); + goto bail; + } + prefix[plen] = FC_DIR_SEPARATOR; + memcpy (&prefix[plen + 1], data, dlen); + prefix[plen + 1 + dlen] = 0; + FcStrFree (data); + data = prefix; + } +#ifdef _WIN32 + if (strcmp (data, "WINDOWSTEMPDIR_FONTCONFIG_CACHE") == 0) + { + int rc; + FcStrFree (data); + data = malloc (1000); + if (!data) + { + FcConfigMessage (parse, FcSevereError, "out of memory"); + goto bail; + } + FcMemAlloc (FC_MEM_STRING, 1000); + rc = GetTempPath (800, data); + if (rc == 0 || rc > 800) + { + FcConfigMessage (parse, FcSevereError, "GetTempPath failed"); + goto bail; + } + if (data [strlen (data) - 1] != '\\') + strcat (data, "\\"); + strcat (data, "fontconfig\\cache"); + } + else if (strcmp (data, "LOCAL_APPDATA_FONTCONFIG_CACHE") == 0) + { + char szFPath[MAX_PATH + 1]; + size_t len; + + if (!(pSHGetFolderPathA && SUCCEEDED(pSHGetFolderPathA(NULL, /* CSIDL_LOCAL_APPDATA */ 28, NULL, 0, szFPath)))) + { + FcConfigMessage (parse, FcSevereError, "SHGetFolderPathA failed"); + goto bail; + } + strncat(szFPath, "\\fontconfig\\cache", MAX_PATH - 1 - strlen(szFPath)); + len = strlen(szFPath) + 1; + FcStrFree (data); + data = malloc(len); + if (!data) + { + FcConfigMessage (parse, FcSevereError, "out of memory"); + goto bail; + } + FcMemAlloc (FC_MEM_STRING, len); + strncpy(data, szFPath, len); + } +#endif + if (strlen ((char *) data) == 0) + FcConfigMessage (parse, FcSevereWarning, "empty cache directory name ignored"); + else if (!FcStrUsesHome (data) || FcConfigHome ()) + { + if (!FcConfigAddCacheDir (parse->config, data)) + FcConfigMessage (parse, FcSevereError, "out of memory; cannot add cache directory %s", data); + } + FcStrBufDestroy (&parse->pstack->str); + + bail: + if (data) + FcStrFree (data); +} + +static void FcParseInclude (FcConfigParse *parse) { FcChar8 *s; - const FcChar8 *i; + const FcChar8 *attr; FcBool ignore_missing = FcFalse; + FcChar8 *prefix = NULL; s = FcStrBufDoneStatic (&parse->pstack->str); if (!s) { FcConfigMessage (parse, FcSevereError, "out of memory"); - return; + goto bail; } - i = FcConfigGetAttribute (parse, "ignore_missing"); - if (i && FcConfigLexBool (parse, (FcChar8 *) i) == FcTrue) + attr = FcConfigGetAttribute (parse, "ignore_missing"); + if (attr && FcConfigLexBool (parse, (FcChar8 *) attr) == FcTrue) ignore_missing = FcTrue; + attr = FcConfigGetAttribute (parse, "prefix"); + if (attr && FcStrCmp (attr, (const FcChar8 *)"xdg") == 0) + prefix = FcConfigXdgConfigHome (); + if (prefix) + { + size_t plen = strlen ((const char *)prefix); + size_t dlen = strlen ((const char *)s); + + prefix = realloc (prefix, plen + 1 + dlen + 1); + if (!prefix) + { + FcConfigMessage (parse, FcSevereError, "out of memory"); + goto bail; + } + prefix[plen] = FC_DIR_SEPARATOR; + memcpy (&prefix[plen + 1], s, dlen); + prefix[plen + 1 + dlen] = 0; + s = prefix; + } if (!FcConfigParseAndLoad (parse->config, s, !ignore_missing)) parse->error = FcTrue; + else + { + attr = FcConfigGetAttribute (parse, "deprecated"); + if (attr && FcConfigLexBool (parse, (FcChar8 *) attr) == FcTrue) + FcConfigMessage (parse, FcSevereWarning, "reading configurations from %s is deprecated.\n", s); + } FcStrBufDestroy (&parse->pstack->str); + + bail: + if (prefix) + free (prefix); } typedef struct _FcOpMap { @@ -2296,129 +2510,11 @@ FcEndElement(void *userData, const XML_Char *name) case FcElementFontconfig: break; case FcElementDir: - data = FcStrBufDoneStatic (&parse->pstack->str); - if (!data) - { - FcConfigMessage (parse, FcSevereError, "out of memory"); - break; - } -#ifdef _WIN32 - if (strcmp (data, "CUSTOMFONTDIR") == 0) - { - char *p; - data = buffer; - if (!GetModuleFileName (NULL, buffer, sizeof (buffer) - 20)) - { - FcConfigMessage (parse, FcSevereError, "GetModuleFileName failed"); - break; - } - /* - * Must use the multi-byte aware function to search - * for backslash because East Asian double-byte code - * pages have characters with backslash as the second - * byte. - */ - p = _mbsrchr (data, '\\'); - if (p) *p = '\0'; - strcat (data, "\\fonts"); - } - else if (strcmp (data, "APPSHAREFONTDIR") == 0) - { - char *p; - data = buffer; - if (!GetModuleFileName (NULL, buffer, sizeof (buffer) - 20)) - { - FcConfigMessage (parse, FcSevereError, "GetModuleFileName failed"); - break; - } - p = _mbsrchr (data, '\\'); - if (p) *p = '\0'; - strcat (data, "\\..\\share\\fonts"); - } - else if (strcmp (data, "WINDOWSFONTDIR") == 0) - { - int rc; - data = buffer; - rc = pGetSystemWindowsDirectory (buffer, sizeof (buffer) - 20); - if (rc == 0 || rc > sizeof (buffer) - 20) - { - FcConfigMessage (parse, FcSevereError, "GetSystemWindowsDirectory failed"); - break; - } - if (data [strlen (data) - 1] != '\\') - strcat (data, "\\"); - strcat (data, "fonts"); - } -#endif - if (strlen ((char *) data) == 0) - FcConfigMessage (parse, FcSevereWarning, "empty font directory name ignored"); - else if (!FcStrUsesHome (data) || FcConfigHome ()) - { - if (!FcConfigAddDir (parse->config, data)) - FcConfigMessage (parse, FcSevereError, "out of memory; cannot add directory %s", data); - } - FcStrBufDestroy (&parse->pstack->str); + FcParseDir (parse); break; case FcElementCacheDir: - data = FcStrBufDone (&parse->pstack->str); - if (!data) - { - FcConfigMessage (parse, FcSevereError, "out of memory"); - break; - } -#ifdef _WIN32 - if (strcmp (data, "WINDOWSTEMPDIR_FONTCONFIG_CACHE") == 0) - { - int rc; - FcStrFree (data); - data = malloc (1000); - if (!data) - { - FcConfigMessage (parse, FcSevereError, "out of memory"); - break; - } - FcMemAlloc (FC_MEM_STRING, 1000); - rc = GetTempPath (800, data); - if (rc == 0 || rc > 800) - { - FcConfigMessage (parse, FcSevereError, "GetTempPath failed"); - FcStrFree (data); - break; - } - if (data [strlen (data) - 1] != '\\') - strcat (data, "\\"); - strcat (data, "fontconfig\\cache"); - } - else if (strcmp (data, "LOCAL_APPDATA_FONTCONFIG_CACHE") == 0) - { - char szFPath[MAX_PATH + 1]; - size_t len; - FcStrFree (data); - if (!(pSHGetFolderPathA && SUCCEEDED(pSHGetFolderPathA(NULL, /* CSIDL_LOCAL_APPDATA */ 28, NULL, 0, szFPath)))) - { - FcConfigMessage (parse, FcSevereError, "SHGetFolderPathA failed"); - break; - } - strncat(szFPath, "\\fontconfig\\cache", MAX_PATH - 1 - strlen(szFPath)); - len = strlen(szFPath) + 1; - data = malloc(len); - if (!data) - { - FcConfigMessage (parse, FcSevereError, "out of memory"); - break; - } - FcMemAlloc (FC_MEM_STRING, len); - strncpy(data, szFPath, len); - } -#endif - if (!FcStrUsesHome (data) || FcConfigHome ()) - { - if (!FcConfigAddCacheDir (parse->config, data)) - FcConfigMessage (parse, FcSevereError, "out of memory; cannot add cache directory %s", data); - } - FcStrFree (data); + FcParseCacheDir (parse); break; - case FcElementCache: data = FcStrBufDoneStatic (&parse->pstack->str); if (!data) diff --git a/mesalib/configure.ac b/mesalib/configure.ac index e177846d7..844990a28 100644 --- a/mesalib/configure.ac +++ b/mesalib/configure.ac @@ -642,8 +642,8 @@ AC_ARG_ENABLE([gallium_gbm], [enable_gallium_gbm=auto]) AC_ARG_ENABLE([r600-llvm-compiler], - [AS_HELP_STRING([--enable-r600-llvm-compilerl], - [Enable experimental LLVM backend for graphics shaders @<:default=disable@:>@])], + [AS_HELP_STRING([--enable-r600-llvm-compiler], + [Enable experimental LLVM backend for graphics shaders @<:@default=disable@:>@])], [enable_r600_llvm="$enableval"], [enable_r600_llvm=no]) diff --git a/mesalib/docs/news.html b/mesalib/docs/news.html index fed8881af..140f35b47 100644 --- a/mesalib/docs/news.html +++ b/mesalib/docs/news.html @@ -11,6 +11,14 @@ <H1>News</H1> +<h2>May 18, 2012</h2> + +<p> +<a href="relnotes-8.0.3.html">Mesa 8.0.3</a> is released. +This is a bug fix release. +</p> + + <h2>March 21, 2012</h2> <p> diff --git a/mesalib/docs/relnotes-8.0.3.html b/mesalib/docs/relnotes-8.0.3.html new file mode 100644 index 000000000..dd27befd2 --- /dev/null +++ b/mesalib/docs/relnotes-8.0.3.html @@ -0,0 +1,319 @@ +<HTML> + +<head> +<TITLE>Mesa Release Notes</TITLE> +<link rel="stylesheet" type="text/css" href="mesa.css"> +<meta http-equiv="content-type" content="text/html; charset=utf-8" /> +</head> + +<BODY> + +<body bgcolor="#eeeeee"> + +<H1>Mesa 8.0.3 Release Notes / May 18, 2012</H1> + +<p> +Mesa 8.0.3 is a bug fix release which fixes bugs found since the 8.0.2 release. +</p> +<p> +Mesa 8.0.3 implements the OpenGL 3.0 API, but the version reported by +glGetString(GL_VERSION) depends on the particular driver being used. +Some drivers don't support all the features required in OpenGL 3.0. +</p> +<p> +See the <a href="install.html">Compiling/Installing page</a> for prerequisites +for DRI hardware acceleration. +</p> + + +<h2>MD5 checksums</h2> +<pre> +b7210a6d6e4584bd852ab29294ce717e MesaLib-8.0.3.tar.gz +cc5ee15e306b8c15da6a478923797171 MesaLib-8.0.3.tar.bz2 +32773634a0f7e70a680505a81426eccf MesaLib-8.0.3.zip +</pre> + +<h2>New features</h2> +<p>None.</p> + +<h2>Bug fixes</h2> + +<p>This list is likely incomplete.</p> + +<ul> + +<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=28138">Bug 28138</a> - [G45] Regnum Online, sparkling in in-game rendering</li> + +<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=30102">Bug 30102</a> - glean depthStencil test fails BadLength with indirect non-swrast rendering</li> + +<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=40361">Bug 40361</a> - Glitches on X3100 after upgrade to 7.11</li> + +<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=41152">Bug 41152</a> - [glsl] Shader backend in Regnum Online does not work</li> + +<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=41216">Bug 41216</a> - [bisected pineview]oglc filtercubemin(basic.sizedRGBA) fails</li> + +<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=41372">Bug 41372</a> - i830_state.c PBO crash</li> + +<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=41495">Bug 41495</a> - i830: intel_get_vb_max / intel_batchbuffer_space mismatch.</li> + +<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=44701">Bug 44701</a> - Regnum online textures flickering</li> + +<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=44961">Bug 44961</a> - [bisected i965] oglc sRGB(Mipmap.1D_textures) regressed</li> + +<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=44970">Bug 44970</a> - [i965]oglc max_values(negative.textureSize.textureCube) segfaults</li> + +<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=45214">Bug 45214</a> - Textures disappearing or missing in RegnumOnline OpenGL game</li> + +<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=45558">Bug 45558</a> - cannot render on a drawable of size equal the max framebuffer size</li> + +<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=45921">Bug 45921</a> - [r300g, bisected] Multiple piglit regressions after glsl_to_tgsi changes</li> + +<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=46303">Bug 46303</a> - [SNB] segfault in intel_miptree_release()</li> + +<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=46739">Bug 46739</a> - [snb-m-gt2+] compiz crashed with SIGSEGV in intel_miptree_release()</li> + +<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=46834">Bug 46834</a> - small performance when playing flightgear (swrast fallback through GTT mapping)</li> + +<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=47126">Bug 47126</a> - tests/fbo/fbo-array.c:109: create_array_fbo: Assertion `glGetError() == 0' failed.</li> + +<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=48218">Bug 48218</a> - brw_fs_schedule_instructions.cpp segfault due to accessing not allocated last_mrf_write[16]</li> + +<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=48545">Bug 48545</a> - LLVMpipe glReadPixels Firefox hits the slow path (WebGL rendering)</li> + +<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=49124">Bug 49124</a> - swrast/s_texfetch.c:1156: set_fetch_functions: Assertion `texImage->FetchTexel' failed.</li> + +<!-- <li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=">Bug </a> - </li> --> + +</ul> + + +<h2>Changes</h2> +<p>The full set of changes can be viewed by using the following GIT command:</p> + +<pre> + git log mesa-8.0.2..mesa-8.0.3 +</pre> + +<p>Alban Browaeys (1): +<ul> + <li>dri/i915: Fix off-by-one in i830 clip region size.</li> +</ul></p> + +<p>Alex Deucher (2): +<ul> + <li>r200: fix fog coordinate emit</li> + <li>radeon: fix fog coordinate emit</li> +</ul></p> + +<p>Alexander von Gluck (4): +<ul> + <li>llvmpipe: fix symbol conflict on Haiku</li> + <li>svga: fix typedef conflicts on Haiku</li> + <li>mesa: Don't use newlocale on Haiku</li> + <li>glsl: Don't use newlocale on Haiku</li> +</ul></p> + +<p>Anuj Phogat (4): +<ul> + <li>mesa: fix issues with texture border and array textures</li> + <li>mesa: Fix valid texture target test in _mesa_GetTexLevelParameteriv()</li> + <li>mesa: Fix the cause of piglit test fbo-array failure</li> + <li>intel: Fix a case when mapping large texture fails</li> +</ul></p> + +<p>Brian Paul (17): +<ul> + <li>mesa: add a couple fast-paths to fast_read_rgba_pixels_memcpy()</li> + <li>mesa/gdi: remove wmesa_set_renderbuffer_funcs() function</li> + <li>mesa/gdi: remove clear_color() function</li> + <li>mesa: bump version to 8.0.2 in configs/default</li> + <li>swrast: include s_fragprog.h to silence warnings</li> + <li>mesa: remove LSB-first pixel packing check in glReadPixels</li> + <li>mesa: fix error in _mesa_format_matches_format_and_type() for RGB888</li> + <li>mesa: add BGR888 code in _mesa_format_matches_format_and_type()</li> + <li>vbo: fix node_attrsz[] usage in vbo_bind_vertex_list()</li> + <li>mesa: add missing texture integer test in glTexSubImage()</li> + <li>mesa: add missing return after _mesa_error() in update_array()</li> + <li>glsl: propagate MaxUnrollIterations to the optimizer's loop unroller</li> + <li>st/mesa: set MaxUnrollIterations = 255</li> + <li>st/mesa: no-op glCopyPixels if source region is out of bounds</li> + <li>mesa: do more teximage error checking for generic compressed formats</li> + <li>mesa: fix/add error check in _mesa_ColorMaterial()</li> + <li>mesa: fix glMaterial / dlist bug</li> +</ul></p> + +<p>Chad Versace (3): +<ul> + <li>glsl: Fix Android build</li> + <li>main: Fix memory leak in _mesa_make_extension_string()</li> + <li>intel: Disable ARB_framebuffer_object in ES contexts</li> +</ul></p> + +<p>Chris Wilson (1): +<ul> + <li>i830: Compute initial number of vertices from remaining batch space</li> +</ul></p> + +<p>Dave Airlie (4): +<ul> + <li>mesa/format_unpack: add LUMINANCE 8/16 UINT/INT</li> + <li>glx/drisw: avoid segfaults when we fail to get visual</li> + <li>drisw: fix image stride calculation for 16-bit.</li> + <li>intel: fix TFP at 16-bpp</li> +</ul></p> + +<p>Dylan Noblesmith (7): +<ul> + <li>intel: fix null dereference processing HiZ buffer</li> + <li>util: fix undefined behavior</li> + <li>util: fix uninitialized table</li> + <li>egl: fix uninitialized values</li> + <li>st/vega: fix uninitialized values</li> + <li>egl-static: fix printf warning</li> + <li>i965: fix typo</li> +</ul></p> + +<p>Eric Anholt (19): +<ul> + <li>i965/fs: Jump from discard statements to the end of the program when done.</li> + <li>intel: Fix rendering from textures after RenderTexture().</li> + <li>mesa: Fix handling of glCopyBufferSubData() for src == dst.</li> + <li>i965/fs: Move GL_CLAMP handling to coordinate setup.</li> + <li>i965/fs: Implement GL_CLAMP behavior on texture rectangles on gen6+.</li> + <li>mesa: Fix push/pop of multisample coverage invert.</li> + <li>mesa: Include the multisample enables under GL_MULTISAMPLE_BIT attrib as well.</li> + <li>mesa: Fix display list handling for GL_ARB_draw_instanced.</li> + <li>mesa: Fix display lists for draw_elements_base_vertex with draw_instanced.</li> + <li>mesa: Add missing error check for first < 0 in glDrawArraysInstanced().</li> + <li>i915: Fix piglit fbo-nodepth-test on i830.</li> + <li>intel: Return success when asked to allocate a 0-width/height renderbuffer.</li> + <li>mesa: Throw error on glGetActiveUniform inside Begin/End.</li> + <li>i965/vs: Fix up swizzle for dereference_array of matrices.</li> + <li>glsl: Fix indentation of switch code.</li> + <li>glsl: Let the constructor figure out the types of switch-related expressions.</li> + <li>glsl: Reject non-scalar switch expressions.</li> + <li>glsl: Fix assertion failure on handling switch on uint expressions.</li> + <li>mesa: Check for framebuffer completeness before looking at the rb.</li> +</ul></p> + +<p>Eugeni Dodonov (1): +<ul> + <li>intel: add PCI IDs for Ivy Bridge GT2 server variant</li> +</ul></p> + +<p>Han Shen(沈涵) (1): +<ul> + <li>bin/mklib: remove '-m32' for arm linux</li> +</ul></p> + +<p>Ian Romanick (1): +<ul> + <li>mesa: Bump version number to 8.0.3</li> +</ul></p> + +<p>Jakob Bornecrantz (1): +<ul> + <li>docs: Add 8.0.2 md5sums</li> +</ul></p> + +<p>Jeremy Huddleston (7): +<ul> + <li>darwin: Eliminate a pthread mutex leak</li> + <li>darwin: Fix an error message</li> + <li>darwin: Make reported errors more user-friendly</li> + <li>darwin: Use ASL for logging</li> + <li>darwin: Unlock our mutex before destroying it</li> + <li>darwin: Eliminate a possible race condition while destroying a surface</li> + <li>darwin: Address a build failure on Leopard and earlier OS versions</li> +</ul></p> + +<p>Jon TURNEY (1): +<ul> + <li>Have __glImageSize handle format GL_DEPTH_STENCIL_NV the same way as the server does</li> +</ul></p> + +<p>Jonas Maebe (2): +<ul> + <li>glapi: Correct size of allocated _glapi_table struct</li> + <li>apple: Fix a use after free</li> +</ul></p> + +<p>Jordan Justen (1): +<ul> + <li>mesa: Add primitive restart support to glArrayElement</li> +</ul></p> + +<p>Kenneth Graunke (12): +<ul> + <li>i965: Actually upload sampler state pointers for the VS unit on Gen6.</li> + <li>i965/fs: Fix FB writes that tried to use the non-existent m16 register.</li> + <li>vbo: Remove pedantic warning about 'end' beind out of bounds.</li> + <li>vbo: Ignore invalid element ranges which are outside VBO bounds.</li> + <li>vbo: Rework checking of 'end' against _MaxElement.</li> + <li>vbo: Eliminate short-circuiting in invalid-start case.</li> + <li>i965: Fix GPU hangs in the dummy fragment shader.</li> + <li>i965: Make the dummy fragment shader work in SIMD16 mode.</li> + <li>drirc: Add force_glsl_extensions_warn workaround for Unigine Heaven.</li> + <li>i965: Avoid explicit accumulator operands in SIMD16 mode on Gen7.</li> + <li>intel: Remove pointless software fallback for glBitmap on Gen6.</li> + <li>glsl: Fix broken constant expression handling for <, <=, >, and >=.</li> +</ul></p> + +<p>Kurt Roeckx (2): +<ul> + <li>i915: Compute maximum number of verts using the actual batchbuffer size.</li> + <li>i915: Fix i830 polygon stipple from PBOs.</li> +</ul></p> + +<p>Marek Olšák (5): +<ul> + <li>r300g/swtcl: don't print an error when getting ClipVertex</li> + <li>r300g/swtcl: don't enter u_vbuf_mgr</li> + <li>r300g/swtcl: don't expose shader subroutine support</li> + <li>r300g/swtcl: fix polygon offset</li> + <li>r300g/swtcl: fix crash when back color is present in vertex shader</li> +</ul></p> + +<p>Mathias Fröhlich (1): +<ul> + <li>glsl: Avoid excessive loop unrolling.</li> +</ul></p> + +<p>Matt Turner (1): +<ul> + <li>Remove -ffast-math from default CFLAGS</li> +</ul></p> + +<p>Paul Berry (1): +<ul> + <li>i915: Initialize swrast_texture_image structure fields.</li> +</ul></p> + +<p>Roland Scheidegger (1): +<ul> + <li>mesa: check_index_bounds off-by-one fix</li> +</ul></p> + +<p>Tom Stellard (2): +<ul> + <li>r300/compiler: Clear loop registers in vertex shaders w/o loops</li> + <li>r300/compiler: Copy all instruction attributes during local transfoms</li> +</ul></p> + +<p>Vinson Lee (5): +<ul> + <li>mesa: Fix memory leak in _mesa_get_uniform_location.</li> + <li>linker: Fix memory leak in count_uniform_size::visit_field.</li> + <li>swrast: Fix memory leaks in blit_linear.</li> + <li>ir_to_mesa: Fix uninitialized member in add_uniform_to_shader.</li> + <li>mesa: Fix memory leak in generate_mipmap_compressed.</li> +</ul></p> + +<p>Yuanhan Liu (2): +<ul> + <li>i915: set SPRITE_POINT_ENABLE bit correctly</li> + <li>i965: fix wrong cube/3D texture layout</li> +</ul></p> + +</body> +</html> diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp index 86bb8741b..e23718bdb 100644 --- a/mesalib/src/glsl/ast_to_hir.cpp +++ b/mesalib/src/glsl/ast_to_hir.cpp @@ -760,13 +760,11 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state, ir_var_temporary); ir_dereference_variable *deref_var = new(ctx) ir_dereference_variable(var); instructions->push_tail(var); - instructions->push_tail(new(ctx) ir_assignment(deref_var, - rhs, - NULL)); + instructions->push_tail(new(ctx) ir_assignment(deref_var, rhs)); deref_var = new(ctx) ir_dereference_variable(var); if (!error_emitted) - instructions->push_tail(new(ctx) ir_assignment(lhs, deref_var, NULL)); + instructions->push_tail(new(ctx) ir_assignment(lhs, deref_var)); return new(ctx) ir_dereference_variable(var); } @@ -783,7 +781,7 @@ get_lvalue_copy(exec_list *instructions, ir_rvalue *lvalue) var->mode = ir_var_auto; instructions->push_tail(new(ctx) ir_assignment(new(ctx) ir_dereference_variable(var), - lvalue, NULL)); + lvalue)); return new(ctx) ir_dereference_variable(var); } @@ -1223,12 +1221,12 @@ ast_expression::hir(exec_list *instructions, stmt->then_instructions.append_list(&rhs_instructions); ir_dereference *const then_deref = new(ctx) ir_dereference_variable(tmp); ir_assignment *const then_assign = - new(ctx) ir_assignment(then_deref, op[1], NULL); + new(ctx) ir_assignment(then_deref, op[1]); stmt->then_instructions.push_tail(then_assign); ir_dereference *const else_deref = new(ctx) ir_dereference_variable(tmp); ir_assignment *const else_assign = - new(ctx) ir_assignment(else_deref, new(ctx) ir_constant(false), NULL); + new(ctx) ir_assignment(else_deref, new(ctx) ir_constant(false)); stmt->else_instructions.push_tail(else_assign); result = new(ctx) ir_dereference_variable(tmp); @@ -1258,13 +1256,13 @@ ast_expression::hir(exec_list *instructions, ir_dereference *const then_deref = new(ctx) ir_dereference_variable(tmp); ir_assignment *const then_assign = - new(ctx) ir_assignment(then_deref, new(ctx) ir_constant(true), NULL); + new(ctx) ir_assignment(then_deref, new(ctx) ir_constant(true)); stmt->then_instructions.push_tail(then_assign); stmt->else_instructions.append_list(&rhs_instructions); ir_dereference *const else_deref = new(ctx) ir_dereference_variable(tmp); ir_assignment *const else_assign = - new(ctx) ir_assignment(else_deref, op[1], NULL); + new(ctx) ir_assignment(else_deref, op[1]); stmt->else_instructions.push_tail(else_assign); result = new(ctx) ir_dereference_variable(tmp); @@ -1452,14 +1450,14 @@ ast_expression::hir(exec_list *instructions, ir_dereference *const then_deref = new(ctx) ir_dereference_variable(tmp); ir_assignment *const then_assign = - new(ctx) ir_assignment(then_deref, op[1], NULL); + new(ctx) ir_assignment(then_deref, op[1]); stmt->then_instructions.push_tail(then_assign); else_instructions.move_nodes_to(& stmt->else_instructions); ir_dereference *const else_deref = new(ctx) ir_dereference_variable(tmp); ir_assignment *const else_assign = - new(ctx) ir_assignment(else_deref, op[2], NULL); + new(ctx) ir_assignment(else_deref, op[2]); stmt->else_instructions.push_tail(else_assign); result = new(ctx) ir_dereference_variable(tmp); @@ -3438,9 +3436,7 @@ ast_jump_statement::hir(exec_list *instructions, new(ctx) ir_dereference_variable(is_break_var); ir_constant *const true_val = new(ctx) ir_constant(true); ir_assignment *const set_break_var = - new(ctx) ir_assignment(deref_is_break_var, - true_val, - NULL); + new(ctx) ir_assignment(deref_is_break_var, true_val); instructions->push_tail(set_break_var); } @@ -3521,11 +3517,9 @@ ast_switch_statement::hir(exec_list *instructions, * * "The type of init-expression in a switch statement must be a * scalar integer." - * - * The checks are separated so that higher quality diagnostics can be - * generated for cases where the rule is violated. */ - if (!test_expression->type->is_integer()) { + if (!test_expression->type->is_scalar() || + !test_expression->type->is_integer()) { YYLTYPE loc = this->test_expression->get_location(); _mesa_glsl_error(& loc, @@ -3556,8 +3550,7 @@ ast_switch_statement::hir(exec_list *instructions, ir_dereference_variable *deref_is_fallthru_var = new(ctx) ir_dereference_variable(state->switch_state.is_fallthru_var); instructions->push_tail(new(ctx) ir_assignment(deref_is_fallthru_var, - is_fallthru_val, - NULL)); + is_fallthru_val)); /* Initalize is_break state to false. */ @@ -3570,13 +3563,12 @@ ast_switch_statement::hir(exec_list *instructions, ir_dereference_variable *deref_is_break_var = new(ctx) ir_dereference_variable(state->switch_state.is_break_var); instructions->push_tail(new(ctx) ir_assignment(deref_is_break_var, - is_break_val, - NULL)); + is_break_val)); /* Cache test expression. */ test_to_hir(instructions, state); - + /* Emit code for body of switch stmt. */ body->hir(instructions, state); @@ -3585,290 +3577,267 @@ ast_switch_statement::hir(exec_list *instructions, state->switch_state = saved; - /* Switch statements do not have r-values. - */ - return NULL; - } - - - void - ast_switch_statement::test_to_hir(exec_list *instructions, - struct _mesa_glsl_parse_state *state) - { - void *ctx = state; - - /* Cache value of test expression. - */ - ir_rvalue *const test_val = - test_expression->hir(instructions, - state); - - state->switch_state.test_var = new(ctx) ir_variable(glsl_type::int_type, - "switch_test_tmp", - ir_var_temporary); - ir_dereference_variable *deref_test_var = - new(ctx) ir_dereference_variable(state->switch_state.test_var); - - instructions->push_tail(state->switch_state.test_var); - instructions->push_tail(new(ctx) ir_assignment(deref_test_var, - test_val, - NULL)); - } - - - ir_rvalue * - ast_switch_body::hir(exec_list *instructions, - struct _mesa_glsl_parse_state *state) - { - if (stmts != NULL) - stmts->hir(instructions, state); - - /* Switch bodies do not have r-values. - */ - return NULL; - } - - - ir_rvalue * - ast_case_statement_list::hir(exec_list *instructions, - struct _mesa_glsl_parse_state *state) - { - foreach_list_typed (ast_case_statement, case_stmt, link, & this->cases) - case_stmt->hir(instructions, state); - - /* Case statements do not have r-values. - */ - return NULL; - } - - - ir_rvalue * - ast_case_statement::hir(exec_list *instructions, - struct _mesa_glsl_parse_state *state) - { - labels->hir(instructions, state); - - /* Conditionally set fallthru state based on break state. - */ - ir_constant *const false_val = new(state) ir_constant(false); - ir_dereference_variable *const deref_is_fallthru_var = - new(state) ir_dereference_variable(state->switch_state.is_fallthru_var); - ir_dereference_variable *const deref_is_break_var = - new(state) ir_dereference_variable(state->switch_state.is_break_var); - ir_assignment *const reset_fallthru_on_break = - new(state) ir_assignment(deref_is_fallthru_var, - false_val, - deref_is_break_var); - instructions->push_tail(reset_fallthru_on_break); - - /* Guard case statements depending on fallthru state. - */ - ir_dereference_variable *const deref_fallthru_guard = - new(state) ir_dereference_variable(state->switch_state.is_fallthru_var); - ir_if *const test_fallthru = new(state) ir_if(deref_fallthru_guard); - - foreach_list_typed (ast_node, stmt, link, & this->stmts) - stmt->hir(& test_fallthru->then_instructions, state); - - instructions->push_tail(test_fallthru); - - /* Case statements do not have r-values. - */ - return NULL; - } - - - ir_rvalue * - ast_case_label_list::hir(exec_list *instructions, - struct _mesa_glsl_parse_state *state) - { - foreach_list_typed (ast_case_label, label, link, & this->labels) - label->hir(instructions, state); - - /* Case labels do not have r-values. - */ - return NULL; - } - - - ir_rvalue * - ast_case_label::hir(exec_list *instructions, - struct _mesa_glsl_parse_state *state) - { - void *ctx = state; - - ir_dereference_variable *deref_fallthru_var = - new(ctx) ir_dereference_variable(state->switch_state.is_fallthru_var); - - ir_rvalue *const true_val = new(ctx) ir_constant(true); - - /* If not default case, ... - */ - if (this->test_value != NULL) { - /* Conditionally set fallthru state based on - * comparison of cached test expression value to case label. - */ - ir_rvalue *const label_rval = this->test_value->hir(instructions, state); - ir_constant *label_const = label_rval->constant_expression_value(); - - if (!label_const) { - YYLTYPE loc = this->test_value->get_location(); - - _mesa_glsl_error(& loc, state, - "switch statement case label must be a " - "constant expression"); - - /* Stuff a dummy value in to allow processing to continue. */ - label_const = new(ctx) ir_constant(0); - } else { - ast_expression *previous_label = (ast_expression *) - hash_table_find(state->switch_state.labels_ht, + /* Switch statements do not have r-values. */ + return NULL; +} + + +void +ast_switch_statement::test_to_hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + void *ctx = state; + + /* Cache value of test expression. */ + ir_rvalue *const test_val = + test_expression->hir(instructions, + state); + + state->switch_state.test_var = new(ctx) ir_variable(test_val->type, + "switch_test_tmp", + ir_var_temporary); + ir_dereference_variable *deref_test_var = + new(ctx) ir_dereference_variable(state->switch_state.test_var); + + instructions->push_tail(state->switch_state.test_var); + instructions->push_tail(new(ctx) ir_assignment(deref_test_var, test_val)); +} + + +ir_rvalue * +ast_switch_body::hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + if (stmts != NULL) + stmts->hir(instructions, state); + + /* Switch bodies do not have r-values. */ + return NULL; +} + +ir_rvalue * +ast_case_statement_list::hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + foreach_list_typed (ast_case_statement, case_stmt, link, & this->cases) + case_stmt->hir(instructions, state); + + /* Case statements do not have r-values. */ + return NULL; +} + +ir_rvalue * +ast_case_statement::hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + labels->hir(instructions, state); + + /* Conditionally set fallthru state based on break state. */ + ir_constant *const false_val = new(state) ir_constant(false); + ir_dereference_variable *const deref_is_fallthru_var = + new(state) ir_dereference_variable(state->switch_state.is_fallthru_var); + ir_dereference_variable *const deref_is_break_var = + new(state) ir_dereference_variable(state->switch_state.is_break_var); + ir_assignment *const reset_fallthru_on_break = + new(state) ir_assignment(deref_is_fallthru_var, + false_val, + deref_is_break_var); + instructions->push_tail(reset_fallthru_on_break); + + /* Guard case statements depending on fallthru state. */ + ir_dereference_variable *const deref_fallthru_guard = + new(state) ir_dereference_variable(state->switch_state.is_fallthru_var); + ir_if *const test_fallthru = new(state) ir_if(deref_fallthru_guard); + + foreach_list_typed (ast_node, stmt, link, & this->stmts) + stmt->hir(& test_fallthru->then_instructions, state); + + instructions->push_tail(test_fallthru); + + /* Case statements do not have r-values. */ + return NULL; +} + + +ir_rvalue * +ast_case_label_list::hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + foreach_list_typed (ast_case_label, label, link, & this->labels) + label->hir(instructions, state); + + /* Case labels do not have r-values. */ + return NULL; +} + +ir_rvalue * +ast_case_label::hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + void *ctx = state; + + ir_dereference_variable *deref_fallthru_var = + new(ctx) ir_dereference_variable(state->switch_state.is_fallthru_var); + + ir_rvalue *const true_val = new(ctx) ir_constant(true); + + /* If not default case, ... */ + if (this->test_value != NULL) { + /* Conditionally set fallthru state based on + * comparison of cached test expression value to case label. + */ + ir_rvalue *const label_rval = this->test_value->hir(instructions, state); + ir_constant *label_const = label_rval->constant_expression_value(); + + if (!label_const) { + YYLTYPE loc = this->test_value->get_location(); + + _mesa_glsl_error(& loc, state, + "switch statement case label must be a " + "constant expression"); + + /* Stuff a dummy value in to allow processing to continue. */ + label_const = new(ctx) ir_constant(0); + } else { + ast_expression *previous_label = (ast_expression *) + hash_table_find(state->switch_state.labels_ht, + (void *)(uintptr_t)label_const->value.u[0]); + + if (previous_label) { + YYLTYPE loc = this->test_value->get_location(); + _mesa_glsl_error(& loc, state, + "duplicate case value"); + + loc = previous_label->get_location(); + _mesa_glsl_error(& loc, state, + "this is the previous case label"); + } else { + hash_table_insert(state->switch_state.labels_ht, + this->test_value, (void *)(uintptr_t)label_const->value.u[0]); + } + } + + ir_dereference_variable *deref_test_var = + new(ctx) ir_dereference_variable(state->switch_state.test_var); + + ir_rvalue *const test_cond = new(ctx) ir_expression(ir_binop_all_equal, + label_const, + deref_test_var); + + ir_assignment *set_fallthru_on_test = + new(ctx) ir_assignment(deref_fallthru_var, + true_val, + test_cond); + + instructions->push_tail(set_fallthru_on_test); + } else { /* default case */ + if (state->switch_state.previous_default) { + printf("a\n"); + YYLTYPE loc = this->get_location(); + _mesa_glsl_error(& loc, state, + "multiple default labels in one switch"); + + printf("b\n"); + + loc = state->switch_state.previous_default->get_location(); + _mesa_glsl_error(& loc, state, + "this is the first default label"); + } + state->switch_state.previous_default = this; + + /* Set falltrhu state. */ + ir_assignment *set_fallthru = + new(ctx) ir_assignment(deref_fallthru_var, true_val); + + instructions->push_tail(set_fallthru); + } - if (previous_label) { - YYLTYPE loc = this->test_value->get_location(); - _mesa_glsl_error(& loc, state, - "duplicate case value"); - - loc = previous_label->get_location(); - _mesa_glsl_error(& loc, state, - "this is the previous case label"); - } else { - hash_table_insert(state->switch_state.labels_ht, - this->test_value, - (void *)(uintptr_t)label_const->value.u[0]); - } - } - - ir_dereference_variable *deref_test_var = - new(ctx) ir_dereference_variable(state->switch_state.test_var); - - ir_rvalue *const test_cond = new(ctx) ir_expression(ir_binop_all_equal, - glsl_type::bool_type, - label_const, - deref_test_var); - - ir_assignment *set_fallthru_on_test = - new(ctx) ir_assignment(deref_fallthru_var, - true_val, - test_cond); - - instructions->push_tail(set_fallthru_on_test); - } else { /* default case */ - if (state->switch_state.previous_default) { - printf("a\n"); - YYLTYPE loc = this->get_location(); - _mesa_glsl_error(& loc, state, - "multiple default labels in one switch"); - - printf("b\n"); - - loc = state->switch_state.previous_default->get_location(); - _mesa_glsl_error(& loc, state, - "this is the first default label"); - } - state->switch_state.previous_default = this; - - /* Set falltrhu state. - */ - ir_assignment *set_fallthru = - new(ctx) ir_assignment(deref_fallthru_var, - true_val, - NULL); - - instructions->push_tail(set_fallthru); - } - - /* Case statements do not have r-values. - */ - return NULL; - } - - - void - ast_iteration_statement::condition_to_hir(ir_loop *stmt, - struct _mesa_glsl_parse_state *state) - { - void *ctx = state; - - if (condition != NULL) { - ir_rvalue *const cond = - condition->hir(& stmt->body_instructions, state); - - if ((cond == NULL) - || !cond->type->is_boolean() || !cond->type->is_scalar()) { - YYLTYPE loc = condition->get_location(); - - _mesa_glsl_error(& loc, state, - "loop condition must be scalar boolean"); - } else { - /* As the first code in the loop body, generate a block that looks - * like 'if (!condition) break;' as the loop termination condition. - */ - ir_rvalue *const not_cond = - new(ctx) ir_expression(ir_unop_logic_not, glsl_type::bool_type, cond, - NULL); - - ir_if *const if_stmt = new(ctx) ir_if(not_cond); - - ir_jump *const break_stmt = - new(ctx) ir_loop_jump(ir_loop_jump::jump_break); - - if_stmt->then_instructions.push_tail(break_stmt); - stmt->body_instructions.push_tail(if_stmt); - } - } - } - - - ir_rvalue * - ast_iteration_statement::hir(exec_list *instructions, - struct _mesa_glsl_parse_state *state) - { - void *ctx = state; - - /* For-loops and while-loops start a new scope, but do-while loops do not. - */ - if (mode != ast_do_while) - state->symbols->push_scope(); - - if (init_statement != NULL) - init_statement->hir(instructions, state); - - ir_loop *const stmt = new(ctx) ir_loop(); - instructions->push_tail(stmt); - - /* Track the current loop nesting. - */ - ast_iteration_statement *nesting_ast = state->loop_nesting_ast; - - state->loop_nesting_ast = this; - - /* Likewise, indicate that following code is closest to a loop, - * NOT closest to a switch. - */ - bool saved_is_switch_innermost = state->switch_state.is_switch_innermost; - state->switch_state.is_switch_innermost = false; - - if (mode != ast_do_while) - condition_to_hir(stmt, state); - - if (body != NULL) - body->hir(& stmt->body_instructions, state); - - if (rest_expression != NULL) - rest_expression->hir(& stmt->body_instructions, state); + /* Case statements do not have r-values. */ + return NULL; +} + +void +ast_iteration_statement::condition_to_hir(ir_loop *stmt, + struct _mesa_glsl_parse_state *state) +{ + void *ctx = state; + + if (condition != NULL) { + ir_rvalue *const cond = + condition->hir(& stmt->body_instructions, state); + + if ((cond == NULL) + || !cond->type->is_boolean() || !cond->type->is_scalar()) { + YYLTYPE loc = condition->get_location(); + + _mesa_glsl_error(& loc, state, + "loop condition must be scalar boolean"); + } else { + /* As the first code in the loop body, generate a block that looks + * like 'if (!condition) break;' as the loop termination condition. + */ + ir_rvalue *const not_cond = + new(ctx) ir_expression(ir_unop_logic_not, cond); + + ir_if *const if_stmt = new(ctx) ir_if(not_cond); + + ir_jump *const break_stmt = + new(ctx) ir_loop_jump(ir_loop_jump::jump_break); + + if_stmt->then_instructions.push_tail(break_stmt); + stmt->body_instructions.push_tail(if_stmt); + } + } +} + + +ir_rvalue * +ast_iteration_statement::hir(exec_list *instructions, + struct _mesa_glsl_parse_state *state) +{ + void *ctx = state; + + /* For-loops and while-loops start a new scope, but do-while loops do not. + */ + if (mode != ast_do_while) + state->symbols->push_scope(); + + if (init_statement != NULL) + init_statement->hir(instructions, state); + + ir_loop *const stmt = new(ctx) ir_loop(); + instructions->push_tail(stmt); + + /* Track the current loop nesting. */ + ast_iteration_statement *nesting_ast = state->loop_nesting_ast; + + state->loop_nesting_ast = this; + + /* Likewise, indicate that following code is closest to a loop, + * NOT closest to a switch. + */ + bool saved_is_switch_innermost = state->switch_state.is_switch_innermost; + state->switch_state.is_switch_innermost = false; + + if (mode != ast_do_while) + condition_to_hir(stmt, state); + + if (body != NULL) + body->hir(& stmt->body_instructions, state); + + if (rest_expression != NULL) + rest_expression->hir(& stmt->body_instructions, state); + + if (mode == ast_do_while) + condition_to_hir(stmt, state); + + if (mode != ast_do_while) + state->symbols->pop_scope(); - if (mode == ast_do_while) - condition_to_hir(stmt, state); - - if (mode != ast_do_while) - state->symbols->pop_scope(); - - /* Restore previous nesting before returning. - */ - state->loop_nesting_ast = nesting_ast; - state->switch_state.is_switch_innermost = saved_is_switch_innermost; + /* Restore previous nesting before returning. */ + state->loop_nesting_ast = nesting_ast; + state->switch_state.is_switch_innermost = saved_is_switch_innermost; /* Loops do not have r-values. */ diff --git a/mesalib/src/glsl/opt_dead_code_local.cpp b/mesalib/src/glsl/opt_dead_code_local.cpp index a81a38fff..4af78a72c 100644 --- a/mesalib/src/glsl/opt_dead_code_local.cpp +++ b/mesalib/src/glsl/opt_dead_code_local.cpp @@ -43,16 +43,20 @@ static bool debug = false; class assignment_entry : public exec_node { public: - assignment_entry(ir_variable *lhs, ir_instruction *ir) + assignment_entry(ir_variable *lhs, ir_assignment *ir) { assert(lhs); assert(ir); this->lhs = lhs; this->ir = ir; + this->available = ir->write_mask; } ir_variable *lhs; - ir_instruction *ir; + ir_assignment *ir; + + /* bitmask of xyzw channels written that haven't been used so far. */ + int available; }; class kill_for_derefs_visitor : public ir_hierarchical_visitor { @@ -62,23 +66,52 @@ public: this->assignments = assignments; } - virtual ir_visitor_status visit(ir_dereference_variable *ir) + void kill_channels(ir_variable *const var, int used) { - ir_variable *const var = ir->variable_referenced(); - foreach_iter(exec_list_iterator, iter, *this->assignments) { assignment_entry *entry = (assignment_entry *)iter.get(); if (entry->lhs == var) { - if (debug) - printf("kill %s\n", entry->lhs->name); - entry->remove(); + if (var->type->is_scalar() || var->type->is_vector()) { + if (debug) + printf("kill %s (0x%01x - 0x%01x)\n", entry->lhs->name, + entry->available, used); + entry->available &= ~used; + if (!entry->available) + entry->remove(); + } else { + if (debug) + printf("kill %s\n", entry->lhs->name); + entry->remove(); + } } } + } + + virtual ir_visitor_status visit(ir_dereference_variable *ir) + { + kill_channels(ir->var, ~0); return visit_continue; } + virtual ir_visitor_status visit(ir_swizzle *ir) + { + ir_dereference_variable *deref = ir->val->as_dereference_variable(); + if (!deref) + return visit_continue; + + int used = 0; + used |= 1 << ir->mask.x; + used |= 1 << ir->mask.y; + used |= 1 << ir->mask.z; + used |= 1 << ir->mask.w; + + kill_channels(deref->var, used); + + return visit_continue_with_parent; + } + private: exec_list *assignments; }; @@ -130,21 +163,91 @@ process_assignment(void *ctx, ir_assignment *ir, exec_list *assignments) assert(var); /* Now, check if we did a whole-variable assignment. */ - if (!ir->condition && (ir->whole_variable_written() != NULL)) { - /* We did a whole-variable assignment. So, any instruction in - * the assignment list with the same LHS is dead. - */ - if (debug) - printf("looking for %s to remove\n", var->name); - foreach_iter(exec_list_iterator, iter, *assignments) { - assignment_entry *entry = (assignment_entry *)iter.get(); + if (!ir->condition) { + ir_dereference_variable *deref_var = ir->lhs->as_dereference_variable(); - if (entry->lhs == var) { - if (debug) - printf("removing %s\n", var->name); - entry->ir->remove(); - entry->remove(); - progress = true; + /* If it's a vector type, we can do per-channel elimination of + * use of the RHS. + */ + if (deref_var && (deref_var->var->type->is_scalar() || + deref_var->var->type->is_vector())) { + + if (debug) + printf("looking for %s.0x%01x to remove\n", var->name, + ir->write_mask); + + foreach_iter(exec_list_iterator, iter, *assignments) { + assignment_entry *entry = (assignment_entry *)iter.get(); + + if (entry->lhs != var) + continue; + + int remove = entry->available & ir->write_mask; + if (debug) { + printf("%s 0x%01x - 0x%01x = 0x%01x\n", + var->name, + entry->ir->write_mask, + remove, entry->ir->write_mask & ~remove); + } + if (remove) { + progress = true; + + if (debug) { + printf("rewriting:\n "); + entry->ir->print(); + printf("\n"); + } + + entry->ir->write_mask &= ~remove; + entry->available &= ~remove; + if (entry->ir->write_mask == 0) { + /* Delete the dead assignment. */ + entry->ir->remove(); + entry->remove(); + } else { + void *mem_ctx = ralloc_parent(entry->ir); + /* Reswizzle the RHS arguments according to the new + * write_mask. + */ + unsigned components[4]; + unsigned channels = 0; + unsigned next = 0; + + for (int i = 0; i < 4; i++) { + if ((entry->ir->write_mask | remove) & (1 << i)) { + if (!(remove & (1 << i))) + components[channels++] = next; + next++; + } + } + + entry->ir->rhs = new(mem_ctx) ir_swizzle(entry->ir->rhs, + components, + channels); + if (debug) { + printf("to:\n "); + entry->ir->print(); + printf("\n"); + } + } + } + } + } else if (ir->whole_variable_written() != NULL) { + /* We did a whole-variable assignment. So, any instruction in + * the assignment list with the same LHS is dead. + */ + if (debug) + printf("looking for %s to remove\n", var->name); + foreach_iter(exec_list_iterator, iter, *assignments) { + assignment_entry *entry = (assignment_entry *)iter.get(); + + if (entry->lhs == var) { + if (debug) + printf("removing %s\n", var->name); + entry->ir->remove(); + entry->remove(); + progress = true; + } } } } @@ -160,7 +263,7 @@ process_assignment(void *ctx, ir_assignment *ir, exec_list *assignments) foreach_iter(exec_list_iterator, iter, *assignments) { assignment_entry *entry = (assignment_entry *)iter.get(); - printf(" %s\n", entry->lhs->name); + printf(" %s (0x%01x)\n", entry->lhs->name, entry->available); } } diff --git a/mesalib/src/mesa/SConscript b/mesalib/src/mesa/SConscript index dc37a6730..d7932c7c9 100644 --- a/mesalib/src/mesa/SConscript +++ b/mesalib/src/mesa/SConscript @@ -215,6 +215,7 @@ vbo_sources = [ 'vbo/vbo_exec_draw.c', 'vbo/vbo_exec_eval.c', 'vbo/vbo_noop.c', + 'vbo/vbo_primitive_restart.c', 'vbo/vbo_rebase.c', 'vbo/vbo_split.c', 'vbo/vbo_split_copy.c', diff --git a/mesalib/src/mesa/main/compiler.h b/mesalib/src/mesa/main/compiler.h index 25d981053..bfa06f37d 100644 --- a/mesalib/src/mesa/main/compiler.h +++ b/mesalib/src/mesa/main/compiler.h @@ -285,12 +285,6 @@ static INLINE GLuint CPU_TO_LE32(GLuint x) #endif -/* This is a macro on IRIX */ -#ifdef _P -#undef _P -#endif - - /* Turn off macro checking systems used by other libraries */ #ifdef CHECK #undef CHECK diff --git a/mesalib/src/mesa/main/context.c b/mesalib/src/mesa/main/context.c index bafd250a1..df0452cd1 100644 --- a/mesalib/src/mesa/main/context.c +++ b/mesalib/src/mesa/main/context.c @@ -662,6 +662,9 @@ _mesa_init_constants(struct gl_context *ctx) /* GL_ARB_robustness */ ctx->Const.ResetStrategy = GL_NO_RESET_NOTIFICATION_ARB; + + /* PrimitiveRestart */ + ctx->Const.PrimitiveRestartInSoftware = GL_FALSE; } diff --git a/mesalib/src/mesa/main/format_unpack.c b/mesalib/src/mesa/main/format_unpack.c index b00e01236..c42bac19c 100644 --- a/mesalib/src/mesa/main/format_unpack.c +++ b/mesalib/src/mesa/main/format_unpack.c @@ -2929,7 +2929,7 @@ unpack_uint_z_Z32_FLOAT(const void *src, GLuint *dst, GLuint n) const float *s = (const float *)src; GLuint i; for (i = 0; i < n; i++) { - dst[i] = FLOAT_TO_UINT(IROUND(CLAMP((s[i]), 0.0F, 1.0F))); + dst[i] = FLOAT_TO_UINT(CLAMP(s[i], 0.0F, 1.0F)); } } @@ -2940,7 +2940,7 @@ unpack_uint_z_Z32_FLOAT_X24S8(const void *src, GLuint *dst, GLuint n) GLuint i; for (i = 0; i < n; i++) { - dst[i] = FLOAT_TO_UINT(IROUND(CLAMP((s[i].z), 0.0F, 1.0F))); + dst[i] = FLOAT_TO_UINT(CLAMP(s[i].z, 0.0F, 1.0F)); } } diff --git a/mesalib/src/mesa/main/imports.h b/mesalib/src/mesa/main/imports.h index aa5eb3200..c0b6cecea 100644 --- a/mesalib/src/mesa/main/imports.h +++ b/mesalib/src/mesa/main/imports.h @@ -285,19 +285,47 @@ static inline int GET_FLOAT_BITS( float x ) #endif -/*** - *** IROUND: return (as an integer) float rounded to nearest integer - ***/ +/** + * Convert float to int by rounding to nearest integer, away from zero. + */ +static inline int IROUND(float f) +{ + return (int) ((f >= 0.0F) ? (f + 0.5F) : (f - 0.5F)); +} + + +/** + * Convert float to int64 by rounding to nearest integer. + */ +static inline GLint64 IROUND64(float f) +{ + return (GLint64) ((f >= 0.0F) ? (f + 0.5F) : (f - 0.5F)); +} + + +/** + * Convert positive float to int by rounding to nearest integer. + */ +static inline int IROUND_POS(float f) +{ + assert(f >= 0.0F); + return (int) (f + 0.5F); +} + + +/** + * Convert float to int using a fast method. The rounding mode may vary. + * XXX We could use an x86-64/SSE2 version here. + */ #if defined(USE_X86_ASM) && defined(__GNUC__) && defined(__i386__) -static inline int iround(float f) +static inline int F_TO_I(float f) { int r; __asm__ ("fistpl %0" : "=m" (r) : "t" (f) : "st"); return r; } -#define IROUND(x) iround(x) #elif defined(USE_X86_ASM) && defined(_MSC_VER) -static inline int iround(float f) +static inline int F_TO_I(float f) { int r; _asm { @@ -306,9 +334,8 @@ static inline int iround(float f) } return r; } -#define IROUND(x) iround(x) #elif defined(__WATCOMC__) && defined(__386__) -long iround(float f); +long F_TO_I(float f); #pragma aux iround = \ "push eax" \ "fistp dword ptr [esp]" \ @@ -316,20 +343,8 @@ long iround(float f); parm [8087] \ value [eax] \ modify exact [eax]; -#define IROUND(x) iround(x) -#else -#define IROUND(f) ((int) (((f) >= 0.0F) ? ((f) + 0.5F) : ((f) - 0.5F))) -#endif - -#define IROUND64(f) ((GLint64) (((f) >= 0.0F) ? ((f) + 0.5F) : ((f) - 0.5F))) - -/*** - *** IROUND_POS: return (as an integer) positive float rounded to nearest int - ***/ -#ifdef DEBUG -#define IROUND_POS(f) (assert((f) >= 0.0F), IROUND(f)) #else -#define IROUND_POS(f) (IROUND(f)) +#define F_TO_I(f) IROUND(f) #endif diff --git a/mesalib/src/mesa/main/macros.h b/mesalib/src/mesa/main/macros.h index dbe5b867c..d1df2ce1b 100644 --- a/mesalib/src/mesa/main/macros.h +++ b/mesalib/src/mesa/main/macros.h @@ -129,12 +129,12 @@ extern GLfloat _mesa_ubyte_to_float_color_tab[256]; #define INT_TO_USHORT(i) ((i) < 0 ? 0 : ((GLushort) ((i) >> 15))) #define UINT_TO_USHORT(i) ((i) < 0 ? 0 : ((GLushort) ((i) >> 16))) #define UNCLAMPED_FLOAT_TO_USHORT(us, f) \ - us = ( (GLushort) IROUND( CLAMP((f), 0.0F, 1.0F) * 65535.0F) ) + us = ( (GLushort) F_TO_I( CLAMP((f), 0.0F, 1.0F) * 65535.0F) ) #define CLAMPED_FLOAT_TO_USHORT(us, f) \ - us = ( (GLushort) IROUND( (f) * 65535.0F) ) + us = ( (GLushort) F_TO_I( (f) * 65535.0F) ) #define UNCLAMPED_FLOAT_TO_SHORT(s, f) \ - s = ( (GLshort) IROUND( CLAMP((f), -1.0F, 1.0F) * 32767.0F) ) + s = ( (GLshort) F_TO_I( CLAMP((f), -1.0F, 1.0F) * 32767.0F) ) /*** *** UNCLAMPED_FLOAT_TO_UBYTE: clamp float to [0,1] and map to ubyte in [0,255] @@ -166,9 +166,9 @@ extern GLfloat _mesa_ubyte_to_float_color_tab[256]; } while (0) #else #define UNCLAMPED_FLOAT_TO_UBYTE(ub, f) \ - ub = ((GLubyte) IROUND(CLAMP((f), 0.0F, 1.0F) * 255.0F)) + ub = ((GLubyte) F_TO_I(CLAMP((f), 0.0F, 1.0F) * 255.0F)) #define CLAMPED_FLOAT_TO_UBYTE(ub, f) \ - ub = ((GLubyte) IROUND((f) * 255.0F)) + ub = ((GLubyte) F_TO_I((f) * 255.0F)) #endif /*@}*/ diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h index c306ac6b9..eefe5e7e9 100644 --- a/mesalib/src/mesa/main/mtypes.h +++ b/mesalib/src/mesa/main/mtypes.h @@ -2355,6 +2355,7 @@ struct gl_shader_program #define GLSL_NOP_VERT 0x20 /**< Force no-op vertex shaders */ #define GLSL_NOP_FRAG 0x40 /**< Force no-op fragment shaders */ #define GLSL_USE_PROG 0x80 /**< Log glUseProgram calls */ +#define GLSL_REPORT_ERRORS 0x100 /**< Print compilation errors */ /** @@ -2845,6 +2846,11 @@ struct gl_constants */ GLboolean GLSLSkipStrictMaxVaryingLimitCheck; GLboolean GLSLSkipStrictMaxUniformLimitCheck; + + /** + * Force software support for primitive restart in the VBO module. + */ + GLboolean PrimitiveRestartInSoftware; }; diff --git a/mesalib/src/mesa/main/pack.c b/mesalib/src/mesa/main/pack.c index 4d4b4a825..c25a02e85 100644 --- a/mesalib/src/mesa/main/pack.c +++ b/mesalib/src/mesa/main/pack.c @@ -1726,9 +1726,9 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4], if (dstFormat == GL_RGB) { GLubyte *dst = (GLubyte *) dstAddr; for (i=0;i<n;i++) { - dst[i] = (IROUND(rgba[i][RCOMP] * 7.0F) << 5) - | (IROUND(rgba[i][GCOMP] * 7.0F) << 2) - | (IROUND(rgba[i][BCOMP] * 3.0F) ); + dst[i] = (F_TO_I(rgba[i][RCOMP] * 7.0F) << 5) + | (F_TO_I(rgba[i][GCOMP] * 7.0F) << 2) + | (F_TO_I(rgba[i][BCOMP] * 3.0F) ); } } break; @@ -1736,9 +1736,9 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4], if (dstFormat == GL_RGB) { GLubyte *dst = (GLubyte *) dstAddr; for (i=0;i<n;i++) { - dst[i] = (IROUND(rgba[i][RCOMP] * 7.0F) ) - | (IROUND(rgba[i][GCOMP] * 7.0F) << 3) - | (IROUND(rgba[i][BCOMP] * 3.0F) << 6); + dst[i] = (F_TO_I(rgba[i][RCOMP] * 7.0F) ) + | (F_TO_I(rgba[i][GCOMP] * 7.0F) << 3) + | (F_TO_I(rgba[i][BCOMP] * 3.0F) << 6); } } break; @@ -1746,9 +1746,9 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4], if (dstFormat == GL_RGB) { GLushort *dst = (GLushort *) dstAddr; for (i=0;i<n;i++) { - dst[i] = (IROUND(rgba[i][RCOMP] * 31.0F) << 11) - | (IROUND(rgba[i][GCOMP] * 63.0F) << 5) - | (IROUND(rgba[i][BCOMP] * 31.0F) ); + dst[i] = (F_TO_I(rgba[i][RCOMP] * 31.0F) << 11) + | (F_TO_I(rgba[i][GCOMP] * 63.0F) << 5) + | (F_TO_I(rgba[i][BCOMP] * 31.0F) ); } } break; @@ -1756,9 +1756,9 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4], if (dstFormat == GL_RGB) { GLushort *dst = (GLushort *) dstAddr; for (i=0;i<n;i++) { - dst[i] = (IROUND(rgba[i][RCOMP] * 31.0F) ) - | (IROUND(rgba[i][GCOMP] * 63.0F) << 5) - | (IROUND(rgba[i][BCOMP] * 31.0F) << 11); + dst[i] = (F_TO_I(rgba[i][RCOMP] * 31.0F) ) + | (F_TO_I(rgba[i][GCOMP] * 63.0F) << 5) + | (F_TO_I(rgba[i][BCOMP] * 31.0F) << 11); } } break; @@ -1766,28 +1766,28 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4], if (dstFormat == GL_RGBA) { GLushort *dst = (GLushort *) dstAddr; for (i=0;i<n;i++) { - dst[i] = (IROUND(rgba[i][RCOMP] * 15.0F) << 12) - | (IROUND(rgba[i][GCOMP] * 15.0F) << 8) - | (IROUND(rgba[i][BCOMP] * 15.0F) << 4) - | (IROUND(rgba[i][ACOMP] * 15.0F) ); + dst[i] = (F_TO_I(rgba[i][RCOMP] * 15.0F) << 12) + | (F_TO_I(rgba[i][GCOMP] * 15.0F) << 8) + | (F_TO_I(rgba[i][BCOMP] * 15.0F) << 4) + | (F_TO_I(rgba[i][ACOMP] * 15.0F) ); } } else if (dstFormat == GL_BGRA) { GLushort *dst = (GLushort *) dstAddr; for (i=0;i<n;i++) { - dst[i] = (IROUND(rgba[i][BCOMP] * 15.0F) << 12) - | (IROUND(rgba[i][GCOMP] * 15.0F) << 8) - | (IROUND(rgba[i][RCOMP] * 15.0F) << 4) - | (IROUND(rgba[i][ACOMP] * 15.0F) ); + dst[i] = (F_TO_I(rgba[i][BCOMP] * 15.0F) << 12) + | (F_TO_I(rgba[i][GCOMP] * 15.0F) << 8) + | (F_TO_I(rgba[i][RCOMP] * 15.0F) << 4) + | (F_TO_I(rgba[i][ACOMP] * 15.0F) ); } } else if (dstFormat == GL_ABGR_EXT) { GLushort *dst = (GLushort *) dstAddr; for (i=0;i<n;i++) { - dst[i] = (IROUND(rgba[i][ACOMP] * 15.0F) << 12) - | (IROUND(rgba[i][BCOMP] * 15.0F) << 8) - | (IROUND(rgba[i][GCOMP] * 15.0F) << 4) - | (IROUND(rgba[i][RCOMP] * 15.0F) ); + dst[i] = (F_TO_I(rgba[i][ACOMP] * 15.0F) << 12) + | (F_TO_I(rgba[i][BCOMP] * 15.0F) << 8) + | (F_TO_I(rgba[i][GCOMP] * 15.0F) << 4) + | (F_TO_I(rgba[i][RCOMP] * 15.0F) ); } } break; @@ -1795,28 +1795,28 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4], if (dstFormat == GL_RGBA) { GLushort *dst = (GLushort *) dstAddr; for (i=0;i<n;i++) { - dst[i] = (IROUND(rgba[i][RCOMP] * 15.0F) ) - | (IROUND(rgba[i][GCOMP] * 15.0F) << 4) - | (IROUND(rgba[i][BCOMP] * 15.0F) << 8) - | (IROUND(rgba[i][ACOMP] * 15.0F) << 12); + dst[i] = (F_TO_I(rgba[i][RCOMP] * 15.0F) ) + | (F_TO_I(rgba[i][GCOMP] * 15.0F) << 4) + | (F_TO_I(rgba[i][BCOMP] * 15.0F) << 8) + | (F_TO_I(rgba[i][ACOMP] * 15.0F) << 12); } } else if (dstFormat == GL_BGRA) { GLushort *dst = (GLushort *) dstAddr; for (i=0;i<n;i++) { - dst[i] = (IROUND(rgba[i][BCOMP] * 15.0F) ) - | (IROUND(rgba[i][GCOMP] * 15.0F) << 4) - | (IROUND(rgba[i][RCOMP] * 15.0F) << 8) - | (IROUND(rgba[i][ACOMP] * 15.0F) << 12); + dst[i] = (F_TO_I(rgba[i][BCOMP] * 15.0F) ) + | (F_TO_I(rgba[i][GCOMP] * 15.0F) << 4) + | (F_TO_I(rgba[i][RCOMP] * 15.0F) << 8) + | (F_TO_I(rgba[i][ACOMP] * 15.0F) << 12); } } else if (dstFormat == GL_ABGR_EXT) { GLushort *dst = (GLushort *) dstAddr; for (i=0;i<n;i++) { - dst[i] = (IROUND(rgba[i][ACOMP] * 15.0F) ) - | (IROUND(rgba[i][BCOMP] * 15.0F) << 4) - | (IROUND(rgba[i][GCOMP] * 15.0F) << 8) - | (IROUND(rgba[i][RCOMP] * 15.0F) << 12); + dst[i] = (F_TO_I(rgba[i][ACOMP] * 15.0F) ) + | (F_TO_I(rgba[i][BCOMP] * 15.0F) << 4) + | (F_TO_I(rgba[i][GCOMP] * 15.0F) << 8) + | (F_TO_I(rgba[i][RCOMP] * 15.0F) << 12); } } break; @@ -1824,28 +1824,28 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4], if (dstFormat == GL_RGBA) { GLushort *dst = (GLushort *) dstAddr; for (i=0;i<n;i++) { - dst[i] = (IROUND(rgba[i][RCOMP] * 31.0F) << 11) - | (IROUND(rgba[i][GCOMP] * 31.0F) << 6) - | (IROUND(rgba[i][BCOMP] * 31.0F) << 1) - | (IROUND(rgba[i][ACOMP] * 1.0F) ); + dst[i] = (F_TO_I(rgba[i][RCOMP] * 31.0F) << 11) + | (F_TO_I(rgba[i][GCOMP] * 31.0F) << 6) + | (F_TO_I(rgba[i][BCOMP] * 31.0F) << 1) + | (F_TO_I(rgba[i][ACOMP] * 1.0F) ); } } else if (dstFormat == GL_BGRA) { GLushort *dst = (GLushort *) dstAddr; for (i=0;i<n;i++) { - dst[i] = (IROUND(rgba[i][BCOMP] * 31.0F) << 11) - | (IROUND(rgba[i][GCOMP] * 31.0F) << 6) - | (IROUND(rgba[i][RCOMP] * 31.0F) << 1) - | (IROUND(rgba[i][ACOMP] * 1.0F) ); + dst[i] = (F_TO_I(rgba[i][BCOMP] * 31.0F) << 11) + | (F_TO_I(rgba[i][GCOMP] * 31.0F) << 6) + | (F_TO_I(rgba[i][RCOMP] * 31.0F) << 1) + | (F_TO_I(rgba[i][ACOMP] * 1.0F) ); } } else if (dstFormat == GL_ABGR_EXT) { GLushort *dst = (GLushort *) dstAddr; for (i=0;i<n;i++) { - dst[i] = (IROUND(rgba[i][ACOMP] * 31.0F) << 11) - | (IROUND(rgba[i][BCOMP] * 31.0F) << 6) - | (IROUND(rgba[i][GCOMP] * 31.0F) << 1) - | (IROUND(rgba[i][RCOMP] * 1.0F) ); + dst[i] = (F_TO_I(rgba[i][ACOMP] * 31.0F) << 11) + | (F_TO_I(rgba[i][BCOMP] * 31.0F) << 6) + | (F_TO_I(rgba[i][GCOMP] * 31.0F) << 1) + | (F_TO_I(rgba[i][RCOMP] * 1.0F) ); } } break; @@ -1853,28 +1853,28 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4], if (dstFormat == GL_RGBA) { GLushort *dst = (GLushort *) dstAddr; for (i=0;i<n;i++) { - dst[i] = (IROUND(rgba[i][RCOMP] * 31.0F) ) - | (IROUND(rgba[i][GCOMP] * 31.0F) << 5) - | (IROUND(rgba[i][BCOMP] * 31.0F) << 10) - | (IROUND(rgba[i][ACOMP] * 1.0F) << 15); + dst[i] = (F_TO_I(rgba[i][RCOMP] * 31.0F) ) + | (F_TO_I(rgba[i][GCOMP] * 31.0F) << 5) + | (F_TO_I(rgba[i][BCOMP] * 31.0F) << 10) + | (F_TO_I(rgba[i][ACOMP] * 1.0F) << 15); } } else if (dstFormat == GL_BGRA) { GLushort *dst = (GLushort *) dstAddr; for (i=0;i<n;i++) { - dst[i] = (IROUND(rgba[i][BCOMP] * 31.0F) ) - | (IROUND(rgba[i][GCOMP] * 31.0F) << 5) - | (IROUND(rgba[i][RCOMP] * 31.0F) << 10) - | (IROUND(rgba[i][ACOMP] * 1.0F) << 15); + dst[i] = (F_TO_I(rgba[i][BCOMP] * 31.0F) ) + | (F_TO_I(rgba[i][GCOMP] * 31.0F) << 5) + | (F_TO_I(rgba[i][RCOMP] * 31.0F) << 10) + | (F_TO_I(rgba[i][ACOMP] * 1.0F) << 15); } } else if (dstFormat == GL_ABGR_EXT) { GLushort *dst = (GLushort *) dstAddr; for (i=0;i<n;i++) { - dst[i] = (IROUND(rgba[i][ACOMP] * 31.0F) ) - | (IROUND(rgba[i][BCOMP] * 31.0F) << 5) - | (IROUND(rgba[i][GCOMP] * 31.0F) << 10) - | (IROUND(rgba[i][RCOMP] * 1.0F) << 15); + dst[i] = (F_TO_I(rgba[i][ACOMP] * 31.0F) ) + | (F_TO_I(rgba[i][BCOMP] * 31.0F) << 5) + | (F_TO_I(rgba[i][GCOMP] * 31.0F) << 10) + | (F_TO_I(rgba[i][RCOMP] * 1.0F) << 15); } } break; @@ -1882,28 +1882,28 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4], if (dstFormat == GL_RGBA) { GLuint *dst = (GLuint *) dstAddr; for (i=0;i<n;i++) { - dst[i] = (IROUND(rgba[i][RCOMP] * 255.F) << 24) - | (IROUND(rgba[i][GCOMP] * 255.F) << 16) - | (IROUND(rgba[i][BCOMP] * 255.F) << 8) - | (IROUND(rgba[i][ACOMP] * 255.F) ); + dst[i] = (F_TO_I(rgba[i][RCOMP] * 255.F) << 24) + | (F_TO_I(rgba[i][GCOMP] * 255.F) << 16) + | (F_TO_I(rgba[i][BCOMP] * 255.F) << 8) + | (F_TO_I(rgba[i][ACOMP] * 255.F) ); } } else if (dstFormat == GL_BGRA) { GLuint *dst = (GLuint *) dstAddr; for (i=0;i<n;i++) { - dst[i] = (IROUND(rgba[i][BCOMP] * 255.F) << 24) - | (IROUND(rgba[i][GCOMP] * 255.F) << 16) - | (IROUND(rgba[i][RCOMP] * 255.F) << 8) - | (IROUND(rgba[i][ACOMP] * 255.F) ); + dst[i] = (F_TO_I(rgba[i][BCOMP] * 255.F) << 24) + | (F_TO_I(rgba[i][GCOMP] * 255.F) << 16) + | (F_TO_I(rgba[i][RCOMP] * 255.F) << 8) + | (F_TO_I(rgba[i][ACOMP] * 255.F) ); } } else if (dstFormat == GL_ABGR_EXT) { GLuint *dst = (GLuint *) dstAddr; for (i=0;i<n;i++) { - dst[i] = (IROUND(rgba[i][ACOMP] * 255.F) << 24) - | (IROUND(rgba[i][BCOMP] * 255.F) << 16) - | (IROUND(rgba[i][GCOMP] * 255.F) << 8) - | (IROUND(rgba[i][RCOMP] * 255.F) ); + dst[i] = (F_TO_I(rgba[i][ACOMP] * 255.F) << 24) + | (F_TO_I(rgba[i][BCOMP] * 255.F) << 16) + | (F_TO_I(rgba[i][GCOMP] * 255.F) << 8) + | (F_TO_I(rgba[i][RCOMP] * 255.F) ); } } break; @@ -1911,28 +1911,28 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4], if (dstFormat == GL_RGBA) { GLuint *dst = (GLuint *) dstAddr; for (i=0;i<n;i++) { - dst[i] = (IROUND(rgba[i][RCOMP] * 255.0F) ) - | (IROUND(rgba[i][GCOMP] * 255.0F) << 8) - | (IROUND(rgba[i][BCOMP] * 255.0F) << 16) - | (IROUND(rgba[i][ACOMP] * 255.0F) << 24); + dst[i] = (F_TO_I(rgba[i][RCOMP] * 255.0F) ) + | (F_TO_I(rgba[i][GCOMP] * 255.0F) << 8) + | (F_TO_I(rgba[i][BCOMP] * 255.0F) << 16) + | (F_TO_I(rgba[i][ACOMP] * 255.0F) << 24); } } else if (dstFormat == GL_BGRA) { GLuint *dst = (GLuint *) dstAddr; for (i=0;i<n;i++) { - dst[i] = (IROUND(rgba[i][BCOMP] * 255.0F) ) - | (IROUND(rgba[i][GCOMP] * 255.0F) << 8) - | (IROUND(rgba[i][RCOMP] * 255.0F) << 16) - | (IROUND(rgba[i][ACOMP] * 255.0F) << 24); + dst[i] = (F_TO_I(rgba[i][BCOMP] * 255.0F) ) + | (F_TO_I(rgba[i][GCOMP] * 255.0F) << 8) + | (F_TO_I(rgba[i][RCOMP] * 255.0F) << 16) + | (F_TO_I(rgba[i][ACOMP] * 255.0F) << 24); } } else if (dstFormat == GL_ABGR_EXT) { GLuint *dst = (GLuint *) dstAddr; for (i=0;i<n;i++) { - dst[i] = (IROUND(rgba[i][ACOMP] * 255.0F) ) - | (IROUND(rgba[i][BCOMP] * 255.0F) << 8) - | (IROUND(rgba[i][GCOMP] * 255.0F) << 16) - | (IROUND(rgba[i][RCOMP] * 255.0F) << 24); + dst[i] = (F_TO_I(rgba[i][ACOMP] * 255.0F) ) + | (F_TO_I(rgba[i][BCOMP] * 255.0F) << 8) + | (F_TO_I(rgba[i][GCOMP] * 255.0F) << 16) + | (F_TO_I(rgba[i][RCOMP] * 255.0F) << 24); } } break; @@ -1940,28 +1940,28 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4], if (dstFormat == GL_RGBA) { GLuint *dst = (GLuint *) dstAddr; for (i=0;i<n;i++) { - dst[i] = (IROUND(rgba[i][RCOMP] * 1023.0F) << 22) - | (IROUND(rgba[i][GCOMP] * 1023.0F) << 12) - | (IROUND(rgba[i][BCOMP] * 1023.0F) << 2) - | (IROUND(rgba[i][ACOMP] * 3.0F) ); + dst[i] = (F_TO_I(rgba[i][RCOMP] * 1023.0F) << 22) + | (F_TO_I(rgba[i][GCOMP] * 1023.0F) << 12) + | (F_TO_I(rgba[i][BCOMP] * 1023.0F) << 2) + | (F_TO_I(rgba[i][ACOMP] * 3.0F) ); } } else if (dstFormat == GL_BGRA) { GLuint *dst = (GLuint *) dstAddr; for (i=0;i<n;i++) { - dst[i] = (IROUND(rgba[i][BCOMP] * 1023.0F) << 22) - | (IROUND(rgba[i][GCOMP] * 1023.0F) << 12) - | (IROUND(rgba[i][RCOMP] * 1023.0F) << 2) - | (IROUND(rgba[i][ACOMP] * 3.0F) ); + dst[i] = (F_TO_I(rgba[i][BCOMP] * 1023.0F) << 22) + | (F_TO_I(rgba[i][GCOMP] * 1023.0F) << 12) + | (F_TO_I(rgba[i][RCOMP] * 1023.0F) << 2) + | (F_TO_I(rgba[i][ACOMP] * 3.0F) ); } } else if (dstFormat == GL_ABGR_EXT) { GLuint *dst = (GLuint *) dstAddr; for (i=0;i<n;i++) { - dst[i] = (IROUND(rgba[i][ACOMP] * 1023.0F) << 22) - | (IROUND(rgba[i][BCOMP] * 1023.0F) << 12) - | (IROUND(rgba[i][GCOMP] * 1023.0F) << 2) - | (IROUND(rgba[i][RCOMP] * 3.0F) ); + dst[i] = (F_TO_I(rgba[i][ACOMP] * 1023.0F) << 22) + | (F_TO_I(rgba[i][BCOMP] * 1023.0F) << 12) + | (F_TO_I(rgba[i][GCOMP] * 1023.0F) << 2) + | (F_TO_I(rgba[i][RCOMP] * 3.0F) ); } } break; @@ -1969,28 +1969,28 @@ _mesa_pack_rgba_span_float(struct gl_context *ctx, GLuint n, GLfloat rgba[][4], if (dstFormat == GL_RGBA) { GLuint *dst = (GLuint *) dstAddr; for (i=0;i<n;i++) { - dst[i] = (IROUND(rgba[i][RCOMP] * 1023.0F) ) - | (IROUND(rgba[i][GCOMP] * 1023.0F) << 10) - | (IROUND(rgba[i][BCOMP] * 1023.0F) << 20) - | (IROUND(rgba[i][ACOMP] * 3.0F) << 30); + dst[i] = (F_TO_I(rgba[i][RCOMP] * 1023.0F) ) + | (F_TO_I(rgba[i][GCOMP] * 1023.0F) << 10) + | (F_TO_I(rgba[i][BCOMP] * 1023.0F) << 20) + | (F_TO_I(rgba[i][ACOMP] * 3.0F) << 30); } } else if (dstFormat == GL_BGRA) { GLuint *dst = (GLuint *) dstAddr; for (i=0;i<n;i++) { - dst[i] = (IROUND(rgba[i][BCOMP] * 1023.0F) ) - | (IROUND(rgba[i][GCOMP] * 1023.0F) << 10) - | (IROUND(rgba[i][RCOMP] * 1023.0F) << 20) - | (IROUND(rgba[i][ACOMP] * 3.0F) << 30); + dst[i] = (F_TO_I(rgba[i][BCOMP] * 1023.0F) ) + | (F_TO_I(rgba[i][GCOMP] * 1023.0F) << 10) + | (F_TO_I(rgba[i][RCOMP] * 1023.0F) << 20) + | (F_TO_I(rgba[i][ACOMP] * 3.0F) << 30); } } else if (dstFormat == GL_ABGR_EXT) { GLuint *dst = (GLuint *) dstAddr; for (i=0;i<n;i++) { - dst[i] = (IROUND(rgba[i][ACOMP] * 1023.0F) ) - | (IROUND(rgba[i][BCOMP] * 1023.0F) << 10) - | (IROUND(rgba[i][GCOMP] * 1023.0F) << 20) - | (IROUND(rgba[i][RCOMP] * 3.0F) << 30); + dst[i] = (F_TO_I(rgba[i][ACOMP] * 1023.0F) ) + | (F_TO_I(rgba[i][BCOMP] * 1023.0F) << 10) + | (F_TO_I(rgba[i][GCOMP] * 1023.0F) << 20) + | (F_TO_I(rgba[i][RCOMP] * 3.0F) << 30); } } break; @@ -3005,7 +3005,7 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4], static inline GLuint clamp_float_to_uint(GLfloat f) { - return f < 0.0F ? 0 : IROUND(f); + return f < 0.0F ? 0 : F_TO_I(f); } @@ -3013,7 +3013,7 @@ static inline GLuint clamp_half_to_uint(GLhalfARB h) { GLfloat f = _mesa_half_to_float(h); - return f < 0.0F ? 0 : IROUND(f); + return f < 0.0F ? 0 : F_TO_I(f); } diff --git a/mesalib/src/mesa/main/pixeltransfer.c b/mesalib/src/mesa/main/pixeltransfer.c index c6172b9fd..fa355eb4a 100644 --- a/mesalib/src/mesa/main/pixeltransfer.c +++ b/mesalib/src/mesa/main/pixeltransfer.c @@ -93,10 +93,10 @@ _mesa_map_rgba( const struct gl_context *ctx, GLuint n, GLfloat rgba[][4] ) GLfloat g = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F); GLfloat b = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F); GLfloat a = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F); - rgba[i][RCOMP] = rMap[IROUND(r * rscale)]; - rgba[i][GCOMP] = gMap[IROUND(g * gscale)]; - rgba[i][BCOMP] = bMap[IROUND(b * bscale)]; - rgba[i][ACOMP] = aMap[IROUND(a * ascale)]; + rgba[i][RCOMP] = rMap[F_TO_I(r * rscale)]; + rgba[i][GCOMP] = gMap[F_TO_I(g * gscale)]; + rgba[i][BCOMP] = bMap[F_TO_I(b * bscale)]; + rgba[i][ACOMP] = aMap[F_TO_I(a * ascale)]; } } @@ -235,7 +235,7 @@ _mesa_apply_ci_transfer_ops(const struct gl_context *ctx, GLuint i; for (i = 0; i < n; i++) { const GLuint j = indexes[i] & mask; - indexes[i] = IROUND(ctx->PixelMaps.ItoI.Map[j]); + indexes[i] = F_TO_I(ctx->PixelMaps.ItoI.Map[j]); } } } diff --git a/mesalib/src/mesa/main/readpix.c b/mesalib/src/mesa/main/readpix.c index 31acfcbf1..138111049 100644 --- a/mesalib/src/mesa/main/readpix.c +++ b/mesalib/src/mesa/main/readpix.c @@ -701,6 +701,12 @@ _mesa_ReadnPixelsARB( GLint x, GLint y, GLsizei width, GLsizei height, return; } + if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { + _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, + "glReadPixels(incomplete framebuffer)" ); + return; + } + /* Check that the destination format and source buffer are both * integer-valued or both non-integer-valued. */ @@ -715,12 +721,6 @@ _mesa_ReadnPixelsARB( GLint x, GLint y, GLsizei width, GLsizei height, } } - if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { - _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, - "glReadPixels(incomplete framebuffer)" ); - return; - } - if (ctx->ReadBuffer->Name != 0 && ctx->ReadBuffer->Visual.samples > 0) { _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(multisample FBO)"); return; diff --git a/mesalib/src/mesa/main/shaderapi.c b/mesalib/src/mesa/main/shaderapi.c index fd793a7ab..6927368de 100644 --- a/mesalib/src/mesa/main/shaderapi.c +++ b/mesalib/src/mesa/main/shaderapi.c @@ -83,6 +83,8 @@ get_shader_flags(void) flags |= GLSL_UNIFORMS; if (strstr(env, "useprog")) flags |= GLSL_USE_PROG; + if (strstr(env, "errors")) + flags |= GLSL_REPORT_ERRORS; } return flags; @@ -627,7 +629,8 @@ get_shader_source(struct gl_context *ctx, GLuint shader, GLsizei maxLength, /** - * Set/replace shader source code. + * Set/replace shader source code. A helper function used by + * glShaderSource[ARB] and glCreateShaderProgramEXT. */ static void shader_source(struct gl_context *ctx, GLuint shader, const GLchar *source) @@ -672,6 +675,12 @@ compile_shader(struct gl_context *ctx, GLuint shaderObj) * compilation was successful. */ _mesa_glsl_compile_shader(ctx, sh); + + if (sh->CompileStatus == GL_FALSE && + (ctx->Shader.Flags & GLSL_REPORT_ERRORS)) { + _mesa_debug(ctx, "Error compiling shader %u:\n%s\n", + sh->Name, sh->InfoLog); + } } @@ -702,6 +711,12 @@ link_program(struct gl_context *ctx, GLuint program) _mesa_glsl_link_shader(ctx, shProg); + if (shProg->LinkStatus == GL_FALSE && + (ctx->Shader.Flags & GLSL_REPORT_ERRORS)) { + _mesa_debug(ctx, "Error linking program %u:\n%s\n", + shProg->Name, shProg->InfoLog); + } + /* debug code */ if (0) { GLuint i; @@ -1534,6 +1549,10 @@ _mesa_use_shader_program(struct gl_context *ctx, GLenum type, ctx->Driver.UseProgram(ctx, shProg); } + +/** + * For GL_EXT_separate_shader_objects + */ void GLAPIENTRY _mesa_UseShaderProgramEXT(GLenum type, GLuint program) { @@ -1570,6 +1589,10 @@ _mesa_UseShaderProgramEXT(GLenum type, GLuint program) _mesa_use_shader_program(ctx, type, shProg); } + +/** + * For GL_EXT_separate_shader_objects + */ void GLAPIENTRY _mesa_ActiveProgramEXT(GLuint program) { @@ -1582,6 +1605,10 @@ _mesa_ActiveProgramEXT(GLuint program) return; } + +/** + * For GL_EXT_separate_shader_objects + */ GLuint GLAPIENTRY _mesa_CreateShaderProgramEXT(GLenum type, const GLchar *string) { diff --git a/mesalib/src/mesa/main/texobj.c b/mesalib/src/mesa/main/texobj.c index 365169ddd..a471bad22 100644 --- a/mesalib/src/mesa/main/texobj.c +++ b/mesalib/src/mesa/main/texobj.c @@ -558,7 +558,8 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, GLuint face; assert(baseImage->Width2 == baseImage->Height); for (face = 1; face < 6; face++) { - assert(t->Image[face][baseLevel]->Width2 == + assert(t->Image[face][baseLevel] == NULL || + t->Image[face][baseLevel]->Width2 == t->Image[face][baseLevel]->Height2); if (t->Image[face][baseLevel] == NULL || t->Image[face][baseLevel]->Width2 != baseImage->Width2) { diff --git a/mesalib/src/mesa/main/uniform_query.cpp b/mesalib/src/mesa/main/uniform_query.cpp index 08d330a52..f5d998ffb 100644 --- a/mesalib/src/mesa/main/uniform_query.cpp +++ b/mesalib/src/mesa/main/uniform_query.cpp @@ -46,6 +46,8 @@ _mesa_GetActiveUniformARB(GLhandleARB program, GLuint index, struct gl_shader_program *shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform"); + ASSERT_OUTSIDE_BEGIN_END(ctx); + if (!shProg) return; diff --git a/mesalib/src/mesa/program/prog_execute.c b/mesalib/src/mesa/program/prog_execute.c index 848c2fec1..dd1706e14 100644 --- a/mesalib/src/mesa/program/prog_execute.c +++ b/mesalib/src/mesa/program/prog_execute.c @@ -1308,8 +1308,8 @@ _mesa_execute_program(struct gl_context * ctx, fetch_vector4(&inst->SrcReg[0], machine, a); a[0] = CLAMP(a[0], 0.0F, 1.0F); a[1] = CLAMP(a[1], 0.0F, 1.0F); - usx = IROUND(a[0] * 65535.0F); - usy = IROUND(a[1] * 65535.0F); + usx = F_TO_I(a[0] * 65535.0F); + usy = F_TO_I(a[1] * 65535.0F); result[0] = result[1] = result[2] = @@ -1326,10 +1326,10 @@ _mesa_execute_program(struct gl_context * ctx, a[1] = CLAMP(a[1], -128.0F / 127.0F, 1.0F); a[2] = CLAMP(a[2], -128.0F / 127.0F, 1.0F); a[3] = CLAMP(a[3], -128.0F / 127.0F, 1.0F); - ubx = IROUND(127.0F * a[0] + 128.0F); - uby = IROUND(127.0F * a[1] + 128.0F); - ubz = IROUND(127.0F * a[2] + 128.0F); - ubw = IROUND(127.0F * a[3] + 128.0F); + ubx = F_TO_I(127.0F * a[0] + 128.0F); + uby = F_TO_I(127.0F * a[1] + 128.0F); + ubz = F_TO_I(127.0F * a[2] + 128.0F); + ubw = F_TO_I(127.0F * a[3] + 128.0F); result[0] = result[1] = result[2] = @@ -1346,10 +1346,10 @@ _mesa_execute_program(struct gl_context * ctx, a[1] = CLAMP(a[1], 0.0F, 1.0F); a[2] = CLAMP(a[2], 0.0F, 1.0F); a[3] = CLAMP(a[3], 0.0F, 1.0F); - ubx = IROUND(255.0F * a[0]); - uby = IROUND(255.0F * a[1]); - ubz = IROUND(255.0F * a[2]); - ubw = IROUND(255.0F * a[3]); + ubx = F_TO_I(255.0F * a[0]); + uby = F_TO_I(255.0F * a[1]); + ubz = F_TO_I(255.0F * a[2]); + ubw = F_TO_I(255.0F * a[3]); result[0] = result[1] = result[2] = diff --git a/mesalib/src/mesa/sources.mak b/mesalib/src/mesa/sources.mak index c746b8afa..19a05ecc8 100644 --- a/mesalib/src/mesa/sources.mak +++ b/mesalib/src/mesa/sources.mak @@ -184,6 +184,7 @@ VBO_SOURCES = \ vbo/vbo_exec_draw.c \ vbo/vbo_exec_eval.c \ vbo/vbo_noop.c \ + vbo/vbo_primitive_restart.c \ vbo/vbo_rebase.c \ vbo/vbo_split.c \ vbo/vbo_split_copy.c \ diff --git a/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c b/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c index 6534a4347..b47a2d87f 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c +++ b/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c @@ -195,6 +195,9 @@ st_bufferobj_data(struct gl_context *ctx, case GL_ELEMENT_ARRAY_BUFFER_ARB: bind = PIPE_BIND_INDEX_BUFFER; break; + case GL_TRANSFORM_FEEDBACK_BUFFER: + bind = PIPE_BIND_STREAM_OUTPUT; + break; default: bind = 0; } diff --git a/mesalib/src/mesa/state_tracker/st_context.c b/mesalib/src/mesa/state_tracker/st_context.c index b44976525..132dcc02f 100644 --- a/mesalib/src/mesa/state_tracker/st_context.c +++ b/mesalib/src/mesa/state_tracker/st_context.c @@ -247,7 +247,7 @@ static void st_destroy_context_priv( struct st_context *st ) st_destroy_drawtex(st); for (i = 0; i < Elements(st->state.sampler_views); i++) { - pipe_sampler_view_reference(&st->state.sampler_views[i], NULL); + pipe_sampler_view_release(st->pipe, &st->state.sampler_views[i]); } if (st->default_texture) { diff --git a/mesalib/src/mesa/state_tracker/st_context.h b/mesalib/src/mesa/state_tracker/st_context.h index 00a405b69..55ae65b3c 100644 --- a/mesalib/src/mesa/state_tracker/st_context.h +++ b/mesalib/src/mesa/state_tracker/st_context.h @@ -79,7 +79,6 @@ struct st_context struct draw_stage *feedback_stage; /**< For GL_FEEDBACK rendermode */ struct draw_stage *selection_stage; /**< For GL_SELECT rendermode */ struct draw_stage *rastpos_stage; /**< For glRasterPos */ - GLboolean sw_primitive_restart; GLboolean clamp_frag_color_in_shader; GLboolean clamp_vert_color_in_shader; diff --git a/mesalib/src/mesa/state_tracker/st_draw.c b/mesalib/src/mesa/state_tracker/st_draw.c index a8c20f45a..0a06e9995 100644 --- a/mesalib/src/mesa/state_tracker/st_draw.c +++ b/mesalib/src/mesa/state_tracker/st_draw.c @@ -638,175 +638,6 @@ check_uniforms(struct gl_context *ctx) } -/* - * Notes on primitive restart: - * The code below is used when the gallium driver does not support primitive - * restart itself. We map the index buffer, find the restart indexes, unmap - * the index buffer then draw the sub-primitives delineated by the restarts. - * A couple possible optimizations: - * 1. Save the list of sub-primitive (start, count) values in a list attached - * to the index buffer for re-use in subsequent draws. The list would be - * invalidated when the contents of the buffer changed. - * 2. If drawing triangle strips or quad strips, create a new index buffer - * that uses duplicated vertices to render the disjoint strips as one - * long strip. We'd have to be careful to avoid using too much memory - * for this. - * Finally, some apps might perform better if they don't use primitive restart - * at all rather than this fallback path. Set MESA_EXTENSION_OVERRIDE to - * "-GL_NV_primitive_restart" to test that. - */ - - -struct sub_primitive -{ - unsigned start, count; -}; - - -/** - * Scan the elements array to find restart indexes. Return a list - * of primitive (start,count) pairs to indicate how to draw the sub- - * primitives delineated by the restart index. - */ -static struct sub_primitive * -find_sub_primitives(const void *elements, unsigned element_size, - unsigned start, unsigned end, unsigned restart_index, - unsigned *num_sub_prims) -{ - const unsigned max_prims = end - start; - struct sub_primitive *sub_prims; - unsigned i, cur_start, cur_count, num; - - sub_prims = (struct sub_primitive *) - malloc(max_prims * sizeof(struct sub_primitive)); - - if (!sub_prims) { - *num_sub_prims = 0; - return NULL; - } - - cur_start = start; - cur_count = 0; - num = 0; - -#define SCAN_ELEMENTS(TYPE) \ - for (i = start; i < end; i++) { \ - if (((const TYPE *) elements)[i] == restart_index) { \ - if (cur_count > 0) { \ - assert(num < max_prims); \ - sub_prims[num].start = cur_start; \ - sub_prims[num].count = cur_count; \ - num++; \ - } \ - cur_start = i + 1; \ - cur_count = 0; \ - } \ - else { \ - cur_count++; \ - } \ - } \ - if (cur_count > 0) { \ - assert(num < max_prims); \ - sub_prims[num].start = cur_start; \ - sub_prims[num].count = cur_count; \ - num++; \ - } - - switch (element_size) { - case 1: - SCAN_ELEMENTS(ubyte); - break; - case 2: - SCAN_ELEMENTS(ushort); - break; - case 4: - SCAN_ELEMENTS(uint); - break; - default: - assert(0 && "bad index_size in find_sub_primitives()"); - } - -#undef SCAN_ELEMENTS - - *num_sub_prims = num; - - return sub_prims; -} - - -/** - * For gallium drivers that don't support the primitive restart - * feature, handle it here by breaking up the indexed primitive into - * sub-primitives. - */ -static void -handle_fallback_primitive_restart(struct cso_context *cso, - struct pipe_context *pipe, - const struct _mesa_index_buffer *ib, - struct pipe_index_buffer *ibuffer, - struct pipe_draw_info *orig_info) -{ - const unsigned start = orig_info->start; - const unsigned count = orig_info->count; - struct pipe_draw_info info = *orig_info; - struct pipe_transfer *transfer = NULL; - unsigned instance, i; - const void *ptr = NULL; - struct sub_primitive *sub_prims; - unsigned num_sub_prims; - - assert(info.indexed); - assert(ibuffer->buffer || ibuffer->user_buffer); - assert(ib); - - if (!ibuffer->buffer || !ibuffer->user_buffer || !ib) - return; - - info.primitive_restart = FALSE; - info.instance_count = 1; - - if (_mesa_is_bufferobj(ib->obj)) { - ptr = pipe_buffer_map_range(pipe, ibuffer->buffer, - start * ibuffer->index_size, /* start */ - count * ibuffer->index_size, /* length */ - PIPE_TRANSFER_READ, &transfer); - if (!ptr) - return; - - ptr = (uint8_t*)ptr + (ibuffer->offset - start * ibuffer->index_size); - } - else { - ptr = ib->ptr; - if (!ptr) - return; - } - - sub_prims = find_sub_primitives(ptr, ibuffer->index_size, - 0, count, orig_info->restart_index, - &num_sub_prims); - - if (transfer) - pipe_buffer_unmap(pipe, transfer); - - /* Now draw the sub primitives. - * Need to loop over instances as well to preserve draw order. - */ - for (instance = 0; instance < orig_info->instance_count; instance++) { - info.start_instance = instance + orig_info->start_instance; - for (i = 0; i < num_sub_prims; i++) { - info.start = sub_prims[i].start; - info.count = sub_prims[i].count; - if (u_trim_pipe_prim(info.mode, &info.count)) { - cso_draw_vbo(cso, &info); - } - } - } - - if (sub_prims) - free(sub_prims); -} - - /** * Translate OpenGL primtive type (GL_POINTS, GL_TRIANGLE_STRIP, etc) to * the corresponding Gallium type. @@ -901,7 +732,6 @@ st_draw_vbo(struct gl_context *ctx, struct gl_transform_feedback_object *tfb_vertcount) { struct st_context *st = st_context(ctx); - struct pipe_context *pipe = st->pipe; struct pipe_index_buffer ibuffer = {0}; struct pipe_draw_info info; const struct gl_client_array **arrays = ctx->Array._DrawArrays; @@ -994,15 +824,8 @@ st_draw_vbo(struct gl_context *ctx, cso_draw_vbo(st->cso_context, &info); } else if (info.primitive_restart) { - if (st->sw_primitive_restart) { - /* Handle primitive restart for drivers that doesn't support it */ - handle_fallback_primitive_restart(st->cso_context, pipe, ib, - &ibuffer, &info); - } - else { - /* don't trim, restarts might be inside index list */ - cso_draw_vbo(st->cso_context, &info); - } + /* don't trim, restarts might be inside index list */ + cso_draw_vbo(st->cso_context, &info); } else if (u_trim_pipe_prim(info.mode, &info.count)) cso_draw_vbo(st->cso_context, &info); diff --git a/mesalib/src/mesa/state_tracker/st_extensions.c b/mesalib/src/mesa/state_tracker/st_extensions.c index 1b4bca681..953155f36 100644 --- a/mesalib/src/mesa/state_tracker/st_extensions.c +++ b/mesalib/src/mesa/state_tracker/st_extensions.c @@ -601,7 +601,7 @@ void st_init_extensions(struct st_context *st) ctx->Extensions.NV_primitive_restart = GL_TRUE; if (!screen->get_param(screen, PIPE_CAP_PRIMITIVE_RESTART)) { - st->sw_primitive_restart = GL_TRUE; + ctx->Const.PrimitiveRestartInSoftware = GL_TRUE; } if (screen->get_param(screen, PIPE_CAP_VERTEX_COLOR_UNCLAMPED)) { diff --git a/mesalib/src/mesa/state_tracker/st_program.c b/mesalib/src/mesa/state_tracker/st_program.c index deee722cf..e6664fb7c 100644 --- a/mesalib/src/mesa/state_tracker/st_program.c +++ b/mesalib/src/mesa/state_tracker/st_program.c @@ -1285,3 +1285,26 @@ st_destroy_program_variants(struct st_context *st) _mesa_HashWalk(st->ctx->Shared->ShaderObjects, destroy_shader_program_variants_cb, st); } + + +/** + * For debugging, print/dump the current vertex program. + */ +void +st_print_current_vertex_program(void) +{ + GET_CURRENT_CONTEXT(ctx); + + if (ctx->VertexProgram._Current) { + struct st_vertex_program *stvp = + (struct st_vertex_program *) ctx->VertexProgram._Current; + struct st_vp_variant *stv; + + debug_printf("Vertex program %u\n", stvp->Base.Base.Id); + + for (stv = stvp->variants; stv; stv = stv->next) { + debug_printf("variant %p\n", stv); + tgsi_dump(stv->tgsi.tokens, 0); + } + } +} diff --git a/mesalib/src/mesa/state_tracker/st_program.h b/mesalib/src/mesa/state_tracker/st_program.h index 6c4b4f6c3..23a262ccc 100644 --- a/mesalib/src/mesa/state_tracker/st_program.h +++ b/mesalib/src/mesa/state_tracker/st_program.h @@ -315,4 +315,8 @@ extern void st_destroy_program_variants(struct st_context *st); +extern void +st_print_current_vertex_program(void); + + #endif diff --git a/mesalib/src/mesa/vbo/vbo.h b/mesalib/src/mesa/vbo/vbo.h index 3cff8987e..4387e10b7 100644 --- a/mesalib/src/mesa/vbo/vbo.h +++ b/mesalib/src/mesa/vbo/vbo.h @@ -157,6 +157,12 @@ void vbo_bind_arrays(struct gl_context *ctx); size_t count_tessellated_primitives(const struct _mesa_prim *prim); +void +vbo_sw_primitive_restart(struct gl_context *ctx, + const struct _mesa_prim *prim, + GLuint nr_prims, + const struct _mesa_index_buffer *ib); + void GLAPIENTRY _es_Color4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a); diff --git a/mesalib/src/mesa/vbo/vbo_exec_array.c b/mesalib/src/mesa/vbo/vbo_exec_array.c index 9303ad719..3fb7c6480 100644 --- a/mesalib/src/mesa/vbo/vbo_exec_array.c +++ b/mesalib/src/mesa/vbo/vbo_exec_array.c @@ -543,6 +543,37 @@ vbo_bind_arrays(struct gl_context *ctx) /** + * Handle a draw case that potentially has primitive restart enabled. + * + * If primitive restart is enabled, and PrimitiveRestartInSoftware is + * set, then vbo_sw_primitive_restart is used to handle the primitive + * restart case in software. + */ +static void +vbo_handle_primitive_restart(struct gl_context *ctx, + const struct _mesa_prim *prim, + GLuint nr_prims, + const struct _mesa_index_buffer *ib, + GLboolean index_bounds_valid, + GLuint min_index, + GLuint max_index) +{ + struct vbo_context *vbo = vbo_context(ctx); + + if ((ib != NULL) && + ctx->Const.PrimitiveRestartInSoftware && + ctx->Array.PrimitiveRestart) { + /* Handle primitive restart in software */ + vbo_sw_primitive_restart(ctx, prim, nr_prims, ib); + } else { + /* Call driver directly for draw_prims */ + vbo->draw_prims(ctx, prim, nr_prims, ib, + index_bounds_valid, min_index, max_index, NULL); + } +} + + +/** * Helper function called by the other DrawArrays() functions below. * This is where we handle primitive restart for drawing non-indexed * arrays. If primitive restart is enabled, it typically means @@ -805,8 +836,8 @@ vbo_validated_drawrangeelements(struct gl_context *ctx, GLenum mode, */ check_buffers_are_unmapped(exec->array.inputs); - vbo->draw_prims( ctx, prim, 1, &ib, - index_bounds_valid, start, end, NULL ); + vbo_handle_primitive_restart(ctx, prim, 1, &ib, + index_bounds_valid, start, end); if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { _mesa_flush(ctx); @@ -1104,8 +1135,8 @@ vbo_validated_multidrawelements(struct gl_context *ctx, GLenum mode, } check_buffers_are_unmapped(exec->array.inputs); - vbo->draw_prims(ctx, prim, primcount, &ib, - GL_FALSE, ~0, ~0, NULL); + vbo_handle_primitive_restart(ctx, prim, primcount, &ib, + GL_FALSE, ~0, ~0); } else { /* render one prim at a time */ for (i = 0; i < primcount; i++) { @@ -1129,8 +1160,8 @@ vbo_validated_multidrawelements(struct gl_context *ctx, GLenum mode, prim[0].basevertex = 0; check_buffers_are_unmapped(exec->array.inputs); - vbo->draw_prims(ctx, prim, 1, &ib, - GL_FALSE, ~0, ~0, NULL); + vbo_handle_primitive_restart(ctx, prim, 1, &ib, + GL_FALSE, ~0, ~0); } } diff --git a/mesalib/src/mesa/vbo/vbo_primitive_restart.c b/mesalib/src/mesa/vbo/vbo_primitive_restart.c new file mode 100644 index 000000000..18d851c1e --- /dev/null +++ b/mesalib/src/mesa/vbo/vbo_primitive_restart.c @@ -0,0 +1,233 @@ +/* + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Copyright © 2012 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Jordan Justen <jordan.l.justen@intel.com> + * + */ + +#include "main/imports.h" +#include "main/bufferobj.h" +#include "main/macros.h" + +#include "vbo.h" +#include "vbo_context.h" + +#define UPDATE_MIN2(a, b) (a) = MIN2((a), (b)) +#define UPDATE_MAX2(a, b) (a) = MAX2((a), (b)) + +/* + * Notes on primitive restart: + * The code below is used when the driver does not support primitive + * restart itself. (ctx->Const.PrimitiveRestartInSoftware == GL_TRUE) + * + * We map the index buffer, find the restart indexes, unmap + * the index buffer then draw the sub-primitives delineated by the restarts. + * + * A couple possible optimizations: + * 1. Save the list of sub-primitive (start, count) values in a list attached + * to the index buffer for re-use in subsequent draws. The list would be + * invalidated when the contents of the buffer changed. + * 2. If drawing triangle strips or quad strips, create a new index buffer + * that uses duplicated vertices to render the disjoint strips as one + * long strip. We'd have to be careful to avoid using too much memory + * for this. + * + * Finally, some apps might perform better if they don't use primitive restart + * at all rather than this fallback path. Set MESA_EXTENSION_OVERRIDE to + * "-GL_NV_primitive_restart" to test that. + */ + + +struct sub_primitive +{ + GLuint start; + GLuint count; + GLuint min_index; + GLuint max_index; +}; + + +/** + * Scan the elements array to find restart indexes. Return an array + * of struct sub_primitive to indicate how to draw the sub-primitives + * are delineated by the restart index. + */ +static struct sub_primitive * +find_sub_primitives(const void *elements, unsigned element_size, + unsigned start, unsigned end, unsigned restart_index, + unsigned *num_sub_prims) +{ + const unsigned max_prims = end - start; + struct sub_primitive *sub_prims; + unsigned i, cur_start, cur_count; + GLuint scan_index; + unsigned scan_num; + + sub_prims = (struct sub_primitive *) + malloc(max_prims * sizeof(struct sub_primitive)); + + if (!sub_prims) { + *num_sub_prims = 0; + return NULL; + } + + cur_start = start; + cur_count = 0; + scan_num = 0; + +#define IB_INDEX_READ(TYPE, INDEX) (((const GL##TYPE *) elements)[INDEX]) + +#define SCAN_ELEMENTS(TYPE) \ + sub_prims[scan_num].min_index = (GL##TYPE) 0xffffffff; \ + sub_prims[scan_num].max_index = 0; \ + for (i = start; i < end; i++) { \ + scan_index = IB_INDEX_READ(TYPE, i); \ + if (scan_index == restart_index) { \ + if (cur_count > 0) { \ + assert(scan_num < max_prims); \ + sub_prims[scan_num].start = cur_start; \ + sub_prims[scan_num].count = cur_count; \ + scan_num++; \ + sub_prims[scan_num].min_index = (GL##TYPE) 0xffffffff; \ + sub_prims[scan_num].max_index = 0; \ + } \ + cur_start = i + 1; \ + cur_count = 0; \ + } \ + else { \ + UPDATE_MIN2(sub_prims[scan_num].min_index, scan_index); \ + UPDATE_MAX2(sub_prims[scan_num].max_index, scan_index); \ + cur_count++; \ + } \ + } \ + if (cur_count > 0) { \ + assert(scan_num < max_prims); \ + sub_prims[scan_num].start = cur_start; \ + sub_prims[scan_num].count = cur_count; \ + scan_num++; \ + } + + switch (element_size) { + case 1: + SCAN_ELEMENTS(ubyte); + break; + case 2: + SCAN_ELEMENTS(ushort); + break; + case 4: + SCAN_ELEMENTS(uint); + break; + default: + assert(0 && "bad index_size in find_sub_primitives()"); + } + +#undef SCAN_ELEMENTS + + *num_sub_prims = scan_num; + + return sub_prims; +} + + +/** + * Handle primitive restart in software. + * + * This function breaks up calls into the driver so primitive restart + * support is not required in the driver. + */ +void +vbo_sw_primitive_restart(struct gl_context *ctx, + const struct _mesa_prim *prims, + GLuint nr_prims, + const struct _mesa_index_buffer *ib) +{ + GLuint prim_num; + struct sub_primitive *sub_prims; + struct sub_primitive *sub_prim; + GLuint num_sub_prims; + GLuint sub_prim_num; + GLuint end_index; + GLuint sub_end_index; + GLuint restart_index = ctx->Array.RestartIndex; + struct _mesa_prim temp_prim; + struct vbo_context *vbo = vbo_context(ctx); + vbo_draw_func draw_prims_func = vbo->draw_prims; + GLboolean map_ib = ib->obj->Name && !ib->obj->Pointer; + void *ptr; + + /* Find the sub-primitives. These are regions in the index buffer which + * are split based on the primitive restart index value. + */ + if (map_ib) { + ctx->Driver.MapBufferRange(ctx, 0, ib->obj->Size, GL_MAP_READ_BIT, + ib->obj); + } + + ptr = ADD_POINTERS(ib->obj->Pointer, ib->ptr); + + sub_prims = find_sub_primitives(ptr, vbo_sizeof_ib_type(ib->type), + 0, ib->count, restart_index, + &num_sub_prims); + + if (map_ib) { + ctx->Driver.UnmapBuffer(ctx, ib->obj); + } + + /* Loop over the primitives, and use the located sub-primitives to draw + * each primitive with a break to implement each primitive restart. + */ + for (prim_num = 0; prim_num < nr_prims; prim_num++) { + end_index = prims[prim_num].start + prims[prim_num].count; + memcpy(&temp_prim, &prims[prim_num], sizeof (temp_prim)); + /* Loop over the sub-primitives drawing sub-ranges of the primitive. */ + for (sub_prim_num = 0; sub_prim_num < num_sub_prims; sub_prim_num++) { + sub_prim = &sub_prims[sub_prim_num]; + sub_end_index = sub_prim->start + sub_prim->count; + if (prims[prim_num].start <= sub_prim->start) { + temp_prim.start = MAX2(prims[prim_num].start, sub_prim->start); + temp_prim.count = MIN2(sub_end_index, end_index) - temp_prim.start; + if ((temp_prim.start == sub_prim->start) && + (temp_prim.count == sub_prim->count)) { + draw_prims_func(ctx, &temp_prim, 1, ib, + GL_TRUE, sub_prim->min_index, sub_prim->max_index, + NULL); + } else { + draw_prims_func(ctx, &temp_prim, 1, ib, + GL_FALSE, -1, -1, + NULL); + } + } + if (sub_end_index >= end_index) { + break; + } + } + } + + if (sub_prims) { + free(sub_prims); + } +} + diff --git a/pixman/configure.ac b/pixman/configure.ac index d9498397b..027a1680e 100644 --- a/pixman/configure.ac +++ b/pixman/configure.ac @@ -54,7 +54,7 @@ AC_PREREQ([2.57]) m4_define([pixman_major], 0) m4_define([pixman_minor], 25) -m4_define([pixman_micro], 3) +m4_define([pixman_micro], 7) m4_define([pixman_version],[pixman_major.pixman_minor.pixman_micro]) @@ -619,6 +619,9 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ #ifndef __arm__ #error "IWMMXT is only available on ARM" #endif +#ifndef __IWMMXT__ +#error "IWMMXT not enabled (with -march=iwmmxt)" +#endif #if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5)) #error "Need GCC >= 4.5 for IWMMXT intrinsics" #endif diff --git a/pixman/demos/Makefile.am b/pixman/demos/Makefile.am index a664d939e..9aac1f5e9 100644 --- a/pixman/demos/Makefile.am +++ b/pixman/demos/Makefile.am @@ -22,6 +22,8 @@ DEMOS = \ quad2quad \ checkerboard +EXTRA_DIST = parrot.c parrot.jpg + gradient_test_SOURCES = gradient-test.c $(GTK_UTILS) alpha_test_SOURCES = alpha-test.c $(GTK_UTILS) composite_test_SOURCES = composite-test.c $(GTK_UTILS) diff --git a/xorg-server/Xi/exevents.c b/xorg-server/Xi/exevents.c index f11e09f38..99224088e 100644 --- a/xorg-server/Xi/exevents.c +++ b/xorg-server/Xi/exevents.c @@ -271,8 +271,6 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to) } } else if (to->intfeed && !from->intfeed) { - ClassesPtr classes; - classes = to->unused_classes; classes->intfeed = to->intfeed; to->intfeed = NULL; @@ -303,8 +301,6 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to) } } else if (to->stringfeed && !from->stringfeed) { - ClassesPtr classes; - classes = to->unused_classes; classes->stringfeed = to->stringfeed; to->stringfeed = NULL; @@ -336,8 +332,6 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to) } } else if (to->bell && !from->bell) { - ClassesPtr classes; - classes = to->unused_classes; classes->bell = to->bell; to->bell = NULL; @@ -371,8 +365,6 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to) } } else if (to->leds && !from->leds) { - ClassesPtr classes; - classes = to->unused_classes; classes->leds = to->leds; to->leds = NULL; @@ -419,8 +411,6 @@ DeepCopyKeyboardClasses(DeviceIntPtr from, DeviceIntPtr to) } } else if (to->kbdfeed && !from->kbdfeed) { - ClassesPtr classes; - classes = to->unused_classes; classes->kbdfeed = to->kbdfeed; to->kbdfeed = NULL; @@ -439,8 +429,6 @@ DeepCopyKeyboardClasses(DeviceIntPtr from, DeviceIntPtr to) CopyKeyClass(from, to); } else if (to->key && !from->key) { - ClassesPtr classes; - classes = to->unused_classes; classes->key = to->key; to->key = NULL; @@ -496,8 +484,6 @@ DeepCopyKeyboardClasses(DeviceIntPtr from, DeviceIntPtr to) } } else if (to->focus) { - ClassesPtr classes; - classes = to->unused_classes; classes->focus = to->focus; to->focus = NULL; @@ -538,8 +524,6 @@ DeepCopyPointerClasses(DeviceIntPtr from, DeviceIntPtr to) } } else if (to->ptrfeed && !from->ptrfeed) { - ClassesPtr classes; - classes = to->unused_classes; classes->ptrfeed = to->ptrfeed; to->ptrfeed = NULL; @@ -566,8 +550,6 @@ DeepCopyPointerClasses(DeviceIntPtr from, DeviceIntPtr to) v->sourceid = from->id; } else if (to->valuator && !from->valuator) { - ClassesPtr classes; - classes = to->unused_classes; classes->valuator = to->valuator; to->valuator = NULL; @@ -603,8 +585,6 @@ DeepCopyPointerClasses(DeviceIntPtr from, DeviceIntPtr to) to->button->sourceid = from->id; } else if (to->button && !from->button) { - ClassesPtr classes; - classes = to->unused_classes; classes->button = to->button; to->button = NULL; @@ -626,8 +606,6 @@ DeepCopyPointerClasses(DeviceIntPtr from, DeviceIntPtr to) to->proximity->sourceid = from->id; } else if (to->proximity) { - ClassesPtr classes; - classes = to->unused_classes; classes->proximity = to->proximity; to->proximity = NULL; @@ -1463,9 +1441,9 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, if (grab->ownerEvents) { WindowPtr focus = NullWindow; - WindowPtr win = dev->spriteInfo->sprite->win; + WindowPtr sprite_win = dev->spriteInfo->sprite->win; - deliveries = DeliverDeviceEvents(win, ptrev, grab, focus, dev); + deliveries = DeliverDeviceEvents(sprite_win, ptrev, grab, focus, dev); } if (!deliveries) @@ -1496,7 +1474,7 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, * the event. */ if (!devgrab && dev->deviceGrab.grab && dev->deviceGrab.implicitGrab) { - TouchListener *listener; + TouchListener *l; devgrab = dev->deviceGrab.grab; @@ -1506,13 +1484,13 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, * selection. Implicit grab activation occurs through delivering an * event selection. Thus, we update the last listener in the array. */ - listener = &ti->listeners[ti->num_listeners - 1]; - listener->listener = devgrab->resource; + l = &ti->listeners[ti->num_listeners - 1]; + l->listener = devgrab->resource; if (devgrab->grabtype != XI2 || devgrab->type != XI_TouchBegin) - listener->type = LISTENER_POINTER_GRAB; + l->type = LISTENER_POINTER_GRAB; else - listener->type = LISTENER_GRAB; + l->type = LISTENER_GRAB; } } @@ -2118,240 +2096,6 @@ SetScrollValuator(DeviceIntPtr dev, int axnum, enum ScrollType type, return TRUE; } -static void -FixDeviceStateNotify(DeviceIntPtr dev, deviceStateNotify * ev, KeyClassPtr k, - ButtonClassPtr b, ValuatorClassPtr v, int first) -{ - ev->type = DeviceStateNotify; - ev->deviceid = dev->id; - ev->time = currentTime.milliseconds; - ev->classes_reported = 0; - ev->num_keys = 0; - ev->num_buttons = 0; - ev->num_valuators = 0; - - if (b) { - ev->classes_reported |= (1 << ButtonClass); - ev->num_buttons = b->numButtons; - memcpy((char *) ev->buttons, (char *) b->down, 4); - } - else if (k) { - ev->classes_reported |= (1 << KeyClass); - ev->num_keys = k->xkbInfo->desc->max_key_code - - k->xkbInfo->desc->min_key_code; - memmove((char *) &ev->keys[0], (char *) k->down, 4); - } - if (v) { - int nval = v->numAxes - first; - - ev->classes_reported |= (1 << ValuatorClass); - ev->classes_reported |= valuator_get_mode(dev, 0) << ModeBitsShift; - ev->num_valuators = nval < 3 ? nval : 3; - switch (ev->num_valuators) { - case 3: - ev->valuator2 = v->axisVal[first + 2]; - case 2: - ev->valuator1 = v->axisVal[first + 1]; - case 1: - ev->valuator0 = v->axisVal[first]; - break; - } - } -} - -static void -FixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v, - int first) -{ - int nval = v->numAxes - first; - - ev->type = DeviceValuator; - ev->deviceid = dev->id; - ev->num_valuators = nval < 3 ? nval : 3; - ev->first_valuator = first; - switch (ev->num_valuators) { - case 3: - ev->valuator2 = v->axisVal[first + 2]; - case 2: - ev->valuator1 = v->axisVal[first + 1]; - case 1: - ev->valuator0 = v->axisVal[first]; - break; - } - first += ev->num_valuators; -} - -static void -DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win) -{ - int evcount = 1; - deviceStateNotify *ev, *sev; - deviceKeyStateNotify *kev; - deviceButtonStateNotify *bev; - - KeyClassPtr k; - ButtonClassPtr b; - ValuatorClassPtr v; - int nval = 0, nkeys = 0, nbuttons = 0, first = 0; - - if (!(wOtherInputMasks(win)) || - !(wOtherInputMasks(win)->inputEvents[dev->id] & DeviceStateNotifyMask)) - return; - - if ((b = dev->button) != NULL) { - nbuttons = b->numButtons; - if (nbuttons > 32) - evcount++; - } - if ((k = dev->key) != NULL) { - nkeys = k->xkbInfo->desc->max_key_code - k->xkbInfo->desc->min_key_code; - if (nkeys > 32) - evcount++; - if (nbuttons > 0) { - evcount++; - } - } - if ((v = dev->valuator) != NULL) { - nval = v->numAxes; - - if (nval > 3) - evcount++; - if (nval > 6) { - if (!(k && b)) - evcount++; - if (nval > 9) - evcount += ((nval - 7) / 3); - } - } - - sev = ev = (deviceStateNotify *) malloc(evcount * sizeof(xEvent)); - FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first); - - if (b != NULL) { - FixDeviceStateNotify(dev, ev++, NULL, b, v, first); - first += 3; - nval -= 3; - if (nbuttons > 32) { - (ev - 1)->deviceid |= MORE_EVENTS; - bev = (deviceButtonStateNotify *) ev++; - bev->type = DeviceButtonStateNotify; - bev->deviceid = dev->id; - memcpy((char *) &bev->buttons[4], (char *) &b->down[4], - DOWN_LENGTH - 4); - } - if (nval > 0) { - (ev - 1)->deviceid |= MORE_EVENTS; - FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); - first += 3; - nval -= 3; - } - } - - if (k != NULL) { - FixDeviceStateNotify(dev, ev++, k, NULL, v, first); - first += 3; - nval -= 3; - if (nkeys > 32) { - (ev - 1)->deviceid |= MORE_EVENTS; - kev = (deviceKeyStateNotify *) ev++; - kev->type = DeviceKeyStateNotify; - kev->deviceid = dev->id; - memmove((char *) &kev->keys[0], (char *) &k->down[4], 28); - } - if (nval > 0) { - (ev - 1)->deviceid |= MORE_EVENTS; - FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); - first += 3; - nval -= 3; - } - } - - while (nval > 0) { - FixDeviceStateNotify(dev, ev++, NULL, NULL, v, first); - first += 3; - nval -= 3; - if (nval > 0) { - (ev - 1)->deviceid |= MORE_EVENTS; - FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); - first += 3; - nval -= 3; - } - } - - DeliverEventsToWindow(dev, win, (xEvent *) sev, evcount, - DeviceStateNotifyMask, NullGrab); - free(sev); -} - -void -DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail, - WindowPtr pWin) -{ - deviceFocus event; - xXIFocusInEvent *xi2event; - DeviceIntPtr mouse; - int btlen, len, i; - - mouse = IsFloating(dev) ? dev : GetMaster(dev, MASTER_POINTER); - - /* XI 2 event */ - btlen = (mouse->button) ? bits_to_bytes(mouse->button->numButtons) : 0; - btlen = bytes_to_int32(btlen); - len = sizeof(xXIFocusInEvent) + btlen * 4; - - xi2event = calloc(1, len); - xi2event->type = GenericEvent; - xi2event->extension = IReqCode; - xi2event->evtype = type; - xi2event->length = bytes_to_int32(len - sizeof(xEvent)); - xi2event->buttons_len = btlen; - xi2event->detail = detail; - xi2event->time = currentTime.milliseconds; - xi2event->deviceid = dev->id; - xi2event->sourceid = dev->id; /* a device doesn't change focus by itself */ - xi2event->mode = mode; - xi2event->root_x = FP1616(mouse->spriteInfo->sprite->hot.x, 0); - xi2event->root_y = FP1616(mouse->spriteInfo->sprite->hot.y, 0); - - for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++) - if (BitIsOn(mouse->button->down, i)) - SetBit(&xi2event[1], mouse->button->map[i]); - - if (dev->key) { - xi2event->mods.base_mods = dev->key->xkbInfo->state.base_mods; - xi2event->mods.latched_mods = dev->key->xkbInfo->state.latched_mods; - xi2event->mods.locked_mods = dev->key->xkbInfo->state.locked_mods; - xi2event->mods.effective_mods = dev->key->xkbInfo->state.mods; - - xi2event->group.base_group = dev->key->xkbInfo->state.base_group; - xi2event->group.latched_group = dev->key->xkbInfo->state.latched_group; - xi2event->group.locked_group = dev->key->xkbInfo->state.locked_group; - xi2event->group.effective_group = dev->key->xkbInfo->state.group; - } - - FixUpEventFromWindow(dev->spriteInfo->sprite, (xEvent *) xi2event, pWin, - None, FALSE); - - DeliverEventsToWindow(dev, pWin, (xEvent *) xi2event, 1, - GetEventFilter(dev, (xEvent *) xi2event), NullGrab); - - free(xi2event); - - /* XI 1.x event */ - event.deviceid = dev->id; - event.mode = mode; - event.type = (type == XI_FocusIn) ? DeviceFocusIn : DeviceFocusOut; - event.detail = detail; - event.window = pWin->drawable.id; - event.time = currentTime.milliseconds; - - DeliverEventsToWindow(dev, pWin, (xEvent *) &event, 1, - DeviceFocusChangeMask, NullGrab); - - if (event.type == DeviceFocusIn) - DeliverStateNotifyEvent(dev, pWin); -} - int CheckGrabValues(ClientPtr client, GrabParameters *param) { diff --git a/xorg-server/Xi/extinit.c b/xorg-server/Xi/extinit.c index 4483076e9..494e887cd 100644 --- a/xorg-server/Xi/extinit.c +++ b/xorg-server/Xi/extinit.c @@ -1137,6 +1137,9 @@ IResetProc(ExtensionEntry * unused) EventSwapVector[DevicePresenceNotify] = NotImplemented; EventSwapVector[DevicePropertyNotify] = NotImplemented; RestoreExtensionEvents(); + + free(xi_all_devices.name); + free(xi_all_master_devices.name); } /*********************************************************************** @@ -1298,9 +1301,9 @@ XInputExtensionInit(void) memset(&xi_all_devices, 0, sizeof(xi_all_devices)); memset(&xi_all_master_devices, 0, sizeof(xi_all_master_devices)); xi_all_devices.id = XIAllDevices; - xi_all_devices.name = "XIAllDevices"; + xi_all_devices.name = strdup("XIAllDevices"); xi_all_master_devices.id = XIAllMasterDevices; - xi_all_master_devices.name = "XIAllMasterDevices"; + xi_all_master_devices.name = strdup("XIAllMasterDevices"); inputInfo.all_devices = &xi_all_devices; inputInfo.all_master_devices = &xi_all_master_devices; diff --git a/xorg-server/Xi/xiproperty.c b/xorg-server/Xi/xiproperty.c index e17efe407..5f46b5435 100644 --- a/xorg-server/Xi/xiproperty.c +++ b/xorg-server/Xi/xiproperty.c @@ -754,7 +754,7 @@ XIChangeDeviceProperty(DeviceIntPtr dev, Atom property, Atom type, break; } if (new_data) - memcpy((char *) new_data, (char *) value, len * size_in_bytes); + memcpy((char *) new_data, value, len * size_in_bytes); if (old_data) memcpy((char *) old_data, (char *) prop_value->data, prop_value->size * size_in_bytes); diff --git a/xorg-server/Xi/xiselectev.c b/xorg-server/Xi/xiselectev.c index 43a67c833..e7e719d16 100644 --- a/xorg-server/Xi/xiselectev.c +++ b/xorg-server/Xi/xiselectev.c @@ -175,17 +175,17 @@ ProcXISelectEvents(ClientPtr client) if (inputMasks) iclient = inputMasks->inputClients; for (; iclient; iclient = iclient->next) { - DeviceIntPtr dummy; + DeviceIntPtr tmp; if (CLIENT_ID(iclient->resource) == client->index) continue; - dixLookupDevice(&dummy, evmask->deviceid, serverClient, + dixLookupDevice(&tmp, evmask->deviceid, serverClient, DixReadAccess); - if (!dummy) + if (!tmp) return BadImplementation; /* this shouldn't happen */ - if (xi2mask_isset(iclient->xi2mask, dummy, XI_TouchBegin)) + if (xi2mask_isset(iclient->xi2mask, tmp, XI_TouchBegin)) return BadAccess; } } diff --git a/xorg-server/dix/devices.c b/xorg-server/dix/devices.c index 21179ee59..7f70ca69a 100644 --- a/xorg-server/dix/devices.c +++ b/xorg-server/dix/devices.c @@ -1340,13 +1340,10 @@ InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes, Atom *labels, /* global list of acceleration schemes */ ValuatorAccelerationRec pointerAccelerationScheme[] = { - {PtrAccelNoOp, NULL, NULL, NULL, NULL} - , + {PtrAccelNoOp, NULL, NULL, NULL, NULL}, {PtrAccelPredictable, acceleratePointerPredictable, NULL, - InitPredictableAccelerationScheme, AccelerationDefaultCleanup} - , - {PtrAccelLightweight, acceleratePointerLightweight, NULL, NULL, NULL} - , + InitPredictableAccelerationScheme, AccelerationDefaultCleanup}, + {PtrAccelLightweight, acceleratePointerLightweight, NULL, NULL, NULL}, {-1, NULL, NULL, NULL, NULL} /* terminator */ }; @@ -1383,8 +1380,7 @@ InitPointerAccelerationScheme(DeviceIntPtr dev, int scheme) if (pointerAccelerationScheme[i].AccelInitProc) { if (!pointerAccelerationScheme[i].AccelInitProc(dev, - &pointerAccelerationScheme - [i])) { + &pointerAccelerationScheme[i])) { return FALSE; } } diff --git a/xorg-server/dix/enterleave.c b/xorg-server/dix/enterleave.c index 725080a4c..761ab3b9f 100644 --- a/xorg-server/dix/enterleave.c +++ b/xorg-server/dix/enterleave.c @@ -30,11 +30,15 @@ #include <X11/X.h> #include <X11/extensions/XI2.h> +#include <X11/extensions/XIproto.h> +#include <X11/extensions/XI2proto.h> #include "inputstr.h" #include "windowstr.h" #include "scrnintstr.h" #include "exglobals.h" #include "enterleave.h" +#include "eventconvert.h" +#include "xkbsrv.h" /** * @file @@ -602,6 +606,241 @@ DoEnterLeaveEvents(DeviceIntPtr pDev, DeviceEnterLeaveEvents(pDev, sourceid, fromWin, toWin, mode); } +static void +FixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v, + int first) +{ + int nval = v->numAxes - first; + + ev->type = DeviceValuator; + ev->deviceid = dev->id; + ev->num_valuators = nval < 3 ? nval : 3; + ev->first_valuator = first; + switch (ev->num_valuators) { + case 3: + ev->valuator2 = v->axisVal[first + 2]; + case 2: + ev->valuator1 = v->axisVal[first + 1]; + case 1: + ev->valuator0 = v->axisVal[first]; + break; + } + first += ev->num_valuators; +} + +static void +FixDeviceStateNotify(DeviceIntPtr dev, deviceStateNotify * ev, KeyClassPtr k, + ButtonClassPtr b, ValuatorClassPtr v, int first) +{ + ev->type = DeviceStateNotify; + ev->deviceid = dev->id; + ev->time = currentTime.milliseconds; + ev->classes_reported = 0; + ev->num_keys = 0; + ev->num_buttons = 0; + ev->num_valuators = 0; + + if (b) { + ev->classes_reported |= (1 << ButtonClass); + ev->num_buttons = b->numButtons; + memcpy((char *) ev->buttons, (char *) b->down, 4); + } + else if (k) { + ev->classes_reported |= (1 << KeyClass); + ev->num_keys = k->xkbInfo->desc->max_key_code - + k->xkbInfo->desc->min_key_code; + memmove((char *) &ev->keys[0], (char *) k->down, 4); + } + if (v) { + int nval = v->numAxes - first; + + ev->classes_reported |= (1 << ValuatorClass); + ev->classes_reported |= valuator_get_mode(dev, 0) << ModeBitsShift; + ev->num_valuators = nval < 3 ? nval : 3; + switch (ev->num_valuators) { + case 3: + ev->valuator2 = v->axisVal[first + 2]; + case 2: + ev->valuator1 = v->axisVal[first + 1]; + case 1: + ev->valuator0 = v->axisVal[first]; + break; + } + } +} + + +static void +DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win) +{ + int evcount = 1; + deviceStateNotify *ev, *sev; + deviceKeyStateNotify *kev; + deviceButtonStateNotify *bev; + + KeyClassPtr k; + ButtonClassPtr b; + ValuatorClassPtr v; + int nval = 0, nkeys = 0, nbuttons = 0, first = 0; + + if (!(wOtherInputMasks(win)) || + !(wOtherInputMasks(win)->inputEvents[dev->id] & DeviceStateNotifyMask)) + return; + + if ((b = dev->button) != NULL) { + nbuttons = b->numButtons; + if (nbuttons > 32) + evcount++; + } + if ((k = dev->key) != NULL) { + nkeys = k->xkbInfo->desc->max_key_code - k->xkbInfo->desc->min_key_code; + if (nkeys > 32) + evcount++; + if (nbuttons > 0) { + evcount++; + } + } + if ((v = dev->valuator) != NULL) { + nval = v->numAxes; + + if (nval > 3) + evcount++; + if (nval > 6) { + if (!(k && b)) + evcount++; + if (nval > 9) + evcount += ((nval - 7) / 3); + } + } + + sev = ev = (deviceStateNotify *) malloc(evcount * sizeof(xEvent)); + FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first); + + if (b != NULL) { + FixDeviceStateNotify(dev, ev++, NULL, b, v, first); + first += 3; + nval -= 3; + if (nbuttons > 32) { + (ev - 1)->deviceid |= MORE_EVENTS; + bev = (deviceButtonStateNotify *) ev++; + bev->type = DeviceButtonStateNotify; + bev->deviceid = dev->id; + memcpy((char *) &bev->buttons[4], (char *) &b->down[4], + DOWN_LENGTH - 4); + } + if (nval > 0) { + (ev - 1)->deviceid |= MORE_EVENTS; + FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); + first += 3; + nval -= 3; + } + } + + if (k != NULL) { + FixDeviceStateNotify(dev, ev++, k, NULL, v, first); + first += 3; + nval -= 3; + if (nkeys > 32) { + (ev - 1)->deviceid |= MORE_EVENTS; + kev = (deviceKeyStateNotify *) ev++; + kev->type = DeviceKeyStateNotify; + kev->deviceid = dev->id; + memmove((char *) &kev->keys[0], (char *) &k->down[4], 28); + } + if (nval > 0) { + (ev - 1)->deviceid |= MORE_EVENTS; + FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); + first += 3; + nval -= 3; + } + } + + while (nval > 0) { + FixDeviceStateNotify(dev, ev++, NULL, NULL, v, first); + first += 3; + nval -= 3; + if (nval > 0) { + (ev - 1)->deviceid |= MORE_EVENTS; + FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); + first += 3; + nval -= 3; + } + } + + DeliverEventsToWindow(dev, win, (xEvent *) sev, evcount, + DeviceStateNotifyMask, NullGrab); + free(sev); +} + +void +DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail, + WindowPtr pWin) +{ + deviceFocus event; + xXIFocusInEvent *xi2event; + DeviceIntPtr mouse; + int btlen, len, i; + + mouse = IsFloating(dev) ? dev : GetMaster(dev, MASTER_POINTER); + + /* XI 2 event */ + btlen = (mouse->button) ? bits_to_bytes(mouse->button->numButtons) : 0; + btlen = bytes_to_int32(btlen); + len = sizeof(xXIFocusInEvent) + btlen * 4; + + xi2event = calloc(1, len); + xi2event->type = GenericEvent; + xi2event->extension = IReqCode; + xi2event->evtype = type; + xi2event->length = bytes_to_int32(len - sizeof(xEvent)); + xi2event->buttons_len = btlen; + xi2event->detail = detail; + xi2event->time = currentTime.milliseconds; + xi2event->deviceid = dev->id; + xi2event->sourceid = dev->id; /* a device doesn't change focus by itself */ + xi2event->mode = mode; + xi2event->root_x = FP1616(mouse->spriteInfo->sprite->hot.x, 0); + xi2event->root_y = FP1616(mouse->spriteInfo->sprite->hot.y, 0); + + for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++) + if (BitIsOn(mouse->button->down, i)) + SetBit(&xi2event[1], mouse->button->map[i]); + + if (dev->key) { + xi2event->mods.base_mods = dev->key->xkbInfo->state.base_mods; + xi2event->mods.latched_mods = dev->key->xkbInfo->state.latched_mods; + xi2event->mods.locked_mods = dev->key->xkbInfo->state.locked_mods; + xi2event->mods.effective_mods = dev->key->xkbInfo->state.mods; + + xi2event->group.base_group = dev->key->xkbInfo->state.base_group; + xi2event->group.latched_group = dev->key->xkbInfo->state.latched_group; + xi2event->group.locked_group = dev->key->xkbInfo->state.locked_group; + xi2event->group.effective_group = dev->key->xkbInfo->state.group; + } + + FixUpEventFromWindow(dev->spriteInfo->sprite, (xEvent *) xi2event, pWin, + None, FALSE); + + DeliverEventsToWindow(dev, pWin, (xEvent *) xi2event, 1, + GetEventFilter(dev, (xEvent *) xi2event), NullGrab); + + free(xi2event); + + /* XI 1.x event */ + event.deviceid = dev->id; + event.mode = mode; + event.type = (type == XI_FocusIn) ? DeviceFocusIn : DeviceFocusOut; + event.detail = detail; + event.window = pWin->drawable.id; + event.time = currentTime.milliseconds; + + DeliverEventsToWindow(dev, pWin, (xEvent *) &event, 1, + DeviceFocusChangeMask, NullGrab); + + if (event.type == DeviceFocusIn) + DeliverStateNotifyEvent(dev, pWin); +} + /** * Send focus out events to all windows between 'child' and 'ancestor'. * Events are sent running up the hierarchy. diff --git a/xorg-server/dix/enterleave.h b/xorg-server/dix/enterleave.h index c937c0e7f..a59d05799 100644 --- a/xorg-server/dix/enterleave.h +++ b/xorg-server/dix/enterleave.h @@ -52,6 +52,11 @@ extern void DeviceEnterLeaveEvent(DeviceIntPtr mouse, int type, int mode, int detail, WindowPtr pWin, Window child); +extern void DeviceFocusEvent(DeviceIntPtr dev, + int type, + int mode, + int detail , + WindowPtr pWin); extern void EnterWindow(DeviceIntPtr dev, WindowPtr win, int mode); diff --git a/xorg-server/dix/getevents.c b/xorg-server/dix/getevents.c index e0ef18365..be369ec72 100644 --- a/xorg-server/dix/getevents.c +++ b/xorg-server/dix/getevents.c @@ -1187,16 +1187,33 @@ static void transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask) { double x, y, ox, oy; + int has_x, has_y; + + has_x = valuator_mask_fetch_double(mask, 0, &ox); + has_y = valuator_mask_fetch_double(mask, 1, &oy); + + if (!has_x && !has_y) + return; + + if (!has_x || !has_y) { + struct pixman_f_transform invert; + + /* undo transformation from last event */ + ox = dev->last.valuators[0]; + oy = dev->last.valuators[1]; + + pixman_f_transform_invert(&invert, &dev->transform); + transform(&invert, &ox, &oy); + + x = ox; + y = oy; + } if (valuator_mask_isset(mask, 0)) ox = x = valuator_mask_get_double(mask, 0); - else - ox = x = dev->last.valuators[0]; if (valuator_mask_isset(mask, 1)) oy = y = valuator_mask_get_double(mask, 1); - else - oy = y = dev->last.valuators[1]; transform(&dev->transform, &x, &y); diff --git a/xorg-server/dix/ptrveloc.c b/xorg-server/dix/ptrveloc.c index 8c266af8c..270a56fcb 100644 --- a/xorg-server/dix/ptrveloc.c +++ b/xorg-server/dix/ptrveloc.c @@ -797,7 +797,8 @@ ComputeAcceleration(DeviceIntPtr dev, result += 4.0f * BasicComputeAcceleration(dev, vel, (vel->last_velocity + - vel->velocity) / 2, threshold, + vel->velocity) / 2, + threshold, acc); result /= 6.0f; DebugAccelF("(dix ptracc) profile average [%.2f ... %.2f] is %.3f\n", diff --git a/xorg-server/hw/xquartz/X11Application.m b/xorg-server/hw/xquartz/X11Application.m index 0c3283ed0..1f9b05dd1 100644 --- a/xorg-server/hw/xquartz/X11Application.m +++ b/xorg-server/hw/xquartz/X11Application.m @@ -1329,6 +1329,11 @@ untrusted_str(NSEvent *e) } #endif +extern void +darwinEvents_lock(void); +extern void +darwinEvents_unlock(void); + - (void) sendX11NSEvent:(NSEvent *)e { NSPoint location = NSZeroPoint; @@ -1341,18 +1346,15 @@ untrusted_str(NSEvent *e) int modifierFlags; BOOL isMouseOrTabletEvent, isTabletEvent; -#ifdef HAVE_LIBDISPATCH - static dispatch_once_t once_pred; - dispatch_once(&once_pred, ^{ - tilt = NSZeroPoint; - darwinTabletCurrent = darwinTabletStylus; - }); -#else if (!darwinTabletCurrent) { + /* Ensure that the event system is initialized */ + darwinEvents_lock(); + darwinEvents_unlock(); + assert(darwinTabletStylus); + tilt = NSZeroPoint; darwinTabletCurrent = darwinTabletStylus; } -#endif isMouseOrTabletEvent = [e type] == NSLeftMouseDown || [e type] == NSOtherMouseDown || @@ -1641,6 +1643,11 @@ handle_mouse: case NSScrollWheel: { +#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050 + float deltaX = [e deltaX]; + float deltaY = [e deltaY]; + BOOL isContinuous = NO; +#else CGFloat deltaX = [e deltaX]; CGFloat deltaY = [e deltaY]; CGEventRef cge = [e CGEvent]; @@ -1662,6 +1669,7 @@ handle_mouse: deltaY *= lineHeight / 5.0; } #endif +#endif #if !defined(XPLUGIN_VERSION) || XPLUGIN_VERSION == 0 /* If we're in the background, we need to send a MotionNotify event diff --git a/xorg-server/hw/xquartz/console_redirect.c b/xorg-server/hw/xquartz/console_redirect.c index 1e0e56bad..91d693b67 100644 --- a/xorg-server/hw/xquartz/console_redirect.c +++ b/xorg-server/hw/xquartz/console_redirect.c @@ -310,6 +310,20 @@ xq_asl_init(void) atexit(redirect_atexit); } +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1050 +#define fls(v) xq_fls(v) + +static inline int fls(int value) { + unsigned int b, v; + + v = *((unsigned int *)&value); + + for(b=0 ; v ; v >>= 1 , b++); + + return b; +} +#endif + int xq_asl_log_fd(aslclient asl, aslmsg msg, int level, int fd) { diff --git a/xorg-server/hw/xquartz/quartz.c b/xorg-server/hw/xquartz/quartz.c index ebaa56785..62a2852b7 100644 --- a/xorg-server/hw/xquartz/quartz.c +++ b/xorg-server/hw/xquartz/quartz.c @@ -69,6 +69,12 @@ #include <rootlessCommon.h> #include <Xplugin.h> +/* Work around a bug on Leopard's headers */ +#if defined (__LP64__) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 && MAC_OS_X_VERSION_MAX_ALLOWED < 1060 +extern OSErr UpdateSystemActivity(UInt8 activity); +#define OverallAct 0 +#endif + DevPrivateKeyRec quartzScreenKeyRec; int aquaMenuBarHeight = 0; QuartzModeProcsPtr quartzProcs = NULL; diff --git a/xorg-server/include/exevents.h b/xorg-server/include/exevents.h index feea170d2..321fc422d 100644 --- a/xorg-server/include/exevents.h +++ b/xorg-server/include/exevents.h @@ -162,13 +162,6 @@ extern void ProcessOtherEvent(InternalEvent * /* ev */ , DeviceIntPtr /* other */ ); -extern void - DeviceFocusEvent(DeviceIntPtr /* dev */ , - int /* type */ , - int /* mode */ , - int /* detail */ , - WindowPtr /* pWin */ ); - extern int CheckGrabValues(ClientPtr /* client */ , GrabParameters * /* param */ ); diff --git a/xorg-server/include/globals.h b/xorg-server/include/globals.h index e9c5fcbde..0294917a9 100644 --- a/xorg-server/include/globals.h +++ b/xorg-server/include/globals.h @@ -102,6 +102,10 @@ extern _X_EXPORT Bool noXFixesExtension; extern _X_EXPORT Bool noPanoramiXExtension; #endif +#ifdef INXQUARTZ +extern _X_EXPORT Bool noPseudoramiXExtension; +#endif + #ifdef XSELINUX extern _X_EXPORT Bool noSELinuxExtension; diff --git a/xorg-server/include/ptrveloc.h b/xorg-server/include/ptrveloc.h index 8778646f5..3bd982a90 100644 --- a/xorg-server/include/ptrveloc.h +++ b/xorg-server/include/ptrveloc.h @@ -101,48 +101,43 @@ typedef struct _PredictableAccelSchemeRec { } PredictableAccelSchemeRec, *PredictableAccelSchemePtr; extern _X_EXPORT void - InitVelocityData(DeviceVelocityPtr vel); +InitVelocityData(DeviceVelocityPtr vel); extern _X_EXPORT void - InitTrackers(DeviceVelocityPtr vel, int ntracker); +InitTrackers(DeviceVelocityPtr vel, int ntracker); extern _X_EXPORT BOOL ProcessVelocityData2D(DeviceVelocityPtr vel, double dx, double dy, int time); extern _X_EXPORT double - BasicComputeAcceleration(DeviceIntPtr dev, DeviceVelocityPtr vel, double velocity, double threshold, double acc); extern _X_EXPORT void - FreeVelocityData(DeviceVelocityPtr vel); +FreeVelocityData(DeviceVelocityPtr vel); extern _X_EXPORT int - SetAccelerationProfile(DeviceVelocityPtr vel, int profile_num); +SetAccelerationProfile(DeviceVelocityPtr vel, int profile_num); extern _X_EXPORT DeviceVelocityPtr GetDevicePredictableAccelData(DeviceIntPtr dev); extern _X_EXPORT void - SetDeviceSpecificAccelerationProfile(DeviceVelocityPtr vel, PointerAccelerationProfileFunc profile); extern _X_INTERNAL void - AccelerationDefaultCleanup(DeviceIntPtr dev); +AccelerationDefaultCleanup(DeviceIntPtr dev); extern _X_INTERNAL Bool - InitPredictableAccelerationScheme(DeviceIntPtr dev, struct _ValuatorAccelerationRec *protoScheme); extern _X_INTERNAL void - acceleratePointerPredictable(DeviceIntPtr dev, ValuatorMask *val, CARD32 evtime); extern _X_INTERNAL void - acceleratePointerLightweight(DeviceIntPtr dev, ValuatorMask *val, CARD32 evtime); diff --git a/xorg-server/include/xkbsrv.h b/xorg-server/include/xkbsrv.h index 3b72885bd..a19c8fb29 100644 --- a/xorg-server/include/xkbsrv.h +++ b/xorg-server/include/xkbsrv.h @@ -305,9 +305,6 @@ extern _X_EXPORT CARD32 xkbDebugFlags; #define _XkbErrCode3(a,b,c) _XkbErrCode2(a,(((unsigned int)(b))<<16)|(c)) #define _XkbErrCode4(a,b,c,d) _XkbErrCode3(a,b,((((unsigned int)(c))<<8)|(d))) -extern _X_EXPORT int DeviceKeyPress, DeviceKeyRelease, DeviceMotionNotify; -extern _X_EXPORT int DeviceButtonPress, DeviceButtonRelease; - #define Status int extern _X_EXPORT void XkbUseMsg(void diff --git a/xorg-server/test/xi2/protocol-common.h b/xorg-server/test/xi2/protocol-common.h index 04a1e8990..f27f248c6 100644 --- a/xorg-server/test/xi2/protocol-common.h +++ b/xorg-server/test/xi2/protocol-common.h @@ -33,8 +33,6 @@ #ifndef PROTOCOL_COMMON_H #define PROTOCOL_COMMON_H -extern int BadDevice; - /* Check default values in a reply */ #define reply_check_defaults(rep, len, type) \ { \ @@ -83,7 +81,7 @@ struct devices { int num_devices; int num_master_devices; -} devices; +}; /** * The set of default devices available in all tests if necessary. diff --git a/xorg-server/test/xi2/protocol-xipassivegrabdevice.c b/xorg-server/test/xi2/protocol-xipassivegrabdevice.c index 53c65bda6..84b386bf3 100644 --- a/xorg-server/test/xi2/protocol-xipassivegrabdevice.c +++ b/xorg-server/test/xi2/protocol-xipassivegrabdevice.c @@ -37,6 +37,7 @@ #include "scrnintstr.h" #include "xipassivegrab.h" #include "exevents.h" +#include "exglobals.h" #include "protocol-common.h" @@ -54,7 +55,7 @@ int __wrap_GrabButton(ClientPtr client, DeviceIntPtr dev, GrabParameters *param, enum InputLevel grabtype, GrabMask *mask); static void reply_XIPassiveGrabDevice_data(ClientPtr client, int len, - char *data, void *userdata); + char *data, void *closure); int __wrap_dixLookupWindow(WindowPtr *win, XID id, ClientPtr client, Mask access) @@ -85,7 +86,7 @@ __wrap_GrabButton(ClientPtr client, DeviceIntPtr dev, } static void -reply_XIPassiveGrabDevice(ClientPtr client, int len, char *data, void *userdata) +reply_XIPassiveGrabDevice(ClientPtr client, int len, char *data, void *closure) { xXIPassiveGrabDeviceReply *rep = (xXIPassiveGrabDeviceReply *) data; @@ -107,7 +108,7 @@ reply_XIPassiveGrabDevice(ClientPtr client, int len, char *data, void *userdata) static void reply_XIPassiveGrabDevice_data(ClientPtr client, int len, char *data, - void *userdata) + void *closure) { int i; diff --git a/xorg-server/test/xi2/protocol-xiquerydevice.c b/xorg-server/test/xi2/protocol-xiquerydevice.c index 5e59e8084..9d13bbb6f 100644 --- a/xorg-server/test/xi2/protocol-xiquerydevice.c +++ b/xorg-server/test/xi2/protocol-xiquerydevice.c @@ -32,6 +32,7 @@ #include <X11/Xatom.h> #include "inputstr.h" #include "extinit.h" +#include "exglobals.h" #include "scrnintstr.h" #include "xkbsrv.h" @@ -54,9 +55,9 @@ struct test_data { }; static void reply_XIQueryDevice_data(ClientPtr client, int len, char *data, - void *userdata); + void *closure); static void reply_XIQueryDevice(ClientPtr client, int len, char *data, - void *userdata); + void *closure); /* reply handling for the first bytes that constitute the reply */ static void @@ -86,10 +87,10 @@ reply_XIQueryDevice(ClientPtr client, int len, char *data, void *userdata) /* reply handling for the trailing bytes that constitute the device info */ static void -reply_XIQueryDevice_data(ClientPtr client, int len, char *data, void *userdata) +reply_XIQueryDevice_data(ClientPtr client, int len, char *data, void *closure) { int i, j; - struct test_data *querydata = (struct test_data *) userdata; + struct test_data *querydata = (struct test_data *) closure; DeviceIntPtr dev; xXIDeviceInfo *info = (xXIDeviceInfo *) data; @@ -222,7 +223,7 @@ reply_XIQueryDevice_data(ClientPtr client, int len, char *data, void *userdata) any->type == XIValuatorClass); if (any->type == XIButtonClass) { - int len; + int l; xXIButtonInfo *bi = (xXIButtonInfo *) any; if (client->swapped) @@ -230,10 +231,9 @@ reply_XIQueryDevice_data(ClientPtr client, int len, char *data, void *userdata) assert(bi->num_buttons == devices.vcp->button->numButtons); - len = - 2 + bi->num_buttons + + l = 2 + bi->num_buttons + bytes_to_int32(bits_to_bytes(bi->num_buttons)); - assert(bi->length == len); + assert(bi->length == l); } else if (any->type == XIValuatorClass) { xXIValuatorInfo *vi = (xXIValuatorInfo *) any; diff --git a/xorg-server/test/xi2/protocol-xiquerypointer.c b/xorg-server/test/xi2/protocol-xiquerypointer.c index 4756a6b2e..fc66b6429 100644 --- a/xorg-server/test/xi2/protocol-xiquerypointer.c +++ b/xorg-server/test/xi2/protocol-xiquerypointer.c @@ -37,12 +37,13 @@ #include "scrnintstr.h" #include "xiquerypointer.h" #include "exevents.h" +#include "exglobals.h" #include "protocol-common.h" static ClientRec client_request; static void reply_XIQueryPointer_data(ClientPtr client, int len, - char *data, void *userdata); + char *data, void *closure); static struct { DeviceIntPtr dev; @@ -70,7 +71,7 @@ __wrap_dixLookupWindow(WindowPtr *win, XID id, ClientPtr client, Mask access) } static void -reply_XIQueryPointer(ClientPtr client, int len, char *data, void *userdata) +reply_XIQueryPointer(ClientPtr client, int len, char *data, void *closure) { xXIQueryPointerReply *rep = (xXIQueryPointerReply *) data; SpritePtr sprite; @@ -121,7 +122,7 @@ reply_XIQueryPointer(ClientPtr client, int len, char *data, void *userdata) } static void -reply_XIQueryPointer_data(ClientPtr client, int len, char *data, void *userdata) +reply_XIQueryPointer_data(ClientPtr client, int len, char *data, void *closure) { reply_handler = reply_XIQueryPointer; } diff --git a/xorg-server/test/xi2/protocol-xiqueryversion.c b/xorg-server/test/xi2/protocol-xiqueryversion.c index 1347e866c..aff023754 100644 --- a/xorg-server/test/xi2/protocol-xiqueryversion.c +++ b/xorg-server/test/xi2/protocol-xiqueryversion.c @@ -59,10 +59,10 @@ struct test_data { }; static void -reply_XIQueryVersion(ClientPtr client, int len, char *data, void *userdata) +reply_XIQueryVersion(ClientPtr client, int len, char *data, void *closure) { xXIQueryVersionReply *rep = (xXIQueryVersionReply *) data; - struct test_data *versions = (struct test_data *) userdata; + struct test_data *versions = (struct test_data *) closure; unsigned int sver, cver, ver; if (client->swapped) { @@ -85,10 +85,10 @@ reply_XIQueryVersion(ClientPtr client, int len, char *data, void *userdata) } static void -reply_XIQueryVersion_multiple(ClientPtr client, int len, char *data, void *userdata) +reply_XIQueryVersion_multiple(ClientPtr client, int len, char *data, void *closure) { xXIQueryVersionReply *rep = (xXIQueryVersionReply *) data; - struct test_data *versions = (struct test_data *) userdata; + struct test_data *versions = (struct test_data *) closure; reply_check_defaults(rep, len, XIQueryVersion); assert(rep->length == 0); diff --git a/xorg-server/test/xi2/protocol-xiselectevents.c b/xorg-server/test/xi2/protocol-xiselectevents.c index 4daba8775..8f6b947d4 100644 --- a/xorg-server/test/xi2/protocol-xiselectevents.c +++ b/xorg-server/test/xi2/protocol-xiselectevents.c @@ -55,6 +55,7 @@ #include "windowstr.h" #include "extinit.h" /* for XInputExtensionInit */ #include "scrnintstr.h" +#include "exglobals.h" #include "xiselectev.h" #include "protocol-common.h" diff --git a/xorg-server/test/xi2/protocol-xisetclientpointer.c b/xorg-server/test/xi2/protocol-xisetclientpointer.c index 51db4ac69..90f1b94c3 100644 --- a/xorg-server/test/xi2/protocol-xisetclientpointer.c +++ b/xorg-server/test/xi2/protocol-xisetclientpointer.c @@ -44,6 +44,7 @@ #include "scrnintstr.h" #include "xisetclientpointer.h" #include "exevents.h" +#include "exglobals.h" #include "protocol-common.h" diff --git a/xorg-server/test/xi2/protocol-xiwarppointer.c b/xorg-server/test/xi2/protocol-xiwarppointer.c index c279ac413..4bea333c3 100644 --- a/xorg-server/test/xi2/protocol-xiwarppointer.c +++ b/xorg-server/test/xi2/protocol-xiwarppointer.c @@ -37,6 +37,7 @@ #include "scrnintstr.h" #include "xiwarppointer.h" #include "exevents.h" +#include "exglobals.h" #include "protocol-common.h" diff --git a/xorg-server/xkeyboard-config/symbols/fr b/xorg-server/xkeyboard-config/symbols/fr index 85bcd5564..45ef6a475 100644 --- a/xorg-server/xkeyboard-config/symbols/fr +++ b/xorg-server/xkeyboard-config/symbols/fr @@ -48,13 +48,17 @@ xkb_symbols "olpc" { name[Group1]="French"; - key <AD02> { [ z, Z, VoidSymbol, guillemotleft ] }; - - key <AC02> { [ s, S, VoidSymbol, ssharp ] }; - - key <AB02> { [ x, X, VoidSymbol, guillemotright ] }; - - key <I219> { [ less, greater ] }; + key <I219> { [ less, greater ] }; + key <AD11> { [ dead_circumflex, dead_diaeresis, notsign, dead_abovering ] }; + key <AB08> { [ semicolon, period, underscore, multiply ] }; + key <TLDE> { [ twosuperior, asciitilde, VoidSymbol, VoidSymbol ] }; + + // Some keys only have the Shift+AltGr character printed on them (alongside + // the unmodified one). Make such keys shift-invariant so that the printed + // value is achieved by pressing AltGr or Shift+AltGr. + key <AB02> { [ x, X, guillemotright, guillemotright ] }; + key <AC02> { [ s, S, ssharp, ssharp ] }; + key <AD02> { [ z, Z, guillemotleft, guillemotleft ] }; }; partial alphanumeric_keys |