From dde22e946ccfb0bd937224daf42403b80528c2a6 Mon Sep 17 00:00:00 2001 From: marha Date: Mon, 25 Mar 2013 10:20:34 +0100 Subject: fontconfig mesa pixman xserver git update 25 Mar 2013 xserver commit 2967391c6d35f03121afa8003e0fb94b62495129 pixman commit d8ac35af1208a4fa4d67f03fee10b5449fb8495a fontconfig commit b561ff2016ce84eef3c81f16dfb0481be6a13f9b mesa commit 92b8a37fdfff9e83f39b8885f51ed2f60326ab6a --- fontconfig/fontconfig/fontconfig.h | 1 + fontconfig/src/fcfreetype.c | 49 +++- fontconfig/src/fcint.h | 6 + fontconfig/src/fcmatch.c | 21 ++ fontconfig/src/fcobjs.h | 1 + fontconfig/src/fcpat.c | 2 + fontconfig/src/fcstr.c | 85 +++--- mesalib/Android.common.mk | 2 + mesalib/configure.ac | 3 + mesalib/docs/GL3.txt | 2 +- mesalib/docs/index.html | 6 + mesalib/docs/relnotes-9.1.1.html | 235 +++++++++++++++++ mesalib/include/GL/internal/dri_interface.h | 15 +- mesalib/scons/gallium.py | 2 +- mesalib/src/gallium/auxiliary/Makefile.sources | 1 + mesalib/src/glsl/glsl_types.cpp | 12 +- mesalib/src/glsl/glsl_types.h | 1 + mesalib/src/glsl/main.cpp | 2 +- mesalib/src/mesa/drivers/common/meta.c | 15 +- .../mesa/drivers/dri/common/xmlpool/t_options.h | 5 + mesalib/src/mesa/main/compiler.h | 3 +- mesalib/src/mesa/main/dd.h | 4 +- mesalib/src/mesa/main/fbobject.c | 39 ++- mesalib/src/mesa/main/fbobject.h | 3 + mesalib/src/mesa/main/ff_fragment_shader.cpp | 16 -- mesalib/src/mesa/main/formatquery.c | 12 +- mesalib/src/mesa/main/framebuffer.c | 4 +- mesalib/src/mesa/main/framebuffer.h | 2 +- mesalib/src/mesa/main/mtypes.h | 2 + mesalib/src/mesa/main/multisample.c | 77 ++++++ mesalib/src/mesa/main/multisample.h | 5 + mesalib/src/mesa/main/readpix.c | 284 +++++++++++++++++---- mesalib/src/mesa/main/readpix.h | 4 + mesalib/src/mesa/main/texgetimage.c | 1 + mesalib/src/mesa/main/teximage.c | 34 +-- mesalib/src/mesa/main/texparam.c | 12 + mesalib/src/mesa/main/texstorage.c | 1 + mesalib/src/mesa/state_tracker/st_cb_blit.c | 21 +- mesalib/src/mesa/state_tracker/st_cb_fbo.c | 24 -- mesalib/src/mesa/state_tracker/st_cb_fbo.h | 5 - mesalib/src/mesa/state_tracker/st_cb_readpixels.c | 188 +++++++++++++- mesalib/src/mesa/state_tracker/st_cb_texture.c | 20 +- mesalib/src/mesa/state_tracker/st_cb_texture.h | 6 + mesalib/src/mesa/state_tracker/st_context.c | 5 + mesalib/src/mesa/state_tracker/st_context.h | 3 + mesalib/src/mesa/state_tracker/st_format.c | 6 +- mesalib/src/mesa/state_tracker/st_format.h | 4 +- mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 142 +++++------ mesalib/src/mesa/state_tracker/st_program.c | 45 +++- pixman/.gitignore | 2 + pixman/demos/Makefile.am | 2 + pixman/demos/linear-gradient.c | 50 ++++ pixman/pixman/pixman-combine-float.c | 34 ++- pixman/pixman/pixman-gradient-walker.c | 106 +++++--- pixman/pixman/pixman-private.h | 13 +- pixman/test/Makefile.sources | 3 +- pixman/test/radial-perf-test.c | 58 +++++ xorg-server/Xext/panoramiX.c | 14 +- xorg-server/Xext/sync.c | 13 +- xorg-server/Xext/xvdisp.c | 8 +- xorg-server/Xi/exevents.c | 33 ++- xorg-server/composite/compext.c | 7 +- xorg-server/configure.ac | 17 +- xorg-server/dix/events.c | 3 + xorg-server/dix/main.c | 2 + xorg-server/dix/touch.c | 3 +- xorg-server/dix/window.c | 4 + xorg-server/fb/fbpict.c | 8 +- xorg-server/glx/extension_string.c | 2 + xorg-server/glx/extension_string.h | 5 + xorg-server/glx/glxcmds.c | 26 +- xorg-server/glx/glxdri.c | 2 + xorg-server/glx/glxdri2.c | 11 +- xorg-server/glx/glxdricommon.c | 4 +- xorg-server/glx/glxscreens.h | 3 + xorg-server/hw/kdrive/ephyr/ephyr.c | 7 +- xorg-server/hw/kdrive/ephyr/ephyrinit.c | 6 + xorg-server/hw/kdrive/ephyr/ephyrvideo.c | 24 -- xorg-server/hw/kdrive/ephyr/hostx.c | 43 +++- xorg-server/hw/kdrive/ephyr/hostx.h | 3 +- xorg-server/hw/kdrive/fbdev/fbdev.c | 10 - xorg-server/hw/kdrive/linux/mouse.c | 6 - xorg-server/hw/kdrive/src/kinput.c | 8 - xorg-server/hw/kdrive/src/kxv.c | 2 - xorg-server/hw/xfree86/common/xf86Events.c | 1 - xorg-server/hw/xfree86/common/xf86Mode.c | 17 +- xorg-server/hw/xfree86/common/xf86Option.c | 2 +- xorg-server/hw/xfree86/common/xf86fbman.c | 12 +- xorg-server/hw/xfree86/common/xf86xvmc.c | 4 +- xorg-server/hw/xfree86/ddc/ddc.c | 7 +- xorg-server/hw/xfree86/ramdac/xf86Cursor.c | 1 - xorg-server/hw/xquartz/GL/visualConfigs.c | 3 + xorg-server/hw/xwin/glx/indirect.c | 2 + xorg-server/include/dix-config.h.in | 3 + xorg-server/include/input.h | 5 + xorg-server/include/list.h | 2 +- xorg-server/os/Makefile.am | 5 + xorg-server/os/backtrace.c | 75 ++++++ xorg-server/os/log.c | 4 + xorg-server/randr/rrcrtc.c | 9 +- xorg-server/xfixes/cursor.c | 10 +- xorg-server/xfixes/xfixesint.h | 2 + xorg-server/xkb/xkb.c | 3 +- xorg-server/xkb/xkbActions.c | 149 ++++++----- 104 files changed, 1702 insertions(+), 594 deletions(-) create mode 100644 mesalib/docs/relnotes-9.1.1.html create mode 100644 pixman/demos/linear-gradient.c create mode 100644 pixman/test/radial-perf-test.c 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 @@ -76,6 +76,24 @@ FcCompareFamily (FcValue *v1, FcValue *v2) return (double) FcStrCmpIgnoreBlanksAndCase (v1_string, v2_string) != 0; } +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) { @@ -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; } @@ -220,6 +200,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 @@

News

+

March 19, 2013

+

+Mesa 9.1.1 is released. +This is a bug fix release. +

+

February 24, 2013

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 @@ + + + + + Mesa Release Notes + + + + +

+

The Mesa 3D Graphics Library

+
+ + +
+ +

Mesa 9.1.1 Release Notes / March 19th, 2013

+ +

+Mesa 9.1.1 is a bug fix release which fixes bugs found since the 9.1 release. +

+

+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 only available if requested at context creation +because GL_ARB_compatibility is not supported. +

+ +

MD5 checksums

+
+6508d9882d8dce7106717f365632700c  MesaLib-9.1.1.tar.gz
+6ea2bdc3b7ecfb4257b39814b4182580  MesaLib-9.1.1.tar.bz2
+3434c0eb47849a08c53cd32833d10d13  MesaLib-9.1.1.zip
+
+ +

New features

+

None.

+ +

Bug fixes

+ +

This list is likely incomplete.

+ + + + +

Changes

+

The full set of changes can be viewed by using the following GIT command:

+ +
+  git log mesa-9.1..mesa-9.1.1
+
+ + +

Adam Sampson (1):

+ + +

Alex Deucher (2):

+ + +

Andreas Boll (2):

+ + +

Anuj Phogat (1):

+ + +

Brian Paul (11):

+ + +

Daniel van Vugt (1):

+ + +

Eric Anholt (7):

+ + +

Frank Henigman (1):

+ + +

Ian Romanick (3):

+ + +

Jakub Bogusz (1):

+ + +

Jerome Glisse (1):

+ + +

John Kåre Alsaker (1):

+ + +

Jordan Justen (1):

+ + +

José Fonseca (3):

+ + +

Keith Kriewall (1):

+ + +

Kenneth Graunke (1):

+ + +

Marek Olšák (5):

+ + +

Martin Andersson (1):

+ + +

Matt Turner (1):

+ + +

Michel Dänzer (3):

+ + +

Tapani Pälli (2):

+ + +

Vadim Girlin (1):

+ + +

Vincent Lejeune (2):

+ + +
+ + 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 @@ -291,6 +291,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" @@ -473,6 +474,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. */ @@ -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 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 is a signed or unsigned integer format and + * 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: + * + * * is a depth/stencil-renderable format and + * is greater than the value of MAX_DEPTH_TEXTURE_SAMPLES + * * is a color-renderable format and is + * grater than the value of MAX_COLOR_TEXTURE_SAMPLES + * * is a signed or unsigned integer format and + * 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 + #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 + +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 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 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 #include +#ifdef HAVE_LIBUNWIND + +#define UNW_LOCAL_ONLY +#include + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include + +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; } -- cgit v1.2.3