aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fontconfig/fontconfig/fontconfig.h1
-rw-r--r--fontconfig/src/fcfreetype.c49
-rw-r--r--fontconfig/src/fcint.h6
-rw-r--r--fontconfig/src/fcmatch.c21
-rw-r--r--fontconfig/src/fcobjs.h1
-rw-r--r--fontconfig/src/fcpat.c2
-rw-r--r--fontconfig/src/fcstr.c85
-rw-r--r--mesalib/Android.common.mk2
-rw-r--r--mesalib/configure.ac3
-rw-r--r--mesalib/docs/GL3.txt2
-rw-r--r--mesalib/docs/index.html6
-rw-r--r--mesalib/docs/relnotes-9.1.1.html235
-rw-r--r--mesalib/include/GL/internal/dri_interface.h15
-rw-r--r--mesalib/scons/gallium.py2
-rw-r--r--mesalib/src/gallium/auxiliary/Makefile.sources1
-rw-r--r--mesalib/src/glsl/glsl_types.cpp12
-rw-r--r--mesalib/src/glsl/glsl_types.h1
-rw-r--r--mesalib/src/glsl/main.cpp2
-rw-r--r--mesalib/src/mesa/drivers/common/meta.c15
-rw-r--r--mesalib/src/mesa/drivers/dri/common/xmlpool/t_options.h5
-rw-r--r--mesalib/src/mesa/main/compiler.h3
-rw-r--r--mesalib/src/mesa/main/dd.h4
-rw-r--r--mesalib/src/mesa/main/fbobject.c39
-rw-r--r--mesalib/src/mesa/main/fbobject.h3
-rw-r--r--mesalib/src/mesa/main/ff_fragment_shader.cpp16
-rw-r--r--mesalib/src/mesa/main/formatquery.c12
-rw-r--r--mesalib/src/mesa/main/framebuffer.c4
-rw-r--r--mesalib/src/mesa/main/framebuffer.h2
-rw-r--r--mesalib/src/mesa/main/mtypes.h2
-rw-r--r--mesalib/src/mesa/main/multisample.c77
-rw-r--r--mesalib/src/mesa/main/multisample.h5
-rw-r--r--mesalib/src/mesa/main/readpix.c284
-rw-r--r--mesalib/src/mesa/main/readpix.h4
-rw-r--r--mesalib/src/mesa/main/texgetimage.c1
-rw-r--r--mesalib/src/mesa/main/teximage.c34
-rw-r--r--mesalib/src/mesa/main/texparam.c12
-rw-r--r--mesalib/src/mesa/main/texstorage.c1
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_blit.c21
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_fbo.c24
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_fbo.h5
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_readpixels.c188
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_texture.c20
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_texture.h6
-rw-r--r--mesalib/src/mesa/state_tracker/st_context.c5
-rw-r--r--mesalib/src/mesa/state_tracker/st_context.h3
-rw-r--r--mesalib/src/mesa/state_tracker/st_format.c6
-rw-r--r--mesalib/src/mesa/state_tracker/st_format.h4
-rw-r--r--mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp142
-rw-r--r--mesalib/src/mesa/state_tracker/st_program.c45
-rw-r--r--pixman/.gitignore2
-rw-r--r--pixman/demos/Makefile.am2
-rw-r--r--pixman/demos/linear-gradient.c50
-rw-r--r--pixman/pixman/pixman-combine-float.c34
-rw-r--r--pixman/pixman/pixman-gradient-walker.c106
-rw-r--r--pixman/pixman/pixman-private.h13
-rw-r--r--pixman/test/Makefile.sources3
-rw-r--r--pixman/test/radial-perf-test.c58
-rw-r--r--xorg-server/Xext/panoramiX.c14
-rw-r--r--xorg-server/Xext/sync.c13
-rw-r--r--xorg-server/Xext/xvdisp.c8
-rw-r--r--xorg-server/Xi/exevents.c33
-rw-r--r--xorg-server/composite/compext.c7
-rw-r--r--xorg-server/configure.ac17
-rw-r--r--xorg-server/dix/events.c3
-rw-r--r--xorg-server/dix/main.c2
-rw-r--r--xorg-server/dix/touch.c3
-rw-r--r--xorg-server/dix/window.c4
-rw-r--r--xorg-server/fb/fbpict.c8
-rw-r--r--xorg-server/glx/extension_string.c2
-rw-r--r--xorg-server/glx/extension_string.h5
-rw-r--r--xorg-server/glx/glxcmds.c26
-rw-r--r--xorg-server/glx/glxdri.c2
-rw-r--r--xorg-server/glx/glxdri2.c11
-rw-r--r--xorg-server/glx/glxdricommon.c4
-rw-r--r--xorg-server/glx/glxscreens.h3
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyr.c7
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyrinit.c6
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyrvideo.c24
-rw-r--r--xorg-server/hw/kdrive/ephyr/hostx.c43
-rw-r--r--xorg-server/hw/kdrive/ephyr/hostx.h3
-rw-r--r--xorg-server/hw/kdrive/fbdev/fbdev.c10
-rw-r--r--xorg-server/hw/kdrive/linux/mouse.c6
-rw-r--r--xorg-server/hw/kdrive/src/kinput.c8
-rw-r--r--xorg-server/hw/kdrive/src/kxv.c2
-rw-r--r--xorg-server/hw/xfree86/common/xf86Events.c1
-rw-r--r--xorg-server/hw/xfree86/common/xf86Mode.c17
-rw-r--r--xorg-server/hw/xfree86/common/xf86Option.c2
-rw-r--r--xorg-server/hw/xfree86/common/xf86fbman.c12
-rw-r--r--xorg-server/hw/xfree86/common/xf86xvmc.c4
-rw-r--r--xorg-server/hw/xfree86/ddc/ddc.c7
-rw-r--r--xorg-server/hw/xfree86/ramdac/xf86Cursor.c1
-rw-r--r--xorg-server/hw/xquartz/GL/visualConfigs.c3
-rw-r--r--xorg-server/hw/xwin/glx/indirect.c2
-rw-r--r--xorg-server/include/dix-config.h.in3
-rw-r--r--xorg-server/include/input.h5
-rw-r--r--xorg-server/include/list.h2
-rw-r--r--xorg-server/os/Makefile.am5
-rw-r--r--xorg-server/os/backtrace.c75
-rw-r--r--xorg-server/os/log.c4
-rw-r--r--xorg-server/randr/rrcrtc.c9
-rw-r--r--xorg-server/xfixes/cursor.c10
-rw-r--r--xorg-server/xfixes/xfixesint.h2
-rw-r--r--xorg-server/xkb/xkb.c3
-rw-r--r--xorg-server/xkb/xkbActions.c149
104 files changed, 1702 insertions, 594 deletions
diff --git a/fontconfig/fontconfig/fontconfig.h b/fontconfig/fontconfig/fontconfig.h
index fc0ed1ab0..194996587 100644
--- a/fontconfig/fontconfig/fontconfig.h
+++ b/fontconfig/fontconfig/fontconfig.h
@@ -116,6 +116,7 @@ typedef int FcBool;
#define FC_NAMELANG "namelang" /* String RFC 3866 langs */
#define FC_PRGNAME "prgname" /* String */
#define FC_HASH "hash" /* String */
+#define FC_POSTSCRIPT_NAME "postscriptname" /* String */
#define FC_CACHE_SUFFIX ".cache-" FC_CACHE_VERSION
#define FC_DIR_CACHE_FILE "fonts.cache-" FC_CACHE_VERSION
diff --git a/fontconfig/src/fcfreetype.c b/fontconfig/src/fcfreetype.c
index 9bd789ca3..8a037c059 100644
--- a/fontconfig/src/fcfreetype.c
+++ b/fontconfig/src/fcfreetype.c
@@ -1101,6 +1101,8 @@ FcFreeTypeQueryFace (const FT_Face face,
FcChar8 *style = 0;
int st;
+ char psname[256];
+ const char *tmp;
FcChar8 *hashstr;
@@ -1201,7 +1203,6 @@ FcFreeTypeQueryFace (const FT_Face face,
case TT_NAME_ID_PREFERRED_FAMILY:
case TT_NAME_ID_FONT_FAMILY:
#if 0
- case TT_NAME_ID_PS_NAME:
case TT_NAME_ID_UNIQUE_ID:
#endif
if (FcDebug () & FC_DBG_SCANV)
@@ -1347,6 +1348,52 @@ FcFreeTypeQueryFace (const FT_Face face,
++nfamily;
}
+ /* Add the PostScript name into the cache */
+ tmp = FT_Get_Postscript_Name (face);
+ if (!tmp)
+ {
+ FcChar8 *family, *familylang = NULL;
+ size_t len;
+ int n = 0;
+
+ /* Workaround when FT_Get_Postscript_Name didn't give any name.
+ * try to find out the English family name and convert.
+ */
+ while (FcPatternObjectGetString (pat, FC_FAMILYLANG_OBJECT, n, &familylang) == FcResultMatch)
+ {
+ if (FcStrCmp (familylang, (const FcChar8 *)"en") == 0)
+ break;
+ n++;
+ familylang = NULL;
+ }
+ if (!familylang)
+ n = 0;
+
+ if (FcPatternObjectGetString (pat, FC_FAMILY_OBJECT, n, &family) != FcResultMatch)
+ goto bail1;
+ len = strlen ((const char *)family);
+ /* the literal name in PostScript Language is limited to 127 characters though,
+ * It is the architectural limit. so assuming 255 characters may works enough.
+ */
+ for (i = 0; i < len && i < 255; i++)
+ {
+ /* those characters are not allowed to be the literal name in PostScript */
+ static const char exclusive_chars[] = "\x04()/<>[]{}\t\f\r\n ";
+
+ if (strchr(exclusive_chars, family[i]) != NULL)
+ psname[i] = '-';
+ else
+ psname[i] = family[i];
+ }
+ psname[i] = 0;
+ }
+ else
+ {
+ strcpy (psname, tmp);
+ }
+ if (!FcPatternAddString (pat, FC_POSTSCRIPT_NAME, (const FcChar8 *)psname))
+ goto bail1;
+
if (!FcPatternAddString (pat, FC_FILE, file))
goto bail1;
diff --git a/fontconfig/src/fcint.h b/fontconfig/src/fcint.h
index d5a7217cc..c45075ecc 100644
--- a/fontconfig/src/fcint.h
+++ b/fontconfig/src/fcint.h
@@ -1063,6 +1063,9 @@ FcStrBufData (FcStrBuf *buf, const FcChar8 *s, int len);
FcPrivate int
FcStrCmpIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2);
+FcPrivate int
+FcStrCmpIgnoreCaseAndDelims (const FcChar8 *s1, const FcChar8 *s2, const FcChar8 *delims);
+
FcPrivate FcBool
FcStrRegexCmp (const FcChar8 *s, const FcChar8 *regex);
@@ -1078,6 +1081,9 @@ FcStrContainsIgnoreCase (const FcChar8 *s1, const FcChar8 *s2);
FcPrivate const FcChar8 *
FcStrContainsWord (const FcChar8 *s1, const FcChar8 *s2);
+FcPrivate int
+FcStrMatchIgnoreCaseAndDelims (const FcChar8 *s1, const FcChar8 *s2, const FcChar8 *delims);
+
FcPrivate FcBool
FcStrUsesHome (const FcChar8 *s);
diff --git a/fontconfig/src/fcmatch.c b/fontconfig/src/fcmatch.c
index 7993b81de..68f39aef5 100644
--- a/fontconfig/src/fcmatch.c
+++ b/fontconfig/src/fcmatch.c
@@ -77,6 +77,24 @@ FcCompareFamily (FcValue *v1, FcValue *v2)
}
static double
+FcComparePostScript (FcValue *v1, FcValue *v2)
+{
+ const FcChar8 *v1_string = FcValueString (v1);
+ const FcChar8 *v2_string = FcValueString (v2);
+ int n;
+ size_t len;
+
+ if (FcToLower (*v1_string) != FcToLower (*v2_string) &&
+ *v1_string != ' ' && *v2_string != ' ')
+ return 1.0;
+
+ n = FcStrMatchIgnoreCaseAndDelims (v1_string, v2_string, (const FcChar8 *)" -");
+ len = strlen ((const char *)v1_string);
+
+ return (double)(len - n) / (double)len;
+}
+
+static double
FcCompareLang (FcValue *v1, FcValue *v2)
{
FcLangResult result;
@@ -198,6 +216,7 @@ FcCompareFilename (FcValue *v1, FcValue *v2)
#define PRI_FcCompareFilename(n) PRI1(n)
#define PRI_FcCompareCharSet(n) PRI1(n)
#define PRI_FcCompareLang(n) PRI1(n)
+#define PRI_FcComparePostScript(n) PRI1(n)
#define FC_OBJECT(NAME, Type, Cmp) PRI_##Cmp(NAME)
@@ -219,8 +238,10 @@ typedef enum _FcMatcherPriority {
PRI1(CHARSET),
PRI_FAMILY_STRONG,
PRI_LANG_STRONG,
+ PRI_POSTSCRIPT_NAME_STRONG,
PRI_LANG_WEAK,
PRI_FAMILY_WEAK,
+ PRI_POSTSCRIPT_NAME_WEAK,
PRI1(SPACING),
PRI1(PIXEL_SIZE),
PRI1(STYLE),
diff --git a/fontconfig/src/fcobjs.h b/fontconfig/src/fcobjs.h
index 4c1138ae4..b7354012d 100644
--- a/fontconfig/src/fcobjs.h
+++ b/fontconfig/src/fcobjs.h
@@ -44,4 +44,5 @@ FC_OBJECT (NAMELANG, FcTypeString, NULL)
FC_OBJECT (FONT_FEATURES, FcTypeString, NULL)
FC_OBJECT (PRGNAME, FcTypeString, NULL)
FC_OBJECT (HASH, FcTypeString, FcCompareString)
+FC_OBJECT (POSTSCRIPT_NAME, FcTypeString, FcComparePostScript)
/* ^-------------- Add new objects here. */
diff --git a/fontconfig/src/fcpat.c b/fontconfig/src/fcpat.c
index b3b155d4d..25bff6456 100644
--- a/fontconfig/src/fcpat.c
+++ b/fontconfig/src/fcpat.c
@@ -843,6 +843,8 @@ FcPatternObjectGet (const FcPattern *p, FcObject object, int id, FcValue *v)
FcPatternElt *e;
FcValueListPtr l;
+ if (!p)
+ return FcResultNoMatch;
e = FcPatternObjectFindElt (p, object);
if (!e)
return FcResultNoMatch;
diff --git a/fontconfig/src/fcstr.c b/fontconfig/src/fcstr.c
index 4d11a4c65..339a3465d 100644
--- a/fontconfig/src/fcstr.c
+++ b/fontconfig/src/fcstr.c
@@ -137,27 +137,7 @@ FcStrCaseWalkerLong (FcCaseWalker *w, FcChar8 r)
}
static FcChar8
-FcStrCaseWalkerNext (FcCaseWalker *w)
-{
- FcChar8 r;
-
- if (w->read)
- {
- if ((r = *w->read++))
- return r;
- w->read = 0;
- }
- r = *w->src++;
-
- if ((r & 0xc0) == 0xc0)
- return FcStrCaseWalkerLong (w, r);
- if ('A' <= r && r <= 'Z')
- r = r - 'A' + 'a';
- return r;
-}
-
-static FcChar8
-FcStrCaseWalkerNextIgnoreBlanks (FcCaseWalker *w)
+FcStrCaseWalkerNext (FcCaseWalker *w, const char *delims)
{
FcChar8 r;
@@ -170,7 +150,7 @@ FcStrCaseWalkerNextIgnoreBlanks (FcCaseWalker *w)
do
{
r = *w->src++;
- } while (r == ' ');
+ } while (r != 0 && delims && strchr (delims, r));
if ((r & 0xc0) == 0xc0)
return FcStrCaseWalkerLong (w, r);
@@ -187,13 +167,13 @@ FcStrDowncase (const FcChar8 *s)
FcChar8 *dst, *d;
FcStrCaseWalkerInit (s, &w);
- while (FcStrCaseWalkerNext (&w))
+ while (FcStrCaseWalkerNext (&w, NULL))
len++;
d = dst = malloc (len + 1);
if (!d)
return 0;
FcStrCaseWalkerInit (s, &w);
- while ((*d++ = FcStrCaseWalkerNext (&w)));
+ while ((*d++ = FcStrCaseWalkerNext (&w, NULL)));
return dst;
}
@@ -210,8 +190,8 @@ FcStrCmpIgnoreCase (const FcChar8 *s1, const FcChar8 *s2)
for (;;)
{
- c1 = FcStrCaseWalkerNext (&w1);
- c2 = FcStrCaseWalkerNext (&w2);
+ c1 = FcStrCaseWalkerNext (&w1, NULL);
+ c2 = FcStrCaseWalkerNext (&w2, NULL);
if (!c1 || (c1 != c2))
break;
}
@@ -221,6 +201,12 @@ FcStrCmpIgnoreCase (const FcChar8 *s1, const FcChar8 *s2)
int
FcStrCmpIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2)
{
+ return FcStrCmpIgnoreCaseAndDelims (s1, s2, (const FcChar8 *)" ");
+}
+
+int
+FcStrCmpIgnoreCaseAndDelims (const FcChar8 *s1, const FcChar8 *s2, const FcChar8 *delims)
+{
FcCaseWalker w1, w2;
FcChar8 c1, c2;
@@ -231,8 +217,8 @@ FcStrCmpIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2)
for (;;)
{
- c1 = FcStrCaseWalkerNextIgnoreBlanks (&w1);
- c2 = FcStrCaseWalkerNextIgnoreBlanks (&w2);
+ c1 = FcStrCaseWalkerNext (&w1, (const char *)delims);
+ c2 = FcStrCaseWalkerNext (&w2, (const char *)delims);
if (!c1 || (c1 != c2))
break;
}
@@ -317,7 +303,7 @@ FcStrHashIgnoreCase (const FcChar8 *s)
FcChar8 c;
FcStrCaseWalkerInit (s, &w);
- while ((c = FcStrCaseWalkerNext (&w)))
+ while ((c = FcStrCaseWalkerNext (&w, NULL)))
h = ((h << 3) ^ (h >> 3)) ^ c;
return h;
}
@@ -337,8 +323,8 @@ FcStrIsAtIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2)
for (;;)
{
- c1 = FcStrCaseWalkerNextIgnoreBlanks (&w1);
- c2 = FcStrCaseWalkerNextIgnoreBlanks (&w2);
+ c1 = FcStrCaseWalkerNext (&w1, " ");
+ c2 = FcStrCaseWalkerNext (&w2, " ");
if (!c1 || (c1 != c2))
break;
}
@@ -396,8 +382,8 @@ FcStrIsAtIgnoreCase (const FcChar8 *s1, const FcChar8 *s2)
for (;;)
{
- c1 = FcStrCaseWalkerNext (&w1);
- c2 = FcStrCaseWalkerNext (&w2);
+ c1 = FcStrCaseWalkerNext (&w1, NULL);
+ c2 = FcStrCaseWalkerNext (&w2, NULL);
if (!c1 || (c1 != c2))
break;
}
@@ -448,6 +434,31 @@ FcStrContainsWord (const FcChar8 *s1, const FcChar8 *s2)
return 0;
}
+/*
+ * returns the number of strings (ignoring delimitors and case) being matched
+ */
+
+int
+FcStrMatchIgnoreCaseAndDelims (const FcChar8 *s1, const FcChar8 *s2, const FcChar8 *delims)
+{
+ FcCaseWalker w1, w2;
+ FcChar8 c1, c2;
+
+ if (s1 == s2) return 0;
+
+ FcStrCaseWalkerInit (s1, &w1);
+ FcStrCaseWalkerInit (s2, &w2);
+
+ for (;;)
+ {
+ c1 = FcStrCaseWalkerNext (&w1, (const char *)delims);
+ c2 = FcStrCaseWalkerNext (&w2, (const char *)delims);
+ if (!c1 || (c1 != c2))
+ break;
+ }
+ return w1.src - s1 - 1;
+}
+
const FcChar8 *
FcStrStrIgnoreCase (const FcChar8 *s1, const FcChar8 *s2)
{
@@ -464,12 +475,12 @@ FcStrStrIgnoreCase (const FcChar8 *s1, const FcChar8 *s2)
FcStrCaseWalkerInit (s1, &w1);
FcStrCaseWalkerInit (s2, &w2);
- c2 = FcStrCaseWalkerNext (&w2);
+ c2 = FcStrCaseWalkerNext (&w2, NULL);
for (;;)
{
cur = w1.src;
- c1 = FcStrCaseWalkerNext (&w1);
+ c1 = FcStrCaseWalkerNext (&w1, NULL);
if (!c1)
break;
if (c1 == c2)
@@ -480,8 +491,8 @@ FcStrStrIgnoreCase (const FcChar8 *s1, const FcChar8 *s2)
for (;;)
{
- c1t = FcStrCaseWalkerNext (&w1t);
- c2t = FcStrCaseWalkerNext (&w2t);
+ c1t = FcStrCaseWalkerNext (&w1t, NULL);
+ c2t = FcStrCaseWalkerNext (&w2t, NULL);
if (!c2t)
return cur;
diff --git a/mesalib/Android.common.mk b/mesalib/Android.common.mk
index d0a5f1aa4..215c640fb 100644
--- a/mesalib/Android.common.mk
+++ b/mesalib/Android.common.mk
@@ -35,6 +35,8 @@ LOCAL_C_INCLUDES += \
# define ANDROID_VERSION (e.g., 4.0.x => 0x0400)
LOCAL_CFLAGS += \
+ -DPACKAGE_VERSION=\"9.2-devel\" \
+ -DPACKAGE_BUGREPORT=\"https://bugs.freedesktop.org/enter_bug.cgi?product=Mesa\" \
-DANDROID_VERSION=0x0$(MESA_ANDROID_MAJOR_VERSION)0$(MESA_ANDROID_MINOR_VERSION)
LOCAL_CFLAGS += \
diff --git a/mesalib/configure.ac b/mesalib/configure.ac
index 4b5b04576..81d4a3f3e 100644
--- a/mesalib/configure.ac
+++ b/mesalib/configure.ac
@@ -452,6 +452,9 @@ if test "x$enable_asm" = xyes; then
linux* | *freebsd* | dragonfly* | *netbsd*)
test "x$enable_64bit" = xyes && asm_arch=x86_64 || asm_arch=x86
;;
+ gnu*)
+ asm_arch=x86
+ ;;
esac
;;
x86_64)
diff --git a/mesalib/docs/GL3.txt b/mesalib/docs/GL3.txt
index de5169373..640dec24c 100644
--- a/mesalib/docs/GL3.txt
+++ b/mesalib/docs/GL3.txt
@@ -133,7 +133,7 @@ GL 4.3:
GLSL 4.3 not started
ARB_arrays_of_arrays not started
-ARB_ES3_compatibility not started
+ARB_ES3_compatibility DONE (i965)
ARB_clear_buffer_object not started
ARB_compute_shader started (gallium)
ARB_copy_image not started
diff --git a/mesalib/docs/index.html b/mesalib/docs/index.html
index c7d16204e..e2ef92aee 100644
--- a/mesalib/docs/index.html
+++ b/mesalib/docs/index.html
@@ -16,6 +16,12 @@
<h1>News</h1>
+<h2>March 19, 2013</h2>
+<p>
+<a href="relnotes-9.1.1.html">Mesa 9.1.1</a> is released.
+This is a bug fix release.
+</p>
+
<h2>February 24, 2013</h2>
<p>
diff --git a/mesalib/docs/relnotes-9.1.1.html b/mesalib/docs/relnotes-9.1.1.html
new file mode 100644
index 000000000..a73c97424
--- /dev/null
+++ b/mesalib/docs/relnotes-9.1.1.html
@@ -0,0 +1,235 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html lang="en">
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=utf-8">
+ <title>Mesa Release Notes</title>
+ <link rel="stylesheet" type="text/css" href="mesa.css">
+</head>
+<body>
+
+<div class="header">
+ <h1>The Mesa 3D Graphics Library</h1>
+</div>
+
+<iframe src="contents.html"></iframe>
+<div class="content">
+
+<h1>Mesa 9.1.1 Release Notes / March 19th, 2013</h1>
+
+<p>
+Mesa 9.1.1 is a bug fix release which fixes bugs found since the 9.1 release.
+</p>
+<p>
+Mesa 9.1 implements the OpenGL 3.1 API, but the version reported by
+glGetString(GL_VERSION) or glGetIntegerv(GL_MAJOR_VERSION) /
+glGetIntegerv(GL_MINOR_VERSION) depends on the particular driver being used.
+Some drivers don't support all the features required in OpenGL 3.1. OpenGL
+3.1 is <strong>only</strong> available if requested at context creation
+because GL_ARB_compatibility is not supported.
+</p>
+
+<h2>MD5 checksums</h2>
+<pre>
+6508d9882d8dce7106717f365632700c MesaLib-9.1.1.tar.gz
+6ea2bdc3b7ecfb4257b39814b4182580 MesaLib-9.1.1.tar.bz2
+3434c0eb47849a08c53cd32833d10d13 MesaLib-9.1.1.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=30232">Bug 30232</a> - [GM45] mesa demos spriteblast render incorrectly</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=32429">Bug 32429</a> - [gles2] Ironlake: gl_PointCoord takes no effect for point sprites</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=38086">Bug 38086</a> - Mesa 7.11-devel implementation error: Unexpected program target in destroy_program_variants_cb()</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=57121">Bug 57121</a> - [snb] corrupted GLSL built-in function results when using Uniform Buffer contents as arguments</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=58042">Bug 58042</a> - [bisected] Garbled UI in Team Fortress 2 and Counter-Strike: Source</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=58960">Bug 58960</a> - Texture flicker with fragment shader</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=59495">Bug 59495</a> - [i965 Bisected]Oglc fbblit(advanced.blitFb-3d-cube.mirror.both) fails</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=59783">Bug 59783</a> - [IVB bisected] 3DMMES2.0 Taiji performance reduced by ~13% with gnome-session enable compositing</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=60121">Bug 60121</a> - build - libvdpau_softpipe fails at runtime.</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=60143">Bug 60143</a> - gbm_dri_bo_create fails to initialize bo-&gt;base.base.format</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=60802">Bug 60802</a> - Corruption with DMA ring on cayman</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=60848">Bug 60848</a> - [bisected] r600g: add htile support cause gpu lockup in Dishonored wine.</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=60938">Bug 60938</a> - [softpipe] piglit interpolation-noperspective-gl_BackColor-flat-fixed regression</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=61012">Bug 61012</a> - alloc_layout_array tx * ty assertion failure when making pbuffer current</li>
+
+<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=61026">Bug 61026</a> - Segfault in glBitmap when called with PBO source</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-9.1..mesa-9.1.1
+</pre>
+
+
+<p>Adam Sampson (1):</p>
+<ul>
+ <li>autotools: oprofilejit should be included in the list of LLVM components required</li>
+</ul>
+
+<p>Alex Deucher (2):</p>
+<ul>
+ <li>r600g: add Richland APU pci ids</li>
+ <li>r600g: Use blitter rather than DMA for 128bpp on cayman (v3)</li>
+</ul>
+
+<p>Andreas Boll (2):</p>
+<ul>
+ <li>docs: Add 9.1 release md5sums</li>
+ <li>docs: add news item for 9.1 release</li>
+</ul>
+
+<p>Anuj Phogat (1):</p>
+<ul>
+ <li>meta: Allocate texture before initializing texture coordinates</li>
+</ul>
+
+<p>Brian Paul (11):</p>
+<ul>
+ <li>docs: remove stray 'date' text</li>
+ <li>docs: insert links to the 9.0.3 release</li>
+ <li>draw: fix non-perspective interpolation in interp()</li>
+ <li>st/mesa: implement glBitmap unpacking from a PBO, for the cache path</li>
+ <li>st/xlib: initialize the drawable size in create_xmesa_buffer()</li>
+ <li>st/mesa: fix trimming of GL_QUAD_STRIP</li>
+ <li>st/mesa: check for dummy programs in destroy_program_variants()</li>
+ <li>st/mesa: fix polygon offset state translation logic</li>
+ <li>draw: fix broken polygon offset stage</li>
+ <li>llvmpipe: add missing checks for polygon offset point/line modes</li>
+ <li>svga: always link with C++</li>
+</ul>
+
+<p>Daniel van Vugt (1):</p>
+<ul>
+ <li>gbm: Remember to init format on gbm_dri_bo_create.</li>
+</ul>
+
+<p>Eric Anholt (7):</p>
+<ul>
+ <li>i965/fs: Do a general SEND dependency workaround for the original 965.</li>
+ <li>i965/fs: Fix copy propagation with smearing.</li>
+ <li>i965/fs: Delay setup of uniform loads until after pre-regalloc scheduling.</li>
+ <li>i965/fs: Only do CSE when the dst types match.</li>
+ <li>i965/fs: Fix broken math on values loaded from uniform buffers on gen6.</li>
+ <li>mesa: Fix setup of ctx-&gt;Point.PointSprite for GLES2.</li>
+ <li>i965: Fix the W value of deprecated pointcoords on pre-gen6.</li>
+</ul>
+
+<p>Frank Henigman (1):</p>
+<ul>
+ <li>i965: Link i965_dri.so with C++ linker.</li>
+</ul>
+
+<p>Ian Romanick (3):</p>
+<ul>
+ <li>mesa: Add previously picked commit to .cherry-ignore</li>
+ <li>mesa: Modify candidate search string</li>
+ <li>egl: Allow 24-bit visuals for 32-bit RGBA8888 configs</li>
+</ul>
+
+<p>Jakub Bogusz (1):</p>
+<ul>
+ <li>vdpau-softpipe: Build correct source file - vl_winsys_xsp.c</li>
+</ul>
+
+<p>Jerome Glisse (1):</p>
+<ul>
+ <li>r600g: workaround hyperz lockup on evergreen</li>
+</ul>
+
+<p>John KÃ¥re Alsaker (1):</p>
+<ul>
+ <li>llvmpipe: Fix creation of shared and scanout textures.</li>
+</ul>
+
+<p>Jordan Justen (1):</p>
+<ul>
+ <li>attrib: push/pop FRAGMENT_PROGRAM_ARB state</li>
+</ul>
+
+<p>José Fonseca (3):</p>
+<ul>
+ <li>scons: Allows choosing VS 10 or 11.</li>
+ <li>scons: Define _ALLOW_KEYWORD_MACROS on MSVC builds.</li>
+ <li>scons: Warn when using MSVS versions prior to 2012.</li>
+</ul>
+
+<p>Keith Kriewall (1):</p>
+<ul>
+ <li>scons: Fix Windows build with LLVM 3.2</li>
+</ul>
+
+<p>Kenneth Graunke (1):</p>
+<ul>
+ <li>i965: Fix Crystal Well PCI IDs.</li>
+</ul>
+
+<p>Marek Olšák (5):</p>
+<ul>
+ <li>r600g: use async DMA with a non-zero src offset</li>
+ <li>r600g: flush and invalidate htile cache when appropriate</li>
+ <li>gallium/util: add helper code for 1D integer range</li>
+ <li>r600g: always map uninitialized buffer range as unsynchronized</li>
+ <li>r600g: pad the DMA CS to a multiple of 8 dwords</li>
+</ul>
+
+<p>Martin Andersson (1):</p>
+<ul>
+ <li>winsys/radeon: Only add bo to hash table when creating flink</li>
+</ul>
+
+<p>Matt Turner (1):</p>
+<ul>
+ <li>mesa: Allow ETC2/EAC formats with ARB_ES3_compatibility.</li>
+</ul>
+
+<p>Michel Dänzer (3):</p>
+<ul>
+ <li>radeonsi: Fix up and enable flat shading.</li>
+ <li>r600g/Cayman: Fix blending using destination alpha factor but non-alpha dest</li>
+ <li>radeonsi: Fix off-by-one for maximum vertex element index in some cases</li>
+</ul>
+
+<p>Tapani Pälli (2):</p>
+<ul>
+ <li>mesa: add missing case in _mesa_GetTexParameterfv()</li>
+ <li>mesa/es: NULL check in EGLImageTargetTexture2DOES</li>
+</ul>
+
+<p>Vadim Girlin (1):</p>
+<ul>
+ <li>r600g: fix check_and_set_bank_swizzle for cayman</li>
+</ul>
+
+<p>Vincent Lejeune (2):</p>
+<ul>
+ <li>r600g/llvm: Add support for UBO</li>
+ <li>r600g: Check comp_mask before merging export instructions</li>
+</ul>
+
+</div>
+</body>
+</html>
diff --git a/mesalib/include/GL/internal/dri_interface.h b/mesalib/include/GL/internal/dri_interface.h
index 42147e90e..30ce175e6 100644
--- a/mesalib/include/GL/internal/dri_interface.h
+++ b/mesalib/include/GL/internal/dri_interface.h
@@ -938,7 +938,7 @@ struct __DRIdri2ExtensionRec {
* extensions.
*/
#define __DRI_IMAGE "DRI_IMAGE"
-#define __DRI_IMAGE_VERSION 6
+#define __DRI_IMAGE_VERSION 7
/**
* These formats correspond to the similarly named MESA_FORMAT_*
@@ -1021,6 +1021,9 @@ struct __DRIdri2ExtensionRec {
#define __DRI_IMAGE_ATTRIB_WIDTH 0x2004 /* available in versions 4+ */
#define __DRI_IMAGE_ATTRIB_HEIGHT 0x2005
#define __DRI_IMAGE_ATTRIB_COMPONENTS 0x2006 /* available in versions 5+ */
+#define __DRI_IMAGE_ATTRIB_FD 0x2007 /* available in versions
+ * 7+. Each query will return a
+ * new fd. */
/**
* \name Reasons that __DRIimageExtensionRec::createImageFromTexture might fail
@@ -1117,6 +1120,16 @@ struct __DRIimageExtensionRec {
int level,
unsigned *error,
void *loaderPrivate);
+ /**
+ * Like createImageFromNames, but takes a prime fd instead.
+ *
+ * \since 7
+ */
+ __DRIimage *(*createImageFromFds)(__DRIscreen *screen,
+ int width, int height, int fourcc,
+ int *fds, int num_fds,
+ int *strides, int *offsets,
+ void *loaderPrivate);
};
diff --git a/mesalib/scons/gallium.py b/mesalib/scons/gallium.py
index b28be5d89..57b5b418f 100644
--- a/mesalib/scons/gallium.py
+++ b/mesalib/scons/gallium.py
@@ -402,7 +402,7 @@ def generate(env):
'/Oi', # enable intrinsic functions
]
else:
- if distutils.version.LooseVersion(env['MSVC_VERSION']) < distutils.version.LooseVersion('11.0'):
+ if 'MSVC_VERSION' in env and distutils.version.LooseVersion(env['MSVC_VERSION']) < distutils.version.LooseVersion('11.0'):
print 'scons: warning: Visual Studio versions prior to 2012 are known to produce incorrect code when optimizations are enabled ( https://bugs.freedesktop.org/show_bug.cgi?id=58718 )'
ccflags += [
'/O2', # optimize for speed
diff --git a/mesalib/src/gallium/auxiliary/Makefile.sources b/mesalib/src/gallium/auxiliary/Makefile.sources
index 74c7902ae..898abe024 100644
--- a/mesalib/src/gallium/auxiliary/Makefile.sources
+++ b/mesalib/src/gallium/auxiliary/Makefile.sources
@@ -164,6 +164,7 @@ GALLIVM_SOURCES := \
gallivm/lp_bld_flow.c \
gallivm/lp_bld_format_aos.c \
gallivm/lp_bld_format_aos_array.c \
+ gallivm/lp_bld_format_float.c \
gallivm/lp_bld_format_soa.c \
gallivm/lp_bld_format_yuv.c \
gallivm/lp_bld_gather.c \
diff --git a/mesalib/src/glsl/glsl_types.cpp b/mesalib/src/glsl/glsl_types.cpp
index a783dcc3b..8b0a24805 100644
--- a/mesalib/src/glsl/glsl_types.cpp
+++ b/mesalib/src/glsl/glsl_types.cpp
@@ -292,6 +292,14 @@ glsl_type::generate_140_types(glsl_symbol_table *symtab)
void
+glsl_type::generate_150_types(glsl_symbol_table *symtab)
+{
+ generate_140_types(symtab);
+ generate_ARB_texture_multisample_types(symtab, false);
+}
+
+
+void
glsl_type::generate_ARB_texture_rectangle_types(glsl_symbol_table *symtab,
bool warn)
{
@@ -385,9 +393,11 @@ _mesa_glsl_initialize_types(struct _mesa_glsl_parse_state *state)
glsl_type::generate_130_types(state->symbols, true, skip_1d);
break;
case 140:
- case 150:
glsl_type::generate_140_types(state->symbols);
break;
+ case 150:
+ glsl_type::generate_150_types(state->symbols);
+ break;
default:
assert(!"Unexpected language version");
break;
diff --git a/mesalib/src/glsl/glsl_types.h b/mesalib/src/glsl/glsl_types.h
index 79304269d..2f3b19f51 100644
--- a/mesalib/src/glsl/glsl_types.h
+++ b/mesalib/src/glsl/glsl_types.h
@@ -583,6 +583,7 @@ private:
static void generate_130_types(glsl_symbol_table *, bool add_deprecated,
bool skip_1d);
static void generate_140_types(glsl_symbol_table *);
+ static void generate_150_types(glsl_symbol_table *);
static void generate_ARB_texture_rectangle_types(glsl_symbol_table *, bool);
static void generate_EXT_texture_array_types(glsl_symbol_table *, bool);
static void generate_OES_texture_3D_types(glsl_symbol_table *, bool);
diff --git a/mesalib/src/glsl/main.cpp b/mesalib/src/glsl/main.cpp
index ed6f12279..ce084b4d7 100644
--- a/mesalib/src/glsl/main.cpp
+++ b/mesalib/src/glsl/main.cpp
@@ -47,7 +47,7 @@ initialize_context(struct gl_context *ctx, gl_api api)
/* The standalone compiler needs to claim support for almost
* everything in order to compile the built-in functions.
*/
- ctx->Const.GLSLVersion = 140;
+ ctx->Const.GLSLVersion = 150;
ctx->Extensions.ARB_ES3_compatibility = true;
ctx->Const.MaxClipPlanes = 8;
diff --git a/mesalib/src/mesa/drivers/common/meta.c b/mesalib/src/mesa/drivers/common/meta.c
index 29a209ede..8114550ba 100644
--- a/mesalib/src/mesa/drivers/common/meta.c
+++ b/mesalib/src/mesa/drivers/common/meta.c
@@ -3118,6 +3118,7 @@ setup_texture_coords(GLenum faceTarget,
GLint slice,
GLint width,
GLint height,
+ GLint depth,
GLfloat coords0[3],
GLfloat coords1[3],
GLfloat coords2[3],
@@ -3134,8 +3135,11 @@ setup_texture_coords(GLenum faceTarget,
case GL_TEXTURE_2D:
case GL_TEXTURE_3D:
case GL_TEXTURE_2D_ARRAY:
- if (faceTarget == GL_TEXTURE_3D)
- r = 1.0F / slice;
+ if (faceTarget == GL_TEXTURE_3D) {
+ assert(slice < depth);
+ assert(depth >= 1);
+ r = (slice + 0.5f) / depth;
+ }
else if (faceTarget == GL_TEXTURE_2D_ARRAY)
r = slice;
else
@@ -3571,10 +3575,10 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target,
else
assert(!genMipmapSave);
- /* Setup texture coordinates */
+ /* Setup texture coordinates */
setup_texture_coords(faceTarget,
slice,
- 0, 0, /* width, height never used here */
+ 0, 0, 1, /* width, height never used here */
verts[0].tex,
verts[1].tex,
verts[2].tex,
@@ -3840,6 +3844,7 @@ decompress_texture_image(struct gl_context *ctx,
struct gl_texture_object *texObj = texImage->TexObject;
const GLint width = texImage->Width;
const GLint height = texImage->Height;
+ const GLint depth = texImage->Height;
const GLenum target = texObj->Target;
GLenum faceTarget;
struct vertex {
@@ -3935,7 +3940,7 @@ decompress_texture_image(struct gl_context *ctx,
_mesa_BindSampler(ctx->Texture.CurrentUnit, decompress->Sampler);
}
- setup_texture_coords(faceTarget, slice, width, height,
+ setup_texture_coords(faceTarget, slice, width, height, depth,
verts[0].tex,
verts[1].tex,
verts[2].tex,
diff --git a/mesalib/src/mesa/drivers/dri/common/xmlpool/t_options.h b/mesalib/src/mesa/drivers/dri/common/xmlpool/t_options.h
index 1e7eced06..7b441c68f 100644
--- a/mesalib/src/mesa/drivers/dri/common/xmlpool/t_options.h
+++ b/mesalib/src/mesa/drivers/dri/common/xmlpool/t_options.h
@@ -75,6 +75,11 @@ DRI_CONF_OPT_BEGIN(always_flush_cache,bool,def) \
DRI_CONF_DESC(en,gettext("Enable flushing GPU caches with each draw call")) \
DRI_CONF_OPT_END
+#define DRI_CONF_DISABLE_THROTTLING(def) \
+DRI_CONF_OPT_BEGIN(disable_throttling,bool,def) \
+ DRI_CONF_DESC(en,gettext("Disable throttling on first batch after flush")) \
+DRI_CONF_OPT_END
+
#define DRI_CONF_FORCE_GLSL_EXTENSIONS_WARN(def) \
DRI_CONF_OPT_BEGIN(force_glsl_extensions_warn,bool,def) \
DRI_CONF_DESC(en,gettext("Force GLSL extension default behavior to 'warn'")) \
diff --git a/mesalib/src/mesa/main/compiler.h b/mesalib/src/mesa/main/compiler.h
index 48712485a..8b23665e6 100644
--- a/mesalib/src/mesa/main/compiler.h
+++ b/mesalib/src/mesa/main/compiler.h
@@ -307,8 +307,9 @@ static INLINE GLuint CPU_TO_LE32(GLuint x)
* USE_IEEE: Determine if we're using IEEE floating point
*/
#if defined(__i386__) || defined(__386__) || defined(__sparc__) || \
- defined(__s390x__) || defined(__powerpc__) || \
+ defined(__s390__) || defined(__s390x__) || defined(__powerpc__) || \
defined(__x86_64__) || \
+ defined(__m68k__) || \
defined(ia64) || defined(__ia64__) || \
defined(__hppa__) || defined(hpux) || \
defined(__mips) || defined(_MIPS_ARCH) || \
diff --git a/mesalib/src/mesa/main/dd.h b/mesalib/src/mesa/main/dd.h
index 4860d4d12..8f3cd3d6b 100644
--- a/mesalib/src/mesa/main/dd.h
+++ b/mesalib/src/mesa/main/dd.h
@@ -195,9 +195,10 @@ struct dd_function_table {
GLenum srcFormat, GLenum srcType );
/**
- * Determine sample counts support for a particular format
+ * Determine sample counts support for a particular target and format
*
* \param ctx GL context
+ * \param target GL target enum
* \param internalFormat GL format enum
* \param samples Buffer to hold the returned sample counts.
* Drivers \b must \b not return more than 16 counts.
@@ -207,6 +208,7 @@ struct dd_function_table {
* \c internaFormat is not renderable, zero is returned.
*/
size_t (*QuerySamplesForFormat)(struct gl_context *ctx,
+ GLenum target,
GLenum internalFormat,
int samples[16]);
diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c
index 0126e2930..3fdf62667 100644
--- a/mesalib/src/mesa/main/fbobject.c
+++ b/mesalib/src/mesa/main/fbobject.c
@@ -43,6 +43,7 @@
#include "hash.h"
#include "macros.h"
#include "mfeatures.h"
+#include "multisample.h"
#include "mtypes.h"
#include "renderbuffer.h"
#include "state.h"
@@ -474,6 +475,32 @@ _mesa_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
/**
+ * Return true if the framebuffer has a combined depth/stencil
+ * renderbuffer attached.
+ */
+GLboolean
+_mesa_has_depthstencil_combined(const struct gl_framebuffer *fb)
+{
+ const struct gl_renderbuffer_attachment *depth =
+ &fb->Attachment[BUFFER_DEPTH];
+ const struct gl_renderbuffer_attachment *stencil =
+ &fb->Attachment[BUFFER_STENCIL];
+
+ if (depth->Type == stencil->Type) {
+ if (depth->Type == GL_RENDERBUFFER_EXT &&
+ depth->Renderbuffer == stencil->Renderbuffer)
+ return GL_TRUE;
+
+ if (depth->Type == GL_TEXTURE &&
+ depth->Texture == stencil->Texture)
+ return GL_TRUE;
+ }
+
+ return GL_FALSE;
+}
+
+
+/**
* For debug only.
*/
static void
@@ -1466,6 +1493,7 @@ renderbuffer_storage(GLenum target, GLenum internalFormat,
"glRenderbufferStorage" : "glRenderbufferStorageMultisample";
struct gl_renderbuffer *rb;
GLenum baseFormat;
+ GLenum sample_count_error;
GET_CURRENT_CONTEXT(ctx);
if (MESA_VERBOSE & VERBOSE_API) {
@@ -1509,9 +1537,14 @@ renderbuffer_storage(GLenum target, GLenum internalFormat,
/* NumSamples == 0 indicates non-multisampling */
samples = 0;
}
- else if (samples > (GLsizei) ctx->Const.MaxSamples) {
- /* note: driver may choose to use more samples than what's requested */
- _mesa_error(ctx, GL_INVALID_VALUE, "%s(samples)", func);
+
+ /* check the sample count;
+ * note: driver may choose to use more samples than what's requested
+ */
+ sample_count_error = _mesa_check_sample_count(ctx, target,
+ internalFormat, samples);
+ if (sample_count_error != GL_NO_ERROR) {
+ _mesa_error(ctx, sample_count_error, "%s(samples)", func);
return;
}
diff --git a/mesalib/src/mesa/main/fbobject.h b/mesalib/src/mesa/main/fbobject.h
index ec8b0afe4..0358864d7 100644
--- a/mesalib/src/mesa/main/fbobject.h
+++ b/mesalib/src/mesa/main/fbobject.h
@@ -113,6 +113,9 @@ _mesa_framebuffer_renderbuffer(struct gl_context *ctx,
extern void
_mesa_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb);
+extern GLboolean
+_mesa_has_depthstencil_combined(const struct gl_framebuffer *fb);
+
extern void
_mesa_test_framebuffer_completeness(struct gl_context *ctx,
struct gl_framebuffer *fb);
diff --git a/mesalib/src/mesa/main/ff_fragment_shader.cpp b/mesalib/src/mesa/main/ff_fragment_shader.cpp
index 186988bbd..01a4542d7 100644
--- a/mesalib/src/mesa/main/ff_fragment_shader.cpp
+++ b/mesalib/src/mesa/main/ff_fragment_shader.cpp
@@ -1350,22 +1350,6 @@ create_new_program(struct gl_context *ctx, struct state_key *key)
_mesa_glsl_link_shader(ctx, p.shader_program);
- /* Set the sampler uniforms, and relink to get them into the linked
- * program.
- */
- struct gl_shader *const fs =
- p.shader_program->_LinkedShaders[MESA_SHADER_FRAGMENT];
- struct gl_program *const fp = fs->Program;
-
- _mesa_generate_parameters_list_for_uniforms(p.shader_program, fs,
- fp->Parameters);
-
- _mesa_associate_uniform_storage(ctx, p.shader_program, fp->Parameters);
-
- _mesa_update_shader_textures_used(p.shader_program, fp);
- if (ctx->Driver.SamplerUniformChange)
- ctx->Driver.SamplerUniformChange(ctx, fp->Target, fp);
-
if (!p.shader_program->LinkStatus)
_mesa_problem(ctx, "Failed to link fixed function fragment shader: %s\n",
p.shader_program->InfoLog);
diff --git a/mesalib/src/mesa/main/formatquery.c b/mesalib/src/mesa/main/formatquery.c
index bd895e874..78c5fbe5e 100644
--- a/mesalib/src/mesa/main/formatquery.c
+++ b/mesalib/src/mesa/main/formatquery.c
@@ -59,9 +59,10 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname,
case GL_TEXTURE_2D_MULTISAMPLE:
case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
- /* Mesa does not currently support GL_ARB_texture_multisample, so these
- * enums are not valid on this implementation either.
- */
+ /* These enums are only valid if ARB_texture_multisample is supported */
+ if (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_multisample)
+ break;
+
default:
_mesa_error(ctx, GL_INVALID_ENUM,
"glGetInternalformativ(target=%s)",
@@ -96,7 +97,8 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname,
switch (pname) {
case GL_SAMPLES:
- count = ctx->Driver.QuerySamplesForFormat(ctx, internalformat, buffer);
+ count = ctx->Driver.QuerySamplesForFormat(ctx, target,
+ internalformat, buffer);
break;
case GL_NUM_SAMPLE_COUNTS: {
/* The driver can return 0, and we should pass that along to the
@@ -115,7 +117,7 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname,
* returned."
*/
const size_t num_samples =
- ctx->Driver.QuerySamplesForFormat(ctx, internalformat, buffer);
+ ctx->Driver.QuerySamplesForFormat(ctx, target, internalformat, buffer);
/* QuerySamplesForFormat writes some stuff to buffer, so we have to
* separately over-write it with the requested value.
diff --git a/mesalib/src/mesa/main/framebuffer.c b/mesalib/src/mesa/main/framebuffer.c
index d3abc2b30..619aaa337 100644
--- a/mesalib/src/mesa/main/framebuffer.c
+++ b/mesalib/src/mesa/main/framebuffer.c
@@ -923,10 +923,10 @@ _mesa_get_color_read_type(struct gl_context *ctx)
* Returns the read renderbuffer for the specified format.
*/
struct gl_renderbuffer *
-_mesa_get_read_renderbuffer_for_format(struct gl_context *ctx,
+_mesa_get_read_renderbuffer_for_format(const struct gl_context *ctx,
GLenum format)
{
- struct gl_framebuffer *rfb = ctx->ReadBuffer;
+ const struct gl_framebuffer *rfb = ctx->ReadBuffer;
if (_mesa_is_color_format(format)) {
return rfb->Attachment[rfb->_ColorReadBufferIndex].Renderbuffer;
diff --git a/mesalib/src/mesa/main/framebuffer.h b/mesalib/src/mesa/main/framebuffer.h
index 06db04925..9b94452d6 100644
--- a/mesalib/src/mesa/main/framebuffer.h
+++ b/mesalib/src/mesa/main/framebuffer.h
@@ -98,7 +98,7 @@ extern GLenum
_mesa_get_color_read_format(struct gl_context *ctx);
extern struct gl_renderbuffer *
-_mesa_get_read_renderbuffer_for_format(struct gl_context *ctx,
+_mesa_get_read_renderbuffer_for_format(const struct gl_context *ctx,
GLenum format);
extern void
diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h
index 83b6c8984..a0e7e281d 100644
--- a/mesalib/src/mesa/main/mtypes.h
+++ b/mesalib/src/mesa/main/mtypes.h
@@ -1179,6 +1179,7 @@ struct gl_texture_object
GLfloat Priority; /**< in [0,1] */
GLint BaseLevel; /**< min mipmap level, OpenGL 1.2 */
GLint MaxLevel; /**< max mipmap level, OpenGL 1.2 */
+ GLint ImmutableLevels; /**< ES 3.0 / ARB_texture_view */
GLint _MaxLevel; /**< actual max mipmap level (q in the spec) */
GLfloat _MaxLambda; /**< = _MaxLevel - BaseLevel (q - b in spec) */
GLint CropRect[4]; /**< GL_OES_draw_texture */
@@ -1796,6 +1797,7 @@ struct gl_transform_feedback_state
typedef enum
{
PROGRAM_TEMPORARY, /**< machine->Temporary[] */
+ PROGRAM_ARRAY, /**< Arrays & Matrixes */
PROGRAM_INPUT, /**< machine->Inputs[] */
PROGRAM_OUTPUT, /**< machine->Outputs[] */
PROGRAM_LOCAL_PARAM, /**< gl_program->LocalParams[] */
diff --git a/mesalib/src/mesa/main/multisample.c b/mesalib/src/mesa/main/multisample.c
index 248494615..b0f45d933 100644
--- a/mesalib/src/mesa/main/multisample.c
+++ b/mesalib/src/mesa/main/multisample.c
@@ -29,6 +29,7 @@
#include "main/multisample.h"
#include "main/mtypes.h"
#include "main/fbobject.h"
+#include "main/glformats.h"
/**
@@ -112,3 +113,79 @@ _mesa_SampleMaski(GLuint index, GLbitfield mask)
FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE);
ctx->Multisample.SampleMaskValue = mask;
}
+
+
+/* Helper for checking a requested sample count against the limit
+ * for a particular (target, internalFormat) pair. The limit imposed,
+ * and the error generated, both depend on which extensions are supported.
+ *
+ * Returns a GL error enum, or GL_NO_ERROR if the requested sample count is
+ * acceptable.
+ */
+GLenum
+_mesa_check_sample_count(struct gl_context *ctx, GLenum target,
+ GLenum internalFormat, GLsizei samples)
+{
+ /* If ARB_internalformat_query is supported, then treat its highest returned sample
+ * count as the absolute maximum for this format; it is allowed to exceed MAX_SAMPLES.
+ *
+ * From the ARB_internalformat_query spec:
+ *
+ * "If <samples is greater than the maximum number of samples supported
+ * for <internalformat> then the error INVALID_OPERATION is generated."
+ */
+ if (ctx->Extensions.ARB_internalformat_query) {
+ GLint buffer[16];
+ int count = ctx->Driver.QuerySamplesForFormat(ctx, target, internalFormat, buffer);
+ int limit = count ? buffer[0] : -1;
+
+ return samples > limit ? GL_INVALID_OPERATION : GL_NO_ERROR;
+ }
+
+ /* If ARB_texture_multisample is supported, we have separate limits,
+ * which may be lower than MAX_SAMPLES:
+ *
+ * From the ARB_texture_multisample spec, when describing the operation
+ * of RenderbufferStorageMultisample:
+ *
+ * "If <internalformat> is a signed or unsigned integer format and
+ * <samples> is greater than the value of MAX_INTEGER_SAMPLES, then the
+ * error INVALID_OPERATION is generated"
+ *
+ * And when describing the operation of TexImage*Multisample:
+ *
+ * "The error INVALID_OPERATION may be generated if any of the following are true:
+ *
+ * * <internalformat> is a depth/stencil-renderable format and <samples>
+ * is greater than the value of MAX_DEPTH_TEXTURE_SAMPLES
+ * * <internalformat> is a color-renderable format and <samples> is
+ * grater than the value of MAX_COLOR_TEXTURE_SAMPLES
+ * * <internalformat> is a signed or unsigned integer format and
+ * <samples> is greater than the value of MAX_INTEGER_SAMPLES
+ */
+
+ if (ctx->Extensions.ARB_texture_multisample) {
+ if (_mesa_is_enum_format_integer(internalFormat))
+ return samples > ctx->Const.MaxIntegerSamples ? GL_INVALID_OPERATION : GL_NO_ERROR;
+
+ if (target == GL_TEXTURE_2D_MULTISAMPLE ||
+ target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) {
+
+ if (_mesa_is_depth_or_stencil_format(internalFormat))
+ return samples > ctx->Const.MaxDepthTextureSamples
+ ? GL_INVALID_OPERATION : GL_NO_ERROR;
+ else
+ return samples > ctx->Const.MaxColorTextureSamples
+ ? GL_INVALID_OPERATION : GL_NO_ERROR;
+ }
+ }
+
+ /* No more specific limit is available, so just use MAX_SAMPLES:
+ *
+ * On p205 of the GL3.1 spec:
+ *
+ * "... or if samples is greater than MAX_SAMPLES, then the error
+ * INVALID_VALUE is generated"
+ */
+ return samples > ctx->Const.MaxSamples ? GL_INVALID_VALUE : GL_NO_ERROR;
+}
diff --git a/mesalib/src/mesa/main/multisample.h b/mesalib/src/mesa/main/multisample.h
index 9e6b8e0d3..f2f01de5c 100644
--- a/mesalib/src/mesa/main/multisample.h
+++ b/mesalib/src/mesa/main/multisample.h
@@ -44,4 +44,9 @@ _mesa_GetMultisamplefv(GLenum pname, GLuint index, GLfloat* val);
extern void GLAPIENTRY
_mesa_SampleMaski(GLuint index, GLbitfield mask);
+
+extern GLenum
+_mesa_check_sample_count(struct gl_context *ctx, GLenum target,
+ GLenum internalFormat, GLsizei samples);
+
#endif
diff --git a/mesalib/src/mesa/main/readpix.c b/mesalib/src/mesa/main/readpix.c
index 2f130ae9a..d3d09dea3 100644
--- a/mesalib/src/mesa/main/readpix.c
+++ b/mesalib/src/mesa/main/readpix.c
@@ -41,11 +41,212 @@
/**
- * Tries to implement glReadPixels() of GL_DEPTH_COMPONENT using memcpy of the
- * mapping.
+ * Return true if the conversion L=R+G+B is needed.
*/
static GLboolean
-fast_read_depth_pixels( struct gl_context *ctx,
+need_rgb_to_luminance_conversion(gl_format texFormat, GLenum format)
+{
+ GLenum baseTexFormat = _mesa_get_format_base_format(texFormat);
+
+ return (baseTexFormat == GL_RG ||
+ baseTexFormat == GL_RGB ||
+ baseTexFormat == GL_RGBA) &&
+ (format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA);
+}
+
+
+/**
+ * Return transfer op flags for this ReadPixels operation.
+ */
+static GLbitfield
+get_readpixels_transfer_ops(const struct gl_context *ctx, gl_format texFormat,
+ GLenum format, GLenum type, GLboolean uses_blit)
+{
+ GLbitfield transferOps = ctx->_ImageTransferState;
+
+ if (format == GL_DEPTH_COMPONENT ||
+ format == GL_DEPTH_STENCIL ||
+ format == GL_STENCIL_INDEX) {
+ return 0;
+ }
+
+ /* Pixel transfer ops (scale, bias, table lookup) do not apply
+ * to integer formats.
+ */
+ if (_mesa_is_enum_format_integer(format)) {
+ return 0;
+ }
+
+ if (uses_blit) {
+ /* For blit-based ReadPixels packing, the clamping is done automatically
+ * unless the type is float. */
+ if (ctx->Color._ClampReadColor == GL_TRUE &&
+ (type == GL_FLOAT || type == GL_HALF_FLOAT)) {
+ transferOps |= IMAGE_CLAMP_BIT;
+ }
+ }
+ else {
+ /* For CPU-based ReadPixels packing, the clamping must always be done
+ * for non-float types, */
+ if (ctx->Color._ClampReadColor == GL_TRUE ||
+ (type != GL_FLOAT && type != GL_HALF_FLOAT)) {
+ transferOps |= IMAGE_CLAMP_BIT;
+ }
+ }
+
+ /* If the format is unsigned normalized, we can ignore clamping
+ * because the values are already in the range [0,1] so it won't
+ * have any effect anyway.
+ */
+ if (_mesa_get_format_datatype(texFormat) == GL_UNSIGNED_NORMALIZED &&
+ !need_rgb_to_luminance_conversion(texFormat, format)) {
+ transferOps &= ~IMAGE_CLAMP_BIT;
+ }
+
+ return transferOps;
+}
+
+
+/**
+ * Return true if memcpy cannot be used for ReadPixels.
+ *
+ * If uses_blit is true, the function returns true if a simple 3D engine blit
+ * cannot be used for ReadPixels packing.
+ *
+ * NOTE: This doesn't take swizzling and format conversions between
+ * the readbuffer and the pixel pack buffer into account.
+ */
+GLboolean
+_mesa_readpixels_needs_slow_path(const struct gl_context *ctx, GLenum format,
+ GLenum type, GLboolean uses_blit)
+{
+ struct gl_renderbuffer *rb =
+ _mesa_get_read_renderbuffer_for_format(ctx, format);
+ GLenum srcType;
+
+ ASSERT(rb);
+
+ /* There are different rules depending on the base format. */
+ switch (format) {
+ case GL_DEPTH_STENCIL:
+ return !_mesa_has_depthstencil_combined(ctx->ReadBuffer) ||
+ ctx->Pixel.DepthScale != 1.0f || ctx->Pixel.DepthBias != 0.0f ||
+ ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset ||
+ ctx->Pixel.MapStencilFlag;
+
+ case GL_DEPTH_COMPONENT:
+ return ctx->Pixel.DepthScale != 1.0f || ctx->Pixel.DepthBias != 0.0f;
+
+ case GL_STENCIL_INDEX:
+ return ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset ||
+ ctx->Pixel.MapStencilFlag;
+
+ default:
+ /* Color formats. */
+ if (need_rgb_to_luminance_conversion(rb->Format, format)) {
+ return GL_TRUE;
+ }
+
+ /* Conversion between signed and unsigned integers needs masking
+ * (it isn't just memcpy). */
+ srcType = _mesa_get_format_datatype(rb->Format);
+
+ if ((srcType == GL_INT &&
+ (type == GL_UNSIGNED_INT ||
+ type == GL_UNSIGNED_SHORT ||
+ type == GL_UNSIGNED_BYTE)) ||
+ (srcType == GL_UNSIGNED_INT &&
+ (type == GL_INT ||
+ type == GL_SHORT ||
+ type == GL_BYTE))) {
+ return GL_TRUE;
+ }
+
+ /* And finally, see if there are any transfer ops. */
+ return get_readpixels_transfer_ops(ctx, rb->Format, format, type,
+ uses_blit) != 0;
+ }
+ return GL_FALSE;
+}
+
+
+static GLboolean
+readpixels_can_use_memcpy(const struct gl_context *ctx, GLenum format, GLenum type,
+ const struct gl_pixelstore_attrib *packing)
+{
+ struct gl_renderbuffer *rb =
+ _mesa_get_read_renderbuffer_for_format(ctx, format);
+
+ ASSERT(rb);
+
+ if (_mesa_readpixels_needs_slow_path(ctx, format, type, GL_FALSE)) {
+ return GL_FALSE;
+ }
+
+ /* The base internal format and the base Mesa format must match. */
+ if (rb->_BaseFormat != _mesa_get_format_base_format(rb->Format)) {
+ return GL_FALSE;
+ }
+
+ /* The Mesa format must match the input format and type. */
+ if (!_mesa_format_matches_format_and_type(rb->Format, format, type,
+ packing->SwapBytes)) {
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+
+static GLboolean
+readpixels_memcpy(struct gl_context *ctx,
+ GLint x, GLint y,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing)
+{
+ struct gl_renderbuffer *rb =
+ _mesa_get_read_renderbuffer_for_format(ctx, format);
+ GLubyte *dst, *map;
+ int dstStride, stride, j, texelBytes;
+
+ /* Fail if memcpy cannot be used. */
+ if (!readpixels_can_use_memcpy(ctx, format, type, packing)) {
+ return GL_FALSE;
+ }
+
+ dstStride = _mesa_image_row_stride(packing, width, format, type);
+ dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
+ format, type, 0, 0);
+
+ ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
+ &map, &stride);
+ if (!map) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
+ return GL_TRUE; /* don't bother trying the slow path */
+ }
+
+ texelBytes = _mesa_get_format_bytes(rb->Format);
+
+ /* memcpy*/
+ for (j = 0; j < height; j++) {
+ memcpy(dst, map, width * texelBytes);
+ dst += dstStride;
+ map += stride;
+ }
+
+ ctx->Driver.UnmapRenderbuffer(ctx, rb);
+ return GL_TRUE;
+}
+
+
+/**
+ * Optimized path for conversion of depth values to GL_DEPTH_COMPONENT,
+ * GL_UNSIGNED_INT.
+ */
+static GLboolean
+read_uint_depth_pixels( struct gl_context *ctx,
GLint x, GLint y,
GLsizei width, GLsizei height,
GLenum type, GLvoid *pixels,
@@ -65,10 +266,6 @@ fast_read_depth_pixels( struct gl_context *ctx,
if (_mesa_get_format_datatype(rb->Format) != GL_UNSIGNED_NORMALIZED)
return GL_FALSE;
- if (!((type == GL_UNSIGNED_SHORT && rb->Format == MESA_FORMAT_Z16) ||
- type == GL_UNSIGNED_INT))
- return GL_FALSE;
-
ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
&map, &stride);
@@ -82,12 +279,7 @@ fast_read_depth_pixels( struct gl_context *ctx,
GL_DEPTH_COMPONENT, type, 0, 0);
for (j = 0; j < height; j++) {
- if (type == GL_UNSIGNED_INT) {
- _mesa_unpack_uint_z_row(rb->Format, width, map, (GLuint *)dst);
- } else {
- ASSERT(type == GL_UNSIGNED_SHORT && rb->Format == MESA_FORMAT_Z16);
- memcpy(dst, map, width * 2);
- }
+ _mesa_unpack_uint_z_row(rb->Format, width, map, (GLuint *)dst);
map += stride;
dst += dstStride;
@@ -123,8 +315,10 @@ read_depth_pixels( struct gl_context *ctx,
ASSERT(x + width <= (GLint) rb->Width);
ASSERT(y + height <= (GLint) rb->Height);
- if (fast_read_depth_pixels(ctx, x, y, width, height, type, pixels, packing))
+ if (type == GL_UNSIGNED_INT &&
+ read_uint_depth_pixels(ctx, x, y, width, height, type, pixels, packing)) {
return;
+ }
dstStride = _mesa_image_row_stride(packing, width, GL_DEPTH_COMPONENT, type);
dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
@@ -212,21 +406,20 @@ read_stencil_pixels( struct gl_context *ctx,
/**
- * Try to do glReadPixels of RGBA data using a simple memcpy or swizzle.
+ * Try to do glReadPixels of RGBA data using swizzle.
* \return GL_TRUE if successful, GL_FALSE otherwise (use the slow path)
*/
static GLboolean
-fast_read_rgba_pixels_memcpy( struct gl_context *ctx,
- GLint x, GLint y,
- GLsizei width, GLsizei height,
- GLenum format, GLenum type,
- GLvoid *pixels,
- const struct gl_pixelstore_attrib *packing,
- GLbitfield transferOps )
+read_rgba_pixels_swizzle(struct gl_context *ctx,
+ GLint x, GLint y,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing)
{
struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
GLubyte *dst, *map;
- int dstStride, stride, j, texelBytes;
+ int dstStride, stride, j;
GLboolean swizzle_rb = GL_FALSE, copy_xrgb = GL_FALSE;
/* XXX we could check for other swizzle/special cases here as needed */
@@ -242,19 +435,9 @@ fast_read_rgba_pixels_memcpy( struct gl_context *ctx,
!ctx->Pack.SwapBytes) {
copy_xrgb = GL_TRUE;
}
- else if (!_mesa_format_matches_format_and_type(rb->Format, format, type,
- ctx->Pack.SwapBytes))
- return GL_FALSE;
-
- /* If the format is unsigned normalized then we can ignore clamping
- * because the values are already in the range [0,1] so it won't
- * have any effect anyway.
- */
- if (_mesa_get_format_datatype(rb->Format) == GL_UNSIGNED_NORMALIZED)
- transferOps &= ~IMAGE_CLAMP_BIT;
-
- if (transferOps)
+ else {
return GL_FALSE;
+ }
dstStride = _mesa_image_row_stride(packing, width, format, type);
dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
@@ -267,8 +450,6 @@ fast_read_rgba_pixels_memcpy( struct gl_context *ctx,
return GL_TRUE; /* don't bother trying the slow path */
}
- texelBytes = _mesa_get_format_bytes(rb->Format);
-
if (swizzle_rb) {
/* swap R/B */
for (j = 0; j < height; j++) {
@@ -294,13 +475,6 @@ fast_read_rgba_pixels_memcpy( struct gl_context *ctx,
dst += dstStride;
map += stride;
}
- } else {
- /* just memcpy */
- for (j = 0; j < height; j++) {
- memcpy(dst, map, width * texelBytes);
- dst += dstStride;
- map += stride;
- }
}
ctx->Driver.UnmapRenderbuffer(ctx, rb);
@@ -379,22 +553,20 @@ read_rgba_pixels( struct gl_context *ctx,
GLenum format, GLenum type, GLvoid *pixels,
const struct gl_pixelstore_attrib *packing )
{
- GLbitfield transferOps = ctx->_ImageTransferState;
+ GLbitfield transferOps;
struct gl_framebuffer *fb = ctx->ReadBuffer;
struct gl_renderbuffer *rb = fb->_ColorReadBuffer;
if (!rb)
return;
- if ((ctx->Color._ClampReadColor == GL_TRUE || type != GL_FLOAT) &&
- !_mesa_is_enum_format_integer(format)) {
- transferOps |= IMAGE_CLAMP_BIT;
- }
+ transferOps = get_readpixels_transfer_ops(ctx, rb->Format, format, type,
+ GL_FALSE);
/* Try the optimized paths first. */
- if (fast_read_rgba_pixels_memcpy(ctx, x, y, width, height,
- format, type, pixels, packing,
- transferOps)) {
+ if (!transferOps &&
+ read_rgba_pixels_swizzle(ctx, x, y, width, height,
+ format, type, pixels, packing)) {
return;
}
@@ -649,6 +821,14 @@ _mesa_readpixels(struct gl_context *ctx,
pixels = _mesa_map_pbo_dest(ctx, &clippedPacking, pixels);
if (pixels) {
+ /* Try memcpy first. */
+ if (readpixels_memcpy(ctx, x, y, width, height, format, type,
+ pixels, packing)) {
+ _mesa_unmap_pbo_dest(ctx, &clippedPacking);
+ return;
+ }
+
+ /* Otherwise take the slow path. */
switch (format) {
case GL_STENCIL_INDEX:
read_stencil_pixels(ctx, x, y, width, height, type, pixels,
diff --git a/mesalib/src/mesa/main/readpix.h b/mesalib/src/mesa/main/readpix.h
index 5a5f73f52..7491c22ff 100644
--- a/mesalib/src/mesa/main/readpix.h
+++ b/mesalib/src/mesa/main/readpix.h
@@ -33,6 +33,10 @@ struct gl_context;
struct gl_pixelstore_attrib;
+extern GLboolean
+_mesa_readpixels_needs_slow_path(const struct gl_context *ctx, GLenum format,
+ GLenum type, GLboolean uses_blit);
+
extern void
_mesa_readpixels(struct gl_context *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
diff --git a/mesalib/src/mesa/main/texgetimage.c b/mesalib/src/mesa/main/texgetimage.c
index 7299a4b23..74b09ef2c 100644
--- a/mesalib/src/mesa/main/texgetimage.c
+++ b/mesalib/src/mesa/main/texgetimage.c
@@ -518,6 +518,7 @@ get_tex_rgba(struct gl_context *ctx, GLuint dimensions,
if (type_needs_clamping(type)) {
/* the returned image type can't have negative values */
if (dataType == GL_FLOAT ||
+ dataType == GL_HALF_FLOAT ||
dataType == GL_SIGNED_NORMALIZED ||
format == GL_LUMINANCE ||
format == GL_LUMINANCE_ALPHA) {
diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c
index 4042e7969..bc755ae79 100644
--- a/mesalib/src/mesa/main/teximage.c
+++ b/mesalib/src/mesa/main/teximage.c
@@ -40,6 +40,7 @@
#include "imports.h"
#include "macros.h"
#include "mfeatures.h"
+#include "multisample.h"
#include "state.h"
#include "texcompress.h"
#include "texcompress_cpal.h"
@@ -4199,6 +4200,7 @@ teximagemultisample(GLuint dims, GLenum target, GLsizei samples,
struct gl_texture_image *texImage;
GLboolean sizeOK, dimensionsOK;
gl_format texFormat;
+ GLenum sample_count_error;
GET_CURRENT_CONTEXT(ctx);
@@ -4225,35 +4227,13 @@ teximagemultisample(GLuint dims, GLenum target, GLsizei samples,
return;
}
- if (_mesa_is_enum_format_integer(internalformat)) {
- if (samples > ctx->Const.MaxIntegerSamples) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glTexImage%uDMultisample(samples>GL_MAX_INTEGER_SAMPLES)",
- dims);
- return;
- }
- }
- else if (_mesa_is_depth_or_stencil_format(internalformat)) {
- if (samples > ctx->Const.MaxDepthTextureSamples) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glTexImage%uDMultisample(samples>GL_MAX_DEPTH_TEXTURE_SAMPLES)",
- dims);
- return;
- }
- }
- else {
- if (samples > ctx->Const.MaxColorTextureSamples) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glTexImage%uDMultisample(samples>GL_MAX_COLOR_TEXTURE_SAMPLES)",
- dims);
- return;
- }
+ sample_count_error = _mesa_check_sample_count(ctx, target,
+ internalformat, samples);
+ if (sample_count_error != GL_NO_ERROR) {
+ _mesa_error(ctx, sample_count_error, "glTexImage%uDMultisample(samples)", dims);
+ return;
}
- /* TODO: should ask the driver for the exact limit for this internalformat
- * once IDR's internalformat_query bits land
- */
-
texObj = _mesa_get_current_tex_object(ctx, target);
texImage = _mesa_get_tex_image(ctx, texObj, 0, 0);
diff --git a/mesalib/src/mesa/main/texparam.c b/mesalib/src/mesa/main/texparam.c
index 120845b4a..bd2f75170 100644
--- a/mesalib/src/mesa/main/texparam.c
+++ b/mesalib/src/mesa/main/texparam.c
@@ -1460,6 +1460,12 @@ _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
*params = (GLfloat) obj->Immutable;
break;
+ case GL_TEXTURE_IMMUTABLE_LEVELS:
+ if (!_mesa_is_gles3(ctx))
+ goto invalid_pname;
+ *params = (GLfloat) obj->ImmutableLevels;
+ break;
+
case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
if (!_mesa_is_gles(ctx) || !ctx->Extensions.OES_EGL_image_external)
goto invalid_pname;
@@ -1637,6 +1643,12 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
*params = (GLint) obj->Immutable;
break;
+ case GL_TEXTURE_IMMUTABLE_LEVELS:
+ if (!_mesa_is_gles3(ctx))
+ goto invalid_pname;
+ *params = obj->ImmutableLevels;
+ break;
+
case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
if (!_mesa_is_gles(ctx) || !ctx->Extensions.OES_EGL_image_external)
goto invalid_pname;
diff --git a/mesalib/src/mesa/main/texstorage.c b/mesalib/src/mesa/main/texstorage.c
index 00f19bae5..675fd745b 100644
--- a/mesalib/src/mesa/main/texstorage.c
+++ b/mesalib/src/mesa/main/texstorage.c
@@ -397,6 +397,7 @@ texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat,
}
texObj->Immutable = GL_TRUE;
+ texObj->ImmutableLevels = levels;
}
}
diff --git a/mesalib/src/mesa/state_tracker/st_cb_blit.c b/mesalib/src/mesa/state_tracker/st_cb_blit.c
index c463e3b04..50cab4294 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_blit.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_blit.c
@@ -239,31 +239,22 @@ st_BlitFramebuffer(struct gl_context *ctx,
/* depth and/or stencil blit */
/* get src/dst depth surfaces */
- struct gl_renderbuffer_attachment *srcDepth =
- &readFB->Attachment[BUFFER_DEPTH];
- struct gl_renderbuffer_attachment *dstDepth =
- &drawFB->Attachment[BUFFER_DEPTH];
- struct gl_renderbuffer_attachment *srcStencil =
- &readFB->Attachment[BUFFER_STENCIL];
- struct gl_renderbuffer_attachment *dstStencil =
- &drawFB->Attachment[BUFFER_STENCIL];
-
struct st_renderbuffer *srcDepthRb =
- st_renderbuffer(srcDepth->Renderbuffer);
+ st_renderbuffer(readFB->Attachment[BUFFER_DEPTH].Renderbuffer);
struct st_renderbuffer *dstDepthRb =
- st_renderbuffer(dstDepth->Renderbuffer);
+ st_renderbuffer(drawFB->Attachment[BUFFER_DEPTH].Renderbuffer);
struct pipe_surface *dstDepthSurf =
dstDepthRb ? dstDepthRb->surface : NULL;
struct st_renderbuffer *srcStencilRb =
- st_renderbuffer(srcStencil->Renderbuffer);
+ st_renderbuffer(readFB->Attachment[BUFFER_STENCIL].Renderbuffer);
struct st_renderbuffer *dstStencilRb =
- st_renderbuffer(dstStencil->Renderbuffer);
+ st_renderbuffer(drawFB->Attachment[BUFFER_STENCIL].Renderbuffer);
struct pipe_surface *dstStencilSurf =
dstStencilRb ? dstStencilRb->surface : NULL;
- if (st_is_depth_stencil_combined(srcDepth, srcStencil) &&
- st_is_depth_stencil_combined(dstDepth, dstStencil)) {
+ if (_mesa_has_depthstencil_combined(readFB) &&
+ _mesa_has_depthstencil_combined(drawFB)) {
blit.mask = 0;
if (mask & GL_DEPTH_BUFFER_BIT)
blit.mask |= PIPE_MASK_Z;
diff --git a/mesalib/src/mesa/state_tracker/st_cb_fbo.c b/mesalib/src/mesa/state_tracker/st_cb_fbo.c
index 87c5b048c..4452e523b 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_fbo.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_fbo.c
@@ -547,30 +547,6 @@ st_validate_attachment(struct gl_context *ctx,
return valid;
}
-
-
-/**
- * Check if two renderbuffer attachments name a combined depth/stencil
- * renderbuffer.
- */
-GLboolean
-st_is_depth_stencil_combined(const struct gl_renderbuffer_attachment *depth,
- const struct gl_renderbuffer_attachment *stencil)
-{
- assert(depth && stencil);
-
- if (depth->Type == stencil->Type) {
- if (depth->Type == GL_RENDERBUFFER_EXT &&
- depth->Renderbuffer == stencil->Renderbuffer)
- return GL_TRUE;
-
- if (depth->Type == GL_TEXTURE &&
- depth->Texture == stencil->Texture)
- return GL_TRUE;
- }
-
- return GL_FALSE;
-}
/**
diff --git a/mesalib/src/mesa/state_tracker/st_cb_fbo.h b/mesalib/src/mesa/state_tracker/st_cb_fbo.h
index 506fd06d6..461dbe985 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_fbo.h
+++ b/mesalib/src/mesa/state_tracker/st_cb_fbo.h
@@ -76,9 +76,4 @@ st_new_renderbuffer_fb(enum pipe_format format, int samples, boolean sw);
extern void
st_init_fbo_functions(struct dd_function_table *functions);
-extern GLboolean
-st_is_depth_stencil_combined(const struct gl_renderbuffer_attachment *depth,
- const struct gl_renderbuffer_attachment *stencil);
-
-
#endif /* ST_CB_FBO_H */
diff --git a/mesalib/src/mesa/state_tracker/st_cb_readpixels.c b/mesalib/src/mesa/state_tracker/st_cb_readpixels.c
index 6b824b161..bfed98870 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_readpixels.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_readpixels.c
@@ -25,35 +25,209 @@
*
**************************************************************************/
-
+#include "main/image.h"
+#include "main/pbo.h"
#include "main/imports.h"
#include "main/readpix.h"
+#include "main/enums.h"
+#include "main/framebuffer.h"
+#include "util/u_inlines.h"
+#include "util/u_format.h"
+#include "st_cb_fbo.h"
#include "st_atom.h"
#include "st_context.h"
#include "st_cb_bitmap.h"
#include "st_cb_readpixels.h"
+#include "state_tracker/st_cb_texture.h"
+#include "state_tracker/st_format.h"
+#include "state_tracker/st_texture.h"
/**
- * The only special thing we need to do for the state tracker's
- * glReadPixels is to validate state (to be sure we have up-to-date
- * framebuffer surfaces) and flush the bitmap cache prior to reading.
+ * This uses a blit to copy the read buffer to a texture format which matches
+ * the format and type combo and then a fast read-back is done using memcpy.
+ * We can do arbitrary X/Y/Z/W/0/1 swizzling here as long as there is
+ * a format which matches the swizzling.
+ *
+ * If such a format isn't available, we fall back to _mesa_readpixels.
+ *
+ * NOTE: Some drivers use a blit to convert between tiled and linear
+ * texture layouts during texture uploads/downloads, so the blit
+ * we do here should be free in such cases.
*/
static void
st_readpixels(struct gl_context *ctx, GLint x, GLint y,
GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *pack,
- GLvoid *dest)
+ GLvoid *pixels)
{
struct st_context *st = st_context(ctx);
+ struct gl_renderbuffer *rb =
+ _mesa_get_read_renderbuffer_for_format(ctx, format);
+ struct st_renderbuffer *strb = st_renderbuffer(rb);
+ struct pipe_context *pipe = st->pipe;
+ struct pipe_screen *screen = pipe->screen;
+ struct pipe_resource *src;
+ struct pipe_resource *dst = NULL;
+ struct pipe_resource dst_templ;
+ enum pipe_format dst_format, src_format;
+ struct pipe_blit_info blit;
+ unsigned bind = PIPE_BIND_TRANSFER_READ;
+ struct pipe_transfer *tex_xfer;
+ ubyte *map = NULL;
+ /* Validate state (to be sure we have up-to-date framebuffer surfaces)
+ * and flush the bitmap cache prior to reading. */
st_validate_state(st);
st_flush_bitmap_cache(st);
- _mesa_readpixels(ctx, x, y, width, height, format, type, pack, dest);
-}
+ if (!st->prefer_blit_based_texture_transfer) {
+ goto fallback;
+ }
+
+ /* This must be done after state validation. */
+ src = strb->texture;
+
+ /* XXX Fallback for depth-stencil formats due to an incomplete
+ * stencil blit implementation in some drivers. */
+ if (format == GL_DEPTH_STENCIL) {
+ goto fallback;
+ }
+
+ /* We are creating a texture of the size of the region being read back.
+ * Need to check for NPOT texture support. */
+ if (!screen->get_param(screen, PIPE_CAP_NPOT_TEXTURES) &&
+ (!util_is_power_of_two(width) ||
+ !util_is_power_of_two(height))) {
+ goto fallback;
+ }
+
+ /* If the base internal format and the texture format don't match, we have
+ * to use the slow path. */
+ if (rb->_BaseFormat !=
+ _mesa_get_format_base_format(rb->Format)) {
+ goto fallback;
+ }
+
+ /* See if the texture format already matches the format and type,
+ * in which case the memcpy-based fast path will likely be used and
+ * we don't have to blit. */
+ if (_mesa_format_matches_format_and_type(rb->Format, format,
+ type, pack->SwapBytes)) {
+ goto fallback;
+ }
+
+ if (_mesa_readpixels_needs_slow_path(ctx, format, type, GL_TRUE)) {
+ goto fallback;
+ }
+
+ /* Convert the source format to what is expected by ReadPixels
+ * and see if it's supported. */
+ src_format = util_format_linear(src->format);
+ src_format = util_format_luminance_to_red(src_format);
+ src_format = util_format_intensity_to_red(src_format);
+
+ if (!src_format ||
+ !screen->is_format_supported(screen, src_format, src->target,
+ src->nr_samples,
+ PIPE_BIND_SAMPLER_VIEW)) {
+ printf("fallback: src format unsupported %s\n", util_format_short_name(src_format));
+ goto fallback;
+ }
+
+ if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL)
+ bind |= PIPE_BIND_DEPTH_STENCIL;
+ else
+ bind |= PIPE_BIND_RENDER_TARGET;
+
+ /* Choose the destination format by finding the best match
+ * for the format+type combo. */
+ dst_format = st_choose_matching_format(screen, bind, format, type,
+ pack->SwapBytes);
+ if (dst_format == PIPE_FORMAT_NONE) {
+ printf("fallback: no matching format for %s, %s\n",
+ _mesa_lookup_enum_by_nr(format), _mesa_lookup_enum_by_nr(type));
+ goto fallback;
+ }
+
+ /* create the destination texture */
+ memset(&dst_templ, 0, sizeof(dst_templ));
+ dst_templ.target = PIPE_TEXTURE_2D;
+ dst_templ.format = dst_format;
+ dst_templ.bind = bind;
+ dst_templ.usage = PIPE_USAGE_STAGING;
+
+ st_gl_texture_dims_to_pipe_dims(GL_TEXTURE_2D, width, height, 1,
+ &dst_templ.width0, &dst_templ.height0,
+ &dst_templ.depth0, &dst_templ.array_size);
+
+ dst = screen->resource_create(screen, &dst_templ);
+ if (!dst) {
+ goto fallback;
+ }
+
+ blit.src.resource = src;
+ blit.src.level = strb->rtt_level;
+ blit.src.format = src_format;
+ blit.dst.resource = dst;
+ blit.dst.level = 0;
+ blit.dst.format = dst->format;
+ blit.src.box.x = x;
+ blit.dst.box.x = 0;
+ blit.src.box.y = y;
+ blit.dst.box.y = 0;
+ blit.src.box.z = strb->rtt_face + strb->rtt_slice;
+ blit.dst.box.z = 0;
+ blit.src.box.width = blit.dst.box.width = width;
+ blit.src.box.height = blit.dst.box.height = height;
+ blit.src.box.depth = blit.dst.box.depth = 1;
+ blit.mask = st_get_blit_mask(rb->_BaseFormat, format);
+ blit.filter = PIPE_TEX_FILTER_NEAREST;
+ blit.scissor_enable = FALSE;
+
+ if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
+ blit.src.box.y = rb->Height - blit.src.box.y;
+ blit.src.box.height = -blit.src.box.height;
+ }
+
+ /* blit */
+ st->pipe->blit(st->pipe, &blit);
+
+ /* map resources */
+ pixels = _mesa_map_pbo_dest(ctx, pack, pixels);
+
+ map = pipe_transfer_map_3d(pipe, dst, 0, PIPE_TRANSFER_READ,
+ 0, 0, 0, width, height, 1, &tex_xfer);
+ if (!map) {
+ _mesa_unmap_pbo_dest(ctx, pack);
+ pipe_resource_reference(&dst, NULL);
+ goto fallback;
+ }
+
+ /* memcpy data into a user buffer */
+ {
+ const uint bytesPerRow = width * util_format_get_blocksize(dst_format);
+ GLuint row;
+
+ for (row = 0; row < height; row++) {
+ GLvoid *dest = _mesa_image_address3d(pack, pixels,
+ width, height, format,
+ type, 0, row, 0);
+ memcpy(dest, map, bytesPerRow);
+ map += tex_xfer->stride;
+ }
+ }
+
+ pipe_transfer_unmap(pipe, tex_xfer);
+ _mesa_unmap_pbo_dest(ctx, pack);
+ pipe_resource_reference(&dst, NULL);
+ return;
+
+fallback:
+ _mesa_readpixels(ctx, x, y, width, height, format, type, pack, pixels);
+}
void st_init_readpixels_functions(struct dd_function_table *functions)
{
diff --git a/mesalib/src/mesa/state_tracker/st_cb_texture.c b/mesalib/src/mesa/state_tracker/st_cb_texture.c
index c922a3164..94fbbf7be 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_texture.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_texture.c
@@ -68,7 +68,7 @@
#define DBG if (0) printf
-static enum pipe_texture_target
+enum pipe_texture_target
gl_target_to_pipe(GLenum target)
{
switch (target) {
@@ -542,8 +542,8 @@ prep_teximage(struct gl_context *ctx, struct gl_texture_image *texImage,
* Return a writemask for the gallium blit. The parameters can be base
* formats or "format" from glDrawPixels/glTexImage/glGetTexImage.
*/
-static unsigned
-get_blit_mask(GLenum srcFormat, GLenum dstFormat)
+unsigned
+st_get_blit_mask(GLenum srcFormat, GLenum dstFormat)
{
switch (dstFormat) {
case GL_DEPTH_STENCIL:
@@ -608,6 +608,10 @@ st_TexSubImage(struct gl_context *ctx, GLuint dims,
unsigned bind;
GLubyte *map;
+ if (!st->prefer_blit_based_texture_transfer) {
+ goto fallback;
+ }
+
if (!dst) {
goto fallback;
}
@@ -769,7 +773,7 @@ st_TexSubImage(struct gl_context *ctx, GLuint dims,
blit.src.box.width = blit.dst.box.width = width;
blit.src.box.height = blit.dst.box.height = height;
blit.src.box.depth = blit.dst.box.depth = depth;
- blit.mask = get_blit_mask(format, texImage->_BaseFormat);
+ blit.mask = st_get_blit_mask(format, texImage->_BaseFormat);
blit.filter = PIPE_TEX_FILTER_NEAREST;
blit.scissor_enable = FALSE;
@@ -860,6 +864,10 @@ st_GetTexImage(struct gl_context * ctx,
ubyte *map = NULL;
boolean done = FALSE;
+ if (!st->prefer_blit_based_texture_transfer) {
+ goto fallback;
+ }
+
if (!stImage->pt) {
goto fallback;
}
@@ -996,7 +1004,7 @@ st_GetTexImage(struct gl_context * ctx,
blit.src.box.width = blit.dst.box.width = width;
blit.src.box.height = blit.dst.box.height = height;
blit.src.box.depth = blit.dst.box.depth = depth;
- blit.mask = get_blit_mask(texImage->_BaseFormat, format);
+ blit.mask = st_get_blit_mask(texImage->_BaseFormat, format);
blit.filter = PIPE_TEX_FILTER_NEAREST;
blit.scissor_enable = FALSE;
@@ -1370,7 +1378,7 @@ st_CopyTexSubImage(struct gl_context *ctx, GLuint dims,
blit.dst.box.width = width;
blit.dst.box.height = height;
blit.dst.box.depth = 1;
- blit.mask = get_blit_mask(rb->_BaseFormat, texImage->_BaseFormat);
+ blit.mask = st_get_blit_mask(rb->_BaseFormat, texImage->_BaseFormat);
blit.filter = PIPE_TEX_FILTER_NEAREST;
/* 1D array textures need special treatment.
diff --git a/mesalib/src/mesa/state_tracker/st_cb_texture.h b/mesalib/src/mesa/state_tracker/st_cb_texture.h
index 27956bcc2..7f70d0b25 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_texture.h
+++ b/mesalib/src/mesa/state_tracker/st_cb_texture.h
@@ -38,6 +38,12 @@ struct gl_texture_object;
struct pipe_context;
struct st_context;
+extern enum pipe_texture_target
+gl_target_to_pipe(GLenum target);
+
+unsigned
+st_get_blit_mask(GLenum srcFormat, GLenum dstFormat);
+
extern GLboolean
st_finalize_texture(struct gl_context *ctx,
struct pipe_context *pipe,
diff --git a/mesalib/src/mesa/state_tracker/st_context.c b/mesalib/src/mesa/state_tracker/st_context.c
index f9a584ba0..cc87f2bb3 100644
--- a/mesalib/src/mesa/state_tracker/st_context.c
+++ b/mesalib/src/mesa/state_tracker/st_context.c
@@ -182,6 +182,11 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe,
st->has_stencil_export =
screen->get_param(screen, PIPE_CAP_SHADER_STENCIL_EXPORT);
st->has_shader_model3 = screen->get_param(screen, PIPE_CAP_SM3);
+ st->prefer_blit_based_texture_transfer = screen->get_param(screen,
+ PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER);
+
+ st->needs_texcoord_semantic =
+ screen->get_param(screen, PIPE_CAP_TGSI_TEXCOORD);
/* GL limits and extensions */
st_init_limits(st);
diff --git a/mesalib/src/mesa/state_tracker/st_context.h b/mesalib/src/mesa/state_tracker/st_context.h
index b9a98cd05..8786a036f 100644
--- a/mesalib/src/mesa/state_tracker/st_context.h
+++ b/mesalib/src/mesa/state_tracker/st_context.h
@@ -84,6 +84,9 @@ struct st_context
boolean has_stencil_export; /**< can do shader stencil export? */
boolean has_time_elapsed;
boolean has_shader_model3;
+ boolean prefer_blit_based_texture_transfer;
+
+ boolean needs_texcoord_semantic;
/* On old libGL's for linux we need to invalidate the drawables
* on glViewpport calls, this is set via a option.
diff --git a/mesalib/src/mesa/state_tracker/st_format.c b/mesalib/src/mesa/state_tracker/st_format.c
index 5fd44e76d..a15706a03 100644
--- a/mesalib/src/mesa/state_tracker/st_format.c
+++ b/mesalib/src/mesa/state_tracker/st_format.c
@@ -1769,13 +1769,15 @@ st_ChooseTextureFormat(struct gl_context *ctx, GLenum target,
* Called via ctx->Driver.ChooseTextureFormat().
*/
size_t
-st_QuerySamplesForFormat(struct gl_context *ctx, GLenum internalFormat,
- int samples[16])
+st_QuerySamplesForFormat(struct gl_context *ctx, GLenum target,
+ GLenum internalFormat, int samples[16])
{
struct st_context *st = st_context(ctx);
enum pipe_format format;
unsigned i, bind, num_sample_counts = 0;
+ (void) target;
+
if (_mesa_is_depth_or_stencil_format(internalFormat))
bind = PIPE_BIND_DEPTH_STENCIL;
else
diff --git a/mesalib/src/mesa/state_tracker/st_format.h b/mesalib/src/mesa/state_tracker/st_format.h
index 3db409b74..0a1c18d92 100644
--- a/mesalib/src/mesa/state_tracker/st_format.h
+++ b/mesalib/src/mesa/state_tracker/st_format.h
@@ -67,8 +67,8 @@ st_ChooseTextureFormat(struct gl_context * ctx, GLenum target,
GLenum format, GLenum type);
size_t
-st_QuerySamplesForFormat(struct gl_context *ctx, GLenum internalFormat,
- int samples[16]);
+st_QuerySamplesForFormat(struct gl_context *ctx, GLenum target,
+ GLenum internalFormat, int samples[16]);
/* can we use a sampler view to translate these formats
only used to make TFP so far */
diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index 0cef092d3..e3718eeda 100644
--- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -85,6 +85,11 @@ extern "C" {
*/
#define MAX_TEMPS 4096
+/**
+ * Maximum number of arrays
+ */
+#define MAX_ARRAYS 256
+
/* will be 4 for GLSL 4.00 */
#define MAX_GLSL_TEXTURE_OFFSET 1
@@ -315,9 +320,11 @@ public:
int next_temp;
+ unsigned array_sizes[MAX_ARRAYS];
+ unsigned next_array;
+
int num_address_regs;
int samplers_used;
- bool indirect_addr_temps;
bool indirect_addr_consts;
int glsl_version;
@@ -549,9 +556,6 @@ glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op,
/* Update indirect addressing status used by TGSI */
if (dst.reladdr) {
switch(dst.file) {
- case PROGRAM_TEMPORARY:
- this->indirect_addr_temps = true;
- break;
case PROGRAM_LOCAL_PARAM:
case PROGRAM_ENV_PARAM:
case PROGRAM_STATE_VAR:
@@ -570,9 +574,6 @@ glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op,
for (i=0; i<3; i++) {
if(inst->src[i].reladdr) {
switch(inst->src[i].file) {
- case PROGRAM_TEMPORARY:
- this->indirect_addr_temps = true;
- break;
case PROGRAM_LOCAL_PARAM:
case PROGRAM_ENV_PARAM:
case PROGRAM_STATE_VAR:
@@ -1005,17 +1006,26 @@ glsl_to_tgsi_visitor::get_temp(const glsl_type *type)
st_src_reg src;
src.type = native_integers ? type->base_type : GLSL_TYPE_FLOAT;
- src.file = PROGRAM_TEMPORARY;
- src.index = next_temp;
src.reladdr = NULL;
- next_temp += type_size(type);
+ src.negate = 0;
+
+ if (type->is_array() || type->is_matrix()) {
+ src.file = PROGRAM_ARRAY;
+ src.index = next_array << 16 | 0x8000;
+ array_sizes[next_array] = type_size(type);
+ ++next_array;
+
+ } else {
+ src.file = PROGRAM_TEMPORARY;
+ src.index = next_temp;
+ next_temp += type_size(type);
+ }
if (type->is_array() || type->is_record()) {
src.swizzle = SWIZZLE_NOOP;
} else {
src.swizzle = swizzle_for_size(type->vector_elements);
}
- src.negate = 0;
return src;
}
@@ -1078,13 +1088,11 @@ glsl_to_tgsi_visitor::visit(ir_variable *ir)
*/
assert((int) ir->num_state_slots == type_size(ir->type));
- storage = new(mem_ctx) variable_storage(ir, PROGRAM_TEMPORARY,
- this->next_temp);
- this->variables.push_tail(storage);
- this->next_temp += type_size(ir->type);
+ dst = st_dst_reg(get_temp(ir->type));
+
+ storage = new(mem_ctx) variable_storage(ir, dst.file, dst.index);
- dst = st_dst_reg(st_src_reg(PROGRAM_TEMPORARY, storage->index,
- native_integers ? ir->type->base_type : GLSL_TYPE_FLOAT));
+ this->variables.push_tail(storage);
}
@@ -2052,11 +2060,11 @@ glsl_to_tgsi_visitor::visit(ir_dereference_variable *ir)
break;
case ir_var_auto:
case ir_var_temporary:
- entry = new(mem_ctx) variable_storage(var, PROGRAM_TEMPORARY,
- this->next_temp);
+ st_src_reg src = get_temp(var->type);
+
+ entry = new(mem_ctx) variable_storage(var, src.file, src.index);
this->variables.push_tail(entry);
- next_temp += type_size(var->type);
break;
}
@@ -2574,11 +2582,10 @@ glsl_to_tgsi_visitor::get_function_signature(ir_function_signature *sig)
storage = find_variable_storage(param);
assert(!storage);
- storage = new(mem_ctx) variable_storage(param, PROGRAM_TEMPORARY,
- this->next_temp);
- this->variables.push_tail(storage);
+ st_src_reg src = get_temp(param->type);
- this->next_temp += type_size(param->type);
+ storage = new(mem_ctx) variable_storage(param, src.file, src.index);
+ this->variables.push_tail(storage);
}
if (!sig->return_type->is_void()) {
@@ -2978,12 +2985,12 @@ glsl_to_tgsi_visitor::glsl_to_tgsi_visitor()
{
result.file = PROGRAM_UNDEFINED;
next_temp = 1;
+ next_array = 0;
next_signature_id = 1;
num_immediates = 0;
current_function = NULL;
num_address_regs = 0;
samplers_used = 0;
- indirect_addr_temps = false;
indirect_addr_consts = false;
glsl_version = 0;
native_integers = false;
@@ -3183,7 +3190,8 @@ glsl_to_tgsi_visitor::simplify_cmp(void)
assert(inst->dst.index < MAX_TEMPS);
prevWriteMask = tempWrites[inst->dst.index];
tempWrites[inst->dst.index] |= inst->dst.writemask;
- }
+ } else
+ break;
/* For a CMP to be considered a conditional write, the destination
* register and source register two must be the same. */
@@ -3821,7 +3829,6 @@ get_pixel_transfer_visitor(struct st_fragment_program *fp,
v->next_temp = original->next_temp;
v->num_address_regs = original->num_address_regs;
v->samplers_used = prog->SamplersUsed = original->samplers_used;
- v->indirect_addr_temps = original->indirect_addr_temps;
v->indirect_addr_consts = original->indirect_addr_consts;
memcpy(&v->immediates, &original->immediates, sizeof(v->immediates));
v->num_immediates = original->num_immediates;
@@ -3952,7 +3959,6 @@ get_bitmap_visitor(struct st_fragment_program *fp,
v->next_temp = original->next_temp;
v->num_address_regs = original->num_address_regs;
v->samplers_used = prog->SamplersUsed = original->samplers_used;
- v->indirect_addr_temps = original->indirect_addr_temps;
v->indirect_addr_consts = original->indirect_addr_consts;
memcpy(&v->immediates, &original->immediates, sizeof(v->immediates));
v->num_immediates = original->num_immediates;
@@ -4014,6 +4020,7 @@ struct st_translate {
struct ureg_program *ureg;
struct ureg_dst temps[MAX_TEMPS];
+ struct ureg_dst arrays[MAX_ARRAYS];
struct ureg_src *constants;
struct ureg_src *immediates;
struct ureg_dst outputs[PIPE_MAX_SHADER_OUTPUTS];
@@ -4022,6 +4029,8 @@ struct st_translate {
struct ureg_src samplers[PIPE_MAX_SAMPLERS];
struct ureg_src systemValues[SYSTEM_VALUE_MAX];
+ unsigned array_sizes[MAX_ARRAYS];
+
const GLuint *inputMapping;
const GLuint *outputMapping;
@@ -4132,16 +4141,34 @@ dst_register(struct st_translate *t,
gl_register_file file,
GLuint index)
{
+ unsigned array;
+
switch(file) {
case PROGRAM_UNDEFINED:
return ureg_dst_undef();
case PROGRAM_TEMPORARY:
+ assert(index >= 0);
+ assert(index < (int) Elements(t->temps));
+
if (ureg_dst_is_undef(t->temps[index]))
t->temps[index] = ureg_DECL_local_temporary(t->ureg);
return t->temps[index];
+ case PROGRAM_ARRAY:
+ array = index >> 16;
+
+ assert(array >= 0);
+ assert(array < (int) Elements(t->arrays));
+
+ if (ureg_dst_is_undef(t->arrays[array]))
+ t->arrays[array] = ureg_DECL_array_temporary(
+ t->ureg, t->array_sizes[array], TRUE);
+
+ return ureg_dst_array_offset(t->arrays[array],
+ (int)(index & 0xFFFF) - 0x8000);
+
case PROGRAM_OUTPUT:
if (t->procType == TGSI_PROCESSOR_VERTEX)
assert(index < VARYING_SLOT_MAX);
@@ -4176,11 +4203,8 @@ src_register(struct st_translate *t,
return ureg_src_undef();
case PROGRAM_TEMPORARY:
- assert(index >= 0);
- assert(index < (int) Elements(t->temps));
- if (ureg_dst_is_undef(t->temps[index]))
- t->temps[index] = ureg_DECL_local_temporary(t->ureg);
- return ureg_src(t->temps[index]);
+ case PROGRAM_ARRAY:
+ return ureg_src(dst_register(t, file, index));
case PROGRAM_ENV_PARAM:
case PROGRAM_LOCAL_PARAM:
@@ -4262,8 +4286,10 @@ translate_dst(struct st_translate *t,
}
}
- if (dst_reg->reladdr != NULL)
+ if (dst_reg->reladdr != NULL) {
+ assert(dst_reg->file != PROGRAM_TEMPORARY);
dst = ureg_dst_indirect(dst, ureg_src(t->address[0]));
+ }
return dst;
}
@@ -4286,26 +4312,8 @@ translate_src(struct st_translate *t, const st_src_reg *src_reg)
src = ureg_negate(src);
if (src_reg->reladdr != NULL) {
- /* Normally ureg_src_indirect() would be used here, but a stupid compiler
- * bug in g++ makes ureg_src_indirect (an inline C function) erroneously
- * set the bit for src.Negate. So we have to do the operation manually
- * here to work around the compiler's problems. */
- /*src = ureg_src_indirect(src, ureg_src(t->address[0]));*/
- struct ureg_src addr = ureg_src(t->address[0]);
- src.Indirect = 1;
- src.IndirectFile = addr.File;
- src.IndirectIndex = addr.Index;
- src.IndirectSwizzle = addr.SwizzleX;
-
- if (src_reg->file != PROGRAM_INPUT &&
- src_reg->file != PROGRAM_OUTPUT) {
- /* If src_reg->index was negative, it was set to zero in
- * src_register(). Reassign it now. But don't do this
- * for input/output regs since they get remapped while
- * const buffers don't.
- */
- src.Index = src_reg->index;
- }
+ assert(src_reg->file != PROGRAM_TEMPORARY);
+ src = ureg_src_indirect(src, ureg_src(t->address[0]));
}
return src;
@@ -4820,16 +4828,9 @@ st_translate_program(
}
}
- if (program->indirect_addr_temps) {
- /* If temps are accessed with indirect addressing, declare temporaries
- * in sequential order. Else, we declare them on demand elsewhere.
- * (Note: the number of temporaries is equal to program->next_temp)
- */
- for (i = 0; i < (unsigned)program->next_temp; i++) {
- /* XXX use TGSI_FILE_TEMPORARY_ARRAY when it's supported by ureg */
- t->temps[i] = ureg_DECL_local_temporary(t->ureg);
- }
- }
+ /* Copy over array sizes
+ */
+ memcpy(t->array_sizes, program->array_sizes, sizeof(unsigned) * program->next_array);
/* Emit constants and uniforms. TGSI uses a single index space for these,
* so we put all the translated regs in t->constants.
@@ -5064,16 +5065,9 @@ get_mesa_program(struct gl_context *ctx,
v->copy_propagate();
while (v->eliminate_dead_code_advanced());
- /* FIXME: These passes to optimize temporary registers don't work when there
- * is indirect addressing of the temporary register space. We need proper
- * array support so that we don't have to give up these passes in every
- * shader that uses arrays.
- */
- if (!v->indirect_addr_temps) {
- v->eliminate_dead_code();
- v->merge_registers();
- v->renumber_registers();
- }
+ v->eliminate_dead_code();
+ v->merge_registers();
+ v->renumber_registers();
/* Write the END instruction. */
v->emit(NULL, TGSI_OPCODE_END);
diff --git a/mesalib/src/mesa/state_tracker/st_program.c b/mesalib/src/mesa/state_tracker/st_program.c
index 6af8df316..7a38da84f 100644
--- a/mesalib/src/mesa/state_tracker/st_program.c
+++ b/mesalib/src/mesa/state_tracker/st_program.c
@@ -177,6 +177,7 @@ void
st_prepare_vertex_program(struct gl_context *ctx,
struct st_vertex_program *stvp)
{
+ struct st_context *st = st_context(ctx);
GLuint attr;
stvp->num_inputs = 0;
@@ -267,7 +268,8 @@ st_prepare_vertex_program(struct gl_context *ctx,
case VARYING_SLOT_TEX5:
case VARYING_SLOT_TEX6:
case VARYING_SLOT_TEX7:
- stvp->output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
+ stvp->output_semantic_name[slot] = st->needs_texcoord_semantic ?
+ TGSI_SEMANTIC_TEXCOORD : TGSI_SEMANTIC_GENERIC;
stvp->output_semantic_index[slot] = attr - VARYING_SLOT_TEX0;
break;
@@ -275,10 +277,8 @@ st_prepare_vertex_program(struct gl_context *ctx,
default:
assert(attr < VARYING_SLOT_MAX);
stvp->output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
- stvp->output_semantic_index[slot] = (VARYING_SLOT_VAR0 -
- VARYING_SLOT_TEX0 +
- attr -
- VARYING_SLOT_VAR0);
+ stvp->output_semantic_index[slot] = st->needs_texcoord_semantic ?
+ (attr - VARYING_SLOT_VAR0) : (attr - VARYING_SLOT_TEX0);
break;
}
}
@@ -585,11 +585,18 @@ st_translate_fragment_program(struct st_context *st,
* fragment shader plus fixed-function hardware (such as
* BFC).
*
- * There is no requirement that semantic indexes start at
- * zero or be restricted to a particular range -- nobody
- * should be building tables based on semantic index.
+ * However, some drivers may need us to identify the PNTC and TEXi
+ * varyings if, for example, their capability to replace them with
+ * sprite coordinates is limited.
*/
case VARYING_SLOT_PNTC:
+ if (st->needs_texcoord_semantic) {
+ input_semantic_name[slot] = TGSI_SEMANTIC_PCOORD;
+ input_semantic_index[slot] = 0;
+ interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
+ break;
+ }
+ /* fall through */
case VARYING_SLOT_TEX0:
case VARYING_SLOT_TEX1:
case VARYING_SLOT_TEX2:
@@ -598,13 +605,29 @@ st_translate_fragment_program(struct st_context *st,
case VARYING_SLOT_TEX5:
case VARYING_SLOT_TEX6:
case VARYING_SLOT_TEX7:
+ if (st->needs_texcoord_semantic) {
+ input_semantic_name[slot] = TGSI_SEMANTIC_TEXCOORD;
+ input_semantic_index[slot] = attr - VARYING_SLOT_TEX0;
+ interpMode[slot] =
+ st_translate_interp(stfp->Base.InterpQualifier[attr], FALSE);
+ break;
+ }
+ /* fall through */
case VARYING_SLOT_VAR0:
default:
- /* Actually, let's try and zero-base this just for
- * readability of the generated TGSI.
+ /* Semantic indices should be zero-based because drivers may choose
+ * to assign a fixed slot determined by that index.
+ * This is useful because ARB_separate_shader_objects uses location
+ * qualifiers for linkage, and if the semantic index corresponds to
+ * these locations, linkage passes in the driver become unecessary.
+ *
+ * If needs_texcoord_semantic is true, no semantic indices will be
+ * consumed for the TEXi varyings, and we can base the locations of
+ * the user varyings on VAR0. Otherwise, we use TEX0 as base index.
*/
assert(attr >= VARYING_SLOT_TEX0);
- input_semantic_index[slot] = (attr - VARYING_SLOT_TEX0);
+ input_semantic_index[slot] = st->needs_texcoord_semantic ?
+ (attr - VARYING_SLOT_VAR0) : (attr - VARYING_SLOT_TEX0);
input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
if (attr == VARYING_SLOT_PNTC)
interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
diff --git a/pixman/.gitignore b/pixman/.gitignore
index 648699bf2..0f114966c 100644
--- a/pixman/.gitignore
+++ b/pixman/.gitignore
@@ -34,6 +34,7 @@ demos/composite-test
demos/conical-test
demos/convolution-test
demos/gradient-test
+demos/linear-gradient
demos/quad2quad
demos/radial-test
demos/scale
@@ -66,6 +67,7 @@ test/lowlevel-blt-bench
test/oob-test
test/pdf-op-test
test/prng-test
+test/radial-perf-test
test/region-contains-test
test/region-test
test/region-translate
diff --git a/pixman/demos/Makefile.am b/pixman/demos/Makefile.am
index 5f53407b0..9be9ab670 100644
--- a/pixman/demos/Makefile.am
+++ b/pixman/demos/Makefile.am
@@ -15,6 +15,7 @@ DEMOS = \
composite-test \
gradient-test \
radial-test \
+ linear-gradient \
conical-test \
alpha-test \
screen-test \
@@ -38,6 +39,7 @@ trap_test_SOURCES = trap-test.c $(GTK_UTILS)
screen_test_SOURCES = screen-test.c $(GTK_UTILS)
convolution_test_SOURCES = convolution-test.c $(GTK_UTILS)
radial_test_SOURCES = radial-test.c $(GTK_UTILS)
+linear_gradient_SOURCES = linear-gradient.c $(GTK_UTILS)
conical_test_SOURCES = conical-test.c $(GTK_UTILS)
tri_test_SOURCES = tri-test.c $(GTK_UTILS)
checkerboard_SOURCES = checkerboard.c $(GTK_UTILS)
diff --git a/pixman/demos/linear-gradient.c b/pixman/demos/linear-gradient.c
new file mode 100644
index 000000000..46433a6e5
--- /dev/null
+++ b/pixman/demos/linear-gradient.c
@@ -0,0 +1,50 @@
+#include "../test/utils.h"
+#include "gtk-utils.h"
+
+#define WIDTH 1024
+#define HEIGHT 640
+
+int
+main (int argc, char **argv)
+{
+ pixman_image_t *src_img, *dest_img;
+ pixman_gradient_stop_t stops[] = {
+ { 0x00000, { 0x0000, 0x0000, 0x4444, 0xdddd } },
+ { 0x10000, { 0xeeee, 0xeeee, 0x8888, 0xdddd } },
+#if 0
+ /* These colors make it very obvious that dithering
+ * is useful even for 8-bit gradients
+ */
+ { 0x00000, { 0x6666, 0x3333, 0x3333, 0xffff } },
+ { 0x10000, { 0x3333, 0x6666, 0x6666, 0xffff } },
+#endif
+ };
+ pixman_point_fixed_t p1, p2;
+
+ enable_divbyzero_exceptions ();
+
+ dest_img = pixman_image_create_bits (PIXMAN_x8r8g8b8,
+ WIDTH, HEIGHT,
+ NULL, 0);
+
+ p1.x = p1.y = 0x0000;
+ p2.x = WIDTH << 16;
+ p2.y = HEIGHT << 16;
+
+ src_img = pixman_image_create_linear_gradient (&p1, &p2, stops, ARRAY_LENGTH (stops));
+
+ pixman_image_composite32 (PIXMAN_OP_OVER,
+ src_img,
+ NULL,
+ dest_img,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ WIDTH, HEIGHT);
+
+ show_image (dest_img);
+
+ pixman_image_unref (dest_img);
+
+ return 0;
+}
diff --git a/pixman/pixman/pixman-combine-float.c b/pixman/pixman/pixman-combine-float.c
index 06ce2037e..5ea739f76 100644
--- a/pixman/pixman/pixman-combine-float.c
+++ b/pixman/pixman/pixman-combine-float.c
@@ -42,8 +42,6 @@
#define force_inline __inline__
#endif
-#define IS_ZERO(f) (-FLT_MIN < (f) && (f) < FLT_MIN)
-
typedef float (* combine_channel_t) (float sa, float s, float da, float d);
static force_inline void
@@ -203,56 +201,56 @@ get_factor (combine_factor_t factor, float sa, float da)
break;
case SA_OVER_DA:
- if (IS_ZERO (da))
+ if (FLOAT_IS_ZERO (da))
f = 1.0f;
else
f = CLAMP (sa / da);
break;
case DA_OVER_SA:
- if (IS_ZERO (sa))
+ if (FLOAT_IS_ZERO (sa))
f = 1.0f;
else
f = CLAMP (da / sa);
break;
case INV_SA_OVER_DA:
- if (IS_ZERO (da))
+ if (FLOAT_IS_ZERO (da))
f = 1.0f;
else
f = CLAMP ((1.0f - sa) / da);
break;
case INV_DA_OVER_SA:
- if (IS_ZERO (sa))
+ if (FLOAT_IS_ZERO (sa))
f = 1.0f;
else
f = CLAMP ((1.0f - da) / sa);
break;
case ONE_MINUS_SA_OVER_DA:
- if (IS_ZERO (da))
+ if (FLOAT_IS_ZERO (da))
f = 0.0f;
else
f = CLAMP (1.0f - sa / da);
break;
case ONE_MINUS_DA_OVER_SA:
- if (IS_ZERO (sa))
+ if (FLOAT_IS_ZERO (sa))
f = 0.0f;
else
f = CLAMP (1.0f - da / sa);
break;
case ONE_MINUS_INV_DA_OVER_SA:
- if (IS_ZERO (sa))
+ if (FLOAT_IS_ZERO (sa))
f = 0.0f;
else
f = CLAMP (1.0f - (1.0f - da) / sa);
break;
case ONE_MINUS_INV_SA_OVER_DA:
- if (IS_ZERO (da))
+ if (FLOAT_IS_ZERO (da))
f = 0.0f;
else
f = CLAMP (1.0f - (1.0f - sa) / da);
@@ -405,11 +403,11 @@ blend_lighten (float sa, float s, float da, float d)
static force_inline float
blend_color_dodge (float sa, float s, float da, float d)
{
- if (IS_ZERO (d))
+ if (FLOAT_IS_ZERO (d))
return 0.0f;
else if (d * sa >= sa * da - s * da)
return sa * da;
- else if (IS_ZERO (sa - s))
+ else if (FLOAT_IS_ZERO (sa - s))
return sa * da;
else
return sa * sa * d / (sa - s);
@@ -422,7 +420,7 @@ blend_color_burn (float sa, float s, float da, float d)
return sa * da;
else if (sa * (da - d) >= s * da)
return 0.0f;
- else if (IS_ZERO (s))
+ else if (FLOAT_IS_ZERO (s))
return 0.0f;
else
return sa * (da - sa * (da - d) / s);
@@ -442,14 +440,14 @@ blend_soft_light (float sa, float s, float da, float d)
{
if (2 * s < sa)
{
- if (IS_ZERO (da))
+ if (FLOAT_IS_ZERO (da))
return d * sa;
else
return d * sa - d * (da - d) * (sa - 2 * s) / da;
}
else
{
- if (IS_ZERO (da))
+ if (FLOAT_IS_ZERO (da))
{
return 0.0f;
}
@@ -658,7 +656,7 @@ clip_color (rgb_t *color, float a)
if (n < 0.0f)
{
t = l - n;
- if (IS_ZERO (t))
+ if (FLOAT_IS_ZERO (t))
{
color->r = 0.0f;
color->g = 0.0f;
@@ -674,7 +672,7 @@ clip_color (rgb_t *color, float a)
if (x > a)
{
t = x - l;
- if (IS_ZERO (t))
+ if (FLOAT_IS_ZERO (t))
{
color->r = a;
color->g = a;
@@ -758,7 +756,7 @@ set_sat (rgb_t *src, float sat)
t = *max - *min;
- if (IS_ZERO (t))
+ if (FLOAT_IS_ZERO (t))
{
*mid = *max = 0.0f;
}
diff --git a/pixman/pixman/pixman-gradient-walker.c b/pixman/pixman/pixman-gradient-walker.c
index e7e724fa6..5944a559a 100644
--- a/pixman/pixman/pixman-gradient-walker.c
+++ b/pixman/pixman/pixman-gradient-walker.c
@@ -37,11 +37,14 @@ _pixman_gradient_walker_init (pixman_gradient_walker_t *walker,
walker->stops = gradient->stops;
walker->left_x = 0;
walker->right_x = 0x10000;
- walker->stepper = 0;
- walker->left_ag = 0;
- walker->left_rb = 0;
- walker->right_ag = 0;
- walker->right_rb = 0;
+ walker->a_s = 0.0f;
+ walker->a_b = 0.0f;
+ walker->r_s = 0.0f;
+ walker->r_b = 0.0f;
+ walker->g_s = 0.0f;
+ walker->g_b = 0.0f;
+ walker->b_s = 0.0f;
+ walker->b_b = 0.0f;
walker->repeat = repeat;
walker->need_reset = TRUE;
@@ -55,6 +58,9 @@ gradient_walker_reset (pixman_gradient_walker_t *walker,
pixman_color_t *left_c, *right_c;
int n, count = walker->num_stops;
pixman_gradient_stop_t *stops = walker->stops;
+ float la, lr, lg, lb;
+ float ra, rr, rg, rb;
+ float lx, rx;
if (walker->repeat == PIXMAN_REPEAT_NORMAL)
{
@@ -116,24 +122,49 @@ gradient_walker_reset (pixman_gradient_walker_t *walker,
left_c = right_c;
}
- walker->left_x = left_x;
- walker->right_x = right_x;
- walker->left_ag = ((left_c->alpha >> 8) << 16) | (left_c->green >> 8);
- walker->left_rb = ((left_c->red & 0xff00) << 8) | (left_c->blue >> 8);
- walker->right_ag = ((right_c->alpha >> 8) << 16) | (right_c->green >> 8);
- walker->right_rb = ((right_c->red & 0xff00) << 8) | (right_c->blue >> 8);
-
- if (walker->left_x == walker->right_x ||
- (walker->left_ag == walker->right_ag &&
- walker->left_rb == walker->right_rb))
+ /* The alpha channel is scaled to be in the [0, 255] interval,
+ * and the red/green/blue channels are scaled to be in [0, 1].
+ * This ensures that after premultiplication all channels will
+ * be in the [0, 255] interval.
+ */
+ la = (left_c->alpha * (1.0f/257.0f));
+ lr = (left_c->red * (1.0f/257.0f));
+ lg = (left_c->green * (1.0f/257.0f));
+ lb = (left_c->blue * (1.0f/257.0f));
+
+ ra = (right_c->alpha * (1.0f/257.0f));
+ rr = (right_c->red * (1.0f/257.0f));
+ rg = (right_c->green * (1.0f/257.0f));
+ rb = (right_c->blue * (1.0f/257.0f));
+
+ lx = left_x * (1.0f/65536.0f);
+ rx = right_x * (1.0f/65536.0f);
+
+ if (FLOAT_IS_ZERO (rx - lx) || left_x == INT32_MIN || right_x == INT32_MAX)
{
- walker->stepper = 0;
+ walker->a_s = walker->r_s = walker->g_s = walker->b_s = 0.0f;
+ walker->a_b = (la + ra) / 2.0f;
+ walker->r_b = (lr + rr) / 510.0f;
+ walker->g_b = (lg + rg) / 510.0f;
+ walker->b_b = (lb + rb) / 510.0f;
}
else
{
- int32_t width = right_x - left_x;
- walker->stepper = ((1 << 24) + width / 2) / width;
+ float w_rec = 1.0f / (rx - lx);
+
+ walker->a_b = (la * rx - ra * lx) * w_rec;
+ walker->r_b = (lr * rx - rr * lx) * w_rec * (1.0f/255.0f);
+ walker->g_b = (lg * rx - rg * lx) * w_rec * (1.0f/255.0f);
+ walker->b_b = (lb * rx - rb * lx) * w_rec * (1.0f/255.0f);
+
+ walker->a_s = (ra - la) * w_rec;
+ walker->r_s = (rr - lr) * w_rec * (1.0f/255.0f);
+ walker->g_s = (rg - lg) * w_rec * (1.0f/255.0f);
+ walker->b_s = (rb - lb) * w_rec * (1.0f/255.0f);
}
+
+ walker->left_x = left_x;
+ walker->right_x = right_x;
walker->need_reset = FALSE;
}
@@ -142,31 +173,30 @@ uint32_t
_pixman_gradient_walker_pixel (pixman_gradient_walker_t *walker,
pixman_fixed_48_16_t x)
{
- int dist, idist;
- uint32_t t1, t2, a, color;
+ float a, r, g, b;
+ uint8_t a8, r8, g8, b8;
+ uint32_t v;
+ float y;
if (walker->need_reset || x < walker->left_x || x >= walker->right_x)
- gradient_walker_reset (walker, x);
-
- dist = ((int)(x - walker->left_x) * walker->stepper) >> 16;
- idist = 256 - dist;
+ gradient_walker_reset (walker, x);
- /* combined INTERPOLATE and premultiply */
- t1 = walker->left_rb * idist + walker->right_rb * dist;
- t1 = (t1 >> 8) & 0xff00ff;
+ y = x * (1.0f / 65536.0f);
- t2 = walker->left_ag * idist + walker->right_ag * dist;
- t2 &= 0xff00ff00;
+ a = walker->a_s * y + walker->a_b;
+ r = a * (walker->r_s * y + walker->r_b);
+ g = a * (walker->g_s * y + walker->g_b);
+ b = a * (walker->b_s * y + walker->b_b);
- color = t2 & 0xff000000;
- a = t2 >> 24;
+ a8 = a + 0.5f;
+ r8 = r + 0.5f;
+ g8 = g + 0.5f;
+ b8 = b + 0.5f;
- t1 = t1 * a + 0x800080;
- t1 = (t1 + ((t1 >> 8) & 0xff00ff)) >> 8;
+ v = ((a8 << 24) & 0xff000000) |
+ ((r8 << 16) & 0x00ff0000) |
+ ((g8 << 8) & 0x0000ff00) |
+ ((b8 >> 0) & 0x000000ff);
- t2 = (t2 >> 8) * a + 0x800080;
- t2 = (t2 + ((t2 >> 8) & 0xff00ff));
-
- return (color | (t1 & 0xff00ff) | (t2 & 0xff00));
+ return v;
}
-
diff --git a/pixman/pixman/pixman-private.h b/pixman/pixman/pixman-private.h
index 181ab5c35..6d9c05321 100644
--- a/pixman/pixman/pixman-private.h
+++ b/pixman/pixman/pixman-private.h
@@ -1,3 +1,5 @@
+#include <float.h>
+
#ifndef PIXMAN_PRIVATE_H
#define PIXMAN_PRIVATE_H
@@ -317,13 +319,12 @@ _pixman_image_validate (pixman_image_t *image);
*/
typedef struct
{
- uint32_t left_ag;
- uint32_t left_rb;
- uint32_t right_ag;
- uint32_t right_rb;
+ float a_s, a_b;
+ float r_s, r_b;
+ float g_s, g_b;
+ float b_s, b_b;
pixman_fixed_t left_x;
pixman_fixed_t right_x;
- pixman_fixed_t stepper;
pixman_gradient_stop_t *stops;
int num_stops;
@@ -879,6 +880,8 @@ pixman_list_move_to_front (pixman_list_t *list, pixman_link_t *link)
#define CLIP(v, low, high) ((v) < (low) ? (low) : ((v) > (high) ? (high) : (v)))
+#define FLOAT_IS_ZERO(f) (-FLT_MIN < (f) && (f) < FLT_MIN)
+
/* Conversion between 8888 and 0565 */
static force_inline uint16_t
diff --git a/pixman/test/Makefile.sources b/pixman/test/Makefile.sources
index 5b30970b9..b5fc740f3 100644
--- a/pixman/test/Makefile.sources
+++ b/pixman/test/Makefile.sources
@@ -28,9 +28,10 @@ TESTPROGRAMS = \
composite \
$(NULL)
-# Benchmarks
+# Other programs
OTHERPROGRAMS = \
lowlevel-blt-bench \
+ radial-perf-test \
check-formats \
$(NULL)
diff --git a/pixman/test/radial-perf-test.c b/pixman/test/radial-perf-test.c
new file mode 100644
index 000000000..71092e27b
--- /dev/null
+++ b/pixman/test/radial-perf-test.c
@@ -0,0 +1,58 @@
+#include "utils.h"
+#include <stdio.h>
+
+int
+main ()
+{
+ static const pixman_point_fixed_t inner = { 0x0000, 0x0000 };
+ static const pixman_point_fixed_t outer = { 0x0000, 0x0000 };
+ static const pixman_fixed_t r_inner = 0;
+ static const pixman_fixed_t r_outer = 64 << 16;
+ static const pixman_gradient_stop_t stops[] = {
+ { 0x00000, { 0x6666, 0x6666, 0x6666, 0xffff } },
+ { 0x10000, { 0x0000, 0x0000, 0x0000, 0xffff } }
+ };
+ static const pixman_transform_t transform = {
+ { { 0x0, 0x26ee, 0x0},
+ { 0xffffeeef, 0x0, 0x0},
+ { 0x0, 0x0, 0x10000}
+ }
+ };
+ static const pixman_color_t z = { 0x0000, 0x0000, 0x0000, 0x0000 };
+ pixman_image_t *dest, *radial, *zero;
+ int i;
+ double before, after;
+
+ dest = pixman_image_create_bits (
+ PIXMAN_x8r8g8b8, 640, 429, NULL, -1);
+ zero = pixman_image_create_solid_fill (&z);
+ radial = pixman_image_create_radial_gradient (
+ &inner, &outer, r_inner, r_outer, stops, ARRAY_LENGTH (stops));
+ pixman_image_set_transform (radial, &transform);
+ pixman_image_set_repeat (radial, PIXMAN_REPEAT_PAD);
+
+#define N_COMPOSITE 500
+
+ before = gettime();
+ for (i = 0; i < N_COMPOSITE; ++i)
+ {
+ before -= gettime();
+
+ pixman_image_composite (
+ PIXMAN_OP_SRC, zero, NULL, dest,
+ 0, 0, 0, 0, 0, 0, 640, 429);
+
+ before += gettime();
+
+ pixman_image_composite32 (
+ PIXMAN_OP_OVER, radial, NULL, dest,
+ - 150, -158, 0, 0, 0, 0, 640, 361);
+ }
+
+ after = gettime();
+
+ write_png (dest, "radial.png");
+
+ printf ("Average time to composite: %f\n", (after - before) / N_COMPOSITE);
+ return 0;
+}
diff --git a/xorg-server/Xext/panoramiX.c b/xorg-server/Xext/panoramiX.c
index be475f7f4..7f888e38d 100644
--- a/xorg-server/Xext/panoramiX.c
+++ b/xorg-server/Xext/panoramiX.c
@@ -596,7 +596,7 @@ Bool
PanoramiXCreateConnectionBlock(void)
{
int i, j, length;
- Bool disableBackingStore = FALSE;
+ Bool disable_backing_store = FALSE;
int old_width, old_height;
float width_mult, height_mult;
xWindowRoot *root;
@@ -622,10 +622,10 @@ PanoramiXCreateConnectionBlock(void)
}
if (pScreen->backingStoreSupport !=
screenInfo.screens[0]->backingStoreSupport)
- disableBackingStore = TRUE;
+ disable_backing_store = TRUE;
}
- if (disableBackingStore) {
+ if (disable_backing_store) {
for (i = 0; i < screenInfo.numScreens; i++) {
pScreen = screenInfo.screens[i];
pScreen->backingStoreSupport = NotUseful;
@@ -831,15 +831,15 @@ PanoramiXConsolidate(void)
saver->type = XRT_WINDOW;
FOR_NSCREENS(i) {
- ScreenPtr pScreen = screenInfo.screens[i];
+ ScreenPtr scr = screenInfo.screens[i];
- root->info[i].id = pScreen->root->drawable.id;
+ root->info[i].id = scr->root->drawable.id;
root->u.win.class = InputOutput;
root->u.win.root = TRUE;
- saver->info[i].id = pScreen->screensaver.wid;
+ saver->info[i].id = scr->screensaver.wid;
saver->u.win.class = InputOutput;
saver->u.win.root = TRUE;
- defmap->info[i].id = pScreen->defColormap;
+ defmap->info[i].id = scr->defColormap;
}
AddResource(root->info[0].id, XRT_WINDOW, root);
diff --git a/xorg-server/Xext/sync.c b/xorg-server/Xext/sync.c
index 4d11992bb..9ae5b3981 100644
--- a/xorg-server/Xext/sync.c
+++ b/xorg-server/Xext/sync.c
@@ -2747,7 +2747,6 @@ init_system_idle_counter(const char *name, int deviceid)
{
CARD64 resolution;
XSyncValue idle;
- IdleCounterPriv *priv = malloc(sizeof(IdleCounterPriv));
SyncCounter *idle_time_counter;
IdleTimeQueryValue(NULL, &idle);
@@ -2758,10 +2757,14 @@ init_system_idle_counter(const char *name, int deviceid)
IdleTimeQueryValue,
IdleTimeBracketValues);
- priv->deviceid = deviceid;
- priv->value_less = priv->value_greater = NULL;
+ if (idle_time_counter != NULL) {
+ IdleCounterPriv *priv = malloc(sizeof(IdleCounterPriv));
- idle_time_counter->pSysCounterInfo->private = priv;
+ priv->value_less = priv->value_greater = NULL;
+ priv->deviceid = deviceid;
+
+ idle_time_counter->pSysCounterInfo->private = priv;
+ }
return idle_time_counter;
}
@@ -2786,6 +2789,6 @@ void SyncRemoveDeviceIdleTime(SyncCounter *counter)
/* FreeAllResources() frees all system counters before the devices are
shut down, check if there are any left before freeing the device's
counter */
- if (!xorg_list_is_empty(&SysCounterList))
+ if (counter && !xorg_list_is_empty(&SysCounterList))
xorg_list_del(&counter->pSysCounterInfo->entry);
}
diff --git a/xorg-server/Xext/xvdisp.c b/xorg-server/Xext/xvdisp.c
index 31b77839f..787729387 100644
--- a/xorg-server/Xext/xvdisp.c
+++ b/xorg-server/Xext/xvdisp.c
@@ -702,7 +702,7 @@ ProcXvUngrabPort(ClientPtr client)
static int
ProcXvStopVideo(ClientPtr client)
{
- int status, rc;
+ int status, ret;
DrawablePtr pDraw;
XvPortPtr pPort;
@@ -716,9 +716,9 @@ ProcXvStopVideo(ClientPtr client)
return status;
}
- rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixWriteAccess);
- if (rc != Success)
- return rc;
+ ret = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixWriteAccess);
+ if (ret != Success)
+ return ret;
return XvdiStopVideo(client, pPort, pDraw);
}
diff --git a/xorg-server/Xi/exevents.c b/xorg-server/Xi/exevents.c
index 609b1268f..6779139b5 100644
--- a/xorg-server/Xi/exevents.c
+++ b/xorg-server/Xi/exevents.c
@@ -1126,20 +1126,22 @@ static void
TouchPuntToNextOwner(DeviceIntPtr dev, TouchPointInfoPtr ti,
TouchOwnershipEvent *ev)
{
+ TouchListener *listener = &ti->listeners[0]; /* new owner */
+
/* Deliver the ownership */
- if (ti->listeners[0].state == LISTENER_AWAITING_OWNER ||
- ti->listeners[0].state == LISTENER_EARLY_ACCEPT)
+ if (listener->state == LISTENER_AWAITING_OWNER ||
+ listener->state == LISTENER_EARLY_ACCEPT)
DeliverTouchEvents(dev, ti, (InternalEvent *) ev,
- ti->listeners[0].listener);
- else if (ti->listeners[0].state == LISTENER_AWAITING_BEGIN) {
+ listener->listener);
+ else if (listener->state == LISTENER_AWAITING_BEGIN) {
/* We can't punt to a pointer listener unless all older pointer
* emulated touches have been seen already. */
- if ((ti->listeners[0].type == LISTENER_POINTER_GRAB ||
- ti->listeners[0].type == LISTENER_POINTER_REGULAR) &&
+ if ((listener->type == LISTENER_POINTER_GRAB ||
+ listener->type == LISTENER_POINTER_REGULAR) &&
ti != FindOldestPointerEmulatedTouch(dev))
return;
- TouchEventHistoryReplay(ti, dev, ti->listeners[0].listener);
+ TouchEventHistoryReplay(ti, dev, listener->listener);
}
/* If we've just removed the last grab and the touch has physically
@@ -1150,7 +1152,7 @@ TouchPuntToNextOwner(DeviceIntPtr dev, TouchPointInfoPtr ti,
return;
}
- if (ti->listeners[0].state == LISTENER_EARLY_ACCEPT)
+ if (listener->state == LISTENER_EARLY_ACCEPT)
ActivateEarlyAccept(dev, ti);
}
@@ -1376,7 +1378,7 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
/* We don't deliver pointer events to non-owners */
if (!TouchResourceIsOwner(ti, listener->listener))
- return Success;
+ return !Success;
nevents = TouchConvertToPointerEvent(ev, &motion, &button);
BUG_RETURN_VAL(nevents == 0, BadValue);
@@ -1398,7 +1400,7 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
/* 'grab' is the passive grab, but if the grab isn't active,
* don't deliver */
if (!dev->deviceGrab.grab)
- return Success;
+ return !Success;
if (grab->ownerEvents) {
WindowPtr focus = NullWindow;
@@ -1896,13 +1898,16 @@ DeliverTouchEndEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev,
goto out;
}
+ /* A client is waiting for the begin, don't give it a TouchEnd */
if (listener->state == LISTENER_AWAITING_BEGIN) {
listener->state = LISTENER_HAS_END;
goto out;
}
/* Event in response to reject */
- if (ev->device_event.flags & TOUCH_REJECT) {
+ if (ev->device_event.flags & TOUCH_REJECT ||
+ (ev->device_event.flags & TOUCH_ACCEPT && !TouchResourceIsOwner(ti, listener->listener))) {
+ /* Touch has been rejected, or accepted by its owner which is not this listener */
if (listener->state != LISTENER_HAS_END)
rc = DeliverOneTouchEvent(client, dev, ti, grab, win, ev);
listener->state = LISTENER_HAS_END;
@@ -1925,12 +1930,6 @@ DeliverTouchEndEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev,
if (normal_end)
listener->state = LISTENER_HAS_END;
}
- else if (ev->device_event.flags & TOUCH_ACCEPT) {
- /* Touch has been accepted by its owner, which is not this listener */
- if (listener->state != LISTENER_HAS_END)
- rc = DeliverOneTouchEvent(client, dev, ti, grab, win, ev);
- listener->state = LISTENER_HAS_END;
- }
out:
return rc;
diff --git a/xorg-server/composite/compext.c b/xorg-server/composite/compext.c
index 8641eff5e..e4821c5fc 100644
--- a/xorg-server/composite/compext.c
+++ b/xorg-server/composite/compext.c
@@ -803,6 +803,7 @@ PanoramiXCompositeGetOverlayWindow(ClientPtr client)
RT_WINDOW, client, DixGetAttrAccess);
if (rc != Success) {
client->errorValue = stuff->window;
+ free(overlayWin);
return rc;
}
pScreen = pWin->drawable.pScreen;
@@ -812,8 +813,10 @@ PanoramiXCompositeGetOverlayWindow(ClientPtr client)
* interest in the overlay window
*/
pOc = compCreateOverlayClient(pScreen, client);
- if (pOc == NULL)
+ if (pOc == NULL) {
+ free(overlayWin);
return BadAlloc;
+ }
/*
* Make sure the overlay window exists
@@ -822,6 +825,7 @@ PanoramiXCompositeGetOverlayWindow(ClientPtr client)
if (cs->pOverlayWin == NULL)
if (!compCreateOverlayWindow(pScreen)) {
FreeResource(pOc->resource, RT_NONE);
+ free(overlayWin);
return BadAlloc;
}
@@ -831,6 +835,7 @@ PanoramiXCompositeGetOverlayWindow(ClientPtr client)
DixGetAttrAccess);
if (rc != Success) {
FreeResource(pOc->resource, RT_NONE);
+ free(overlayWin);
return rc;
}
}
diff --git a/xorg-server/configure.ac b/xorg-server/configure.ac
index 6e1ff65c4..e0750bbcc 100644
--- a/xorg-server/configure.ac
+++ b/xorg-server/configure.ac
@@ -26,9 +26,9 @@ dnl
dnl Process this file with autoconf to create configure.
AC_PREREQ(2.60)
-AC_INIT([xorg-server], 1.14.0, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
-RELEASE_DATE="2013-03-05"
-RELEASE_NAME="Keemun Mao Feng"
+AC_INIT([xorg-server], 1.14.99.0, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
+RELEASE_DATE="2013-03-18"
+RELEASE_NAME="Pok Pok Meyer Lemon"
AC_CONFIG_SRCDIR([Makefile.am])
AM_INIT_AUTOMAKE([foreign dist-bzip2])
@@ -308,6 +308,13 @@ AC_CHECK_HEADER([execinfo.h],[
])]
)
+PKG_CHECK_MODULES(LIBUNWIND, libunwind, [HAVE_LIBUNWIND=yes], [HAVE_LIBUNWIND=no])
+if test "x$HAVE_LIBUNWIND" = xyes; then
+ AC_DEFINE(HAVE_LIBUNWIND, 1, [Have libunwind support])
+fi
+AM_CONDITIONAL(HAVE_LIBUNWIND, [test "x$HAVE_LIBUNWIND" = xyes])
+
+
dnl ---------------------------------------------------------------------------
dnl Bus options and CPU capabilities. Replaces logic in
dnl hw/xfree86/os-support/bus/Makefile.am, among others.
@@ -788,7 +795,7 @@ XPROTO="xproto >= 7.0.22"
RANDRPROTO="randrproto >= 1.4.0"
RENDERPROTO="renderproto >= 0.11"
XEXTPROTO="xextproto >= 7.1.99"
-INPUTPROTO="inputproto >= 2.2.99.1"
+INPUTPROTO="inputproto >= 2.3"
KBPROTO="kbproto >= 1.0.3"
FONTSPROTO="fontsproto"
FIXESPROTO="fixesproto >= 5.0"
@@ -1336,7 +1343,7 @@ AC_DEFINE(BIGREQS, 1, [Support BigRequests extension])
if test "x$SPECIAL_DTRACE_OBJECTS" = "xyes" ; then
DIX_LIB='$(top_builddir)/dix/dix.O'
- OS_LIB='$(top_builddir)/os/os.O $(SHA1_LIBS) $(DLOPEN_LIBS)'
+ OS_LIB='$(top_builddir)/os/os.O $(SHA1_LIBS) $(DLOPEN_LIBS) $(LIBUNWIND_LIBS)'
else
DIX_LIB='$(top_builddir)/dix/libdix.la'
OS_LIB='$(top_builddir)/os/libos.la'
diff --git a/xorg-server/dix/events.c b/xorg-server/dix/events.c
index 2682ecd46..051205233 100644
--- a/xorg-server/dix/events.c
+++ b/xorg-server/dix/events.c
@@ -1200,6 +1200,9 @@ PlayReleasedEvents(void)
case ET_KeyRelease:
case ET_ProximityIn:
case ET_ProximityOut:
+ case ET_TouchBegin:
+ case ET_TouchUpdate:
+ case ET_TouchEnd:
ev->root_x += screenInfo.screens[0]->x -
pDev->spriteInfo->sprite->screen->x;
ev->root_y += screenInfo.screens[0]->y -
diff --git a/xorg-server/dix/main.c b/xorg-server/dix/main.c
index fb935c969..bea1a8d5a 100644
--- a/xorg-server/dix/main.c
+++ b/xorg-server/dix/main.c
@@ -357,6 +357,8 @@ main(int argc, char *argv[], char *envp[])
FreeFonts();
+ FreeAllAtoms();
+
FreeAuditTimer();
if (dispatchException & DE_TERMINATE) {
diff --git a/xorg-server/dix/touch.c b/xorg-server/dix/touch.c
index 0db842c65..891cc7803 100644
--- a/xorg-server/dix/touch.c
+++ b/xorg-server/dix/touch.c
@@ -902,7 +902,8 @@ TouchSetupListeners(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev)
}
/**
- * Remove the touch pointer grab from the device. Called from AllowSome()
+ * Remove the touch pointer grab from the device. Called from
+ * DeactivatePointerGrab()
*/
void
TouchRemovePointerGrab(DeviceIntPtr dev)
diff --git a/xorg-server/dix/window.c b/xorg-server/dix/window.c
index a5b28a630..a9297f3c8 100644
--- a/xorg-server/dix/window.c
+++ b/xorg-server/dix/window.c
@@ -1431,6 +1431,8 @@ ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client)
}
}
+ CursorVisible = TRUE;
+
if (pWin->realized)
WindowHasNewCursor(pWin);
@@ -3430,6 +3432,8 @@ ChangeWindowDeviceCursor(WindowPtr pWin, DeviceIntPtr pDev, CursorPtr pCursor)
}
out:
+ CursorVisible = TRUE;
+
if (pWin->realized)
WindowHasNewCursor(pWin);
diff --git a/xorg-server/fb/fbpict.c b/xorg-server/fb/fbpict.c
index 2804ff481..b50385805 100644
--- a/xorg-server/fb/fbpict.c
+++ b/xorg-server/fb/fbpict.c
@@ -185,19 +185,15 @@ fbGlyphs(CARD8 op,
if (maskFormat) {
pixman_format_code_t format;
pixman_box32_t extents;
- int x, y;
format = maskFormat->format | (maskFormat->depth << 24);
pixman_glyph_get_extents(glyphCache, n_glyphs, pglyphs, &extents);
- x = extents.x1;
- y = extents.y1;
-
pixman_composite_glyphs(op, srcImage, dstImage, format,
xSrc + srcXoff + xDst, ySrc + srcYoff + yDst,
- x, y,
- x + dstXoff, y + dstYoff,
+ extents.x1, extents.y1,
+ extents.x1 + dstXoff, extents.y1 + dstYoff,
extents.x2 - extents.x1,
extents.y2 - extents.y1,
glyphCache, n_glyphs, pglyphs);
diff --git a/xorg-server/glx/extension_string.c b/xorg-server/glx/extension_string.c
index 544ca1f5e..58f930f75 100644
--- a/xorg-server/glx/extension_string.c
+++ b/xorg-server/glx/extension_string.c
@@ -71,9 +71,11 @@ static const struct extension_info known_glx_extensions[] = {
{ GLX(ARB_create_context), VER(0,0), N, },
{ GLX(ARB_create_context_profile), VER(0,0), N, },
{ GLX(ARB_create_context_robustness), VER(0,0), N, },
+ { GLX(ARB_framebuffer_sRGB), VER(0,0), N, },
{ GLX(ARB_multisample), VER(1,4), Y, },
{ GLX(EXT_create_context_es2_profile), VER(0,0), N, },
+ { GLX(EXT_framebuffer_sRGB), VER(0,0), N, },
{ GLX(EXT_import_context), VER(0,0), Y, },
{ GLX(EXT_texture_from_pixmap), VER(0,0), Y, },
{ GLX(EXT_visual_info), VER(0,0), Y, },
diff --git a/xorg-server/glx/extension_string.h b/xorg-server/glx/extension_string.h
index 7a4a8b1c2..81b7de372 100644
--- a/xorg-server/glx/extension_string.h
+++ b/xorg-server/glx/extension_string.h
@@ -39,6 +39,7 @@ enum {
ARB_create_context_bit = 0,
ARB_create_context_profile_bit,
ARB_create_context_robustness_bit,
+ ARB_framebuffer_sRGB_bit,
ARB_multisample_bit,
EXT_create_context_es2_profile_bit,
EXT_import_context_bit,
@@ -58,6 +59,10 @@ enum {
__NUM_GLX_EXTS,
};
+/* For extensions which have identical ARB and EXT implementation
+ * in GLX area, use one enabling bit for both. */
+#define EXT_framebuffer_sRGB_bit ARB_framebuffer_sRGB_bit
+
#define __GLX_EXT_BYTES ((__NUM_GLX_EXTS + 7) / 8)
extern int __glXGetExtensionString(const unsigned char *enable_bits,
diff --git a/xorg-server/glx/glxcmds.c b/xorg-server/glx/glxcmds.c
index c1f4e22f8..5b7a628cc 100644
--- a/xorg-server/glx/glxcmds.c
+++ b/xorg-server/glx/glxcmds.c
@@ -913,7 +913,7 @@ __glXDisp_CopyContext(__GLXclientState * cl, GLbyte * pc)
enum {
GLX_VIS_CONFIG_UNPAIRED = 18,
- GLX_VIS_CONFIG_PAIRED = 20
+ GLX_VIS_CONFIG_PAIRED = 22
};
enum {
@@ -1005,8 +1005,17 @@ __glXDisp_GetVisualConfigs(__GLXclientState * cl, GLbyte * pc)
buf[p++] = modes->samples;
buf[p++] = GLX_SAMPLE_BUFFERS_SGIS;
buf[p++] = modes->sampleBuffers;
- buf[p++] = 0; /* copy over visualSelectGroup (GLX_VISUAL_SELECT_GROUP_SGIX)? */
- buf[p++] = 0;
+ /* Add attribute only if its value is not default. */
+ if (modes->sRGBCapable != GL_FALSE) {
+ buf[p++] = GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT;
+ buf[p++] = modes->sRGBCapable;
+ }
+ /* Don't add visualSelectGroup (GLX_VISUAL_SELECT_GROUP_SGIX)?
+ * Pad the remaining place with zeroes, so that attributes count is constant. */
+ while (p < GLX_VIS_CONFIG_TOTAL) {
+ buf[p++] = 0;
+ buf[p++] = 0;
+ }
assert(p == GLX_VIS_CONFIG_TOTAL);
if (client->swapped) {
@@ -1017,7 +1026,7 @@ __glXDisp_GetVisualConfigs(__GLXclientState * cl, GLbyte * pc)
return Success;
}
-#define __GLX_TOTAL_FBCONFIG_ATTRIBS (36)
+#define __GLX_TOTAL_FBCONFIG_ATTRIBS (37)
#define __GLX_FBCONFIG_ATTRIBS_LENGTH (__GLX_TOTAL_FBCONFIG_ATTRIBS * 2)
/**
* Send the set of GLXFBConfigs to the client. There is not currently
@@ -1109,6 +1118,15 @@ DoGetFBConfigs(__GLXclientState * cl, unsigned screen)
WRITE_PAIR(GLX_BIND_TO_MIPMAP_TEXTURE_EXT, modes->bindToMipmapTexture);
WRITE_PAIR(GLX_BIND_TO_TEXTURE_TARGETS_EXT,
modes->bindToTextureTargets);
+ /* Add attribute only if its value is not default. */
+ if (modes->sRGBCapable != GL_FALSE) {
+ WRITE_PAIR(GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT, modes->sRGBCapable);
+ }
+ /* Pad the remaining place with zeroes, so that attributes count is constant. */
+ while (p < __GLX_FBCONFIG_ATTRIBS_LENGTH) {
+ WRITE_PAIR(0, 0);
+ }
+ assert(p == __GLX_FBCONFIG_ATTRIBS_LENGTH);
if (client->swapped) {
__GLX_SWAP_INT_ARRAY(buf, __GLX_FBCONFIG_ATTRIBS_LENGTH);
diff --git a/xorg-server/glx/glxdri.c b/xorg-server/glx/glxdri.c
index da4646845..a997e2f8a 100644
--- a/xorg-server/glx/glxdri.c
+++ b/xorg-server/glx/glxdri.c
@@ -971,6 +971,8 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
size_t buffer_size;
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+ framebuffer.base = NULL;
+
if (!xf86LoaderCheckSymbol("DRIQueryDirectRenderingCapable") ||
!DRIQueryDirectRenderingCapable(pScreen, &isCapable) || !isCapable) {
LogMessage(X_INFO,
diff --git a/xorg-server/glx/glxdri2.c b/xorg-server/glx/glxdri2.c
index b26e501dc..e07cb5632 100644
--- a/xorg-server/glx/glxdri2.c
+++ b/xorg-server/glx/glxdri2.c
@@ -857,8 +857,6 @@ initializeExtensions(__GLXDRIscreen * screen)
__glXEnableExtension(screen->glx_enable_bits, "GLX_MESA_copy_sub_buffer");
LogMessage(X_INFO, "AIGLX: enabled GLX_MESA_copy_sub_buffer\n");
- __glXEnableExtension(screen->glx_enable_bits, "GLX_INTEL_swap_event");
- LogMessage(X_INFO, "AIGLX: enabled GLX_INTEL_swap_event\n");
#if __DRI_DRI2_VERSION >= 3
if (screen->dri2->base.version >= 3) {
@@ -876,12 +874,21 @@ initializeExtensions(__GLXDRIscreen * screen)
#endif
if (DRI2HasSwapControl(pScreen)) {
+ __glXEnableExtension(screen->glx_enable_bits, "GLX_INTEL_swap_event");
__glXEnableExtension(screen->glx_enable_bits, "GLX_SGI_swap_control");
__glXEnableExtension(screen->glx_enable_bits, "GLX_MESA_swap_control");
+ LogMessage(X_INFO, "AIGLX: enabled GLX_INTEL_swap_event\n");
LogMessage(X_INFO,
"AIGLX: enabled GLX_SGI_swap_control and GLX_MESA_swap_control\n");
}
+ /* enable EXT_framebuffer_sRGB extension (even if there are no sRGB capable fbconfigs) */
+ {
+ __glXEnableExtension(screen->glx_enable_bits,
+ "GLX_EXT_framebuffer_sRGB");
+ LogMessage(X_INFO, "AIGLX: enabled GLX_EXT_framebuffer_sRGB\n");
+ }
+
for (i = 0; extensions[i]; i++) {
#ifdef __DRI_READ_DRAWABLE
if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) {
diff --git a/xorg-server/glx/glxdricommon.c b/xorg-server/glx/glxdricommon.c
index c90f38098..b027f2498 100644
--- a/xorg-server/glx/glxdricommon.c
+++ b/xorg-server/glx/glxdricommon.c
@@ -105,7 +105,9 @@ __ATTRIB(__DRI_ATTRIB_BUFFER_SIZE, rgbBits),
__ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB, bindToTextureRgb),
__ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA, bindToTextureRgba),
__ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE, bindToMipmapTexture),
- __ATTRIB(__DRI_ATTRIB_YINVERTED, yInverted),};
+ __ATTRIB(__DRI_ATTRIB_YINVERTED, yInverted),
+ __ATTRIB(__DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE, sRGBCapable),
+ };
static void
setScalar(__GLXconfig * config, unsigned int attrib, unsigned int value)
diff --git a/xorg-server/glx/glxscreens.h b/xorg-server/glx/glxscreens.h
index b29df58a5..0a7b6043e 100644
--- a/xorg-server/glx/glxscreens.h
+++ b/xorg-server/glx/glxscreens.h
@@ -102,6 +102,9 @@ struct __GLXconfig {
GLint bindToMipmapTexture;
GLint bindToTextureTargets;
GLint yInverted;
+
+ /* ARB_framebuffer_sRGB */
+ GLint sRGBCapable;
};
GLint glxConvertToXVisualType(int visualType);
diff --git a/xorg-server/hw/kdrive/ephyr/ephyr.c b/xorg-server/hw/kdrive/ephyr/ephyr.c
index e6520d035..02d497073 100644
--- a/xorg-server/hw/kdrive/ephyr/ephyr.c
+++ b/xorg-server/hw/kdrive/ephyr/ephyr.c
@@ -56,6 +56,7 @@ typedef struct _EphyrInputPrivate {
} EphyrKbdPrivate, EphyrPointerPrivate;
Bool EphyrWantGrayScale = 0;
+Bool EphyrWantResize = 0;
Bool
ephyrInitialize(KdCardInfo * card, EphyrPriv * priv)
@@ -237,13 +238,11 @@ ephyrMapFramebuffer(KdScreenInfo * screen)
KdComputePointerMatrix(&m, ephyrRandr, screen->width, screen->height);
KdSetPointerMatrix(&m);
- priv->bytes_per_line =
- ((screen->width * screen->fb.bitsPerPixel + 31) >> 5) << 2;
-
buffer_height = ephyrBufferHeight(screen);
priv->base =
- hostx_screen_init(screen, screen->width, screen->height, buffer_height);
+ hostx_screen_init(screen, screen->width, screen->height, buffer_height,
+ &priv->bytes_per_line, &screen->fb.bitsPerPixel);
if ((scrpriv->randr & RR_Rotate_0) && !(scrpriv->randr & RR_Reflect_All)) {
scrpriv->shadow = FALSE;
diff --git a/xorg-server/hw/kdrive/ephyr/ephyrinit.c b/xorg-server/hw/kdrive/ephyr/ephyrinit.c
index 5e2eb672f..adacac949 100644
--- a/xorg-server/hw/kdrive/ephyr/ephyrinit.c
+++ b/xorg-server/hw/kdrive/ephyr/ephyrinit.c
@@ -31,6 +31,7 @@
extern Window EphyrPreExistingHostWin;
extern Bool EphyrWantGrayScale;
+extern Bool EphyrWantResize;
extern Bool kdHasPointer;
extern Bool kdHasKbd;
@@ -116,6 +117,7 @@ ddxUseMsg(void)
ErrorF("-host-cursor Re-use exisiting X host server cursor\n");
ErrorF("-fullscreen Attempt to run Xephyr fullscreen\n");
ErrorF("-grayscale Simulate 8bit grayscale\n");
+ ErrorF("-resizeable Make Xephyr windows resizeable\n");
ErrorF
("-fakexa Simulate acceleration using software rendering\n");
ErrorF("-verbosity <level> Set log verbosity level\n");
@@ -210,6 +212,10 @@ ddxProcessArgument(int argc, char **argv, int i)
EphyrWantGrayScale = 1;
return 1;
}
+ else if (!strcmp(argv[i], "-resizeable")) {
+ EphyrWantResize = 1;
+ return 1;
+ }
else if (!strcmp(argv[i], "-fakexa")) {
ephyrFuncs.initAccel = ephyrDrawInit;
ephyrFuncs.enableAccel = ephyrDrawEnable;
diff --git a/xorg-server/hw/kdrive/ephyr/ephyrvideo.c b/xorg-server/hw/kdrive/ephyr/ephyrvideo.c
index 55dbd2e3a..dfc29f533 100644
--- a/xorg-server/hw/kdrive/ephyr/ephyrvideo.c
+++ b/xorg-server/hw/kdrive/ephyr/ephyrvideo.c
@@ -1006,7 +1006,6 @@ ephyrPutVideo(KdScreenInfo * a_info,
EphyrPortPriv *port_priv = a_port_priv;
BoxRec clipped_area, dst_box;
int result = BadImplementation;
- int drw_x = 0, drw_y = 0, drw_w = 0, drw_h = 0;
EPHYR_RETURN_VAL_IF_FAIL(a_info->pScreen, BadValue);
EPHYR_RETURN_VAL_IF_FAIL(a_drawable && port_priv, BadValue);
@@ -1024,11 +1023,6 @@ ephyrPutVideo(KdScreenInfo * a_info,
goto out;
}
- drw_x = clipped_area.x1;
- drw_y = clipped_area.y1;
- drw_w = clipped_area.x2 - clipped_area.x1;
- drw_h = clipped_area.y2 - clipped_area.y1;
-
if (!ephyrHostXVPutVideo(a_info->pScreen->myNum,
port_priv->port_number,
a_vid_x, a_vid_y, a_vid_w, a_vid_h,
@@ -1055,7 +1049,6 @@ ephyrGetVideo(KdScreenInfo * a_info,
EphyrPortPriv *port_priv = a_port_priv;
BoxRec clipped_area, dst_box;
int result = BadImplementation;
- int drw_x = 0, drw_y = 0, drw_w = 0, drw_h = 0;
EPHYR_RETURN_VAL_IF_FAIL(a_info && a_info->pScreen, BadValue);
EPHYR_RETURN_VAL_IF_FAIL(a_drawable && port_priv, BadValue);
@@ -1073,11 +1066,6 @@ ephyrGetVideo(KdScreenInfo * a_info,
goto out;
}
- drw_x = clipped_area.x1;
- drw_y = clipped_area.y1;
- drw_w = clipped_area.x2 - clipped_area.x1;
- drw_h = clipped_area.y2 - clipped_area.y1;
-
if (!ephyrHostXVGetVideo(a_info->pScreen->myNum,
port_priv->port_number,
a_vid_x, a_vid_y, a_vid_w, a_vid_h,
@@ -1104,7 +1092,6 @@ ephyrPutStill(KdScreenInfo * a_info,
EphyrPortPriv *port_priv = a_port_priv;
BoxRec clipped_area, dst_box;
int result = BadImplementation;
- int drw_x = 0, drw_y = 0, drw_w = 0, drw_h = 0;
EPHYR_RETURN_VAL_IF_FAIL(a_info && a_info->pScreen, BadValue);
EPHYR_RETURN_VAL_IF_FAIL(a_drawable && port_priv, BadValue);
@@ -1122,11 +1109,6 @@ ephyrPutStill(KdScreenInfo * a_info,
goto out;
}
- drw_x = clipped_area.x1;
- drw_y = clipped_area.y1;
- drw_w = clipped_area.x2 - clipped_area.x1;
- drw_h = clipped_area.y2 - clipped_area.y1;
-
if (!ephyrHostXVPutStill(a_info->pScreen->myNum,
port_priv->port_number,
a_vid_x, a_vid_y, a_vid_w, a_vid_h,
@@ -1153,7 +1135,6 @@ ephyrGetStill(KdScreenInfo * a_info,
EphyrPortPriv *port_priv = a_port_priv;
BoxRec clipped_area, dst_box;
int result = BadImplementation;
- int drw_x = 0, drw_y = 0, drw_w = 0, drw_h = 0;
EPHYR_RETURN_VAL_IF_FAIL(a_info && a_info->pScreen, BadValue);
EPHYR_RETURN_VAL_IF_FAIL(a_drawable && port_priv, BadValue);
@@ -1171,11 +1152,6 @@ ephyrGetStill(KdScreenInfo * a_info,
goto out;
}
- drw_x = clipped_area.x1;
- drw_y = clipped_area.y1;
- drw_w = clipped_area.x2 - clipped_area.x1;
- drw_h = clipped_area.y2 - clipped_area.y1;
-
if (!ephyrHostXVGetStill(a_info->pScreen->myNum,
port_priv->port_number,
a_vid_x, a_vid_y, a_vid_w, a_vid_h,
diff --git a/xorg-server/hw/kdrive/ephyr/hostx.c b/xorg-server/hw/kdrive/ephyr/hostx.c
index 157ac36b2..f2b458d90 100644
--- a/xorg-server/hw/kdrive/ephyr/hostx.c
+++ b/xorg-server/hw/kdrive/ephyr/hostx.c
@@ -117,6 +117,8 @@ extern EphyrKeySyms ephyrKeySyms;
extern int monitorResolution;
+extern Bool EphyrWantResize;
+
char *ephyrResName = NULL;
int ephyrResNameFromCmd = 0;
char *ephyrTitle = NULL;
@@ -617,7 +619,8 @@ hostx_set_cmap_entry(unsigned char idx,
*/
void *
hostx_screen_init(EphyrScreenInfo screen,
- int width, int height, int buffer_height)
+ int width, int height, int buffer_height,
+ int *bytes_per_line, int *bits_per_pixel)
{
int bitmap_pad;
Bool shm_success = False;
@@ -694,10 +697,13 @@ hostx_screen_init(EphyrScreenInfo screen,
malloc(host_screen->ximg->bytes_per_line * buffer_height);
}
+ *bytes_per_line = host_screen->ximg->bytes_per_line;
+ *bits_per_pixel = host_screen->ximg->bits_per_pixel;
+
XResizeWindow(HostX.dpy, host_screen->win, width, height);
/* Ask the WM to keep our size static */
- if (host_screen->win_pre_existing == None) {
+ if (host_screen->win_pre_existing == None && !EphyrWantResize) {
size_hints = XAllocSizeHints();
size_hints->max_width = size_hints->min_width = width;
size_hints->max_height = size_hints->min_height = height;
@@ -858,7 +864,7 @@ hostx_load_keymap(void)
(max_keycode - min_keycode + 1) *
width);
if (!ephyrKeySyms.map)
- return;
+ goto out;
for (i = 0; i < (max_keycode - min_keycode + 1); i++)
for (j = 0; j < width; j++)
@@ -871,6 +877,7 @@ hostx_load_keymap(void)
ephyrKeySyms.maxKeyCode = max_keycode;
ephyrKeySyms.mapWidth = width;
+ out:
XFree(keymap);
}
@@ -1011,19 +1018,27 @@ hostx_get_event(EphyrHostXEvent * ev)
case ConfigureNotify:
{
- struct EphyrHostScreen *host_screen =
- host_screen_from_window(xev.xconfigure.window);
-
- if (host_screen && host_screen->win_pre_existing != None) {
- ev->type = EPHYR_EV_CONFIGURE;
- ev->data.configure.width = xev.xconfigure.width;
- ev->data.configure.height = xev.xconfigure.height;
- ev->data.configure.window = xev.xconfigure.window;
- ev->data.configure.screen = host_screen->mynum;
- return 1;
+ struct EphyrHostScreen *host_screen;
+
+ /* event compression as for Expose events, cause
+ * we don't want to resize the framebuffer for
+ * every single change */
+ while (XCheckTypedWindowEvent(HostX.dpy, xev.xconfigure.window,
+ ConfigureNotify, &xev));
+ host_screen = host_screen_from_window(xev.xconfigure.window);
+
+ if (!host_screen ||
+ (host_screen->win_pre_existing == None && !EphyrWantResize)) {
+ return 0;
}
- return 0;
+ ev->type = EPHYR_EV_CONFIGURE;
+ ev->data.configure.width = xev.xconfigure.width;
+ ev->data.configure.height = xev.xconfigure.height;
+ ev->data.configure.window = xev.xconfigure.window;
+ ev->data.configure.screen = host_screen->mynum;
+
+ return 1;
}
default:
break;
diff --git a/xorg-server/hw/kdrive/ephyr/hostx.h b/xorg-server/hw/kdrive/ephyr/hostx.h
index 31c4053aa..38b7b3768 100644
--- a/xorg-server/hw/kdrive/ephyr/hostx.h
+++ b/xorg-server/hw/kdrive/ephyr/hostx.h
@@ -193,7 +193,8 @@ hostx_set_cmap_entry(unsigned char idx,
unsigned char r, unsigned char g, unsigned char b);
void *hostx_screen_init(EphyrScreenInfo screen,
- int width, int height, int buffer_height);
+ int width, int height, int buffer_height,
+ int *bytes_per_line, int *bits_per_pixel);
void
diff --git a/xorg-server/hw/kdrive/fbdev/fbdev.c b/xorg-server/hw/kdrive/fbdev/fbdev.c
index fd14afa92..fb6e3a292 100644
--- a/xorg-server/hw/kdrive/fbdev/fbdev.c
+++ b/xorg-server/hw/kdrive/fbdev/fbdev.c
@@ -465,16 +465,6 @@ fbdevRandRSetConfig(ScreenPtr pScreen,
int oldheight;
int oldmmwidth;
int oldmmheight;
- int newwidth, newheight;
-
- if (screen->randr & (RR_Rotate_0 | RR_Rotate_180)) {
- newwidth = pSize->width;
- newheight = pSize->height;
- }
- else {
- newwidth = pSize->height;
- newheight = pSize->width;
- }
if (wasEnabled)
KdDisableScreen(pScreen);
diff --git a/xorg-server/hw/kdrive/linux/mouse.c b/xorg-server/hw/kdrive/linux/mouse.c
index c87507790..f4424478a 100644
--- a/xorg-server/hw/kdrive/linux/mouse.c
+++ b/xorg-server/hw/kdrive/linux/mouse.c
@@ -441,10 +441,8 @@ ps2SkipInit(KdPointerInfo * pi, int ninit, Bool ret_next)
{
Kmouse *km = pi->driverPrivate;
int c = -1;
- int skipping;
Bool waiting;
- skipping = 0;
waiting = FALSE;
while (ninit || ret_next) {
c = MouseReadByte(&km->iob, MOUSE_TIMEOUT);
@@ -469,8 +467,6 @@ static Bool
ps2Init(KdPointerInfo * pi)
{
Kmouse *km = pi->driverPrivate;
- int skipping;
- Bool waiting;
int id;
unsigned char *init;
int ninit;
@@ -483,8 +479,6 @@ ps2Init(KdPointerInfo * pi)
*/
if (!MouseWriteByte(km->iob.fd, PSMC_SEND_DEV_ID, 100))
return FALSE;
- skipping = 0;
- waiting = FALSE;
id = ps2SkipInit(pi, 0, TRUE);
switch (id) {
case 3:
diff --git a/xorg-server/hw/kdrive/src/kinput.c b/xorg-server/hw/kdrive/src/kinput.c
index b1068bbee..c30f1708d 100644
--- a/xorg-server/hw/kdrive/src/kinput.c
+++ b/xorg-server/hw/kdrive/src/kinput.c
@@ -1821,16 +1821,11 @@ KdEnqueueKeyboardEvent(KdKeyboardInfo * ki,
unsigned char scan_code, unsigned char is_up)
{
unsigned char key_code;
- KeyClassPtr keyc = NULL;
- KeybdCtrl *ctrl = NULL;
int type;
if (!ki || !ki->dixdev || !ki->dixdev->kbdfeed || !ki->dixdev->key)
return;
- keyc = ki->dixdev->key;
- ctrl = &ki->dixdev->kbdfeed->ctrl;
-
if (scan_code >= ki->minScanCode && scan_code <= ki->maxScanCode) {
key_code = scan_code + KD_MIN_KEYCODE - ki->minScanCode;
@@ -1864,7 +1859,6 @@ void
KdEnqueuePointerEvent(KdPointerInfo * pi, unsigned long flags, int rx, int ry,
int rz)
{
- CARD32 ms;
unsigned char buttons;
int x, y, z;
int (*matrix)[3] = kdPointerMatrix.matrix;
@@ -1875,8 +1869,6 @@ KdEnqueuePointerEvent(KdPointerInfo * pi, unsigned long flags, int rx, int ry,
if (!pi)
return;
- ms = GetTimeInMillis();
-
/* we don't need to transform z, so we don't. */
if (flags & KD_MOUSE_DELTA) {
if (pi->transformCoordinates) {
diff --git a/xorg-server/hw/kdrive/src/kxv.c b/xorg-server/hw/kdrive/src/kxv.c
index cf656363d..22639728d 100644
--- a/xorg-server/hw/kdrive/src/kxv.c
+++ b/xorg-server/hw/kdrive/src/kxv.c
@@ -1174,7 +1174,6 @@ void
KdXVDisable(ScreenPtr pScreen)
{
XvScreenPtr pxvs;
- KdXVScreenPtr ScreenPriv;
XvAdaptorPtr pAdaptor;
XvPortPtr pPort;
XvPortRecPrivatePtr pPriv;
@@ -1184,7 +1183,6 @@ KdXVDisable(ScreenPtr pScreen)
return;
pxvs = GET_XV_SCREEN(pScreen);
- ScreenPriv = GET_KDXV_SCREEN(pScreen);
for (i = 0; i < pxvs->nAdaptors; i++) {
pAdaptor = &pxvs->pAdaptors[i];
diff --git a/xorg-server/hw/xfree86/common/xf86Events.c b/xorg-server/hw/xfree86/common/xf86Events.c
index d92174edf..055223310 100644
--- a/xorg-server/hw/xfree86/common/xf86Events.c
+++ b/xorg-server/hw/xfree86/common/xf86Events.c
@@ -413,7 +413,6 @@ static void
xf86VTSwitch(void)
{
int i;
- static int prevSIGIO;
InputInfoPtr pInfo;
IHPtr ih;
diff --git a/xorg-server/hw/xfree86/common/xf86Mode.c b/xorg-server/hw/xfree86/common/xf86Mode.c
index d80dec892..706ab64fc 100644
--- a/xorg-server/hw/xfree86/common/xf86Mode.c
+++ b/xorg-server/hw/xfree86/common/xf86Mode.c
@@ -1370,7 +1370,6 @@ xf86ValidateModes(ScrnInfoPtr scrp, DisplayModePtr availModes,
int saveType;
PixmapFormatRec *BankFormat;
ClockRangePtr cp;
- ClockRangePtr storeClockRanges;
int numTimings = 0;
range hsync[MAX_HSYNC];
range vrefresh[MAX_VREFRESH];
@@ -1492,16 +1491,14 @@ xf86ValidateModes(ScrnInfoPtr scrp, DisplayModePtr availModes,
/*
* Store the clockRanges for later use by the VidMode extension.
*/
- storeClockRanges = scrp->clockRanges;
- while (storeClockRanges != NULL) {
- storeClockRanges = storeClockRanges->next;
- }
- for (cp = clockRanges; cp != NULL; cp = cp->next,
- storeClockRanges = storeClockRanges->next) {
- storeClockRanges = xnfalloc(sizeof(ClockRange));
+ nt_list_for_each_entry(cp, clockRanges, next) {
+ ClockRangePtr newCR = xnfalloc(sizeof(ClockRange));
+ memcpy(newCR, cp, sizeof(ClockRange));
+ newCR->next = NULL;
if (scrp->clockRanges == NULL)
- scrp->clockRanges = storeClockRanges;
- memcpy(storeClockRanges, cp, sizeof(ClockRange));
+ scrp->clockRanges = newCR;
+ else
+ nt_list_append(newCR, scrp->clockRanges, ClockRange, next);
}
/* Determine which pixmap format to pass to scanLineWidth() */
diff --git a/xorg-server/hw/xfree86/common/xf86Option.c b/xorg-server/hw/xfree86/common/xf86Option.c
index 40c9d15f4..607c33354 100644
--- a/xorg-server/hw/xfree86/common/xf86Option.c
+++ b/xorg-server/hw/xfree86/common/xf86Option.c
@@ -743,7 +743,7 @@ xf86TokenToOptName(const OptionInfoRec * table, int token)
const OptionInfoRec *p;
p = xf86TokenToOptinfo(table, token);
- return p->name;
+ return p ? p->name : NULL;
}
Bool
diff --git a/xorg-server/hw/xfree86/common/xf86fbman.c b/xorg-server/hw/xfree86/common/xf86fbman.c
index c2e7bab9f..4da6af2b6 100644
--- a/xorg-server/hw/xfree86/common/xf86fbman.c
+++ b/xorg-server/hw/xfree86/common/xf86fbman.c
@@ -320,15 +320,17 @@ localRegisterFreeBoxCallback(ScreenPtr pScreen,
newCallbacks = realloc(offman->FreeBoxesUpdateCallback,
sizeof(FreeBoxCallbackProcPtr) *
(offman->NumCallbacks + 1));
+ if (!newCallbacks)
+ return FALSE;
+ else
+ offman->FreeBoxesUpdateCallback = newCallbacks;
newPrivates = realloc(offman->devPrivates,
sizeof(DevUnion) * (offman->NumCallbacks + 1));
-
- if (!newCallbacks || !newPrivates)
+ if (!newPrivates)
return FALSE;
-
- offman->FreeBoxesUpdateCallback = newCallbacks;
- offman->devPrivates = newPrivates;
+ else
+ offman->devPrivates = newPrivates;
offman->FreeBoxesUpdateCallback[offman->NumCallbacks] = FreeBoxCallback;
offman->devPrivates[offman->NumCallbacks].ptr = devPriv;
diff --git a/xorg-server/hw/xfree86/common/xf86xvmc.c b/xorg-server/hw/xfree86/common/xf86xvmc.c
index 78a32bfe1..3169c054c 100644
--- a/xorg-server/hw/xfree86/common/xf86xvmc.c
+++ b/xorg-server/hw/xfree86/common/xf86xvmc.c
@@ -158,8 +158,10 @@ xf86XvMCScreenInit(ScreenPtr pScreen,
if (!(pAdapt = malloc(sizeof(XvMCAdaptorRec) * num_adaptors)))
return FALSE;
- if (!dixRegisterPrivateKey(&XF86XvMCScreenKeyRec, PRIVATE_SCREEN, 0))
+ if (!dixRegisterPrivateKey(&XF86XvMCScreenKeyRec, PRIVATE_SCREEN, 0)) {
+ free(pAdapt);
return FALSE;
+ }
if (!(pScreenPriv = malloc(sizeof(xf86XvMCScreenRec)))) {
free(pAdapt);
diff --git a/xorg-server/hw/xfree86/ddc/ddc.c b/xorg-server/hw/xfree86/ddc/ddc.c
index 28c969646..44c1d535c 100644
--- a/xorg-server/hw/xfree86/ddc/ddc.c
+++ b/xorg-server/hw/xfree86/ddc/ddc.c
@@ -91,15 +91,16 @@ resort(unsigned char *s_block)
unsigned char *d_new, *d_ptr, *d_end, *s_ptr, *s_end;
unsigned char tmp;
+ s_ptr = find_header(s_block);
+ if (!s_ptr)
+ return NULL;
s_end = s_block + EDID1_LEN;
+
d_new = malloc(EDID1_LEN);
if (!d_new)
return NULL;
d_end = d_new + EDID1_LEN;
- s_ptr = find_header(s_block);
- if (!s_ptr)
- return NULL;
for (d_ptr = d_new; d_ptr < d_end; d_ptr++) {
tmp = *(s_ptr++);
*d_ptr = tmp;
diff --git a/xorg-server/hw/xfree86/ramdac/xf86Cursor.c b/xorg-server/hw/xfree86/ramdac/xf86Cursor.c
index 8d48a7542..d32aac1cf 100644
--- a/xorg-server/hw/xfree86/ramdac/xf86Cursor.c
+++ b/xorg-server/hw/xfree86/ramdac/xf86Cursor.c
@@ -16,7 +16,6 @@
* Externing inputInfo is not the nice way to do it but it works.
*/
#include "inputstr.h"
-extern InputInfo inputInfo;
DevPrivateKeyRec xf86CursorScreenKeyRec;
diff --git a/xorg-server/hw/xquartz/GL/visualConfigs.c b/xorg-server/hw/xquartz/GL/visualConfigs.c
index 03486cd66..a00abf29a 100644
--- a/xorg-server/hw/xquartz/GL/visualConfigs.c
+++ b/xorg-server/hw/xquartz/GL/visualConfigs.c
@@ -262,6 +262,9 @@ __GLXconfig *__glXAquaCreateVisualConfigs(int *numConfigsPtr, int screenNumber)
c->bindToTextureTargets = 0;
c->yInverted = 0;
+ /* EXT_framebuffer_sRGB */
+ c->sRGBCapable = GL_FALSE;
+
c = c->next;
}
}
diff --git a/xorg-server/hw/xwin/glx/indirect.c b/xorg-server/hw/xwin/glx/indirect.c
index 00cef3673..14a47110a 100644
--- a/xorg-server/hw/xwin/glx/indirect.c
+++ b/xorg-server/hw/xwin/glx/indirect.c
@@ -2025,6 +2025,7 @@ glxWinCreateConfigs(HDC hdc, glxWinScreen * screen)
c->base.bindToMipmapTexture = -1;
c->base.bindToTextureTargets = -1;
c->base.yInverted = -1;
+ c->base.sRGBCapable = 0;
n++;
@@ -2419,6 +2420,7 @@ glxWinCreateConfigsExt(HDC hdc, glxWinScreen * screen)
GLX_TEXTURE_1D_BIT_EXT | GLX_TEXTURE_2D_BIT_EXT |
GLX_TEXTURE_RECTANGLE_BIT_EXT;
c->base.yInverted = -1;
+ c->base.sRGBCapable = 0;
n++;
diff --git a/xorg-server/include/dix-config.h.in b/xorg-server/include/dix-config.h.in
index e1cb9eb51..a643dfcc8 100644
--- a/xorg-server/include/dix-config.h.in
+++ b/xorg-server/include/dix-config.h.in
@@ -60,6 +60,9 @@
/* Has backtrace support */
#undef HAVE_BACKTRACE
+/* Has libunwind support */
+#undef HAVE_LIBUNWIND
+
/* Define to 1 if you have the <byteswap.h> header file. */
#undef HAVE_BYTESWAP_H
diff --git a/xorg-server/include/input.h b/xorg-server/include/input.h
index 5c65597e4..304895ffc 100644
--- a/xorg-server/include/input.h
+++ b/xorg-server/include/input.h
@@ -638,6 +638,11 @@ extern _X_HIDDEN void valuator_set_mode(DeviceIntPtr dev, int axis, int mode);
xfixes/cursor.c uses it to determine if the cursor is enabled */
extern Bool EnableCursor;
+/* Set to FALSE by default - ChangeWindowAttributes sets it to TRUE on
+ * CWCursor, xfixes/cursor.c uses it to determine if the cursor is enabled
+ */
+extern Bool CursorVisible;
+
extern _X_EXPORT ValuatorMask *valuator_mask_new(int num_valuators);
extern _X_EXPORT void valuator_mask_free(ValuatorMask **mask);
extern _X_EXPORT void valuator_mask_set_range(ValuatorMask *mask,
diff --git a/xorg-server/include/list.h b/xorg-server/include/list.h
index 067c6794f..11de7c561 100644
--- a/xorg-server/include/list.h
+++ b/xorg-server/include/list.h
@@ -119,7 +119,7 @@ struct xorg_list {
*
* @param The list to initialized.
*/
-static void
+static inline void
xorg_list_init(struct xorg_list *list)
{
list->next = list->prev = list;
diff --git a/xorg-server/os/Makefile.am b/xorg-server/os/Makefile.am
index 88914852f..364b6da2d 100644
--- a/xorg-server/os/Makefile.am
+++ b/xorg-server/os/Makefile.am
@@ -34,6 +34,11 @@ if XDMCP
libos_la_SOURCES += $(XDMCP_SRCS)
endif
+if HAVE_LIBUNWIND
+AM_CFLAGS += $(LIBUNWIND_CFLAGS)
+libos_la_LIBADD += $(LIBUNWIND_LIBS)
+endif
+
EXTRA_DIST = $(SECURERPC_SRCS) $(XDMCP_SRCS)
if SPECIAL_DTRACE_OBJECTS
diff --git a/xorg-server/os/backtrace.c b/xorg-server/os/backtrace.c
index daac60cf6..426f9b15b 100644
--- a/xorg-server/os/backtrace.c
+++ b/xorg-server/os/backtrace.c
@@ -30,6 +30,80 @@
#include <errno.h>
#include <string.h>
+#ifdef HAVE_LIBUNWIND
+
+#define UNW_LOCAL_ONLY
+#include <libunwind.h>
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <dlfcn.h>
+
+void
+xorg_backtrace(void)
+{
+ unw_cursor_t cursor;
+ unw_context_t context;
+ unw_word_t off;
+ unw_proc_info_t pip;
+ int ret, i = 0;
+ char procname[256];
+ const char *filename;
+ Dl_info dlinfo;
+
+ pip.unwind_info = NULL;
+ ret = unw_getcontext(&context);
+ if (ret) {
+ ErrorFSigSafe("unw_getcontext failed: %s [%d]\n", unw_strerror(ret),
+ ret);
+ return;
+ }
+
+ ret = unw_init_local(&cursor, &context);
+ if (ret) {
+ ErrorFSigSafe("unw_init_local failed: %s [%d]\n", unw_strerror(ret),
+ ret);
+ return;
+ }
+
+ ErrorFSigSafe("\n");
+ ErrorFSigSafe("Backtrace:\n");
+ ret = unw_step(&cursor);
+ while (ret > 0) {
+ ret = unw_get_proc_info(&cursor, &pip);
+ if (ret) {
+ ErrorFSigSafe("unw_get_proc_info failed: %s [%d]\n",
+ unw_strerror(ret), ret);
+ break;
+ }
+
+ ret = unw_get_proc_name(&cursor, procname, 256, &off);
+ if (ret && ret != -UNW_ENOMEM) {
+ if (ret != -UNW_EUNSPEC)
+ ErrorFSigSafe("unw_get_proc_name failed: %s [%d]\n",
+ unw_strerror(ret), ret);
+ procname[0] = '?';
+ procname[1] = 0;
+ }
+
+ if (dladdr((void *)(pip.start_ip + off), &dlinfo) && dlinfo.dli_fname &&
+ *dlinfo.dli_fname)
+ filename = dlinfo.dli_fname;
+ else
+ filename = "?";
+
+ ErrorFSigSafe("%u: %s (%s%s+0x%x) [%p]\n", i++, filename, procname,
+ ret == -UNW_ENOMEM ? "..." : "", (int)off,
+ (void *)(pip.start_ip + off));
+
+ ret = unw_step(&cursor);
+ if (ret < 0)
+ ErrorFSigSafe("unw_step failed: %s [%d]\n", unw_strerror(ret), ret);
+ }
+ ErrorFSigSafe("\n");
+}
+#else /* HAVE_LIBUNWIND */
#ifdef HAVE_BACKTRACE
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
@@ -246,3 +320,4 @@ xorg_backtrace(void)
#endif
#endif
+#endif
diff --git a/xorg-server/os/log.c b/xorg-server/os/log.c
index 95bd8cca9..dc6e2888b 100644
--- a/xorg-server/os/log.c
+++ b/xorg-server/os/log.c
@@ -279,6 +279,10 @@ LogSetParameter(LogParameter param, int value)
}
}
+/**
+ * Signal-safe snprintf, with some limitations over snprintf. Be careful
+ * which directives you use.
+ */
static int
pnprintf(char *string, size_t size, const char *f, va_list args)
{
diff --git a/xorg-server/randr/rrcrtc.c b/xorg-server/randr/rrcrtc.c
index 6e2eca5ad..721b05ac3 100644
--- a/xorg-server/randr/rrcrtc.c
+++ b/xorg-server/randr/rrcrtc.c
@@ -363,13 +363,12 @@ void
RRCrtcDetachScanoutPixmap(RRCrtcPtr crtc)
{
ScreenPtr master = crtc->pScreen->current_master;
- int ret;
PixmapPtr mscreenpix;
rrScrPriv(crtc->pScreen);
mscreenpix = master->GetScreenPixmap(master);
- ret = pScrPriv->rrCrtcSetScanoutPixmap(crtc, NULL);
+ pScrPriv->rrCrtcSetScanoutPixmap(crtc, NULL);
if (crtc->scanout_pixmap) {
master->StopPixmapTracking(mscreenpix, crtc->scanout_pixmap);
/*
@@ -442,7 +441,7 @@ rrCheckPixmapBounding(ScreenPtr pScreen,
RRCrtcPtr rr_crtc, int x, int y, int w, int h)
{
RegionRec root_pixmap_region, total_region, new_crtc_region;
- int i, c;
+ int c;
BoxRec newbox;
BoxPtr newsize;
ScreenPtr slave;
@@ -502,10 +501,8 @@ rrCheckPixmapBounding(ScreenPtr pScreen,
new_height == screen_pixmap->drawable.height) {
ErrorF("adjust shatters %d %d\n", newsize->x1, newsize->x2);
} else {
- int ret;
rrScrPriv(pScreen);
- ret = pScrPriv->rrScreenSetSize(pScreen,
- new_width, new_height, 0, 0);
+ pScrPriv->rrScreenSetSize(pScreen, new_width, new_height, 0, 0);
}
/* set shatters TODO */
diff --git a/xorg-server/xfixes/cursor.c b/xorg-server/xfixes/cursor.c
index 568e717fa..90a026b28 100644
--- a/xorg-server/xfixes/cursor.c
+++ b/xorg-server/xfixes/cursor.c
@@ -129,8 +129,7 @@ typedef struct _CursorScreen {
#define Unwrap(as,s,elt,backup) (((backup) = (s)->elt), (s)->elt = (as)->elt)
/* The cursor doesn't show up until the first XDefineCursor() */
-static Bool CursorVisible = FALSE;
-
+Bool CursorVisible = FALSE;
Bool EnableCursor = TRUE;
static Bool
@@ -142,12 +141,7 @@ CursorDisplayCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
Unwrap(cs, pScreen, DisplayCursor, backupProc);
- /*
- * Have to check ConnectionInfo to distinguish client requests from
- * initial root window setup. Not a great way to do it, I admit.
- */
- if (ConnectionInfo)
- CursorVisible = EnableCursor;
+ CursorVisible = CursorVisible && EnableCursor;
if (cs->pCursorHideCounts != NULL || !CursorVisible) {
ret = (*pScreen->DisplayCursor) (pDev, pScreen, NullCursor);
diff --git a/xorg-server/xfixes/xfixesint.h b/xorg-server/xfixes/xfixesint.h
index 334c71fbf..44e889040 100644
--- a/xorg-server/xfixes/xfixesint.h
+++ b/xorg-server/xfixes/xfixesint.h
@@ -291,8 +291,10 @@ int
SProcXFixesDestroyPointerBarrier(ClientPtr client);
/* Xinerama */
+#ifdef PANORAMIX
extern int (*PanoramiXSaveXFixesVector[XFixesNumberRequests]) (ClientPtr);
void PanoramiXFixesInit(void);
void PanoramiXFixesReset(void);
+#endif
#endif /* _XFIXESINT_H_ */
diff --git a/xorg-server/xkb/xkb.c b/xorg-server/xkb/xkb.c
index 7e51e4080..c78aceb78 100644
--- a/xorg-server/xkb/xkb.c
+++ b/xorg-server/xkb/xkb.c
@@ -3073,6 +3073,7 @@ XkbComputeGetIndicatorMapReplySize(XkbIndicatorPtr indicators,
nIndicators++;
}
rep->length = (nIndicators * SIZEOF(xkbIndicatorMapWireDesc)) / 4;
+ rep->nIndicators = nIndicators;
return Success;
}
@@ -3984,13 +3985,11 @@ _XkbSetNamesCheck(ClientPtr client, DeviceIntPtr dev,
xkbSetNamesReq * stuff, CARD32 *data)
{
XkbDescRec *xkb;
- XkbNamesRec *names;
CARD32 *tmp;
Atom bad;
tmp = data;
xkb = dev->key->xkbInfo->desc;
- names = xkb->names;
if (stuff->which & XkbKeyTypeNamesMask) {
int i;
diff --git a/xorg-server/xkb/xkbActions.c b/xorg-server/xkb/xkbActions.c
index 416de925d..e32005cf6 100644
--- a/xorg-server/xkb/xkbActions.c
+++ b/xorg-server/xkb/xkbActions.c
@@ -222,7 +222,6 @@ _XkbFilterSetState(XkbSrvInfoPtr xkbi,
#define LATCH_KEY_DOWN 1
#define LATCH_PENDING 2
-#define NO_LATCH 3
static int
_XkbFilterLatchState(XkbSrvInfoPtr xkbi,
@@ -230,6 +229,7 @@ _XkbFilterLatchState(XkbSrvInfoPtr xkbi,
{
if (filter->keycode == 0) { /* initial press */
+ AccessXCancelRepeatKey(xkbi,keycode);
filter->keycode = keycode;
filter->active = 1;
filter->filterOthers = 1;
@@ -250,91 +250,102 @@ _XkbFilterLatchState(XkbSrvInfoPtr xkbi,
else if (pAction && (filter->priv == LATCH_PENDING)) {
if (((1 << pAction->type) & XkbSA_BreakLatch) != 0) {
filter->active = 0;
- if (filter->upAction.type == XkbSA_LatchMods)
- xkbi->state.latched_mods &= ~filter->upAction.mods.mask;
- else
- xkbi->state.latched_group -=
- XkbSAGroup(&filter->upAction.group);
- }
- else if ((pAction->type == filter->upAction.type) &&
- (pAction->mods.flags == filter->upAction.mods.flags) &&
- (pAction->mods.mask == filter->upAction.mods.mask)) {
- if (filter->upAction.mods.flags & XkbSA_LatchToLock) {
- XkbControlsPtr ctrls = xkbi->desc->ctrls;
-
- if (filter->upAction.type == XkbSA_LatchMods)
- pAction->mods.type = XkbSA_LockMods;
- else
- pAction->group.type = XkbSA_LockGroup;
- if (XkbAX_NeedFeedback(ctrls, XkbAX_StickyKeysFBMask) &&
- (ctrls->enabled_ctrls & XkbStickyKeysMask)) {
- XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_LOCK,
- XkbStickyKeysMask);
- }
- }
- else {
- if (filter->upAction.type == XkbSA_LatchMods)
- pAction->mods.type = XkbSA_SetMods;
- else
- pAction->group.type = XkbSA_SetGroup;
- }
- if (filter->upAction.type == XkbSA_LatchMods)
- xkbi->state.latched_mods &= ~filter->upAction.mods.mask;
- else
- xkbi->state.latched_group -=
- XkbSAGroup(&filter->upAction.group);
- filter->active = 0;
+ /* If one latch is broken, all latches are broken, so it's no use
+ to find out which particular latch this filter tracks. */
+ xkbi->state.latched_mods = 0;
+ xkbi->state.latched_group = 0;
}
}
- else if (filter->keycode == keycode) { /* release */
+ else if (filter->keycode == keycode && filter->priv != LATCH_PENDING){
+ /* The test above for LATCH_PENDING skips subsequent releases of the
+ key after it has been released first time and the latch became
+ pending. */
XkbControlsPtr ctrls = xkbi->desc->ctrls;
- int needBeep;
- int beepType = _BEEP_NONE;
+ int needBeep = ((ctrls->enabled_ctrls & XkbStickyKeysMask) &&
+ XkbAX_NeedFeedback(ctrls, XkbAX_StickyKeysFBMask));
- needBeep = ((ctrls->enabled_ctrls & XkbStickyKeysMask) &&
- XkbAX_NeedFeedback(ctrls, XkbAX_StickyKeysFBMask));
if (filter->upAction.type == XkbSA_LatchMods) {
- xkbi->clearMods = filter->upAction.mods.mask;
- if ((filter->upAction.mods.flags & XkbSA_ClearLocks) &&
- (xkbi->clearMods & xkbi->state.locked_mods) ==
- xkbi->clearMods) {
- xkbi->state.locked_mods &= ~xkbi->clearMods;
- filter->priv = NO_LATCH;
- beepType = _BEEP_STICKY_UNLOCK;
+ unsigned char mask = filter->upAction.mods.mask;
+ unsigned char common;
+
+ xkbi->clearMods = mask;
+
+ /* ClearLocks */
+ common = mask & xkbi->state.locked_mods;
+ if ((filter->upAction.mods.flags & XkbSA_ClearLocks) && common) {
+ mask &= ~common;
+ xkbi->state.locked_mods &= ~common;
+ if (needBeep)
+ XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_UNLOCK,
+ XkbStickyKeysMask);
+ }
+ /* LatchToLock */
+ common = mask & xkbi->state.latched_mods;
+ if ((filter->upAction.mods.flags & XkbSA_LatchToLock) && common) {
+ unsigned char newlocked;
+
+ mask &= ~common;
+ newlocked = common & ~xkbi->state.locked_mods;
+ if(newlocked){
+ xkbi->state.locked_mods |= newlocked;
+ if (needBeep)
+ XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_LOCK,
+ XkbStickyKeysMask);
+
+ }
+ xkbi->state.latched_mods &= ~common;
+ }
+ /* Latch remaining modifiers, if any. */
+ if (mask) {
+ xkbi->state.latched_mods |= mask;
+ filter->priv = LATCH_PENDING;
+ if (needBeep)
+ XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_LATCH,
+ XkbStickyKeysMask);
}
}
else {
xkbi->groupChange = -XkbSAGroup(&filter->upAction.group);
+ /* ClearLocks */
if ((filter->upAction.group.flags & XkbSA_ClearLocks) &&
(xkbi->state.locked_group)) {
xkbi->state.locked_group = 0;
- filter->priv = NO_LATCH;
- beepType = _BEEP_STICKY_UNLOCK;
+ if (needBeep)
+ XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_UNLOCK,
+ XkbStickyKeysMask);
}
- }
- if (filter->priv == NO_LATCH) {
- filter->active = 0;
- }
- else {
- filter->priv = LATCH_PENDING;
- if (filter->upAction.type == XkbSA_LatchMods) {
- xkbi->state.latched_mods |= filter->upAction.mods.mask;
- needBeep = xkbi->state.latched_mods ? needBeep : 0;
- xkbi->state.latched_mods |= filter->upAction.mods.mask;
+ /* LatchToLock */
+ else if ((filter->upAction.group.flags & XkbSA_LatchToLock)
+ && (xkbi->state.latched_group)) {
+ xkbi->state.locked_group += XkbSAGroup(&filter->upAction.group);
+ xkbi->state.latched_group -= XkbSAGroup(&filter->upAction.group);
+ if(XkbSAGroup(&filter->upAction.group) && needBeep)
+ XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_LOCK,
+ XkbStickyKeysMask);
}
- else {
- xkbi->state.latched_group +=
- XkbSAGroup(&filter->upAction.group);
+ /* Latch group */
+ else if(XkbSAGroup(&filter->upAction.group)){
+ xkbi->state.latched_group += XkbSAGroup(&filter->upAction.group);
+ filter->priv = LATCH_PENDING;
+ if (needBeep)
+ XkbDDXAccessXBeep(xkbi->device, _BEEP_STICKY_LATCH,
+ XkbStickyKeysMask);
}
- if (needBeep && (beepType == _BEEP_NONE))
- beepType = _BEEP_STICKY_LATCH;
}
- if (needBeep && (beepType != _BEEP_NONE))
- XkbDDXAccessXBeep(xkbi->device, beepType, XkbStickyKeysMask);
+
+ if (filter->priv != LATCH_PENDING)
+ filter->active = 0;
}
- else if (filter->priv == LATCH_KEY_DOWN) {
- filter->priv = NO_LATCH;
- filter->filterOthers = 0;
+ else if (pAction && (filter->priv == LATCH_KEY_DOWN)) {
+ /* Latch was broken before it became pending: degrade to a
+ SetMods/SetGroup. */
+ if (filter->upAction.type == XkbSA_LatchMods)
+ filter->upAction.type = XkbSA_SetMods;
+ else
+ filter->upAction.type = XkbSA_SetGroup;
+ filter->filter = _XkbFilterSetState;
+ filter->priv = 0;
+ return filter->filter(xkbi, filter, keycode, pAction);
}
return 1;
}