From dc8a528cd6b9a4da3e60fa31428c37f5b34a897f Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Wed, 25 Jul 2007 14:57:13 -0700 Subject: [PATCH 01/33] ProcRenderAddGlyphs: Convert while loops to for loops where more natural --- render/render.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/render/render.c b/render/render.c index caaa2781c..d311fb383 100644 --- a/render/render.c +++ b/render/render.c @@ -1098,6 +1098,7 @@ ProcRenderAddGlyphs (ClientPtr client) CARD8 *bits; int size; int err = BadAlloc; + int i; REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq); glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client, @@ -1131,7 +1132,7 @@ ProcRenderAddGlyphs (ClientPtr client) gi = (xGlyphInfo *) (gids + nglyphs); bits = (CARD8 *) (gi + nglyphs); remain -= (sizeof (CARD32) + sizeof (xGlyphInfo)) * nglyphs; - while (remain >= 0 && nglyphs) + for (i = 0; i < nglyphs; i++) { glyph = AllocateGlyph (gi, glyphSet->fdepth); if (!glyph) @@ -1155,21 +1156,19 @@ ProcRenderAddGlyphs (ClientPtr client) gi++; gids++; glyphs++; - nglyphs--; } - if (nglyphs || remain) + if (remain || i < nglyphs) { err = BadLength; goto bail; } - nglyphs = stuff->nglyphs; if (!ResizeGlyphSet (glyphSet, nglyphs)) { err = BadAlloc; goto bail; } glyphs = glyphsBase; - while (nglyphs--) { + for (i = 0; i < nglyphs; i++) { AddGlyph (glyphSet, glyphs->glyph, glyphs->id); glyphs++; } From 363d764ea32b938f3dff35df7cf3370363c04d5c Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Mon, 30 Jul 2007 15:10:11 -0700 Subject: [PATCH 02/33] ProcRenderAddGlyphs: Take advantage of the for loops to simplify the code a bit --- render/render.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/render/render.c b/render/render.c index d311fb383..10a5b805c 100644 --- a/render/render.c +++ b/render/render.c @@ -1134,7 +1134,7 @@ ProcRenderAddGlyphs (ClientPtr client) remain -= (sizeof (CARD32) + sizeof (xGlyphInfo)) * nglyphs; for (i = 0; i < nglyphs; i++) { - glyph = AllocateGlyph (gi, glyphSet->fdepth); + glyph = AllocateGlyph (&gi[i], glyphSet->fdepth); if (!glyph) { err = BadAlloc; @@ -1142,7 +1142,7 @@ ProcRenderAddGlyphs (ClientPtr client) } glyphs->glyph = glyph; - glyphs->id = *gids; + glyphs->id = gids[i]; size = glyph->size - sizeof (xGlyphInfo); if (remain < size) @@ -1153,8 +1153,6 @@ ProcRenderAddGlyphs (ClientPtr client) size += 4 - (size & 3); bits += size; remain -= size; - gi++; - gids++; glyphs++; } if (remain || i < nglyphs) @@ -1168,10 +1166,8 @@ ProcRenderAddGlyphs (ClientPtr client) goto bail; } glyphs = glyphsBase; - for (i = 0; i < nglyphs; i++) { - AddGlyph (glyphSet, glyphs->glyph, glyphs->id); - glyphs++; - } + for (i = 0; i < nglyphs; i++) + AddGlyph (glyphSet, glyphs[i].glyph, glyphs[i].id); if (glyphsBase != glyphsLocal) Xfree (glyphsBase); From 4c6abe1c7c8abcf203572bbf86b21d97ea4e756f Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Mon, 30 Jul 2007 21:43:20 -0700 Subject: [PATCH 03/33] Split HashGlyph functionality out into HashGlyphInfoAndBits This is in preparation for a future change that will take advantage of being able to compute a hash for a separate xGlyphInfo and chunk of bits without a combined Glyph object. --- render/glyph.c | 23 ++++++++++++++++++++--- render/glyphstr.h | 3 +++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/render/glyph.c b/render/glyph.c index 583a52ba3..53c00b326 100644 --- a/render/glyph.c +++ b/render/glyph.c @@ -461,18 +461,35 @@ FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare) } CARD32 -HashGlyph (GlyphPtr glyph) +HashGlyphInfoAndBits (xGlyphInfo *gi, CARD8 *data, unsigned int size) { - CARD32 *bits = (CARD32 *) &(glyph->info); + CARD32 *bits; CARD32 hash; - int n = glyph->size / sizeof (CARD32); + int n; hash = 0; + + bits = (CARD32 *) gi; + n = sizeof (xGlyphInfo) / sizeof (CARD32); while (n--) hash ^= *bits++; + + bits = (CARD32 *) data; + n = size / sizeof (CARD32); + while (n--) + hash ^= *bits++; + return hash; } +CARD32 +HashGlyph (GlyphPtr glyph) +{ + return HashGlyphInfoAndBits (&glyph->info, + (CARD8 *) (&glyph->info + 1), + glyph->size - sizeof (xGlyphInfo)); +} + #ifdef CHECK_DUPLICATES void DuplicateRef (GlyphPtr glyph, char *where) diff --git a/render/glyphstr.h b/render/glyphstr.h index 22150deee..b941dabaf 100644 --- a/render/glyphstr.h +++ b/render/glyphstr.h @@ -129,6 +129,9 @@ FindGlyphHashSet (CARD32 filled); GlyphRefPtr FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare); +CARD32 +HashGlyphInfoAndBits (xGlyphInfo *gi, CARD8 *data, unsigned int size); + CARD32 HashGlyph (GlyphPtr glyph); From 516b96387b0e57b524a37a96da22dbeeeb041712 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Mon, 30 Jul 2007 17:31:47 -0700 Subject: [PATCH 04/33] ProcRenderAddGlyphs: Avoid allocating a glyph just to find it cached This is a cleanup without any real savings (yet). Previously, the implementation would allocate a new glyph, then (often) find it in the cache, and immediately discard the allocated object. This re-organization first uses a new FindGlyphByHash function and only allocates the glyph if nothing is found. This isn't a real savings yet, since FindGlyphByHash currently still does a temporary glyph allocation, but this is expected to be replaced immediately as we switch to an alternate hashing mechanism (SHA1). --- render/glyph.c | 29 ++++++++++++++++++++-- render/glyphstr.h | 6 +++++ render/render.c | 61 +++++++++++++++++++++++++++++------------------ 3 files changed, 71 insertions(+), 25 deletions(-) diff --git a/render/glyph.c b/render/glyph.c index 53c00b326..1204c3b79 100644 --- a/render/glyph.c +++ b/render/glyph.c @@ -490,6 +490,31 @@ HashGlyph (GlyphPtr glyph) glyph->size - sizeof (xGlyphInfo)); } +GlyphPtr +FindGlyphByHash (CARD32 hash, + xGlyphInfo *gi, + CARD8 *bits, + int format) +{ + GlyphRefPtr gr; + GlyphPtr template; + + /* XXX: Should handle out-of-memory here */ + template = AllocateGlyph (gi, format); + memcpy ((CARD8 *) (template + 1), bits, + template->size - sizeof (xGlyphInfo)); + + gr = FindGlyphRef (&globalGlyphs[format], + hash, TRUE, template); + + xfree (template); + + if (gr->glyph && gr->glyph != DeletedGlyph) + return gr->glyph; + else + return NULL; +} + #ifdef CHECK_DUPLICATES void DuplicateRef (GlyphPtr glyph, char *where) @@ -572,7 +597,7 @@ AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id) /* Locate existing matching glyph */ hash = HashGlyph (glyph); gr = FindGlyphRef (&globalGlyphs[glyphSet->fdepth], hash, TRUE, glyph); - if (gr->glyph && gr->glyph != DeletedGlyph) + if (gr->glyph && gr->glyph != DeletedGlyph && gr->glyph != glyph) { PictureScreenPtr ps; int i; @@ -588,7 +613,7 @@ AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id) xfree (glyph); glyph = gr->glyph; } - else + else if (gr->glyph != glyph) { gr->glyph = glyph; gr->signature = hash; diff --git a/render/glyphstr.h b/render/glyphstr.h index b941dabaf..37462f744 100644 --- a/render/glyphstr.h +++ b/render/glyphstr.h @@ -129,6 +129,12 @@ FindGlyphHashSet (CARD32 filled); GlyphRefPtr FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare); +GlyphPtr +FindGlyphByHash (CARD32 hash, + xGlyphInfo *gi, + CARD8 *bits, + int format); + CARD32 HashGlyphInfoAndBits (xGlyphInfo *gi, CARD8 *data, unsigned int size); diff --git a/render/render.c b/render/render.c index 10a5b805c..831c98417 100644 --- a/render/render.c +++ b/render/render.c @@ -1082,6 +1082,8 @@ ProcRenderFreeGlyphSet (ClientPtr client) typedef struct _GlyphNew { Glyph id; GlyphPtr glyph; + Bool found; + CARD32 hash; } GlyphNewRec, *GlyphNewPtr; static int @@ -1090,8 +1092,7 @@ ProcRenderAddGlyphs (ClientPtr client) GlyphSetPtr glyphSet; REQUEST(xRenderAddGlyphsReq); GlyphNewRec glyphsLocal[NLOCALGLYPH]; - GlyphNewPtr glyphsBase, glyphs; - GlyphPtr glyph; + GlyphNewPtr glyphsBase, glyphs, glyph_new; int remain, nglyphs; CARD32 *gids; xGlyphInfo *gi; @@ -1115,11 +1116,13 @@ ProcRenderAddGlyphs (ClientPtr client) if (nglyphs > UINT32_MAX / sizeof(GlyphNewRec)) return BadAlloc; - if (nglyphs <= NLOCALGLYPH) + if (nglyphs <= NLOCALGLYPH) { + memset (glyphsLocal, 0, sizeof (glyphsLocal)); glyphsBase = glyphsLocal; + } else { - glyphsBase = (GlyphNewPtr) Xalloc (nglyphs * sizeof (GlyphNewRec)); + glyphsBase = (GlyphNewPtr) Xcalloc (nglyphs * sizeof (GlyphNewRec)); if (!glyphsBase) return BadAlloc; } @@ -1134,26 +1137,41 @@ ProcRenderAddGlyphs (ClientPtr client) remain -= (sizeof (CARD32) + sizeof (xGlyphInfo)) * nglyphs; for (i = 0; i < nglyphs; i++) { - glyph = AllocateGlyph (&gi[i], glyphSet->fdepth); - if (!glyph) - { - err = BadAlloc; - goto bail; - } - - glyphs->glyph = glyph; - glyphs->id = gids[i]; - - size = glyph->size - sizeof (xGlyphInfo); + glyph_new = &glyphs[i]; + size = gi[i].height * PixmapBytePad (gi[i].width, + glyphSet->format->depth); if (remain < size) break; - memcpy ((CARD8 *) (glyph + 1), bits, size); + + glyph_new->hash = HashGlyphInfoAndBits (&gi[i], bits, size); + + glyph_new->glyph = FindGlyphByHash (glyph_new->hash, + &gi[i], bits, + glyphSet->fdepth); + + if (glyph_new->glyph && glyph_new->glyph != DeletedGlyph) + { + glyph_new->found = TRUE; + } + else + { + glyph_new->found = FALSE; + glyph_new->glyph = AllocateGlyph (&gi[i], glyphSet->fdepth); + if (! glyph_new->glyph) + { + err = BadAlloc; + goto bail; + } + + memcpy ((CARD8 *) (glyph_new->glyph + 1), bits, size); + } + + glyph_new->id = gids[i]; if (size & 3) size += 4 - (size & 3); bits += size; remain -= size; - glyphs++; } if (remain || i < nglyphs) { @@ -1165,7 +1183,6 @@ ProcRenderAddGlyphs (ClientPtr client) err = BadAlloc; goto bail; } - glyphs = glyphsBase; for (i = 0; i < nglyphs; i++) AddGlyph (glyphSet, glyphs[i].glyph, glyphs[i].id); @@ -1173,11 +1190,9 @@ ProcRenderAddGlyphs (ClientPtr client) Xfree (glyphsBase); return client->noClientException; bail: - while (glyphs != glyphsBase) - { - --glyphs; - xfree (glyphs->glyph); - } + for (i = 0; i < nglyphs; i++) + if (glyphs[i].glyph && ! glyphs[i].found) + xfree (glyphs[i].glyph); if (glyphsBase != glyphsLocal) Xfree (glyphsBase); return err; From 19b3b1fd8feb343a690331cafe88ef10b34b9d98 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Tue, 31 Jul 2007 17:04:13 -0700 Subject: [PATCH 05/33] Use strong hash (SHA1) for glyphs Using a cryptographically strong hash means that comparing the hash alone is sufficient for determining glyph equality (no need to compare the glyph bits directly). This will allow us to replace system-memory copies of the glyph bits, (which we've only been holding onto for comparisons), with Pixmaps. --- configure.ac | 2 +- render/glyph.c | 84 ++++++++++++++++++++++------------------------- render/glyphstr.h | 29 ++++++++-------- render/render.c | 16 +++++---- 4 files changed, 65 insertions(+), 66 deletions(-) diff --git a/configure.ac b/configure.ac index 518f332a8..89c6b55b1 100644 --- a/configure.ac +++ b/configure.ac @@ -621,7 +621,7 @@ PIXMAN="[pixman >= 0.9.2]" dnl Core modules for most extensions, et al. REQUIRED_MODULES="[randrproto >= 1.2] renderproto [fixesproto >= 4.0] [damageproto >= 1.1] xcmiscproto xextproto [xproto >= 7.0.9] xtrans [scrnsaverproto >= 1.1] bigreqsproto resourceproto fontsproto [inputproto >= 1.4.2] [kbproto >= 1.0.3]" -REQUIRED_LIBS="xfont xau fontenc $PIXMAN" +REQUIRED_LIBS="xfont xau fontenc $PIXMAN openssl" dnl HAVE_DBUS is true if we actually have the D-Bus library, whereas dnl CONFIG_DBUS_API is true if we want to enable the D-Bus config diff --git a/render/glyph.c b/render/glyph.c index 1204c3b79..7dbdda2d9 100644 --- a/render/glyph.c +++ b/render/glyph.c @@ -26,6 +26,8 @@ #include #endif +#include + #include "misc.h" #include "scrnintstr.h" #include "os.h" @@ -412,7 +414,10 @@ _GlyphSetSetNewPrivate (GlyphSetPtr glyphSet, int n, pointer ptr) } GlyphRefPtr -FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare) +FindGlyphRef (GlyphHashPtr hash, + CARD32 signature, + Bool match, + unsigned char sha1[20]) { CARD32 elt, step, s; GlyphPtr glyph; @@ -443,7 +448,7 @@ FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare) } else if (s == signature && (!match || - memcmp (&compare->info, &glyph->info, compare->size) == 0)) + memcmp (glyph->sha1, sha1, 20) == 0)) { break; } @@ -460,54 +465,42 @@ FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare) return gr; } -CARD32 -HashGlyphInfoAndBits (xGlyphInfo *gi, CARD8 *data, unsigned int size) +int +HashGlyph (xGlyphInfo *gi, + CARD8 *bits, + unsigned long size, + unsigned char sha1[20]) { - CARD32 *bits; - CARD32 hash; - int n; + SHA_CTX ctx; + int success; - hash = 0; + success = SHA1_Init (&ctx); + if (! success) + return BadAlloc; - bits = (CARD32 *) gi; - n = sizeof (xGlyphInfo) / sizeof (CARD32); - while (n--) - hash ^= *bits++; + success = SHA1_Update (&ctx, gi, sizeof (xGlyphInfo)); + if (! success) + return BadAlloc; - bits = (CARD32 *) data; - n = size / sizeof (CARD32); - while (n--) - hash ^= *bits++; + success = SHA1_Update (&ctx, bits, size); + if (! success) + return BadAlloc; - return hash; -} + success = SHA1_Final (sha1, &ctx); + if (! success) + return BadAlloc; -CARD32 -HashGlyph (GlyphPtr glyph) -{ - return HashGlyphInfoAndBits (&glyph->info, - (CARD8 *) (&glyph->info + 1), - glyph->size - sizeof (xGlyphInfo)); + return Success; } GlyphPtr -FindGlyphByHash (CARD32 hash, - xGlyphInfo *gi, - CARD8 *bits, - int format) +FindGlyphByHash (unsigned char sha1[20], int format) { GlyphRefPtr gr; - GlyphPtr template; - - /* XXX: Should handle out-of-memory here */ - template = AllocateGlyph (gi, format); - memcpy ((CARD8 *) (template + 1), bits, - template->size - sizeof (xGlyphInfo)); + CARD32 signature = *(CARD32 *) sha1; gr = FindGlyphRef (&globalGlyphs[format], - hash, TRUE, template); - - xfree (template); + signature, TRUE, sha1); if (gr->glyph && gr->glyph != DeletedGlyph) return gr->glyph; @@ -553,6 +546,7 @@ FreeGlyph (GlyphPtr glyph, int format) GlyphRefPtr gr; int i; int first; + CARD32 signature; first = -1; for (i = 0; i < globalGlyphs[format].hashSet->size; i++) @@ -563,8 +557,9 @@ FreeGlyph (GlyphPtr glyph, int format) first = i; } - gr = FindGlyphRef (&globalGlyphs[format], - HashGlyph (glyph), TRUE, glyph); + signature = *(CARD32 *) glyph->sha1; + gr = FindGlyphRef (&globalGlyphs[format], signature, + TRUE, glyph->sha1); if (gr - globalGlyphs[format].table != first) DuplicateRef (glyph, "Found wrong one"); if (gr->glyph && gr->glyph != DeletedGlyph) @@ -591,12 +586,13 @@ void AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id) { GlyphRefPtr gr; - CARD32 hash; + CARD32 signature; CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph top global"); /* Locate existing matching glyph */ - hash = HashGlyph (glyph); - gr = FindGlyphRef (&globalGlyphs[glyphSet->fdepth], hash, TRUE, glyph); + signature = *(CARD32 *) glyph->sha1; + gr = FindGlyphRef (&globalGlyphs[glyphSet->fdepth], signature, + TRUE, glyph->sha1); if (gr->glyph && gr->glyph != DeletedGlyph && gr->glyph != glyph) { PictureScreenPtr ps; @@ -616,7 +612,7 @@ AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id) else if (gr->glyph != glyph) { gr->glyph = glyph; - gr->signature = hash; + gr->signature = signature; globalGlyphs[glyphSet->fdepth].tableEntries++; } @@ -753,7 +749,7 @@ ResizeGlyphHash (GlyphHashPtr hash, CARD32 change, Bool global) if (glyph && glyph != DeletedGlyph) { s = hash->table[i].signature; - gr = FindGlyphRef (&newHash, s, global, glyph); + gr = FindGlyphRef (&newHash, s, global, glyph->sha1); gr->signature = s; gr->glyph = glyph; ++newHash.tableEntries; diff --git a/render/glyphstr.h b/render/glyphstr.h index 37462f744..d47dfecfc 100644 --- a/render/glyphstr.h +++ b/render/glyphstr.h @@ -39,10 +39,11 @@ #define GlyphFormatNum 5 typedef struct _Glyph { - CARD32 refcnt; - DevUnion *devPrivates; - CARD32 size; /* info + bitmap */ - xGlyphInfo info; + CARD32 refcnt; + DevUnion *devPrivates; + unsigned char sha1[20]; + CARD32 size; /* info + bitmap */ + xGlyphInfo info; /* bits follow */ } GlyphRec, *GlyphPtr; @@ -127,19 +128,19 @@ GlyphHashSetPtr FindGlyphHashSet (CARD32 filled); GlyphRefPtr -FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare); +FindGlyphRef (GlyphHashPtr hash, + CARD32 signature, + Bool match, + unsigned char sha1[20]); GlyphPtr -FindGlyphByHash (CARD32 hash, - xGlyphInfo *gi, - CARD8 *bits, - int format); +FindGlyphByHash (unsigned char sha1[20], int format); -CARD32 -HashGlyphInfoAndBits (xGlyphInfo *gi, CARD8 *data, unsigned int size); - -CARD32 -HashGlyph (GlyphPtr glyph); +int +HashGlyph (xGlyphInfo *gi, + CARD8 *bits, + unsigned long size, + unsigned char sha1[20]); void FreeGlyph (GlyphPtr glyph, int format); diff --git a/render/render.c b/render/render.c index 831c98417..c7a6dcb44 100644 --- a/render/render.c +++ b/render/render.c @@ -1080,10 +1080,10 @@ ProcRenderFreeGlyphSet (ClientPtr client) } typedef struct _GlyphNew { - Glyph id; - GlyphPtr glyph; - Bool found; - CARD32 hash; + Glyph id; + GlyphPtr glyph; + Bool found; + unsigned char sha1[20]; } GlyphNewRec, *GlyphNewPtr; static int @@ -1143,10 +1143,11 @@ ProcRenderAddGlyphs (ClientPtr client) if (remain < size) break; - glyph_new->hash = HashGlyphInfoAndBits (&gi[i], bits, size); + err = HashGlyph (&gi[i], bits, size, glyph_new->sha1); + if (err) + goto bail; - glyph_new->glyph = FindGlyphByHash (glyph_new->hash, - &gi[i], bits, + glyph_new->glyph = FindGlyphByHash (glyph_new->sha1, glyphSet->fdepth); if (glyph_new->glyph && glyph_new->glyph != DeletedGlyph) @@ -1164,6 +1165,7 @@ ProcRenderAddGlyphs (ClientPtr client) } memcpy ((CARD8 *) (glyph_new->glyph + 1), bits, size); + memcpy (glyph_new->glyph->sha1, glyph_new->sha1, 20); } glyph_new->id = gids[i]; From a2af34d5a861982a03afad8e586bb0181b72bbd0 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Wed, 1 Aug 2007 15:48:30 -0700 Subject: [PATCH 06/33] Use per-screen Pixmaps for glyphs Instead of system-memory data which prevents accelerated compositing of glyphs, (at least without forcing an upload of the glyph data before compositing). --- exa/exa_priv.h | 1 + exa/exa_render.c | 99 +++++++---------------------------------------- render/glyph.c | 55 ++++++++++++++++---------- render/glyphstr.h | 4 +- render/miglyph.c | 40 +++++-------------- render/render.c | 67 +++++++++++++++++++++++++++++++- 6 files changed, 127 insertions(+), 139 deletions(-) diff --git a/exa/exa_priv.h b/exa/exa_priv.h index a6d98cd2d..a80704a21 100644 --- a/exa/exa_priv.h +++ b/exa/exa_priv.h @@ -50,6 +50,7 @@ #include "fboverlay.h" #ifdef RENDER #include "fbpict.h" +#include "glyphstr.h" #endif #include "damage.h" diff --git a/exa/exa_render.c b/exa/exa_render.c index 5e7c67feb..332683949 100644 --- a/exa/exa_render.c +++ b/exa/exa_render.c @@ -996,8 +996,6 @@ exaGlyphs (CARD8 op, { GCPtr pGC = NULL; int maxwidth = 0, maxheight = 0, i; - ExaMigrationRec pixmaps[1]; - PixmapPtr pScratchPixmap = NULL; x += list->xOff; y += list->yOff; @@ -1021,37 +1019,9 @@ exaGlyphs (CARD8 op, continue; } - /* Create the (real) temporary pixmap to store the current glyph in */ - pPixmap = (*pScreen->CreatePixmap) (pScreen, maxwidth, maxheight, - list->format->depth); - if (!pPixmap) - return; - - /* Create a temporary picture to wrap the temporary pixmap, so it can be - * used as a source for Composite. - */ - component_alpha = NeedsComponent(list->format->format); - pPicture = CreatePicture (0, &pPixmap->drawable, list->format, - CPComponentAlpha, &component_alpha, - serverClient, &error); - if (!pPicture) { - (*pScreen->DestroyPixmap) (pPixmap); - return; - } - ValidatePicture(pPicture); - - /* Give the temporary pixmap an initial kick towards the screen, so - * it'll stick there. - */ - pixmaps[0].as_dst = TRUE; - pixmaps[0].as_src = TRUE; - pixmaps[0].pPix = pPixmap; - exaDoMigration (pixmaps, 1, pExaScr->info->PrepareComposite != NULL); - while (n--) { GlyphPtr glyph = *glyphs++; - pointer glyphdata = (pointer) (glyph + 1); DrawablePtr pCmpDrw = (maskFormat ? pMask : pDst)->pDrawable; x1 = x - glyph->info.x; @@ -1061,60 +1031,19 @@ exaGlyphs (CARD8 op, (x1 + glyph->info.width) <= 0 || (y1 + glyph->info.height) <= 0) goto nextglyph; - (*pScreen->ModifyPixmapHeader) (pScratchPixmap, - glyph->info.width, - glyph->info.height, - 0, 0, -1, glyphdata); + /* The glyph already has a pixmap waiting for us to use. */ + pPixmap = GlyphPixmap (glyph)[pScreen->myNum]; - /* Copy the glyph data into the proper pixmap instead of a fake. - * First we try to use UploadToScreen, if we can, then we fall back - * to a plain exaCopyArea in case of failure. + /* Create a temporary picture to wrap the pixmap, so it can be + * used as a source for Composite. */ - if (pExaScr->info->UploadToScreen && - exaPixmapIsOffscreen(pPixmap) && - (*pExaScr->info->UploadToScreen) (pPixmap, 0, 0, - glyph->info.width, - glyph->info.height, - glyphdata, - PixmapBytePad(glyph->info.width, - list->format->depth))) - { - exaMarkSync (pScreen); - } else { - /* Set up the scratch pixmap/GC for doing a CopyArea. */ - if (pScratchPixmap == NULL) { - /* Get a scratch pixmap to wrap the original glyph data */ - pScratchPixmap = GetScratchPixmapHeader (pScreen, - glyph->info.width, - glyph->info.height, - list->format->depth, - list->format->depth, - -1, glyphdata); - if (!pScratchPixmap) { - FreePicture(pPicture, 0); - (*pScreen->DestroyPixmap) (pPixmap); - return; - } - - /* Get a scratch GC with which to copy the glyph data from - * scratch to temporary - */ - pGC = GetScratchGC (list->format->depth, pScreen); - ValidateGC (&pPixmap->drawable, pGC); - } else { - (*pScreen->ModifyPixmapHeader) (pScratchPixmap, - glyph->info.width, - glyph->info.height, - 0, 0, -1, glyphdata); - pScratchPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; - } - - exaCopyArea (&pScratchPixmap->drawable, &pPixmap->drawable, pGC, - 0, 0, glyph->info.width, glyph->info.height, 0, 0); - } - - exaPixmapDirty (pPixmap, 0, 0, - glyph->info.width, glyph->info.height); + component_alpha = NeedsComponent(list->format->format); + pPicture = CreatePicture (0, &pPixmap->drawable, list->format, + CPComponentAlpha, &component_alpha, + serverClient, &error); + if (!pPicture) + return; + ValidatePicture(pPicture); if (maskFormat) { @@ -1134,6 +1063,8 @@ exaGlyphs (CARD8 op, exaPixmapDirty(pDstPixmap, x1, y1, x1 + glyph->info.width, y1 + glyph->info.height); } + FreePicture ((pointer) pPicture, 0); + nextglyph: x += glyph->info.xOff; y += glyph->info.yOff; @@ -1141,10 +1072,6 @@ nextglyph: list++; if (pGC != NULL) FreeScratchGC (pGC); - FreePicture ((pointer) pPicture, 0); - (*pScreen->DestroyPixmap) (pPixmap); - if (pScratchPixmap != NULL) - FreeScratchPixmapHeader (pScratchPixmap); } if (maskFormat) { diff --git a/render/glyph.c b/render/glyph.c index 7dbdda2d9..7fd3705df 100644 --- a/render/glyph.c +++ b/render/glyph.c @@ -571,9 +571,13 @@ FreeGlyph (GlyphPtr glyph, int format) for (i = 0; i < screenInfo.numScreens; i++) { - ps = GetPictureScreenIfSet (screenInfo.screens[i]); + ScreenPtr pScreen = screenInfo.screens[i]; + + (pScreen->DestroyPixmap) (GlyphPixmap (glyph)[i]); + + ps = GetPictureScreenIfSet (pScreen); if (ps) - (*ps->UnrealizeGlyph) (screenInfo.screens[i], glyph); + (*ps->UnrealizeGlyph) (pScreen, glyph); } if (glyph->devPrivates) @@ -665,7 +669,7 @@ AllocateGlyph (xGlyphInfo *gi, int fdepth) GlyphPtr glyph; int i; - size = gi->height * PixmapBytePad (gi->width, glyphDepths[fdepth]); + size = screenInfo.numScreens * sizeof (PixmapPtr); glyph = (GlyphPtr) xalloc (size + sizeof (GlyphRec)); if (!glyph) return 0; @@ -685,27 +689,38 @@ AllocateGlyph (xGlyphInfo *gi, int fdepth) for (i = 0; i < screenInfo.numScreens; i++) { - ps = GetPictureScreenIfSet (screenInfo.screens[i]); - if (ps) - { - if (!(*ps->RealizeGlyph) (screenInfo.screens[i], glyph)) - { - while (i--) - { - ps = GetPictureScreenIfSet (screenInfo.screens[i]); - if (ps) - (*ps->UnrealizeGlyph) (screenInfo.screens[i], glyph); - } - - if (glyph->devPrivates) - xfree (glyph->devPrivates); - xfree (glyph); - return 0; - } + ScreenPtr pScreen = screenInfo.screens[i]; + + GlyphPixmap (glyph)[i] = (pScreen->CreatePixmap) (pScreen, + gi->width, gi->height, + glyphDepths[fdepth]); + if (! GlyphPixmap (glyph)[i]) + goto bail; + + ps = GetPictureScreenIfSet (pScreen); + if (! ps) + continue; + + if (!(*ps->RealizeGlyph) (pScreen, glyph)) { + (pScreen->DestroyPixmap) (GlyphPixmap (glyph)[i]); + goto bail; } } return glyph; + +bail: + while (i--) + { + ps = GetPictureScreenIfSet (screenInfo.screens[i]); + if (ps) + (*ps->UnrealizeGlyph) (screenInfo.screens[i], glyph); + } + + if (glyph->devPrivates) + xfree (glyph->devPrivates); + xfree (glyph); + return 0; } Bool diff --git a/render/glyphstr.h b/render/glyphstr.h index d47dfecfc..4f8746003 100644 --- a/render/glyphstr.h +++ b/render/glyphstr.h @@ -44,9 +44,11 @@ typedef struct _Glyph { unsigned char sha1[20]; CARD32 size; /* info + bitmap */ xGlyphInfo info; - /* bits follow */ + /* per-screen pixmaps follow */ } GlyphRec, *GlyphPtr; +#define GlyphPixmap(glyph) ((PixmapPtr *) ((glyph) + 1)) + typedef struct _GlyphRef { CARD32 signature; GlyphPtr glyph; diff --git a/render/miglyph.c b/render/miglyph.c index 7968c90ea..2aa94bd09 100644 --- a/render/miglyph.c +++ b/render/miglyph.c @@ -112,7 +112,7 @@ miGlyphs (CARD8 op, GlyphListPtr list, GlyphPtr *glyphs) { - PixmapPtr pPixmap = 0; + PixmapPtr pPixmap; PicturePtr pPicture; PixmapPtr pMaskPixmap = 0; PicturePtr pMask; @@ -166,7 +166,6 @@ miGlyphs (CARD8 op, x = 0; y = 0; } - pPicture = 0; while (nlist--) { x += list->xOff; @@ -175,28 +174,14 @@ miGlyphs (CARD8 op, while (n--) { glyph = *glyphs++; + pPixmap = GlyphPixmap (glyph)[pScreen->myNum]; + component_alpha = NeedsComponent(list->format->format); + pPicture = CreatePicture (0, &pPixmap->drawable, list->format, + CPComponentAlpha, &component_alpha, + serverClient, &error); if (!pPicture) - { - pPixmap = GetScratchPixmapHeader (pScreen, glyph->info.width, glyph->info.height, - list->format->depth, - list->format->depth, - 0, (pointer) (glyph + 1)); - if (!pPixmap) - return; - component_alpha = NeedsComponent(list->format->format); - pPicture = CreatePicture (0, &pPixmap->drawable, list->format, - CPComponentAlpha, &component_alpha, - serverClient, &error); - if (!pPicture) - { - FreeScratchPixmapHeader (pPixmap); - return; - } - } - (*pScreen->ModifyPixmapHeader) (pPixmap, - glyph->info.width, glyph->info.height, - 0, 0, -1, (pointer) (glyph + 1)); - pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; + return; + if (maskFormat) { CompositePicture (PictOpAdd, @@ -224,17 +209,12 @@ miGlyphs (CARD8 op, glyph->info.width, glyph->info.height); } + FreePicture ((pointer) pPicture, 0); + x += glyph->info.xOff; y += glyph->info.yOff; } list++; - if (pPicture) - { - FreeScratchPixmapHeader (pPixmap); - FreePicture ((pointer) pPicture, 0); - pPicture = 0; - pPixmap = 0; - } } if (maskFormat) { diff --git a/render/render.c b/render/render.c index c7a6dcb44..4bad379f6 100644 --- a/render/render.c +++ b/render/render.c @@ -1099,7 +1099,9 @@ ProcRenderAddGlyphs (ClientPtr client) CARD8 *bits; int size; int err = BadAlloc; - int i; + int i, screen; + PicturePtr pSrc = NULL, pDst = NULL; + PixmapPtr pSrcPix = NULL, pDstPix = NULL; REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq); glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client, @@ -1164,7 +1166,62 @@ ProcRenderAddGlyphs (ClientPtr client) goto bail; } - memcpy ((CARD8 *) (glyph_new->glyph + 1), bits, size); + for (screen = 0; screen < screenInfo.numScreens; screen++) + { + int width = gi[i].width; + int height = gi[i].height; + int depth = glyphSet->format->depth; + ScreenPtr pScreen; + int error; + + pScreen = screenInfo.screens[screen]; + pSrcPix = GetScratchPixmapHeader (pScreen, + width, height, + depth, depth, + -1, bits); + if (! pSrcPix) + { + err = BadAlloc; + goto bail; + } + + pSrc = CreatePicture (0, &pSrcPix->drawable, + glyphSet->format, 0, NULL, + serverClient, &error); + if (! pSrc) + { + err = BadAlloc; + goto bail; + } + + pDstPix = GlyphPixmap (glyph_new->glyph)[screen]; + + pDst = CreatePicture (0, &pDstPix->drawable, + glyphSet->format, 0, NULL, + serverClient, &error); + if (! pDst) + { + err = BadAlloc; + goto bail; + } + + CompositePicture (PictOpSrc, + pSrc, + None, + pDst, + 0, 0, + 0, 0, + 0, 0, + width, height); + + FreePicture ((pointer) pSrc, 0); + pSrc = NULL; + FreePicture ((pointer) pDst, 0); + pDst = NULL; + FreeScratchPixmapHeader (pSrcPix); + pSrcPix = NULL; + } + memcpy (glyph_new->glyph->sha1, glyph_new->sha1, 20); } @@ -1192,6 +1249,12 @@ ProcRenderAddGlyphs (ClientPtr client) Xfree (glyphsBase); return client->noClientException; bail: + if (pSrc) + FreePicture ((pointer) pSrc, 0); + if (pDst) + FreePicture ((pointer) pDst, 0); + if (pSrcPix) + FreeScratchPixmapHeader (pSrcPix); for (i = 0; i < nglyphs; i++) if (glyphs[i].glyph && ! glyphs[i].found) xfree (glyphs[i].glyph); From 0a71e1542a07abc5e32501973a7cf6de3f641317 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Thu, 2 Aug 2007 22:48:32 -0700 Subject: [PATCH 07/33] Create a Picture as well as a Pixmap at the time of AllocateGlyph This avoids some inefficiency in creating a temporary Picture for every glyph at rendering time. My measurements with an i965 showed the previous patch causing a 10-15% slowdown for NoAccel and XAA cases, (while providing an 18% speedup for EXA). With this change, the NoAccel and XAA performance regression is eliminated, and the overall EXA speedup, (before any of the glyphs-as-pixmaps work), is now 32%. --- exa/exa_render.c | 16 ++-------------- render/glyph.c | 23 +++++++---------------- render/glyphstr.h | 2 +- render/miglyph.c | 9 +-------- render/render.c | 26 ++++++++++++++++---------- 5 files changed, 27 insertions(+), 49 deletions(-) diff --git a/exa/exa_render.c b/exa/exa_render.c index 332683949..24411dda7 100644 --- a/exa/exa_render.c +++ b/exa/exa_render.c @@ -896,7 +896,6 @@ exaGlyphs (CARD8 op, GlyphPtr *glyphs) { ExaScreenPriv (pDst->pDrawable->pScreen); - PixmapPtr pPixmap = NULL; PicturePtr pPicture; PixmapPtr pMaskPixmap = NULL; PixmapPtr pDstPixmap = exaGetDrawablePixmap(pDst->pDrawable); @@ -1031,18 +1030,8 @@ exaGlyphs (CARD8 op, (x1 + glyph->info.width) <= 0 || (y1 + glyph->info.height) <= 0) goto nextglyph; - /* The glyph already has a pixmap waiting for us to use. */ - pPixmap = GlyphPixmap (glyph)[pScreen->myNum]; - - /* Create a temporary picture to wrap the pixmap, so it can be - * used as a source for Composite. - */ - component_alpha = NeedsComponent(list->format->format); - pPicture = CreatePicture (0, &pPixmap->drawable, list->format, - CPComponentAlpha, &component_alpha, - serverClient, &error); - if (!pPicture) - return; + /* The glyph already has a Picture ready for us to use. */ + pPicture = GlyphPicture (glyph)[pScreen->myNum]; ValidatePicture(pPicture); if (maskFormat) @@ -1063,7 +1052,6 @@ exaGlyphs (CARD8 op, exaPixmapDirty(pDstPixmap, x1, y1, x1 + glyph->info.width, y1 + glyph->info.height); } - FreePicture ((pointer) pPicture, 0); nextglyph: x += glyph->info.xOff; diff --git a/render/glyph.c b/render/glyph.c index 7fd3705df..975c62b77 100644 --- a/render/glyph.c +++ b/render/glyph.c @@ -573,7 +573,7 @@ FreeGlyph (GlyphPtr glyph, int format) { ScreenPtr pScreen = screenInfo.screens[i]; - (pScreen->DestroyPixmap) (GlyphPixmap (glyph)[i]); + FreePicture ((pointer) GlyphPicture (glyph)[i], 0); ps = GetPictureScreenIfSet (pScreen); if (ps) @@ -669,7 +669,7 @@ AllocateGlyph (xGlyphInfo *gi, int fdepth) GlyphPtr glyph; int i; - size = screenInfo.numScreens * sizeof (PixmapPtr); + size = screenInfo.numScreens * sizeof (PicturePtr); glyph = (GlyphPtr) xalloc (size + sizeof (GlyphRec)); if (!glyph) return 0; @@ -689,21 +689,12 @@ AllocateGlyph (xGlyphInfo *gi, int fdepth) for (i = 0; i < screenInfo.numScreens; i++) { - ScreenPtr pScreen = screenInfo.screens[i]; + ps = GetPictureScreenIfSet (screenInfo.screens[i]); - GlyphPixmap (glyph)[i] = (pScreen->CreatePixmap) (pScreen, - gi->width, gi->height, - glyphDepths[fdepth]); - if (! GlyphPixmap (glyph)[i]) - goto bail; - - ps = GetPictureScreenIfSet (pScreen); - if (! ps) - continue; - - if (!(*ps->RealizeGlyph) (pScreen, glyph)) { - (pScreen->DestroyPixmap) (GlyphPixmap (glyph)[i]); - goto bail; + if (ps) + { + if (!(*ps->RealizeGlyph) (screenInfo.screens[i], glyph)) + goto bail; } } diff --git a/render/glyphstr.h b/render/glyphstr.h index 4f8746003..c6ab5aa11 100644 --- a/render/glyphstr.h +++ b/render/glyphstr.h @@ -47,7 +47,7 @@ typedef struct _Glyph { /* per-screen pixmaps follow */ } GlyphRec, *GlyphPtr; -#define GlyphPixmap(glyph) ((PixmapPtr *) ((glyph) + 1)) +#define GlyphPicture(glyph) ((PicturePtr *) ((glyph) + 1)) typedef struct _GlyphRef { CARD32 signature; diff --git a/render/miglyph.c b/render/miglyph.c index 2aa94bd09..a52ea49d6 100644 --- a/render/miglyph.c +++ b/render/miglyph.c @@ -174,13 +174,7 @@ miGlyphs (CARD8 op, while (n--) { glyph = *glyphs++; - pPixmap = GlyphPixmap (glyph)[pScreen->myNum]; - component_alpha = NeedsComponent(list->format->format); - pPicture = CreatePicture (0, &pPixmap->drawable, list->format, - CPComponentAlpha, &component_alpha, - serverClient, &error); - if (!pPicture) - return; + pPicture = GlyphPicture (glyph)[pScreen->myNum]; if (maskFormat) { @@ -209,7 +203,6 @@ miGlyphs (CARD8 op, glyph->info.width, glyph->info.height); } - FreePicture ((pointer) pPicture, 0); x += glyph->info.xOff; y += glyph->info.yOff; diff --git a/render/render.c b/render/render.c index 4bad379f6..300b78488 100644 --- a/render/render.c +++ b/render/render.c @@ -1086,6 +1086,8 @@ typedef struct _GlyphNew { unsigned char sha1[20]; } GlyphNewRec, *GlyphNewPtr; +#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0) + static int ProcRenderAddGlyphs (ClientPtr client) { @@ -1102,6 +1104,7 @@ ProcRenderAddGlyphs (ClientPtr client) int i, screen; PicturePtr pSrc = NULL, pDst = NULL; PixmapPtr pSrcPix = NULL, pDstPix = NULL; + CARD32 component_alpha; REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq); glyphSet = (GlyphSetPtr) SecurityLookupIDByType (client, @@ -1118,6 +1121,8 @@ ProcRenderAddGlyphs (ClientPtr client) if (nglyphs > UINT32_MAX / sizeof(GlyphNewRec)) return BadAlloc; + component_alpha = NeedsComponent (glyphSet->format->format); + if (nglyphs <= NLOCALGLYPH) { memset (glyphsLocal, 0, sizeof (glyphsLocal)); glyphsBase = glyphsLocal; @@ -1158,9 +1163,11 @@ ProcRenderAddGlyphs (ClientPtr client) } else { + GlyphPtr glyph; + glyph_new->found = FALSE; - glyph_new->glyph = AllocateGlyph (&gi[i], glyphSet->fdepth); - if (! glyph_new->glyph) + glyph_new->glyph = glyph = AllocateGlyph (&gi[i], glyphSet->fdepth); + if (! glyph) { err = BadAlloc; goto bail; @@ -1194,11 +1201,14 @@ ProcRenderAddGlyphs (ClientPtr client) goto bail; } - pDstPix = GlyphPixmap (glyph_new->glyph)[screen]; + pDstPix = (pScreen->CreatePixmap) (pScreen, + width, height, depth); - pDst = CreatePicture (0, &pDstPix->drawable, - glyphSet->format, 0, NULL, - serverClient, &error); + GlyphPicture (glyph)[screen] = pDst = + CreatePicture (0, &pDstPix->drawable, + glyphSet->format, + CPComponentAlpha, &component_alpha, + serverClient, &error); if (! pDst) { err = BadAlloc; @@ -1216,8 +1226,6 @@ ProcRenderAddGlyphs (ClientPtr client) FreePicture ((pointer) pSrc, 0); pSrc = NULL; - FreePicture ((pointer) pDst, 0); - pDst = NULL; FreeScratchPixmapHeader (pSrcPix); pSrcPix = NULL; } @@ -1251,8 +1259,6 @@ ProcRenderAddGlyphs (ClientPtr client) bail: if (pSrc) FreePicture ((pointer) pSrc, 0); - if (pDst) - FreePicture ((pointer) pDst, 0); if (pSrcPix) FreeScratchPixmapHeader (pSrcPix); for (i = 0; i < nglyphs; i++) From 93ae6fe18c417a22f1fccb22add4890a20cae713 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Thu, 23 Aug 2007 16:33:05 -0700 Subject: [PATCH 08/33] Avoid leaking a Pixmap for every glyph --- render/render.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/render/render.c b/render/render.c index 300b78488..1a1cd7a0e 100644 --- a/render/render.c +++ b/render/render.c @@ -1209,6 +1209,11 @@ ProcRenderAddGlyphs (ClientPtr client) glyphSet->format, CPComponentAlpha, &component_alpha, serverClient, &error); + + /* The picture takes a reference to the pixmap, so we + drop ours. */ + (pScreen->DestroyPixmap) (pDstPix); + if (! pDst) { err = BadAlloc; From a358b87f45ce75e5d013fc904a07dfe394f74387 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 2 Oct 2007 13:13:51 -0700 Subject: [PATCH 09/33] Just link against libcrypto instead of relying on openssl pkg-config. Also fix incorrect library inclusion by kdrive which broke the build. --- configure.ac | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index d7c513e18..ee631b1d1 100644 --- a/configure.ac +++ b/configure.ac @@ -631,7 +631,7 @@ else fi REQUIRED_MODULES="[randrproto >= 1.2] $RENDERPROTO [fixesproto >= 4.0] [damageproto >= 1.1] xcmiscproto xextproto [xproto >= 7.0.9] xtrans [scrnsaverproto >= 1.1] bigreqsproto resourceproto fontsproto [inputproto >= 1.4.2] [kbproto >= 1.0.3]" -REQUIRED_LIBS="xfont xau fontenc [pixman-1 >= 0.9.5] openssl" +REQUIRED_LIBS="xfont xau fontenc [pixman-1 >= 0.9.5]" dnl HAVE_DBUS is true if we actually have the D-Bus library, whereas dnl CONFIG_DBUS_API is true if we want to enable the D-Bus config @@ -1081,7 +1081,7 @@ PKG_CHECK_MODULES([XSERVERLIBS], [$REQUIRED_LIBS]) # XSERVER_CFLAGS="${XSERVERCFLAGS_CFLAGS}" XSERVER_LIBS="$DIX_LIB $CONFIG_LIB $MI_LIB $OS_LIB" -XSERVER_SYS_LIBS="${XSERVERLIBS_LIBS} ${SYS_LIBS} ${LIBS}" +XSERVER_SYS_LIBS="${XSERVERLIBS_LIBS} ${SYS_LIBS} ${LIBS} -lcrypto" AC_SUBST([XSERVER_LIBS]) AC_SUBST([XSERVER_SYS_LIBS]) @@ -1875,7 +1875,7 @@ if test "$KDRIVE" = yes; then KDRIVE_LOCAL_LIBS="$TSLIB_LIBS $DIX_LIB $KDRIVE_LIB $KDRIVE_STUB_LIB $CONFIG_LIB" KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $FB_LIB $MI_LIB $KDRIVE_PURE_LIBS" KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $KDRIVE_OS_LIB $OS_LIB" - KDRIVE_LIBS="$KDRIVE_LOCAL_LIBS $XSERVERLIBS_LIBS" + KDRIVE_LIBS="$KDRIVE_LOCAL_LIBS $XSERVER_SYS_LIBS" # check if we can build Xephyr PKG_CHECK_MODULES(XEPHYR, x11 xext xfont xau xdmcp, [xephyr="yes"], [xephyr="no"]) From 5d74416740de883b7ef0994afea4bbd4d3901be0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 18 Oct 2007 17:44:14 +0200 Subject: [PATCH 10/33] EXA: Don't attempt to move in pixmaps that can't be accelerated. Fixes https://bugs.freedesktop.org/show_bug.cgi?id=12815 . --- exa/exa_accel.c | 3 +++ exa/exa_migration.c | 3 +++ exa/exa_render.c | 16 ++++++++++++++-- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/exa/exa_accel.c b/exa/exa_accel.c index 8bbf036e4..52cc5c40a 100644 --- a/exa/exa_accel.c +++ b/exa/exa_accel.c @@ -152,6 +152,9 @@ exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, int bpp = pDrawable->bitsPerPixel; Bool access_prepared = FALSE; + if (pExaPixmap->accel_blocked) + return FALSE; + /* Don't bother with under 8bpp, XYPixmaps. */ if (format != ZPixmap || bpp < 8) return FALSE; diff --git a/exa/exa_migration.c b/exa/exa_migration.c index 7968521c5..d69526b7f 100644 --- a/exa/exa_migration.c +++ b/exa/exa_migration.c @@ -299,6 +299,9 @@ exaDoMoveInPixmap (ExaMigrationPtr migrate) if (pPixmap->drawable.bitsPerPixel < 8) return; + if (pExaPixmap->accel_blocked) + return; + if (pExaPixmap->area == NULL) { pExaPixmap->area = exaOffscreenAlloc (pScreen, pExaPixmap->fb_size, diff --git a/exa/exa_render.c b/exa/exa_render.c index 2ad53041a..65e67d8d9 100644 --- a/exa/exa_render.c +++ b/exa/exa_render.c @@ -247,10 +247,24 @@ exaTryDriverSolidFill(PicturePtr pSrc, int nbox; int dst_off_x, dst_off_y; PixmapPtr pSrcPix, pDstPix; + ExaPixmapPrivPtr pSrcExaPix, pDstExaPix; CARD32 pixel; CARD16 red, green, blue, alpha; ExaMigrationRec pixmaps[1]; + pDstPix = exaGetDrawablePixmap (pDst->pDrawable); + pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable); + + pSrcExaPix = ExaGetPixmapPriv(pSrcPix); + pDstExaPix = ExaGetPixmapPriv(pDstPix); + + /* Check whether the accelerator can use these pixmaps. + */ + if (pSrcExaPix->accel_blocked || pDstExaPix->accel_blocked) + { + return -1; + } + xDst += pDst->pDrawable->x; yDst += pDst->pDrawable->y; xSrc += pSrc->pDrawable->x; @@ -261,12 +275,10 @@ exaTryDriverSolidFill(PicturePtr pSrc, width, height)) return 1; - pDstPix = exaGetDrawablePixmap (pDst->pDrawable); exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &dst_off_x, &dst_off_y); REGION_TRANSLATE(pScreen, ®ion, dst_off_x, dst_off_y); - pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable); pixel = exaGetPixmapFirstPixel (pSrcPix); pixmaps[0].as_dst = TRUE; From ce50bfd3369686cfecee5a138bd84ef1107a249d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 18 Oct 2007 17:44:48 +0200 Subject: [PATCH 11/33] EXA: Skip empty glyphs. --- exa/exa_render.c | 1 + 1 file changed, 1 insertion(+) diff --git a/exa/exa_render.c b/exa/exa_render.c index 65e67d8d9..cc2f59d6d 100644 --- a/exa/exa_render.c +++ b/exa/exa_render.c @@ -1246,6 +1246,7 @@ exaGlyphs (CARD8 op, y1 = y - glyph->info.y; if (x1 >= pCmpDrw->width || y1 >= pCmpDrw->height || + glyph->info.width == 0 || glyph->info.height == 0 || (x1 + glyph->info.width) <= 0 || (y1 + glyph->info.height) <= 0) goto nextglyph; From ab4bce02a9457dd9c86b774fc74caf3dd6b287ca Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 18 Oct 2007 15:22:42 -0700 Subject: [PATCH 12/33] Add a quirk for Philips 107P5 which lacks the preferred bit on detailed timing. Also fix the prefer-large-75 quirk if the prefer-first-detailed bit was set, though it's not the case for the existing prefer-large-75 consumer. --- hw/xfree86/modes/xf86EdidModes.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c index 9fa5fef9e..2f26a6450 100644 --- a/hw/xfree86/modes/xf86EdidModes.c +++ b/hw/xfree86/modes/xf86EdidModes.c @@ -64,6 +64,8 @@ typedef enum { * maximum size and use that. */ DDC_QUIRK_DETAILED_USE_MAXIMUM_SIZE = 1 << 5, + /* Monitor forgot to set the first detailed is preferred bit. */ + DDC_QUIRK_FIRST_DETAILED_PREFERRED = 1 << 6, } ddc_quirk_t; static Bool quirk_prefer_large_60 (int scrnIndex, xf86MonPtr DDC) @@ -147,6 +149,16 @@ static Bool quirk_135_clock_too_high (int scrnIndex, xf86MonPtr DDC) return FALSE; } +static Bool quirk_first_detailed_preferred (int scrnIndex, xf86MonPtr DDC) +{ + /* Philips 107p5 CRT. Reported on xorg@ with pastebin. */ + if (memcmp (DDC->vendor.name, "PHL", 4) == 0 && + DDC->vendor.prod_id == 57364) + return TRUE; + + return FALSE; +} + typedef struct { Bool (*detect) (int scrnIndex, xf86MonPtr DDC); ddc_quirk_t quirk; @@ -178,6 +190,10 @@ static const ddc_quirk_map_t ddc_quirks[] = { quirk_detailed_use_maximum_size, DDC_QUIRK_DETAILED_USE_MAXIMUM_SIZE, "Detailed timings give sizes in cm." }, + { + quirk_first_detailed_preferred, DDC_QUIRK_FIRST_DETAILED_PREFERRED, + "First detailed timing was not marked as preferred." + }, { NULL, DDC_QUIRK_NONE, "No known quirks" @@ -257,7 +273,7 @@ DDCModesFromStandardTiming(int scrnIndex, struct std_timings *timing, */ static DisplayModePtr DDCModeFromDetailedTiming(int scrnIndex, struct detailed_timings *timing, - int preferred, ddc_quirk_t quirks) + Bool preferred, ddc_quirk_t quirks) { DisplayModePtr Mode; @@ -470,9 +486,10 @@ xf86DDCSetPreferredRefresh(int scrnIndex, DisplayModePtr modes, _X_EXPORT DisplayModePtr xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC) { - int preferred, i; + int i; DisplayModePtr Modes = NULL, Mode; ddc_quirk_t quirks; + Bool preferred; xf86DrvMsg (scrnIndex, X_INFO, "EDID vendor \"%s\", prod id %d\n", DDC->vendor.name, DDC->vendor.prod_id); @@ -480,8 +497,10 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC) quirks = xf86DDCDetectQuirks(scrnIndex, DDC, TRUE); preferred = PREFERRED_TIMING_MODE(DDC->features.msc); - if (quirks & DDC_QUIRK_PREFER_LARGE_60) - preferred = 0; + if (quirks & DDC_QUIRK_FIRST_DETAILED_PREFERRED) + preferred = TRUE; + if (quirks & (DDC_QUIRK_PREFER_LARGE_60 | DDC_QUIRK_PREFER_LARGE_75)) + preferred = FALSE; for (i = 0; i < DET_TIMINGS; i++) { struct detailed_monitor_section *det_mon = &DDC->det_mon[i]; @@ -492,7 +511,7 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC) &det_mon->section.d_timings, preferred, quirks); - preferred = 0; + preferred = FALSE; Modes = xf86ModesAdd(Modes, Mode); break; case DS_STD_TIMINGS: From 7d74690536b64f7b8e8036507ab7790807349c50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Sun, 14 Oct 2007 15:39:21 -0400 Subject: [PATCH 13/33] Simplify and clean up GLX visual initialization. Instead of the fragile setup where we filter the modes common between the DDX generated GLX visuals and the DRI driver generated fbconfigs, we now just take the fbconfigs returned by the DRI driver to be our supported set. --- GL/glx/Makefile.am | 1 - GL/glx/glxdri.c | 66 +---- GL/glx/glxscreens.c | 9 +- GL/glx/glxvisuals.c | 520 --------------------------------- hw/xfree86/dixmods/glxmodule.c | 5 - hw/xnest/Screen.c | 15 - mi/miinitext.c | 5 +- 7 files changed, 9 insertions(+), 612 deletions(-) delete mode 100644 GL/glx/glxvisuals.c diff --git a/GL/glx/Makefile.am b/GL/glx/Makefile.am index 7c1730e39..8eda1531e 100644 --- a/GL/glx/Makefile.am +++ b/GL/glx/Makefile.am @@ -53,7 +53,6 @@ libglx_la_SOURCES = \ glxserver.h \ glxutil.c \ glxutil.h \ - glxvisuals.c \ indirect_dispatch.c \ indirect_dispatch.h \ indirect_dispatch_swap.c \ diff --git a/GL/glx/glxdri.c b/GL/glx/glxdri.c index 2ded6aa81..f11051b81 100644 --- a/GL/glx/glxdri.c +++ b/GL/glx/glxdri.c @@ -658,64 +658,6 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen, return &private->base; } - -static unsigned -filter_modes(__GLcontextModes **server_modes, - const __GLcontextModes *driver_modes) -{ - __GLcontextModes * m; - __GLcontextModes ** prev_next; - const __GLcontextModes * check; - unsigned modes_count = 0; - - if ( driver_modes == NULL ) { - LogMessage(X_WARNING, - "AIGLX: 3D driver returned no fbconfigs.\n"); - return 0; - } - - /* For each mode in server_modes, check to see if a matching mode exists - * in driver_modes. If not, then the mode is not available. - */ - - prev_next = server_modes; - for ( m = *prev_next ; m != NULL ; m = *prev_next ) { - GLboolean do_delete = GL_TRUE; - - for ( check = driver_modes ; check != NULL ; check = check->next ) { - if ( _gl_context_modes_are_same( m, check ) ) { - do_delete = GL_FALSE; - break; - } - } - - /* The 3D has to support all the modes that match the GLX visuals - * sent from the X server. - */ - if ( do_delete && (m->visualID != 0) ) { - do_delete = GL_FALSE; - - LogMessage(X_WARNING, - "AIGLX: 3D driver claims to not support " - "visual 0x%02x\n", m->visualID); - } - - if ( do_delete ) { - *prev_next = m->next; - - m->next = NULL; - _gl_context_modes_destroy( m ); - } - else { - modes_count++; - prev_next = & m->next; - } - } - - return modes_count; -} - - static GLboolean getDrawableInfo(__DRIdrawable *driDrawable, unsigned int *index, unsigned int *stamp, @@ -923,7 +865,6 @@ __glXDRIscreenProbe(ScreenPtr pScreen) char *driverName; drm_handle_t hFB; int junk; - __GLcontextModes * driver_modes; __GLXDRIscreen *screen; void *dev_priv = NULL; char filename[128]; @@ -1073,7 +1014,6 @@ __glXDRIscreenProbe(ScreenPtr pScreen) goto handle_error; } - driver_modes = NULL; screen->driScreen.private = (*createNewScreen)(pScreen->myNum, &screen->driScreen, @@ -1085,7 +1025,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen) fd, api_ver, &interface_methods, - &driver_modes); + &screen->base.modes); if (screen->driScreen.private == NULL) { LogMessage(X_ERROR, "AIGLX error: Calling driver entry point failed"); @@ -1110,10 +1050,6 @@ __glXDRIscreenProbe(ScreenPtr pScreen) screen->base.GLXextensions); } - - filter_modes(&screen->base.modes, driver_modes); - _gl_context_modes_destroy(driver_modes); - __glXsetEnterLeaveServerFuncs(__glXDRIenterServer, __glXDRIleaveServer); screen->enterVT = pScrn->EnterVT; diff --git a/GL/glx/glxscreens.c b/GL/glx/glxscreens.c index c6f060b3d..3d69645f8 100644 --- a/GL/glx/glxscreens.c +++ b/GL/glx/glxscreens.c @@ -281,6 +281,13 @@ glxGetScreen(ScreenPtr pScreen) return (__GLXscreen *) pScreen->devPrivates[glxScreenPrivateIndex].ptr; } +void GlxSetVisualConfigs(int nconfigs, + __GLXvisualConfig *configs, void **privates) +{ + /* We keep this stub around for the DDX drivers that still + * call it. */ +} + void __glXScreenInit(__GLXscreen *glxScreen, ScreenPtr pScreen) { static int glxGeneration; @@ -306,8 +313,6 @@ void __glXScreenInit(__GLXscreen *glxScreen, ScreenPtr pScreen) glxScreen->CloseScreen = pScreen->CloseScreen; pScreen->CloseScreen = glxCloseScreen; - __glXScreenInitVisuals(glxScreen); - pScreen->devPrivates[glxScreenPrivateIndex].ptr = (pointer) glxScreen; } diff --git a/GL/glx/glxvisuals.c b/GL/glx/glxvisuals.c deleted file mode 100644 index 46b380b3d..000000000 --- a/GL/glx/glxvisuals.c +++ /dev/null @@ -1,520 +0,0 @@ -/* - * Copyright © 2006 Red Hat, Inc. - * (C) Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sub license, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * RED HAT, INC, OR PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT - * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR - * THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * Authors: - * Kevin E. Martin - * Brian Paul - * Kristian Høgsberg - * - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void GlxWrapInitVisuals(miInitVisualsProcPtr *); - -extern Bool noGlxVisualInit; -#include "glcontextmodes.h" - -struct ScreenVisualsRec { - int num_vis; - void *private; - __GLcontextModes *modes; -}; -typedef struct ScreenVisualsRec ScreenVisuals; - -static ScreenVisuals screenVisuals[MAXSCREENS]; - -static int numConfigs = 0; -static __GLXvisualConfig *visualConfigs = NULL; -static void **visualPrivates = NULL; - -static int count_bits(unsigned int n) -{ - int bits = 0; - - while (n > 0) { - if (n & 1) bits++; - n >>= 1; - } - return bits; -} - -/* - * In the case the driver defines no GLX visuals we'll use these. - * Note that for TrueColor and DirectColor visuals, bufferSize is the - * sum of redSize, greenSize, blueSize and alphaSize, which may be larger - * than the nplanes/rootDepth of the server's X11 visuals - */ -#define NUM_FALLBACK_CONFIGS 5 -static __GLXvisualConfig FallbackConfigs[NUM_FALLBACK_CONFIGS] = { - /* [0] = RGB, double buffered, Z */ - { - -1, /* vid */ - -1, /* class */ - True, /* rgba */ - -1, -1, -1, 0, /* rgba sizes */ - -1, -1, -1, 0, /* rgba masks */ - 0, 0, 0, 0, /* rgba accum sizes */ - True, /* doubleBuffer */ - False, /* stereo */ - -1, /* bufferSize */ - 16, /* depthSize */ - 0, /* stencilSize */ - 0, /* auxBuffers */ - 0, /* level */ - GLX_NONE, /* visualRating */ - GLX_NONE, /* transparentPixel */ - 0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */ - 0 /* transparentIndex */ - }, - /* [1] = RGB, double buffered, Z, stencil, accum */ - { - -1, /* vid */ - -1, /* class */ - True, /* rgba */ - -1, -1, -1, 0, /* rgba sizes */ - -1, -1, -1, 0, /* rgba masks */ - 16, 16, 16, 0, /* rgba accum sizes */ - True, /* doubleBuffer */ - False, /* stereo */ - -1, /* bufferSize */ - 16, /* depthSize */ - 8, /* stencilSize */ - 0, /* auxBuffers */ - 0, /* level */ - GLX_NONE, /* visualRating */ - GLX_NONE, /* transparentPixel */ - 0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */ - 0 /* transparentIndex */ - }, - /* [2] = RGB+Alpha, double buffered, Z, stencil, accum */ - { - -1, /* vid */ - -1, /* class */ - True, /* rgba */ - -1, -1, -1, 8, /* rgba sizes */ - -1, -1, -1, -1, /* rgba masks */ - 16, 16, 16, 16, /* rgba accum sizes */ - True, /* doubleBuffer */ - False, /* stereo */ - -1, /* bufferSize */ - 16, /* depthSize */ - 8, /* stencilSize */ - 0, /* auxBuffers */ - 0, /* level */ - GLX_NONE, /* visualRating */ - GLX_NONE, /* transparentPixel */ - 0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */ - 0 /* transparentIndex */ - }, - /* [3] = RGB+Alpha, single buffered, Z, stencil, accum */ - { - -1, /* vid */ - -1, /* class */ - True, /* rgba */ - -1, -1, -1, 8, /* rgba sizes */ - -1, -1, -1, -1, /* rgba masks */ - 16, 16, 16, 16, /* rgba accum sizes */ - False, /* doubleBuffer */ - False, /* stereo */ - -1, /* bufferSize */ - 16, /* depthSize */ - 8, /* stencilSize */ - 0, /* auxBuffers */ - 0, /* level */ - GLX_NONE, /* visualRating */ - GLX_NONE, /* transparentPixel */ - 0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */ - 0 /* transparentIndex */ - }, - /* [4] = CI, double buffered, Z */ - { - -1, /* vid */ - -1, /* class */ - False, /* rgba? (false = color index) */ - -1, -1, -1, 0, /* rgba sizes */ - -1, -1, -1, 0, /* rgba masks */ - 0, 0, 0, 0, /* rgba accum sizes */ - True, /* doubleBuffer */ - False, /* stereo */ - -1, /* bufferSize */ - 16, /* depthSize */ - 0, /* stencilSize */ - 0, /* auxBuffers */ - 0, /* level */ - GLX_NONE, /* visualRating */ - GLX_NONE, /* transparentPixel */ - 0, 0, 0, 0, /* transparent rgba color (floats scaled to ints) */ - 0 /* transparentIndex */ - }, -}; - - -static Bool init_visuals(int *nvisualp, VisualPtr *visualp, - VisualID *defaultVisp, - int ndepth, DepthPtr pdepth, - int rootDepth) -{ - int numRGBconfigs; - int numCIconfigs; - int numVisuals = *nvisualp; - int numNewVisuals; - int numNewConfigs; - VisualPtr pVisual = *visualp; - VisualPtr pVisualNew = NULL; - VisualID *orig_vid = NULL; - __GLcontextModes *modes; - __GLXvisualConfig *pNewVisualConfigs = NULL; - void **glXVisualPriv; - void **pNewVisualPriv; - int found_default; - int i, j, k; - - if (numConfigs > 0) - numNewConfigs = numConfigs; - else - numNewConfigs = NUM_FALLBACK_CONFIGS; - - /* Alloc space for the list of new GLX visuals */ - pNewVisualConfigs = (__GLXvisualConfig *) - xalloc(numNewConfigs * sizeof(__GLXvisualConfig)); - if (!pNewVisualConfigs) { - return FALSE; - } - - /* Alloc space for the list of new GLX visual privates */ - pNewVisualPriv = (void **) xalloc(numNewConfigs * sizeof(void *)); - if (!pNewVisualPriv) { - xfree(pNewVisualConfigs); - return FALSE; - } - - /* - ** If SetVisualConfigs was not called, then use default GLX - ** visual configs. - */ - if (numConfigs == 0) { - memcpy(pNewVisualConfigs, FallbackConfigs, - NUM_FALLBACK_CONFIGS * sizeof(__GLXvisualConfig)); - memset(pNewVisualPriv, 0, NUM_FALLBACK_CONFIGS * sizeof(void *)); - } - else { - /* copy driver's visual config info */ - for (i = 0; i < numConfigs; i++) { - pNewVisualConfigs[i] = visualConfigs[i]; - pNewVisualPriv[i] = visualPrivates[i]; - } - } - - /* Count the number of RGB and CI visual configs */ - numRGBconfigs = 0; - numCIconfigs = 0; - for (i = 0; i < numNewConfigs; i++) { - if (pNewVisualConfigs[i].rgba) - numRGBconfigs++; - else - numCIconfigs++; - } - - /* Count the total number of visuals to compute */ - numNewVisuals = 0; - for (i = 0; i < numVisuals; i++) { - numNewVisuals += - (pVisual[i].class == TrueColor || pVisual[i].class == DirectColor) - ? numRGBconfigs : numCIconfigs; - } - - /* Reset variables for use with the next screen/driver's visual configs */ - visualConfigs = NULL; - numConfigs = 0; - - /* Alloc temp space for the list of orig VisualIDs for each new visual */ - orig_vid = (VisualID *) xalloc(numNewVisuals * sizeof(VisualID)); - if (!orig_vid) { - xfree(pNewVisualPriv); - xfree(pNewVisualConfigs); - return FALSE; - } - - /* Alloc space for the list of glXVisuals */ - modes = _gl_context_modes_create(numNewVisuals, sizeof(__GLcontextModes)); - if (modes == NULL) { - xfree(orig_vid); - xfree(pNewVisualPriv); - xfree(pNewVisualConfigs); - return FALSE; - } - - /* Alloc space for the list of glXVisualPrivates */ - glXVisualPriv = (void **)xalloc(numNewVisuals * sizeof(void *)); - if (!glXVisualPriv) { - _gl_context_modes_destroy( modes ); - xfree(orig_vid); - xfree(pNewVisualPriv); - xfree(pNewVisualConfigs); - return FALSE; - } - - /* Alloc space for the new list of the X server's visuals */ - pVisualNew = (VisualPtr)xalloc(numNewVisuals * sizeof(VisualRec)); - if (!pVisualNew) { - xfree(glXVisualPriv); - _gl_context_modes_destroy( modes ); - xfree(orig_vid); - xfree(pNewVisualPriv); - xfree(pNewVisualConfigs); - return FALSE; - } - - /* Initialize the new visuals */ - found_default = FALSE; - screenVisuals[screenInfo.numScreens-1].modes = modes; - for (i = j = 0; i < numVisuals; i++) { - int is_rgb = (pVisual[i].class == TrueColor || - pVisual[i].class == DirectColor); - - for (k = 0; k < numNewConfigs; k++) { - if (pNewVisualConfigs[k].rgba != is_rgb) - continue; - - assert( modes != NULL ); - - /* Initialize the new visual */ - pVisualNew[j] = pVisual[i]; - pVisualNew[j].vid = FakeClientID(0); - - /* Check for the default visual */ - if (!found_default && pVisual[i].vid == *defaultVisp) { - *defaultVisp = pVisualNew[j].vid; - found_default = TRUE; - } - - /* Save the old VisualID */ - orig_vid[j] = pVisual[i].vid; - - /* Initialize the glXVisual */ - _gl_copy_visual_to_context_mode( modes, & pNewVisualConfigs[k] ); - modes->visualID = pVisualNew[j].vid; - if (modes->fbconfigID == GLX_DONT_CARE) - modes->fbconfigID = modes->visualID; - - /* - * If the class is -1, then assume the X visual information - * is identical to what GLX needs, and take them from the X - * visual. NOTE: if class != -1, then all other fields MUST - * be initialized. - */ - if (modes->visualType == GLX_NONE) { - modes->visualType = _gl_convert_from_x_visual_type( pVisual[i].class ); - modes->redBits = count_bits(pVisual[i].redMask); - modes->greenBits = count_bits(pVisual[i].greenMask); - modes->blueBits = count_bits(pVisual[i].blueMask); - modes->alphaBits = modes->alphaBits; - modes->redMask = pVisual[i].redMask; - modes->greenMask = pVisual[i].greenMask; - modes->blueMask = pVisual[i].blueMask; - modes->alphaMask = modes->alphaMask; - modes->rgbBits = (is_rgb) - ? (modes->redBits + modes->greenBits + - modes->blueBits + modes->alphaBits) - : rootDepth; - } - - /* Save the device-dependent private for this visual */ - glXVisualPriv[j] = pNewVisualPriv[k]; - - j++; - modes = modes->next; - } - } - - assert(j <= numNewVisuals); - - /* Save the GLX visuals in the screen structure */ - screenVisuals[screenInfo.numScreens-1].num_vis = numNewVisuals; - screenVisuals[screenInfo.numScreens-1].private = glXVisualPriv; - - /* Set up depth's VisualIDs */ - for (i = 0; i < ndepth; i++) { - int numVids = 0; - VisualID *pVids = NULL; - int k, n = 0; - - /* Count the new number of VisualIDs at this depth */ - for (j = 0; j < pdepth[i].numVids; j++) - for (k = 0; k < numNewVisuals; k++) - if (pdepth[i].vids[j] == orig_vid[k]) - numVids++; - - /* Allocate a new list of VisualIDs for this depth */ - pVids = (VisualID *)xalloc(numVids * sizeof(VisualID)); - - /* Initialize the new list of VisualIDs for this depth */ - for (j = 0; j < pdepth[i].numVids; j++) - for (k = 0; k < numNewVisuals; k++) - if (pdepth[i].vids[j] == orig_vid[k]) - pVids[n++] = pVisualNew[k].vid; - - /* Update this depth's list of VisualIDs */ - xfree(pdepth[i].vids); - pdepth[i].vids = pVids; - pdepth[i].numVids = numVids; - } - - /* Update the X server's visuals */ - *nvisualp = numNewVisuals; - *visualp = pVisualNew; - - /* Free the old list of the X server's visuals */ - xfree(pVisual); - - /* Clean up temporary allocations */ - xfree(orig_vid); - xfree(pNewVisualPriv); - xfree(pNewVisualConfigs); - - /* Free the private list created by DDX HW driver */ - if (visualPrivates) - xfree(visualPrivates); - visualPrivates = NULL; - - return TRUE; -} - -void GlxSetVisualConfigs(int nconfigs, - __GLXvisualConfig *configs, void **privates) -{ - numConfigs = nconfigs; - visualConfigs = configs; - visualPrivates = privates; -} - -static miInitVisualsProcPtr saveInitVisualsProc; - -Bool GlxInitVisuals(VisualPtr *visualp, DepthPtr *depthp, - int *nvisualp, int *ndepthp, - int *rootDepthp, VisualID *defaultVisp, - unsigned long sizes, int bitsPerRGB, - int preferredVis) -{ - Bool ret; - - if (saveInitVisualsProc) { - ret = saveInitVisualsProc(visualp, depthp, nvisualp, ndepthp, - rootDepthp, defaultVisp, sizes, bitsPerRGB, - preferredVis); - if (!ret) - return False; - } - - /* - * Setup the visuals supported by this particular screen. - */ - if (!noGlxVisualInit) { - init_visuals(nvisualp, visualp, defaultVisp, - *ndepthp, *depthp, *rootDepthp); - } - - - return True; -} - -/************************************************************************/ - - -void -GlxWrapInitVisuals(miInitVisualsProcPtr *initVisProc) -{ - saveInitVisualsProc = *initVisProc; - *initVisProc = GlxInitVisuals; -} - -static void fixup_visuals(int screen) -{ - ScreenPtr pScreen = screenInfo.screens[screen]; - ScreenVisuals *psv = &screenVisuals[screen]; - int j; - __GLcontextModes *modes; - - for ( modes = psv->modes ; modes != NULL ; modes = modes->next ) { - const int vis_class = _gl_convert_to_x_visual_type( modes->visualType ); - const int nplanes = (modes->rgbBits - modes->alphaBits); - const VisualPtr pVis = pScreen->visuals; - - /* Find a visual that matches the GLX visual's class and size */ - for (j = 0; j < pScreen->numVisuals; j++) { - if (pVis[j].class == vis_class && - pVis[j].nplanes == nplanes) { - - /* Fixup the masks */ - modes->redMask = pVis[j].redMask; - modes->greenMask = pVis[j].greenMask; - modes->blueMask = pVis[j].blueMask; - - /* Recalc the sizes */ - modes->redBits = count_bits(modes->redMask); - modes->greenBits = count_bits(modes->greenMask); - modes->blueBits = count_bits(modes->blueMask); - } - } - } -} - -void __glXScreenInitVisuals(__GLXscreen *screen) -{ - int index = screen->pScreen->myNum; - - screen->modes = screenVisuals[index].modes; - screen->pVisualPriv = screenVisuals[index].private; - screen->numVisuals = screenVisuals[index].num_vis; - screen->numUsableVisuals = screenVisuals[index].num_vis; - - /* - * The ordering of the rgb compenents might have been changed by the - * driver after mi initialized them. - */ - fixup_visuals(index); -} diff --git a/hw/xfree86/dixmods/glxmodule.c b/hw/xfree86/dixmods/glxmodule.c index 5384f434b..f1c861b3d 100644 --- a/hw/xfree86/dixmods/glxmodule.c +++ b/hw/xfree86/dixmods/glxmodule.c @@ -52,7 +52,6 @@ struct __GLXprovider { extern void GlxPushProvider(__GLXprovider *provider); extern void GlxExtensionInit(void); -extern void GlxWrapInitVisuals(miInitVisualsProcPtr *); static MODULESETUPPROTO(glxSetup); @@ -140,10 +139,6 @@ glxSetup(pointer module, pointer opts, int *errmaj, int *errmin) } LoadExtension(&GLXExt, FALSE); - /* Wrap the init visuals routine in micmap.c */ - GlxWrapInitVisuals(&miInitVisualsProc); - /* Make sure this gets wrapped each time InitVisualWrap is called */ - miHookInitVisuals(NULL, GlxWrapInitVisuals); bail: return module; diff --git a/hw/xnest/Screen.c b/hw/xnest/Screen.c index 86f856e35..02e82d193 100644 --- a/hw/xnest/Screen.c +++ b/hw/xnest/Screen.c @@ -45,10 +45,6 @@ is" without express or implied warranty. Window xnestDefaultWindows[MAXSCREENS]; Window xnestScreenSaverWindows[MAXSCREENS]; -#ifdef GLXEXT -extern void GlxWrapInitVisuals(miInitVisualsProcPtr *); -#endif - static int xnestScreenGeneration = -1; ScreenPtr @@ -230,17 +226,6 @@ xnestOpenScreen(int index, ScreenPtr pScreen, int argc, char *argv[]) defaultVisual = visuals[xnestDefaultVisualIndex].vid; rootDepth = visuals[xnestDefaultVisualIndex].nplanes; -#ifdef GLXEXT - { - miInitVisualsProcPtr proc = NULL; - - GlxWrapInitVisuals(&proc); - /* GlxInitVisuals ignores the last three arguments. */ - proc(&visuals, &depths, &numVisuals, &numDepths, - &rootDepth, &defaultVisual, 0, 0, 0); - } -#endif - if (xnestParentWindow != 0) { XGetWindowAttributes(xnestDisplay, xnestParentWindow, &gattributes); xnestWidth = gattributes.width; diff --git a/mi/miinitext.c b/mi/miinitext.c index 0fc6d1521..556bfc84b 100644 --- a/mi/miinitext.c +++ b/mi/miinitext.c @@ -347,7 +347,6 @@ extern void DarwinGlxWrapInitVisuals(miInitVisualsProcPtr *); extern __GLXprovider __glXMesaProvider; extern void GlxPushProvider(__GLXprovider *impl); extern void GlxExtensionInit(INITARGS); -extern void GlxWrapInitVisuals(miInitVisualsProcPtr *); #endif // INXDARWINAPP #endif // GLXEXT #ifdef XF86DRI @@ -673,9 +672,7 @@ InitVisualWrap() { miResetInitVisuals(); #ifdef GLXEXT -#ifndef __DARWIN__ - GlxWrapInitVisuals(&miInitVisualsProc); -#else +#ifdef __DARWIN__ DarwinGlxWrapInitVisuals(&miInitVisualsProc); #endif #endif From 0af8180683247955ce4cfd48e6a5b4d00bbe618a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Wed, 17 Oct 2007 17:18:47 -0400 Subject: [PATCH 14/33] Drop VisualConfigPriv support from the DRI module. No DDX driver uses this, and this patch stops the DRI module from poking around GLX module data structures. --- hw/xfree86/dri/dri.c | 40 ++++------------------------------------ hw/xfree86/dri/xf86dri.c | 12 +----------- 2 files changed, 5 insertions(+), 47 deletions(-) diff --git a/hw/xfree86/dri/dri.c b/hw/xfree86/dri/dri.c index 1a54f2c03..2408357e5 100644 --- a/hw/xfree86/dri/dri.c +++ b/hw/xfree86/dri/dri.c @@ -67,7 +67,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "dristruct.h" #include "xf86.h" #include "xf86drm.h" -#include "glxserver.h" #include "mi.h" #include "mipointer.h" #include "xf86_OSproc.h" @@ -972,24 +971,8 @@ static Bool DRICreateDummyContext(ScreenPtr pScreen, Bool needCtxPriv) { DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); - __GLXscreen *pGLXScreen = glxGetScreen(pScreen); - __GLcontextModes *modes = pGLXScreen->modes; - void **pVisualConfigPriv = pGLXScreen->pVisualPriv; DRIContextPrivPtr pDRIContextPriv; void *contextStore; - VisualPtr visual; - int visNum; - - visual = pScreen->visuals; - - /* Find the X visual that corresponds the the first GLX visual */ - for (visNum = 0; - visNum < pScreen->numVisuals; - visNum++, visual++) { - if (modes->visualID == visual->vid) - break; - } - if (visNum == pScreen->numVisuals) return FALSE; if (!(pDRIContextPriv = DRICreateContextPriv(pScreen, @@ -999,9 +982,9 @@ DRICreateDummyContext(ScreenPtr pScreen, Bool needCtxPriv) contextStore = DRIGetContextStore(pDRIContextPriv); if (pDRIPriv->pDriverInfo->CreateContext && needCtxPriv) { - if (!pDRIPriv->pDriverInfo->CreateContext(pScreen, visual, + if (!pDRIPriv->pDriverInfo->CreateContext(pScreen, NULL, pDRIPriv->pSAREA->dummy_context, - *pVisualConfigPriv, + NULL, (DRIContextType)(long)contextStore)) { DRIDestroyContextPriv(pDRIContextPriv); return FALSE; @@ -1036,9 +1019,6 @@ DRICreateContext(ScreenPtr pScreen, VisualPtr visual, XID context, drm_context_t * pHWContext) { DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); - __GLXscreen *pGLXScreen = glxGetScreen(pScreen); - __GLcontextModes *modes = pGLXScreen->modes; - void **pVisualConfigPriv = pGLXScreen->pVisualPriv; DRIContextPrivPtr pDRIContextPriv; void *contextStore; @@ -1050,26 +1030,14 @@ DRICreateContext(ScreenPtr pScreen, VisualPtr visual, } } - /* Find the GLX visual associated with the one requested */ - for (modes = pGLXScreen->modes; modes != NULL; modes = modes->next) { - if (modes->visualID == visual->vid) - break; - pVisualConfigPriv++; - } - - if (modes == NULL) { - /* No matching GLX visual found */ - return FALSE; - } - if (!(pDRIContextPriv = DRICreateContextPriv(pScreen, pHWContext, 0))) { return FALSE; } contextStore = DRIGetContextStore(pDRIContextPriv); if (pDRIPriv->pDriverInfo->CreateContext) { - if (!((*pDRIPriv->pDriverInfo->CreateContext)(pScreen, visual, - *pHWContext, *pVisualConfigPriv, + if (!((*pDRIPriv->pDriverInfo->CreateContext)(pScreen, NULL, + *pHWContext, NULL, (DRIContextType)(long)contextStore))) { DRIDestroyContextPriv(pDRIContextPriv); return FALSE; diff --git a/hw/xfree86/dri/xf86dri.c b/hw/xfree86/dri/xf86dri.c index fdf0e9983..130afdfa4 100644 --- a/hw/xfree86/dri/xf86dri.c +++ b/hw/xfree86/dri/xf86dri.c @@ -337,19 +337,9 @@ ProcXF86DRICreateContext( rep.sequenceNumber = client->sequence; pScreen = screenInfo.screens[stuff->screen]; - visual = pScreen->visuals; - - /* Find the requested X visual */ - for (i = 0; i < pScreen->numVisuals; i++, visual++) - if (visual->vid == stuff->visual) - break; - if (i == pScreen->numVisuals) { - /* No visual found */ - return BadValue; - } if (!DRICreateContext( pScreen, - visual, + NULL, stuff->context, (drm_context_t *)&rep.hHWContext)) { return BadValue; From 8fc635e6a8072c7cd2777d804dd6f8eda2eecc15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 18 Oct 2007 15:51:11 -0400 Subject: [PATCH 15/33] Separate handling of GLX visuals and GLX FBConfigs. XIDs for GLX visuals and FBConfigs used to be interchangable and the list of GLX visuals was identical to the list for FBConfigs. This patch splits handling of these two data types and allows the X server to pick and choose the FBConfigs that are exposed as visuals. --- GL/glx/glxcmds.c | 492 ++++++++++++++++++-------------------------- GL/glx/glxdri.c | 2 +- GL/glx/glxglcore.c | 4 +- GL/glx/glxscreens.c | 37 +++- GL/glx/glxscreens.h | 11 +- 5 files changed, 247 insertions(+), 299 deletions(-) diff --git a/GL/glx/glxcmds.c b/GL/glx/glxcmds.c index f6e032193..ac2393c3b 100644 --- a/GL/glx/glxcmds.c +++ b/GL/glx/glxcmds.c @@ -59,16 +59,91 @@ #include "indirect_table.h" #include "indirect_util.h" -/************************************************************************/ - void GlxSetRenderTables (struct _glapi_table *table) { _glapi_set_dispatch (table); } +static int +validGlxScreen(ClientPtr client, int screen, __GLXscreen **pGlxScreen, int *err) +{ + /* + ** Check if screen exists. + */ + if (screen >= screenInfo.numScreens) { + client->errorValue = screen; + *err = BadValue; + return FALSE; + } + *pGlxScreen = glxGetScreen(screenInfo.screens[screen]); -/************************************************************************/ + return TRUE; +} + +static int +validGlxFBConfig(ClientPtr client, __GLXscreen *pGlxScreen, XID id, + __GLcontextModes **config, int *err) +{ + __GLcontextModes *m; + + for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next) + if (m->fbconfigID == id) { + *config = m; + return TRUE; + } + + client->errorValue = id; + *err = __glXError(GLXBadFBConfig); + + return FALSE; +} + +static int +validGlxVisual(ClientPtr client, __GLXscreen *pGlxScreen, XID id, + __GLcontextModes **config, int *err) +{ + int i; + + for (i = 0; i < pGlxScreen->numVisuals; i++) + if (pGlxScreen->visuals[i]->visualID == id) { + *config = pGlxScreen->visuals[i]; + return TRUE; + } + + client->errorValue = id; + *err = BadValue; + + return FALSE; +} + +static int +validGlxFBConfigForWindow(ClientPtr client, __GLcontextModes *config, + DrawablePtr pDraw, int *err) +{ + ScreenPtr pScreen = pDraw->pScreen; + VisualPtr pVisual = NULL; + XID vid; + int i; + + vid = wVisual((WindowPtr)pDraw); + for (i = 0; i < pScreen->numVisuals; i++) { + if (pScreen->visuals[i].vid == vid) { + pVisual = &pScreen->visuals[i]; + break; + } + } + + /* FIXME: What exactly should we check here... */ + if (pVisual->class != _gl_convert_to_x_visual_type(config->visualType) || + !(config->drawableType & GLX_WINDOW_BIT)) { + client->errorValue = pDraw->id; + *err = BadMatch; + return FALSE; + } + + return TRUE; +} void __glXContextDestroy(__GLXcontext *context) @@ -111,58 +186,14 @@ static __GLXcontext *__glXdirectContextCreate(__GLXscreen *screen, static int DoCreateContext(__GLXclientState *cl, GLXContextID gcId, - GLXContextID shareList, VisualID visual, - GLuint screen, GLboolean isDirect) + GLXContextID shareList, __GLcontextModes *config, + __GLXscreen *pGlxScreen, GLboolean isDirect) { ClientPtr client = cl->client; VisualPtr pVisual; - ScreenPtr pScreen; __GLXcontext *glxc, *shareglxc; - __GLcontextModes *modes; - __GLXscreen *pGlxScreen; - GLint i; LEGAL_NEW_RESOURCE(gcId, client); - - /* - ** Check if screen exists. - */ - if (screen >= screenInfo.numScreens) { - client->errorValue = screen; - return BadValue; - } - pScreen = screenInfo.screens[screen]; - pGlxScreen = glxGetScreen(pScreen); - - /* - ** Check if the visual ID is valid for this screen. - */ - pVisual = pScreen->visuals; - for (i = 0; i < pScreen->numVisuals; i++, pVisual++) { - if (pVisual->vid == visual) { - break; - } - } - if (i == pScreen->numVisuals) { - client->errorValue = visual; - return BadValue; - } - - /* - ** Get configuration of the visual. This assumes that the - ** glxScreen structure contains visual configurations only for the - ** subset of Visuals that are supported by this implementation of the - ** OpenGL. - */ - - modes = _gl_context_modes_find_visual( pGlxScreen->modes, visual ); - if (modes == NULL) { - /* - ** Visual not support on this screen by this OpenGL implementation. - */ - client->errorValue = visual; - return BadValue; - } /* ** Find the display list space that we want to share. @@ -206,9 +237,9 @@ DoCreateContext(__GLXclientState *cl, GLXContextID gcId, ** Allocate memory for the new context */ if (!isDirect) - glxc = pGlxScreen->createContext(pGlxScreen, modes, shareglxc); + glxc = pGlxScreen->createContext(pGlxScreen, config, shareglxc); else - glxc = __glXdirectContextCreate(pGlxScreen, modes, shareglxc); + glxc = __glXdirectContextCreate(pGlxScreen, config, shareglxc); if (!glxc) { return BadAlloc; } @@ -217,10 +248,10 @@ DoCreateContext(__GLXclientState *cl, GLXContextID gcId, ** Initially, setup the part of the context that could be used by ** a GL core that needs windowing information (e.g., Mesa). */ - glxc->pScreen = pScreen; + glxc->pScreen = pGlxScreen->pScreen; glxc->pGlxScreen = pGlxScreen; glxc->pVisual = pVisual; - glxc->modes = modes; + glxc->modes = config; /* ** Register this context as a resource. @@ -245,34 +276,54 @@ DoCreateContext(__GLXclientState *cl, GLXContextID gcId, return Success; } - int __glXDisp_CreateContext(__GLXclientState *cl, GLbyte *pc) { xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc; - return DoCreateContext( cl, req->context, req->shareList, req->visual, - req->screen, req->isDirect ); -} + __GLcontextModes *config; + __GLXscreen *pGlxScreen; + int err; + if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) + return err; + if (!validGlxVisual(cl->client, pGlxScreen, req->visual, &config, &err)) + return err; + + return DoCreateContext(cl, req->context, req->shareList, + config, pGlxScreen, req->isDirect); +} int __glXDisp_CreateNewContext(__GLXclientState *cl, GLbyte *pc) { xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc; - return DoCreateContext( cl, req->context, req->shareList, req->fbconfig, - req->screen, req->isDirect ); -} + __GLcontextModes *config; + __GLXscreen *pGlxScreen; + int err; + if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) + return err; + if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err)) + return err; + + return DoCreateContext(cl, req->context, req->shareList, + config, pGlxScreen, req->isDirect); +} int __glXDisp_CreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc) { xGLXCreateContextWithConfigSGIXReq *req = (xGLXCreateContextWithConfigSGIXReq *) pc; - return DoCreateContext( cl, req->context, req->shareList, req->fbconfig, - req->screen, req->isDirect ); -} + __GLcontextModes *config; + __GLXscreen *pGlxScreen; + int err; -/* -** Destroy a GL context as an X resource. -*/ + if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) + return err; + if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err)) + return err; + + return DoCreateContext(cl, req->context, req->shareList, + config, pGlxScreen, req->isDirect); +} int __glXDisp_DestroyContext(__GLXclientState *cl, GLbyte *pc) { ClientPtr client = cl->client; @@ -407,9 +458,7 @@ __glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client, int *error) { DrawablePtr pDraw; - __GLcontextModes *modes; __GLXdrawable *pGlxDraw; - VisualID vid; int rc; /* This is the GLX 1.3 case - the client passes in a GLXWindow or @@ -446,21 +495,17 @@ __glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client, return NULL; } - vid = wVisual((WindowPtr)pDraw); - modes = _gl_context_modes_find_visual(glxc->pGlxScreen->modes, vid); - /* We're binding an X Window for the first time and need to create - * a GLX drawable for it. First check that the drawable screen - * and fbconfig matches the context ditto. */ - if (pDraw->pScreen != glxc->pScreen || modes != glxc->modes) { - client->errorValue = drawId; - *error = BadMatch; + * a GLX drawable for it. Check that the drawable screen matches + * the context screen and that the context fbconfig is compatible + * with the window visual. */ + if (pDraw->pScreen != glxc->pScreen || + !validGlxFBConfigForWindow(client, glxc->modes, pDraw, error)) return NULL; - } pGlxDraw = glxc->pGlxScreen->createDrawable(glxc->pGlxScreen, pDraw, GLX_DRAWABLE_WINDOW, - drawId, modes); + drawId, glxc->modes); /* since we are creating the drawablePrivate, drawId should be new */ if (!AddResource(drawId, __glXDrawableRes, pGlxDraw)) { @@ -830,29 +875,24 @@ int __glXDisp_CopyContext(__GLXclientState *cl, GLbyte *pc) } -static int -DoGetVisualConfigs(__GLXclientState *cl, unsigned screen) +int __glXDisp_GetVisualConfigs(__GLXclientState *cl, GLbyte *pc) { + xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc; ClientPtr client = cl->client; xGLXGetVisualConfigsReply reply; __GLXscreen *pGlxScreen; __GLcontextModes *modes; CARD32 buf[__GLX_TOTAL_CONFIG]; - int p; + int p, i, err; __GLX_DECLARE_SWAP_VARIABLES; __GLX_DECLARE_SWAP_ARRAY_VARIABLES; - if (screen >= screenInfo.numScreens) { - /* The client library must send a valid screen number. */ - client->errorValue = screen; - return BadValue; - } - pGlxScreen = glxGetScreen(screenInfo.screens[screen]); + if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) + return err; - reply.numVisuals = pGlxScreen->numUsableVisuals; + reply.numVisuals = pGlxScreen->numVisuals; reply.numProps = __GLX_TOTAL_CONFIG; - reply.length = (pGlxScreen->numUsableVisuals * __GLX_SIZE_CARD32 * - __GLX_TOTAL_CONFIG) >> 2; + reply.length = (reply.numVisuals * __GLX_SIZE_CARD32 * __GLX_TOTAL_CONFIG) >> 2; reply.type = X_Reply; reply.sequenceNumber = client->sequence; @@ -865,11 +905,9 @@ DoGetVisualConfigs(__GLXclientState *cl, unsigned screen) WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char *)&reply); - for ( modes = pGlxScreen->modes ; modes != NULL ; modes = modes->next ) { - if (modes->visualID == 0) { - /* not a usable visual */ - continue; - } + for (i = 0; i < pGlxScreen->numVisuals; i++) { + modes = pGlxScreen->visuals[i]; + p = 0; buf[p++] = modes->visualID; buf[p++] = _gl_convert_to_x_visual_type( modes->visualType ); @@ -919,93 +957,6 @@ DoGetVisualConfigs(__GLXclientState *cl, unsigned screen) return Success; } -int __glXDisp_GetVisualConfigs(__GLXclientState *cl, GLbyte *pc) -{ - xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc; - return DoGetVisualConfigs(cl, req->screen); -} - - -/* Composite adds a 32 bit ARGB visual after glxvisuals.c have created - * the context modes for the screens. This visual is useful for GLX - * pixmaps, so we create a single mode for this visual with no extra - * buffers. */ -static void -__glXCreateARGBConfig(__GLXscreen *screen) -{ - __GLcontextModes *modes; - VisualPtr visual; - int i; - - /* search for a 32-bit visual */ - visual = NULL; - for (i = 0; i < screen->pScreen->numVisuals; i++) - if (screen->pScreen->visuals[i].nplanes == 32) { - visual = &screen->pScreen->visuals[i]; - break; - } - - if (visual == NULL || visual->class != TrueColor) - return; - - /* Stop now if we already added the mode. */ - if (_gl_context_modes_find_visual (screen->modes, visual->vid)) - return; - - modes = _gl_context_modes_create(1, sizeof(__GLcontextModes)); - if (modes == NULL) - return; - - /* Insert this new mode at the TAIL of the linked list. - * Previously, the mode was incorrectly inserted at the head of the - * list, causing find_mesa_visual() to be off by one. This would - * GLX clients to blow up if they attempted to use the last mode - * in the list! - */ - { - __GLcontextModes *prev = NULL, *m; - for (m = screen->modes; m; m = m->next) - prev = m; - if (prev) - prev->next = modes; - else - screen->modes = modes; - } - - screen->numUsableVisuals++; - screen->numVisuals++; - - modes->visualID = visual->vid; - modes->fbconfigID = visual->vid; - modes->visualType = GLX_TRUE_COLOR; - modes->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT; - modes->renderType = GLX_RGBA_BIT; - modes->xRenderable = GL_TRUE; - modes->rgbMode = TRUE; - modes->colorIndexMode = FALSE; - modes->doubleBufferMode = FALSE; - modes->stereoMode = FALSE; - modes->haveAccumBuffer = FALSE; - - modes->redBits = visual->bitsPerRGBValue;; - modes->greenBits = visual->bitsPerRGBValue; - modes->blueBits = visual->bitsPerRGBValue; - modes->alphaBits = visual->bitsPerRGBValue; - - modes->rgbBits = 4 * visual->bitsPerRGBValue; - modes->indexBits = 0; - modes->level = 0; - modes->numAuxBuffers = 0; - - modes->haveDepthBuffer = FALSE; - modes->depthBits = 0; - modes->haveStencilBuffer = FALSE; - modes->stencilBits = 0; - - modes->visualRating = GLX_NON_CONFORMANT_CONFIG; -} - - #define __GLX_TOTAL_FBCONFIG_ATTRIBS (28) #define __GLX_FBCONFIG_ATTRIBS_LENGTH (__GLX_TOTAL_FBCONFIG_ATTRIBS * 2) /** @@ -1025,25 +976,15 @@ DoGetFBConfigs(__GLXclientState *cl, unsigned screen) xGLXGetFBConfigsReply reply; __GLXscreen *pGlxScreen; CARD32 buf[__GLX_FBCONFIG_ATTRIBS_LENGTH]; - int p; + int p, err; __GLcontextModes *modes; __GLX_DECLARE_SWAP_VARIABLES; __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + if (!validGlxScreen(cl->client, screen, &pGlxScreen, &err)) + return err; - if (screen >= screenInfo.numScreens) { - /* The client library must send a valid screen number. */ - client->errorValue = screen; - return BadValue; - } - pGlxScreen = glxGetScreen(screenInfo.screens[screen]); - - /* Create the "extra" 32bpp ARGB visual, if not already added. - * XXX This is questionable place to do so! Re-examine this someday. - */ - __glXCreateARGBConfig(pGlxScreen); - - reply.numFBConfigs = pGlxScreen->numUsableVisuals; + reply.numFBConfigs = pGlxScreen->numFBConfigs; reply.numAttribs = __GLX_TOTAL_FBCONFIG_ATTRIBS; reply.length = (__GLX_FBCONFIG_ATTRIBS_LENGTH * reply.numFBConfigs); reply.type = X_Reply; @@ -1058,18 +999,14 @@ DoGetFBConfigs(__GLXclientState *cl, unsigned screen) WriteToClient(client, sz_xGLXGetFBConfigsReply, (char *)&reply); - for ( modes = pGlxScreen->modes ; modes != NULL ; modes = modes->next ) { - if (modes->visualID == 0) { - /* not a usable visual */ - continue; - } + for (modes = pGlxScreen->fbconfigs; modes != NULL; modes = modes->next) { p = 0; #define WRITE_PAIR(tag,value) \ do { buf[p++] = tag ; buf[p++] = value ; } while( 0 ) WRITE_PAIR( GLX_VISUAL_ID, modes->visualID ); - WRITE_PAIR( GLX_FBCONFIG_ID, modes->visualID ); + WRITE_PAIR( GLX_FBCONFIG_ID, modes->fbconfigID ); WRITE_PAIR( GLX_X_RENDERABLE, GL_TRUE ); WRITE_PAIR( GLX_RGBA, modes->rgbMode ); @@ -1089,12 +1026,7 @@ DoGetFBConfigs(__GLXclientState *cl, unsigned screen) WRITE_PAIR( GLX_ACCUM_ALPHA_SIZE, modes->accumAlphaBits ); WRITE_PAIR( GLX_DEPTH_SIZE, modes->depthBits ); WRITE_PAIR( GLX_STENCIL_SIZE, modes->stencilBits ); - WRITE_PAIR( GLX_X_VISUAL_TYPE, modes->visualType ); - - /* - ** Add token/value pairs for extensions. - */ WRITE_PAIR( GLX_CONFIG_CAVEAT, modes->visualRating ); WRITE_PAIR( GLX_TRANSPARENT_TYPE, modes->transparentPixel ); WRITE_PAIR( GLX_TRANSPARENT_RED_VALUE, modes->transparentRed ); @@ -1127,44 +1059,18 @@ int __glXDisp_GetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc) } static int -DoCreateGLXDrawable(ClientPtr client, int screenNum, XID fbconfigId, +DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, __GLcontextModes *config, DrawablePtr pDraw, XID glxDrawableId, int type) { - ScreenPtr pScreen; - VisualPtr pVisual; - __GLXscreen *pGlxScreen; __GLXdrawable *pGlxDraw; - __GLcontextModes *modes; - int i; LEGAL_NEW_RESOURCE(glxDrawableId, client); - /* Check if screen of the fbconfig matches screen of drawable. */ - pScreen = pDraw->pScreen; - if (screenNum != pScreen->myNum) + if (pGlxScreen->pScreen != pDraw->pScreen) return BadMatch; - /* If this fbconfig has a corresponding VisualRec the number of - * planes must match the drawable depth. */ - pVisual = pScreen->visuals; - for (i = 0; i < pScreen->numVisuals; i++, pVisual++) { - if (pVisual->vid == fbconfigId && pVisual->nplanes != pDraw->depth) - return BadMatch; - } - - /* Get configuration of the visual. */ - pGlxScreen = glxGetScreen(pScreen); - modes = _gl_context_modes_find_visual(pGlxScreen->modes, fbconfigId); - if (modes == NULL) { - /* Visual not support on this screen by this OpenGL implementation. */ - client->errorValue = fbconfigId; - return BadValue; - } - - /* FIXME: We need to check that the window visual is compatible - * with the specified fbconfig. */ pGlxDraw = pGlxScreen->createDrawable(pGlxScreen, pDraw, type, - glxDrawableId, modes); + glxDrawableId, config); if (pGlxDraw == NULL) return BadAlloc; @@ -1177,7 +1083,7 @@ DoCreateGLXDrawable(ClientPtr client, int screenNum, XID fbconfigId, } static int -DoCreateGLXPixmap(ClientPtr client, int screenNum, XID fbconfigId, +DoCreateGLXPixmap(ClientPtr client, __GLXscreen *pGlxScreen, __GLcontextModes *config, XID drawableId, XID glxDrawableId) { DrawablePtr pDraw; @@ -1189,7 +1095,7 @@ DoCreateGLXPixmap(ClientPtr client, int screenNum, XID fbconfigId, return BadPixmap; } - err = DoCreateGLXDrawable(client, screenNum, fbconfigId, pDraw, + err = DoCreateGLXDrawable(client, pGlxScreen, config, pDraw, glxDrawableId, GLX_DRAWABLE_PIXMAP); if (err == Success) @@ -1235,17 +1141,32 @@ determineTextureTarget(XID glxDrawableID, CARD32 *attribs, CARD32 numAttribs) int __glXDisp_CreateGLXPixmap(__GLXclientState *cl, GLbyte *pc) { xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc; + __GLcontextModes *config; + __GLXscreen *pGlxScreen; + int err; - return DoCreateGLXPixmap(cl->client, req->screen, req->visual, + if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) + return err; + if (!validGlxVisual(cl->client, pGlxScreen, req->visual, &config, &err)) + return err; + + return DoCreateGLXPixmap(cl->client, pGlxScreen, config, req->pixmap, req->glxpixmap); } int __glXDisp_CreatePixmap(__GLXclientState *cl, GLbyte *pc) { xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc; + __GLcontextModes *config; + __GLXscreen *pGlxScreen; int err; - err = DoCreateGLXPixmap(cl->client, req->screen, req->fbconfig, + if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) + return err; + if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err)) + return err; + + err = DoCreateGLXPixmap(cl->client, pGlxScreen, config, req->pixmap, req->glxpixmap); if (err != Success) return err; @@ -1260,9 +1181,17 @@ int __glXDisp_CreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc) { xGLXCreateGLXPixmapWithConfigSGIXReq *req = (xGLXCreateGLXPixmapWithConfigSGIXReq *) pc; + __GLcontextModes *config; + __GLXscreen *pGlxScreen; + int err; - return DoCreateGLXPixmap(cl->client, req->screen, req->fbconfig, - req->pixmap, req->glxpixmap); + if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) + return err; + if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err)) + return err; + + return DoCreateGLXPixmap(cl->client, pGlxScreen, + config, req->pixmap, req->glxpixmap); } @@ -1309,29 +1238,23 @@ static int DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId, int width, int height, XID glxDrawableId) { - ScreenPtr pScreen; - VisualPtr pVisual; - PixmapPtr pPixmap; - int i; + __GLcontextModes *config; + __GLXscreen *pGlxScreen; + PixmapPtr pPixmap; + int err; - pScreen = screenInfo.screens[screenNum]; - - pVisual = pScreen->visuals; - for (i = 0; i < pScreen->numVisuals; i++, pVisual++) { - if (pVisual->vid == fbconfigId) - break; - } - if (i == pScreen->numVisuals) - return __glXError(GLXBadFBConfig); + if (!validGlxScreen(client, screenNum, &pGlxScreen, &err)) + return err; + if (!validGlxFBConfig(client, pGlxScreen, fbconfigId, &config, &err)) + return err; __glXenterServer(GL_FALSE); - pPixmap = (*pScreen->CreatePixmap) (pScreen, - width, height, pVisual->nplanes); + pPixmap = (*pGlxScreen->pScreen->CreatePixmap) (pGlxScreen->pScreen, + width, height, config->rgbBits); __glXleaveServer(GL_FALSE); - return DoCreateGLXDrawable(client, screenNum, fbconfigId, - &pPixmap->drawable, glxDrawableId, - GLX_DRAWABLE_PBUFFER); + return DoCreateGLXDrawable(client, pGlxScreen, config, &pPixmap->drawable, + glxDrawableId, GLX_DRAWABLE_PBUFFER); } int __glXDisp_CreatePbuffer(__GLXclientState *cl, GLbyte *pc) @@ -1428,17 +1351,27 @@ int __glXDisp_ChangeDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc) int __glXDisp_CreateWindow(__GLXclientState *cl, GLbyte *pc) { xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc; + __GLcontextModes *config; + __GLXscreen *pGlxScreen; ClientPtr client = cl->client; DrawablePtr pDraw; int err; + if (!validGlxScreen(client, req->screen, &pGlxScreen, &err)) + return err; + if (!validGlxFBConfig(client, pGlxScreen, req->fbconfig, &config, &err)) + return err; + err = dixLookupDrawable(&pDraw, req->window, client, 0, DixUnknownAccess); if (err != Success || pDraw->type != DRAWABLE_WINDOW) { client->errorValue = req->window; return BadWindow; } - return DoCreateGLXDrawable(client, req->screen, req->fbconfig, + if (!validGlxFBConfigForWindow(client, config, pDraw, &err)) + return err; + + return DoCreateGLXDrawable(client, pGlxScreen, config, pDraw, req->glxwindow, GLX_DRAWABLE_WINDOW); } @@ -2338,23 +2271,15 @@ int __glXDisp_QueryExtensionsString(__GLXclientState *cl, GLbyte *pc) ClientPtr client = cl->client; xGLXQueryExtensionsStringReq *req = (xGLXQueryExtensionsStringReq *) pc; xGLXQueryExtensionsStringReply reply; - GLuint screen; + __GLXscreen *pGlxScreen; size_t n, length; - const char *ptr; char *buf; + int err; - screen = req->screen; - /* - ** Check if screen exists. - */ - if (screen >= screenInfo.numScreens) { - client->errorValue = screen; - return BadValue; - } + if (!validGlxScreen(client, req->screen, &pGlxScreen, &err)) + return err; - ptr = glxGetScreen(screenInfo.screens[screen])->GLXextensions; - - n = strlen(ptr) + 1; + n = strlen(pGlxScreen->GLXextensions) + 1; length = __GLX_PAD(n) >> 2; reply.type = X_Reply; reply.sequenceNumber = client->sequence; @@ -2365,7 +2290,7 @@ int __glXDisp_QueryExtensionsString(__GLXclientState *cl, GLbyte *pc) buf = (char *) xalloc(length << 2); if (buf == NULL) return BadAlloc; - memcpy(buf, ptr, n); + memcpy(buf, pGlxScreen->GLXextensions, n); if (client->swapped) { glxSwapQueryExtensionsStringReply(client, &reply, buf); @@ -2383,25 +2308,16 @@ int __glXDisp_QueryServerString(__GLXclientState *cl, GLbyte *pc) ClientPtr client = cl->client; xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) pc; xGLXQueryServerStringReply reply; - int name; - GLuint screen; size_t n, length; const char *ptr; char *buf; __GLXscreen *pGlxScreen; + int err; - name = req->name; - screen = req->screen; - /* - ** Check if screen exists. - */ - if (screen >= screenInfo.numScreens) { - client->errorValue = screen; - return BadValue; - } - pGlxScreen = glxGetScreen(screenInfo.screens[screen]); + if (!validGlxScreen(client, req->screen, &pGlxScreen, &err)) + return err; - switch(name) { + switch(req->name) { case GLX_VENDOR: ptr = pGlxScreen->GLXvendor; break; diff --git a/GL/glx/glxdri.c b/GL/glx/glxdri.c index f11051b81..3688d50a8 100644 --- a/GL/glx/glxdri.c +++ b/GL/glx/glxdri.c @@ -1025,7 +1025,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen) fd, api_ver, &interface_methods, - &screen->base.modes); + &screen->base.fbconfigs); if (screen->driScreen.private == NULL) { LogMessage(X_ERROR, "AIGLX error: Calling driver entry point failed"); diff --git a/GL/glx/glxglcore.c b/GL/glx/glxglcore.c index fd4e57d59..b50967a16 100644 --- a/GL/glx/glxglcore.c +++ b/GL/glx/glxglcore.c @@ -280,7 +280,7 @@ find_mesa_visual(__GLXscreen *screen, VisualID vid) const __GLcontextModes *modes; unsigned i = 0; - for ( modes = screen->modes ; modes != NULL ; modes = modes->next ) { + for ( modes = screen->fbconfigs ; modes != NULL ; modes = modes->next ) { if ( modes->visualID == vid ) { break; } @@ -314,7 +314,7 @@ static void init_screen_visuals(__GLXMESAscreen *screen) memset(used, 0, pScreen->numVisuals * sizeof(int)); num_vis = 0; - for ( modes = screen->base.modes; modes != NULL; modes = modes->next ) { + for ( modes = screen->base.fbconfigs; modes != NULL; modes = modes->next ) { const int vis_class = _gl_convert_to_x_visual_type( modes->visualType ); const int nplanes = (modes->rgbBits - modes->alphaBits); const VisualPtr pVis = pScreen->visuals; diff --git a/GL/glx/glxscreens.c b/GL/glx/glxscreens.c index 3d69645f8..e2d3d4ae1 100644 --- a/GL/glx/glxscreens.c +++ b/GL/glx/glxscreens.c @@ -44,6 +44,7 @@ #include "glxserver.h" #include "glxutil.h" #include "glxext.h" +#include "glcontextmodes.h" static int glxScreenPrivateIndex; @@ -284,13 +285,28 @@ glxGetScreen(ScreenPtr pScreen) void GlxSetVisualConfigs(int nconfigs, __GLXvisualConfig *configs, void **privates) { - /* We keep this stub around for the DDX drivers that still - * call it. */ + /* We keep this stub around for the DDX drivers that still + * call it. */ +} + +static XID +findVisualForConfig(ScreenPtr pScreen, __GLcontextModes *m) +{ + int i; + + for (i = 0; i < pScreen->numVisuals; i++) { + if (_gl_convert_to_x_visual_type(m->visualType) == pScreen->visuals[i].class) + return pScreen->visuals[i].vid; + } + + return 0; } void __glXScreenInit(__GLXscreen *glxScreen, ScreenPtr pScreen) { static int glxGeneration; + __GLcontextModes *m; + int i; if (glxGeneration != serverGeneration) { @@ -301,6 +317,23 @@ void __glXScreenInit(__GLXscreen *glxScreen, ScreenPtr pScreen) glxGeneration = serverGeneration; } + i = 0; + for (m = glxScreen->fbconfigs; m != NULL; m = m->next) { + m->fbconfigID = i++; + m->visualID = findVisualForConfig(pScreen, m); + ErrorF("mapping fbconfig %d to visual 0x%02x\n", + m->fbconfigID, m->visualID); + } + glxScreen->numFBConfigs = i; + + /* Select a subset of fbconfigs that we send to the client when it + * asks for the glx visuals. All the fbconfigs here have a valid + * value for visual ID and each visual ID is only present once. + * This runs before composite adds its extra visual so we have to + * remember the number of visuals here.*/ + glxScreen->visuals = NULL; + glxScreen->numVisuals = 0; + glxScreen->pScreen = pScreen; glxScreen->GLextensions = xstrdup(GLServerExtensions); glxScreen->GLXvendor = xstrdup(GLXServerVendorName); diff --git a/GL/glx/glxscreens.h b/GL/glx/glxscreens.h index 7b1bbcd58..f1eef912c 100644 --- a/GL/glx/glxscreens.h +++ b/GL/glx/glxscreens.h @@ -83,14 +83,13 @@ struct __GLXscreen { ScreenPtr pScreen; - /** - * Linked list of valid context modes for this screen. - */ - __GLcontextModes *modes; + /* Linked list of valid fbconfigs for this screen. */ + __GLcontextModes *fbconfigs; + int numFBConfigs; - void **pVisualPriv; + /* Subset of fbconfigs that are exposed as GLX visuals. */ + __GLcontextModes **visuals; GLint numVisuals; - GLint numUsableVisuals; char *GLextensions; From 9e3cfd950d279353f1795352ad2c4132aabc1bab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 18 Oct 2007 19:12:24 -0400 Subject: [PATCH 16/33] Add code to set up GLX visuals and add one for the first double buffered FBConfig. --- GL/glx/glxscreens.c | 152 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 142 insertions(+), 10 deletions(-) diff --git a/GL/glx/glxscreens.c b/GL/glx/glxscreens.c index e2d3d4ae1..bfd49a129 100644 --- a/GL/glx/glxscreens.c +++ b/GL/glx/glxscreens.c @@ -40,6 +40,7 @@ #include #include #include +#include #include "glxserver.h" #include "glxutil.h" @@ -302,6 +303,144 @@ findVisualForConfig(ScreenPtr pScreen, __GLcontextModes *m) return 0; } +/* This code inspired by composite/compinit.c. We could move this to + * mi/ and share it with composite.*/ + +static VisualPtr +AddScreenVisuals(ScreenPtr pScreen, int count, int d) +{ + XID *installedCmaps, *vids, vid; + int numInstalledCmaps, numVisuals, i, j; + VisualPtr visuals; + ColormapPtr installedCmap; + DepthPtr depth; + + depth = NULL; + for (i = 0; i < pScreen->numDepths; i++) { + if (pScreen->allowedDepths[i].depth == d) { + depth = &pScreen->allowedDepths[i]; + break; + } + } + if (depth == NULL) + return NULL; + + /* Find the installed colormaps */ + installedCmaps = xalloc (pScreen->maxInstalledCmaps * sizeof (XID)); + if (!installedCmaps) + return NULL; + + numInstalledCmaps = pScreen->ListInstalledColormaps(pScreen, installedCmaps); + + /* realloc the visual array to fit the new one in place */ + numVisuals = pScreen->numVisuals; + visuals = xrealloc(pScreen->visuals, (numVisuals + count) * sizeof(VisualRec)); + if (!visuals) { + xfree(installedCmaps); + return NULL; + } + + vids = xrealloc(depth->vids, (depth->numVids + count) * sizeof(XID)); + if (vids == NULL) { + xfree(installedCmaps); + xfree(visuals); + return NULL; + } + + /* + * Fix up any existing installed colormaps -- we'll assume that + * the only ones created so far have been installed. If this + * isn't true, we'll have to walk the resource database looking + * for all colormaps. + */ + for (i = 0; i < numInstalledCmaps; i++) { + installedCmap = LookupIDByType (installedCmaps[i], RT_COLORMAP); + if (!installedCmap) + continue; + j = installedCmap->pVisual - pScreen->visuals; + installedCmap->pVisual = &visuals[j]; + } + + xfree(installedCmaps); + + for (i = 0; i < count; i++) { + vid = FakeClientID(0); + visuals[pScreen->numVisuals + i].vid = vid; + vids[depth->numVids + i] = vid; + } + + pScreen->visuals = visuals; + pScreen->numVisuals += count; + depth->vids = vids; + depth->numVids += count; + + /* Return a pointer to the first of the added visuals. */ + return pScreen->visuals + pScreen->numVisuals - count; +} + +static int +findFirstSet(unsigned int v) +{ + int i; + + for (i = 0; i < 32; i++) + if (v & (1 << i)) + return i; + + return -1; +} + +static void +initGlxVisual(VisualPtr visual, __GLcontextModes *config) +{ + ErrorF("Adding visual 0x%02lx for fbconfig %d\n", + visual->vid, config->fbconfigID); + + config->visualID = visual[0].vid; + visual->class = _gl_convert_to_x_visual_type(config->visualType); + visual->bitsPerRGBValue = config->redBits; + visual->ColormapEntries = 1 << config->redBits; + visual->nplanes = config->redBits + config->greenBits + config->blueBits; + + visual->redMask = config->redMask; + visual->greenMask = config->greenMask; + visual->blueMask = config->blueMask; + visual->offsetRed = findFirstSet(config->redMask); + visual->offsetGreen = findFirstSet(config->greenMask); + visual->offsetBlue = findFirstSet(config->blueMask); +} + +static void +addGlxVisuals(__GLXscreen *pGlxScreen) +{ + __GLcontextModes *config; + VisualPtr visual; + + /* Select a subset of fbconfigs that we send to the client when it + * asks for the glx visuals. All the fbconfigs here have a valid + * value for visual ID and each visual ID is only present once. + * This runs before composite adds its extra visual so we have to + * remember the number of visuals here.*/ + + /* For now, just add the first double buffer fbconfig. */ + for (config = pGlxScreen->fbconfigs; config != NULL; config = config->next) + if (config->doubleBufferMode) + break; + if (config == NULL) + config = pGlxScreen->fbconfigs; + + pGlxScreen->visuals = xcalloc(1, sizeof (__GLcontextModes *)); + visual = AddScreenVisuals(pGlxScreen->pScreen, 1, config->rgbBits); + if (visual == NULL) { + xfree(pGlxScreen->visuals); + return; + } + + pGlxScreen->numVisuals = 1; + pGlxScreen->visuals[0] = config; + initGlxVisual(&visual[0], config); +} + void __glXScreenInit(__GLXscreen *glxScreen, ScreenPtr pScreen) { static int glxGeneration; @@ -319,20 +458,13 @@ void __glXScreenInit(__GLXscreen *glxScreen, ScreenPtr pScreen) i = 0; for (m = glxScreen->fbconfigs; m != NULL; m = m->next) { - m->fbconfigID = i++; + m->fbconfigID = FakeClientID(0); m->visualID = findVisualForConfig(pScreen, m); - ErrorF("mapping fbconfig %d to visual 0x%02x\n", - m->fbconfigID, m->visualID); + i++; } glxScreen->numFBConfigs = i; - /* Select a subset of fbconfigs that we send to the client when it - * asks for the glx visuals. All the fbconfigs here have a valid - * value for visual ID and each visual ID is only present once. - * This runs before composite adds its extra visual so we have to - * remember the number of visuals here.*/ - glxScreen->visuals = NULL; - glxScreen->numVisuals = 0; + addGlxVisuals(glxScreen); glxScreen->pScreen = pScreen; glxScreen->GLextensions = xstrdup(GLServerExtensions); From 8e3c1dfc48930c455529313a42efa35e3b9071b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 18 Oct 2007 21:01:51 -0400 Subject: [PATCH 17/33] Introduce a new "GlxVisuals" option that controls which visuals are added. Right now we default to "all" which gives us a situation much like before, but when the "typical" option is implemented, we can change the default and reduce the number of visuals the GLX module bloats the X server with. --- GL/glx/glxdrawable.h | 4 - GL/glx/glxscreens.c | 120 ++++++++++++++++++++------- GL/glx/glxserver.h | 10 +++ hw/xfree86/common/xf86Config.c | 29 ++++++- hw/xfree86/common/xf86Privstr.h | 9 ++ hw/xfree86/dixmods/glxmodule.c | 29 ++++--- hw/xfree86/doc/man/xorg.conf.man.pre | 11 +++ 7 files changed, 161 insertions(+), 51 deletions(-) diff --git a/GL/glx/glxdrawable.h b/GL/glx/glxdrawable.h index 858bbb35b..f62d1ee34 100644 --- a/GL/glx/glxdrawable.h +++ b/GL/glx/glxdrawable.h @@ -42,10 +42,6 @@ #include -#ifdef XF86DRI -#include -#endif - /* We just need to avoid clashing with DRAWABLE_{WINDOW,PIXMAP} */ enum { GLX_DRAWABLE_WINDOW, diff --git a/GL/glx/glxscreens.c b/GL/glx/glxscreens.c index bfd49a129..511aa8ad9 100644 --- a/GL/glx/glxscreens.c +++ b/GL/glx/glxscreens.c @@ -393,10 +393,7 @@ findFirstSet(unsigned int v) static void initGlxVisual(VisualPtr visual, __GLcontextModes *config) { - ErrorF("Adding visual 0x%02lx for fbconfig %d\n", - visual->vid, config->fbconfigID); - - config->visualID = visual[0].vid; + config->visualID = visual->vid; visual->class = _gl_convert_to_x_visual_type(config->visualType); visual->bitsPerRGBValue = config->redBits; visual->ColormapEntries = 1 << config->redBits; @@ -411,37 +408,84 @@ initGlxVisual(VisualPtr visual, __GLcontextModes *config) } static void -addGlxVisuals(__GLXscreen *pGlxScreen) +addMinimalSet(__GLXscreen *pGlxScreen) { __GLcontextModes *config; - VisualPtr visual; + VisualPtr visuals; + int depth; - /* Select a subset of fbconfigs that we send to the client when it - * asks for the glx visuals. All the fbconfigs here have a valid - * value for visual ID and each visual ID is only present once. - * This runs before composite adds its extra visual so we have to - * remember the number of visuals here.*/ - - /* For now, just add the first double buffer fbconfig. */ - for (config = pGlxScreen->fbconfigs; config != NULL; config = config->next) - if (config->doubleBufferMode) + for (config = pGlxScreen->fbconfigs; config != NULL; config = config->next) { + if (config->visualRating != GLX_NONE) + continue; + if (config->doubleBufferMode && config->depthBits > 0) break; + } if (config == NULL) config = pGlxScreen->fbconfigs; pGlxScreen->visuals = xcalloc(1, sizeof (__GLcontextModes *)); - visual = AddScreenVisuals(pGlxScreen->pScreen, 1, config->rgbBits); - if (visual == NULL) { + if (pGlxScreen->visuals == NULL) { + ErrorF("Failed to allocate for minimal set of GLX visuals\n"); + return; + } + + depth = config->redBits + config->greenBits + config->blueBits; + visuals = AddScreenVisuals(pGlxScreen->pScreen, 1, depth); + if (visuals == NULL) { xfree(pGlxScreen->visuals); return; } pGlxScreen->numVisuals = 1; pGlxScreen->visuals[0] = config; - initGlxVisual(&visual[0], config); + initGlxVisual(&visuals[0], config); } -void __glXScreenInit(__GLXscreen *glxScreen, ScreenPtr pScreen) +static void +addTypicalSet(__GLXscreen *pGlxScreen) +{ + addMinimalSet(pGlxScreen); +} + +static void +addFullSet(__GLXscreen *pGlxScreen) +{ + __GLcontextModes *config; + VisualPtr visuals; + int i, depth; + + pGlxScreen->visuals = + xcalloc(pGlxScreen->numFBConfigs, sizeof (__GLcontextModes *)); + if (pGlxScreen->visuals == NULL) { + ErrorF("Failed to allocate for full set of GLX visuals\n"); + return; + } + + config = pGlxScreen->fbconfigs; + depth = config->redBits + config->greenBits + config->blueBits; + visuals = AddScreenVisuals(pGlxScreen->pScreen, pGlxScreen->numFBConfigs, depth); + if (visuals == NULL) { + xfree(pGlxScreen->visuals); + return; + } + + ErrorF("addFullSet, setting numVisuals to %d\n", pGlxScreen->numFBConfigs); + + pGlxScreen->numVisuals = pGlxScreen->numFBConfigs; + for (i = 0, config = pGlxScreen->fbconfigs; config; config = config->next, i++) { + pGlxScreen->visuals[i] = config; + initGlxVisual(&visuals[i], config); + } +} + +static int glxVisualConfig = GLX_ALL_VISUALS; + +void GlxSetVisualConfig(int config) +{ + glxVisualConfig = config; +} + +void __glXScreenInit(__GLXscreen *pGlxScreen, ScreenPtr pScreen) { static int glxGeneration; __GLcontextModes *m; @@ -457,28 +501,44 @@ void __glXScreenInit(__GLXscreen *glxScreen, ScreenPtr pScreen) } i = 0; - for (m = glxScreen->fbconfigs; m != NULL; m = m->next) { + for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next) { m->fbconfigID = FakeClientID(0); m->visualID = findVisualForConfig(pScreen, m); i++; } - glxScreen->numFBConfigs = i; + pGlxScreen->numFBConfigs = i; - addGlxVisuals(glxScreen); + /* Select a subset of fbconfigs that we send to the client when it + * asks for the glx visuals. All the fbconfigs here have a valid + * value for visual ID and each visual ID is only present once. + * This runs before composite adds its extra visual so we have to + * remember the number of visuals here.*/ - glxScreen->pScreen = pScreen; - glxScreen->GLextensions = xstrdup(GLServerExtensions); - glxScreen->GLXvendor = xstrdup(GLXServerVendorName); - glxScreen->GLXversion = xstrdup(GLXServerVersion); - glxScreen->GLXextensions = xstrdup(GLXServerExtensions); + switch (glxVisualConfig) { + case GLX_MINIMAL_VISUALS: + addMinimalSet(pGlxScreen); + break; + case GLX_TYPICAL_VISUALS: + addTypicalSet(pGlxScreen); + break; + case GLX_ALL_VISUALS: + addFullSet(pGlxScreen); + break; + } - glxScreen->PositionWindow = pScreen->PositionWindow; + pGlxScreen->pScreen = pScreen; + pGlxScreen->GLextensions = xstrdup(GLServerExtensions); + pGlxScreen->GLXvendor = xstrdup(GLXServerVendorName); + pGlxScreen->GLXversion = xstrdup(GLXServerVersion); + pGlxScreen->GLXextensions = xstrdup(GLXServerExtensions); + + pGlxScreen->PositionWindow = pScreen->PositionWindow; pScreen->PositionWindow = glxPositionWindow; - glxScreen->CloseScreen = pScreen->CloseScreen; + pGlxScreen->CloseScreen = pScreen->CloseScreen; pScreen->CloseScreen = glxCloseScreen; - pScreen->devPrivates[glxScreenPrivateIndex].ptr = (pointer) glxScreen; + pScreen->devPrivates[glxScreenPrivateIndex].ptr = (pointer) pGlxScreen; } void __glXScreenDestroy(__GLXscreen *screen) diff --git a/GL/glx/glxserver.h b/GL/glx/glxserver.h index 45de8e794..518868981 100644 --- a/GL/glx/glxserver.h +++ b/GL/glx/glxserver.h @@ -95,6 +95,8 @@ extern __GLXclientState *glxGetClient(ClientPtr pClient); /************************************************************************/ +void GlxExtensionInit(void); + void GlxSetVisualConfigs(int nconfigs, __GLXvisualConfig *configs, void **privates); @@ -132,6 +134,14 @@ struct __GLXprovider { void GlxPushProvider(__GLXprovider *provider); +enum { + GLX_MINIMAL_VISUALS, + GLX_TYPICAL_VISUALS, + GLX_ALL_VISUALS +}; + +void GlxSetVisualConfig(int config); + void __glXsetEnterLeaveServerFuncs(void (*enter)(GLboolean), void (*leave)(GLboolean)); void __glXenterServer(GLboolean rendering); diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c index 96fadc9dd..35b62a244 100644 --- a/hw/xfree86/common/xf86Config.c +++ b/hw/xfree86/common/xf86Config.c @@ -792,6 +792,7 @@ typedef enum { FLAG_USE_DEFAULT_FONT_PATH, FLAG_AUTO_ADD_DEVICES, FLAG_AUTO_ENABLE_DEVICES, + FLAG_GLX_VISUALS, } FlagValues; static OptionInfoRec FlagOptions[] = { @@ -873,6 +874,8 @@ static OptionInfoRec FlagOptions[] = { {0}, TRUE }, { FLAG_AUTO_ENABLE_DEVICES, "AutoEnableDevices", OPTV_BOOLEAN, {0}, TRUE }, + { FLAG_GLX_VISUALS, "GlxVisuals", OPTV_STRING, + {0}, FALSE }, { -1, NULL, OPTV_NONE, {0}, FALSE }, }; @@ -904,6 +907,7 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts) Pix24Flags pix24 = Pix24DontCare; Bool value; MessageType from; + const char *s; /* * Merge the ServerLayout and ServerFlags options. The former have @@ -1021,7 +1025,6 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts) if (xf86GetOptValBool(FlagOptions, FLAG_NOPM, &value)) xf86Info.pmFlag = !value; { - const char *s; if ((s = xf86GetOptValString(FlagOptions, FLAG_LOG))) { if (!xf86NameCmp(s,"flush")) { xf86Msg(X_CONFIG, "Flushing logfile enabled\n"); @@ -1040,8 +1043,6 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts) #ifdef RENDER { - const char *s; - if ((s = xf86GetOptValString(FlagOptions, FLAG_RENDER_COLORMAP_MODE))){ int policy = PictureParseCmapPolicy (s); if (policy == PictureCmapPolicyInvalid) @@ -1055,7 +1056,6 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts) } #endif { - const char *s; if ((s = xf86GetOptValString(FlagOptions, FLAG_HANDLE_SPECIAL_KEYS))) { if (!xf86NameCmp(s,"always")) { xf86Msg(X_CONFIG, "Always handling special keys in DDX\n"); @@ -1093,6 +1093,27 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts) xf86Info.aiglxFrom = X_CONFIG; } +#ifdef GLXEXT + xf86Info.glxVisuals = XF86_GlxVisualsAll; + xf86Info.glxVisualsFrom = X_DEFAULT; + if ((s = xf86GetOptValString(FlagOptions, FLAG_GLX_VISUALS))) { + if (!xf86NameCmp(s, "minimal")) { + xf86Info.glxVisuals = XF86_GlxVisualsMinimal; + } else if (!xf86NameCmp(s, "typical")) { + xf86Info.glxVisuals = XF86_GlxVisualsTypical; + } else if (!xf86NameCmp(s, "all")) { + xf86Info.glxVisuals = XF86_GlxVisualsAll; + } else { + xf86Msg(X_WARNING,"Unknown HandleSpecialKeys option\n"); + } + } + + if (xf86GetOptValBool(FlagOptions, FLAG_AIGLX, &value)) { + xf86Info.aiglx = value; + xf86Info.aiglxFrom = X_CONFIG; + } +#endif + xf86Info.allowEmptyInput = FALSE; if (xf86GetOptValBool(FlagOptions, FLAG_ALLOW_EMPTY_INPUT, &value)) xf86Info.allowEmptyInput = TRUE; diff --git a/hw/xfree86/common/xf86Privstr.h b/hw/xfree86/common/xf86Privstr.h index 75d497471..92a6305a0 100644 --- a/hw/xfree86/common/xf86Privstr.h +++ b/hw/xfree86/common/xf86Privstr.h @@ -60,6 +60,12 @@ typedef enum { SKAlways } SpecialKeysInDDX; +typedef enum { + XF86_GlxVisualsMinimal, + XF86_GlxVisualsTypical, + XF86_GlxVisualsAll, +} XF86_GlxVisuals; + /* * xf86InfoRec contains global parameters which the video drivers never * need to access. Global parameters which the video drivers do need @@ -120,6 +126,9 @@ typedef struct { MessageType randRFrom; Bool aiglx; MessageType aiglxFrom; + XF86_GlxVisuals glxVisuals; + MessageType glxVisualsFrom; + Bool useDefaultFontPath; MessageType useDefaultFontPathFrom; Bool ignoreABI; diff --git a/hw/xfree86/dixmods/glxmodule.c b/hw/xfree86/dixmods/glxmodule.c index f1c861b3d..847f0d4a2 100644 --- a/hw/xfree86/dixmods/glxmodule.c +++ b/hw/xfree86/dixmods/glxmodule.c @@ -41,17 +41,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "colormap.h" #include "micmap.h" #include "globals.h" - -typedef struct __GLXscreen __GLXscreen; -typedef struct __GLXprovider __GLXprovider; -struct __GLXprovider { - __GLXscreen *(*screenProbe)(ScreenPtr pScreen); - const char *name; - __GLXprovider *next; -}; - -extern void GlxPushProvider(__GLXprovider *provider); -extern void GlxExtensionInit(void); +#include "glxserver.h" static MODULESETUPPROTO(glxSetup); @@ -113,7 +103,6 @@ static __GLXprovider __glXMesaProxyProvider = { NULL }; - static pointer glxSetup(pointer module, pointer opts, int *errmaj, int *errmin) { @@ -138,8 +127,22 @@ glxSetup(pointer module, pointer opts, int *errmaj, int *errmin) GlxPushProvider(provider); } + switch (xf86Info.glxVisuals) { + case XF86_GlxVisualsMinimal: + GlxSetVisualConfig(GLX_MINIMAL_VISUALS); + xf86Msg(xf86Info.aiglxFrom, "Exporting only minimal set of GLX visuals\n"); + break; + case XF86_GlxVisualsTypical: + GlxSetVisualConfig(GLX_TYPICAL_VISUALS); + xf86Msg(xf86Info.aiglxFrom, "Exporting typical set of GLX visuals\n"); + break; + case XF86_GlxVisualsAll: + GlxSetVisualConfig(GLX_ALL_VISUALS); + xf86Msg(xf86Info.aiglxFrom, "Exporting all GLX visuals\n"); + break; + } + LoadExtension(&GLXExt, FALSE); - bail: return module; } diff --git a/hw/xfree86/doc/man/xorg.conf.man.pre b/hw/xfree86/doc/man/xorg.conf.man.pre index 54d8eaa87..4064ef6d8 100644 --- a/hw/xfree86/doc/man/xorg.conf.man.pre +++ b/hw/xfree86/doc/man/xorg.conf.man.pre @@ -700,6 +700,17 @@ the builtin handler will be used. .BI "Option \*qAIGLX\*q \*q" boolean \*q enable or disable AIGLX. AIGLX is enabled by default. .TP 7 +.BI "Option \*qGlxVisuals\*q \*q" string \*q +This option controls how many GLX visuals the GLX modules sets up. +The default value is +.BR "typical" , +which will setup up a typical subset of +the GLXFBConfigs provided by the driver as GLX visuals. Other options are +.BR "minimal" , +which will set up the minimal set allowed by the GLX specification and +.BR "all" +which will setup GLX visuals for all GLXFBConfigs. +.TP 7 .BI "Option \*qUseDefaultFontPath\*q \*q" boolean \*q Include the default font path even if other paths are specified in xorg.conf. If enabled, other font paths are included as well. Enabled by From 6fdf3ddfef2707755cec0fc9cbce354fd472bb52 Mon Sep 17 00:00:00 2001 From: Matthias Hopf Date: Fri, 19 Oct 2007 17:20:21 +0200 Subject: [PATCH 18/33] Fix ids of ACPI events according to ACPI spec. --- hw/xfree86/os-support/linux/lnx_acpi.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/hw/xfree86/os-support/linux/lnx_acpi.c b/hw/xfree86/os-support/linux/lnx_acpi.c index 024e6ef09..9808e37e0 100644 --- a/hw/xfree86/os-support/linux/lnx_acpi.c +++ b/hw/xfree86/os-support/linux/lnx_acpi.c @@ -23,11 +23,11 @@ #define ACPI_VIDEO_NOTIFY_NEXT_OUTPUT 0x83 #define ACPI_VIDEO_NOTIFY_PREV_OUTPUT 0x84 -#define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS 0x82 -#define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS 0x83 -#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x84 -#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS 0x85 -#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF 0x86 +#define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS 0x85 +#define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS 0x86 +#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x87 +#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS 0x88 +#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF 0x89 #define ACPI_VIDEO_HEAD_INVALID (~0u - 1) #define ACPI_VIDEO_HEAD_END (~0u) From 74e84b8d891632141a60e2d29463ab46f622df3f Mon Sep 17 00:00:00 2001 From: Matthias Hopf Date: Fri, 19 Oct 2007 17:28:15 +0200 Subject: [PATCH 19/33] Only issue XF86_APM_CAPABILITY_CHANGED for video change ACPI events (not e.g. brightness etc.). --- hw/xfree86/os-support/linux/lnx_acpi.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/hw/xfree86/os-support/linux/lnx_acpi.c b/hw/xfree86/os-support/linux/lnx_acpi.c index 9808e37e0..bb975cc5d 100644 --- a/hw/xfree86/os-support/linux/lnx_acpi.c +++ b/hw/xfree86/os-support/linux/lnx_acpi.c @@ -69,9 +69,11 @@ lnxACPIGetEventFromOs(int fd, pmEvent *events, int num) TimerSet(NULL, 0, ACPI_REOPEN_DELAY, lnxACPIReopen, NULL); return 0; } + /* FIXME: this only processes the first read ACPI event & might break + * with interrupted reads. */ /* Check that we have a video event */ - if (strstr(ev, "video") == ev) { + if (!strncmp(ev, "video", 5)) { char *video = NULL; char *GFX = NULL; char *notify = NULL; @@ -97,26 +99,19 @@ lnxACPIGetEventFromOs(int fd, pmEvent *events, int num) ErrorF("data: 0x%lx\n",data_l); #endif - /* We currently don't differentiate between any event */ + /* Differentiate between events */ switch (notify_l) { case ACPI_VIDEO_NOTIFY_SWITCH: - break; - case ACPI_VIDEO_NOTIFY_PROBE: - break; case ACPI_VIDEO_NOTIFY_CYCLE: - break; case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: - break; case ACPI_VIDEO_NOTIFY_PREV_OUTPUT: - break; + events[0] = XF86_APM_CAPABILITY_CHANGED; + return 1; + case ACPI_VIDEO_NOTIFY_PROBE: + return 0; default: - break; + return 0; } - - /* Deal with all ACPI events as a capability change */ - events[0] = XF86_APM_CAPABILITY_CHANGED; - - return 1; } return 0; From 89c6108531e603bdc81faf2ea860f318a2e94a39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Fri, 19 Oct 2007 16:21:54 -0400 Subject: [PATCH 20/33] Fix software GL to provide a list of supported fbconfigs like the DRI case. --- GL/glx/glxglcore.c | 201 ++++++++++++++++++++++++-------------------- GL/glx/glxscreens.c | 28 +++--- 2 files changed, 126 insertions(+), 103 deletions(-) diff --git a/GL/glx/glxglcore.c b/GL/glx/glxglcore.c index b50967a16..6aa4e7f5c 100644 --- a/GL/glx/glxglcore.c +++ b/GL/glx/glxglcore.c @@ -70,7 +70,7 @@ struct __GLXMESAdrawable { XMesaBuffer xm_buf; }; -static XMesaVisual find_mesa_visual(__GLXscreen *screen, VisualID vid); +static XMesaVisual find_mesa_visual(__GLXscreen *screen, XID fbconfigID); static void @@ -141,7 +141,7 @@ __glXMesaScreenCreateDrawable(__GLXscreen *screen, glxPriv->base.resize = __glXMesaDrawableResize; glxPriv->base.swapBuffers = __glXMesaDrawableSwapBuffers; - xm_vis = find_mesa_visual(screen, modes->visualID); + xm_vis = find_mesa_visual(screen, modes->fbconfigID); if (xm_vis == NULL) { ErrorF("find_mesa_visual returned NULL for visualID = 0x%04x\n", modes->visualID); @@ -155,6 +155,11 @@ __glXMesaScreenCreateDrawable(__GLXscreen *screen, glxPriv->xm_buf = XMesaCreatePixmapBuffer(xm_vis, (PixmapPtr)pDraw, 0); } + if (glxPriv->xm_buf == NULL) { + xfree(glxPriv); + return NULL; + } + return &glxPriv->base; } @@ -235,7 +240,7 @@ __glXMesaScreenCreateContext(__GLXscreen *screen, context->base.copy = __glXMesaContextCopy; context->base.forceCurrent = __glXMesaContextForceCurrent; - xm_vis = find_mesa_visual(screen, modes->visualID); + xm_vis = find_mesa_visual(screen, modes->fbconfigID); if (!xm_vis) { ErrorF("find_mesa_visual returned NULL for visualID = 0x%04x\n", modes->visualID); @@ -274,107 +279,122 @@ __glXMesaScreenDestroy(__GLXscreen *screen) } static XMesaVisual -find_mesa_visual(__GLXscreen *screen, VisualID vid) +find_mesa_visual(__GLXscreen *screen, XID fbconfigID) { __GLXMESAscreen *mesaScreen = (__GLXMESAscreen *) screen; const __GLcontextModes *modes; unsigned i = 0; - for ( modes = screen->fbconfigs ; modes != NULL ; modes = modes->next ) { - if ( modes->visualID == vid ) { - break; - } - + for (modes = screen->fbconfigs; modes != NULL; modes = modes->next) { + if (modes->fbconfigID == fbconfigID) + return mesaScreen->xm_vis[i]; i++; } - return (modes != NULL) ? mesaScreen->xm_vis[i] : NULL; + return NULL; } -static void init_screen_visuals(__GLXMESAscreen *screen) +const static int numBack = 2; +const static int numDepth = 2; +const static int numStencil = 2; + +static __GLcontextModes * +createFBConfigsForVisual(__GLXscreen *screen, ScreenPtr pScreen, + VisualPtr visual, __GLcontextModes *config) { - ScreenPtr pScreen = screen->base.pScreen; - __GLcontextModes *modes; - XMesaVisual *pXMesaVisual; - int *used; - int num_vis, j, size; + int back, depth, stencil; - /* Alloc space for the list of XMesa visuals */ - size = screen->base.numVisuals * sizeof(XMesaVisual); - pXMesaVisual = (XMesaVisual *) xalloc(size); - memset(pXMesaVisual, 0, size); + /* FIXME: Ok, I'm making all this up... anybody has a better idea? */ - /* FIXME: Change 'used' to be a array of bits (rather than of ints), - * FIXME: create a stack array of 8 or 16 bytes. If 'numVisuals' is less - * FIXME: than 64 or 128 the stack array can be used instead of calling - * FIXME: __glXMalloc / __glXFree. If nothing else, convert 'used' to - * FIXME: array of bytes instead of ints! - */ - used = (int *) xalloc(pScreen->numVisuals * sizeof(int)); - memset(used, 0, pScreen->numVisuals * sizeof(int)); + for (back = numBack - 1; back >= 0; back--) + for (depth = 0; depth < numDepth; depth++) + for (stencil = 0; stencil < numStencil; stencil++) { + config->visualType = _gl_convert_from_x_visual_type(visual->class); + config->xRenderable = GL_TRUE; + config->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT; + config->rgbMode = (visual->class >= TrueColor); + config->colorIndexMode = !config->rgbMode; + config->renderType = + (config->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT; + config->doubleBufferMode = back; + config->haveDepthBuffer = depth; + config->depthBits = depth ? visual->nplanes : 0; + config->haveStencilBuffer = stencil; + config->stencilBits = stencil ? visual->bitsPerRGBValue : 0; + config->haveAccumBuffer = 0; - num_vis = 0; - for ( modes = screen->base.fbconfigs; modes != NULL; modes = modes->next ) { - const int vis_class = _gl_convert_to_x_visual_type( modes->visualType ); - const int nplanes = (modes->rgbBits - modes->alphaBits); - const VisualPtr pVis = pScreen->visuals; + config->redBits = Ones(visual->redMask); + config->greenBits = Ones(visual->greenMask); + config->blueBits = Ones(visual->blueMask); + config->alphaBits = 0; + config->redMask = visual->redMask; + config->greenMask = visual->greenMask; + config->blueMask = visual->blueMask; + config->alphaMask = 0; + config->rgbBits = config->rgbMode ? visual->nplanes : 0; + config->indexBits = config->colorIndexMode ? visual->nplanes : 0; + config = config->next; + } - for (j = 0; j < pScreen->numVisuals; j++) { - if (pVis[j].class == vis_class && - pVis[j].nplanes == nplanes && - pVis[j].redMask == modes->redMask && - pVis[j].greenMask == modes->greenMask && - pVis[j].blueMask == modes->blueMask && - !used[j]) { + return config; +} - /* Create the XMesa visual */ - assert(num_vis < screen->base.numVisuals); - pXMesaVisual[num_vis] = - XMesaCreateVisual(pScreen, - &pVis[j], - modes->rgbMode, - (modes->alphaBits > 0), - modes->doubleBufferMode, - modes->stereoMode, - GL_TRUE, /* ximage_flag */ - modes->depthBits, - modes->stencilBits, - modes->accumRedBits, - modes->accumGreenBits, - modes->accumBlueBits, - modes->accumAlphaBits, - modes->samples, - modes->level, - modes->visualRating); - /* Set the VisualID */ - modes->visualID = pVis[j].vid; +static void +createFBConfigs(__GLXscreen *pGlxScreen, ScreenPtr pScreen) +{ + __GLcontextModes *configs; + int i; - /* Mark this visual used */ - used[j] = 1; + /* We assume here that each existing visual correspond to a + * different visual class. Note, this runs before COMPOSITE adds + * its visual, so it's not entirely crazy. */ + pGlxScreen->numFBConfigs = pScreen->numVisuals * numBack * numDepth * numStencil; + pGlxScreen->fbconfigs = _gl_context_modes_create(pGlxScreen->numFBConfigs, + sizeof *configs); + + configs = pGlxScreen->fbconfigs; + for (i = 0; i < pScreen->numVisuals; i++) + configs = createFBConfigsForVisual(pGlxScreen, pScreen, + &pScreen->visuals[i], configs); +} + +static void +createMesaVisuals(__GLXMESAscreen *pMesaScreen) +{ + __GLcontextModes *config; + ScreenPtr pScreen; + VisualPtr visual; + int i, j; + + i = 0; + pScreen = pMesaScreen->base.pScreen; + pMesaScreen->xm_vis = + xcalloc(pMesaScreen->base.numFBConfigs, sizeof (XMesaVisual)); + for (config = pMesaScreen->base.fbconfigs; config != NULL; config = config->next) { + for (j = 0; j < pScreen->numVisuals; j++) + if (pScreen->visuals[j].vid == config->visualID) { + visual = &pScreen->visuals[j]; break; } - } - if ( j == pScreen->numVisuals ) { - ErrorF("No matching visual for __GLcontextMode with " - "visual class = %d (%d), nplanes = %u\n", - vis_class, - modes->visualType, - (modes->rgbBits - modes->alphaBits) ); - } - else if ( modes->visualID == -1 ) { - FatalError( "Matching visual found, but visualID still -1!\n" ); - } - - num_vis++; + pMesaScreen->xm_vis[i++] = + XMesaCreateVisual(pScreen, + visual, + config->rgbMode, + (config->alphaBits > 0), + config->doubleBufferMode, + config->stereoMode, + GL_TRUE, /* ximage_flag */ + config->depthBits, + config->stencilBits, + config->accumRedBits, + config->accumGreenBits, + config->accumBlueBits, + config->accumAlphaBits, + config->samples, + config->level, + config->visualRating); } - - xfree(used); - - screen->num_vis = num_vis; - screen->xm_vis = pXMesaVisual; - - assert(screen->num_vis <= screen->base.numVisuals); } static __GLXscreen * @@ -386,19 +406,22 @@ __glXMesaScreenProbe(ScreenPtr pScreen) if (screen == NULL) return NULL; + /* + * Find the GLX visuals that are supported by this screen and create + * XMesa's visuals. + */ + createFBConfigs(&screen->base, pScreen); + __glXScreenInit(&screen->base, pScreen); + /* Now that GLX has created the corresponding X visual, create the mesa visuals. */ + createMesaVisuals(screen); + screen->base.destroy = __glXMesaScreenDestroy; screen->base.createContext = __glXMesaScreenCreateContext; screen->base.createDrawable = __glXMesaScreenCreateDrawable; screen->base.pScreen = pScreen; - /* - * Find the GLX visuals that are supported by this screen and create - * XMesa's visuals. - */ - init_screen_visuals(screen); - return &screen->base; } diff --git a/GL/glx/glxscreens.c b/GL/glx/glxscreens.c index 511aa8ad9..2c8f810e6 100644 --- a/GL/glx/glxscreens.c +++ b/GL/glx/glxscreens.c @@ -469,8 +469,6 @@ addFullSet(__GLXscreen *pGlxScreen) return; } - ErrorF("addFullSet, setting numVisuals to %d\n", pGlxScreen->numFBConfigs); - pGlxScreen->numVisuals = pGlxScreen->numFBConfigs; for (i = 0, config = pGlxScreen->fbconfigs; config; config = config->next, i++) { pGlxScreen->visuals[i] = config; @@ -500,10 +498,24 @@ void __glXScreenInit(__GLXscreen *pGlxScreen, ScreenPtr pScreen) glxGeneration = serverGeneration; } + pGlxScreen->pScreen = pScreen; + pGlxScreen->GLextensions = xstrdup(GLServerExtensions); + pGlxScreen->GLXvendor = xstrdup(GLXServerVendorName); + pGlxScreen->GLXversion = xstrdup(GLXServerVersion); + pGlxScreen->GLXextensions = xstrdup(GLXServerExtensions); + + pGlxScreen->PositionWindow = pScreen->PositionWindow; + pScreen->PositionWindow = glxPositionWindow; + + pGlxScreen->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = glxCloseScreen; + i = 0; for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next) { m->fbconfigID = FakeClientID(0); m->visualID = findVisualForConfig(pScreen, m); + ErrorF("mapping fbconfig id 0x%02lx to visual id 0x%02lx\n", + m->fbconfigID, m->visualID); i++; } pGlxScreen->numFBConfigs = i; @@ -526,18 +538,6 @@ void __glXScreenInit(__GLXscreen *pGlxScreen, ScreenPtr pScreen) break; } - pGlxScreen->pScreen = pScreen; - pGlxScreen->GLextensions = xstrdup(GLServerExtensions); - pGlxScreen->GLXvendor = xstrdup(GLXServerVendorName); - pGlxScreen->GLXversion = xstrdup(GLXServerVersion); - pGlxScreen->GLXextensions = xstrdup(GLXServerExtensions); - - pGlxScreen->PositionWindow = pScreen->PositionWindow; - pScreen->PositionWindow = glxPositionWindow; - - pGlxScreen->CloseScreen = pScreen->CloseScreen; - pScreen->CloseScreen = glxCloseScreen; - pScreen->devPrivates[glxScreenPrivateIndex].ptr = (pointer) pGlxScreen; } From 7e1cada6c6b9fa41ef3ead00bf7725d626dda193 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 19 Oct 2007 15:16:19 -0700 Subject: [PATCH 21/33] Disable debian pci-id-list autoconfig code on non-linux. It contains static paths, fails to build on non-glibc, and apparently just exists to support distributions managing binary drivers and open-source drivers together. Also restores previous code for fallback to vesa if nothing is detected. --- hw/xfree86/common/xf86AutoConfig.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/hw/xfree86/common/xf86AutoConfig.c b/hw/xfree86/common/xf86AutoConfig.c index a6bfc0190..8117ace24 100644 --- a/hw/xfree86/common/xf86AutoConfig.c +++ b/hw/xfree86/common/xf86AutoConfig.c @@ -329,6 +329,7 @@ autoConfigDevice(GDevPtr preconf_device) return ptr; } +#ifdef __linux__ static void matchDriverFromFiles (char** matches, uint16_t match_vendor, uint16_t match_chip) { @@ -421,6 +422,7 @@ matchDriverFromFiles (char** matches, uint16_t match_vendor, uint16_t match_chip xfree(line); closedir(idsdir); } +#endif /* __linux__ */ char* chooseVideoDriver(void) @@ -448,24 +450,27 @@ chooseVideoDriver(void) ErrorF("Primary device is not PCI\n"); } +#ifdef __linux__ matchDriverFromFiles(matches, info->vendor_id, info->device_id); +#endif /* __linux__ */ /* TODO Handle multiple drivers claiming to support the same PCI ID */ if (matches[0]) { chosen_driver = matches[0]; } else { - chosen_driver = videoPtrToDriverName(info); - #if 0 /* Save for later */ - #if defined __i386__ || defined __amd64__ || defined __hurd__ - chosen_driver = "vesa"; - #elif defined __alpha__ - chosen_driver = "vga"; - #elif defined __sparc__ - chosen_driver = "sunffb"; - #else - chosen_driver = "fbdev"; - #endif - #endif + if (info != NULL) + chosen_driver = videoPtrToDriverName(info); + if (chosen_driver == NULL) { +#if defined __i386__ || defined __amd64__ || defined __hurd__ + chosen_driver = "vesa"; +#elif defined __alpha__ + chosen_driver = "vga"; +#elif defined __sparc__ + chosen_driver = "sunffb"; +#else + chosen_driver = "fbdev"; +#endif + } } xf86Msg(X_DEFAULT, "Matched %s for the autoconfigured driver\n", chosen_driver); From 4b14c9a9cd2033d3839c4ba364d41ab4c4b198ab Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 19 Oct 2007 16:34:54 -0700 Subject: [PATCH 22/33] Replace calls to Glyphs screen hook with CompositeGlyphs and remove dead code. Not all of the DDX/miext Glyphs hook implementations have been removed, but they should be. --- exa/exa.c | 8 +- exa/exa_render.c | 258 -------------------------------------- hw/xfree86/loader/misym.c | 3 - miext/cw/cw.h | 1 - miext/cw/cw_render.c | 30 ----- render/Makefile.am | 1 - render/glyph.c | 213 +++++++++++++++++++++++++++++++ render/miglyph.c | 228 --------------------------------- render/mipict.c | 2 +- render/mipict.h | 6 - render/picture.c | 18 --- render/picturestr.h | 2 +- 12 files changed, 218 insertions(+), 552 deletions(-) delete mode 100644 render/miglyph.c diff --git a/exa/exa.c b/exa/exa.c index 7ad226fba..6d6c0549f 100644 --- a/exa/exa.c +++ b/exa/exa.c @@ -291,7 +291,9 @@ exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth) pExaPixmap->fb_ptr = NULL; } else { pExaPixmap->driverPriv = NULL; - /* Glyphs have w/h equal to zero, and may not be migrated. See exaGlyphs. */ + /* Scratch pixmaps may have w/h equal to zero, and may not be + * migrated. + */ if (!w || !h) pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED; else @@ -696,7 +698,6 @@ exaCloseScreen(int i, ScreenPtr pScreen) #ifdef RENDER if (ps) { ps->Composite = pExaScr->SavedComposite; - ps->Glyphs = pExaScr->SavedGlyphs; ps->Trapezoids = pExaScr->SavedTrapezoids; } #endif @@ -865,9 +866,6 @@ exaDriverInit (ScreenPtr pScreen, pExaScr->SavedTriangles = ps->Triangles; ps->Triangles = exaTriangles; - pExaScr->SavedGlyphs = ps->Glyphs; - ps->Glyphs = exaGlyphs; - pExaScr->SavedTrapezoids = ps->Trapezoids; ps->Trapezoids = exaTrapezoids; } diff --git a/exa/exa_render.c b/exa/exa_render.c index 847a36182..6a9e53f3e 100644 --- a/exa/exa_render.c +++ b/exa/exa_render.c @@ -997,261 +997,3 @@ exaTriangles (CARD8 op, PicturePtr pSrc, PicturePtr pDst, exaTriangles (op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, tris); } } - -/** - * Returns TRUE if the glyphs in the lists intersect. Only checks based on - * bounding box, which appears to be good enough to catch most cases at least. - */ -static Bool -exaGlyphsIntersect(int nlist, GlyphListPtr list, GlyphPtr *glyphs) -{ - int x1, x2, y1, y2; - int n; - GlyphPtr glyph; - int x, y; - BoxRec extents; - Bool first = TRUE; - - x = 0; - y = 0; - while (nlist--) { - x += list->xOff; - y += list->yOff; - n = list->len; - list++; - while (n--) { - glyph = *glyphs++; - - if (glyph->info.width == 0 || glyph->info.height == 0) { - x += glyph->info.xOff; - y += glyph->info.yOff; - continue; - } - - x1 = x - glyph->info.x; - if (x1 < MINSHORT) - x1 = MINSHORT; - y1 = y - glyph->info.y; - if (y1 < MINSHORT) - y1 = MINSHORT; - x2 = x1 + glyph->info.width; - if (x2 > MAXSHORT) - x2 = MAXSHORT; - y2 = y1 + glyph->info.height; - if (y2 > MAXSHORT) - y2 = MAXSHORT; - - if (first) { - extents.x1 = x1; - extents.y1 = y1; - extents.x2 = x2; - extents.y2 = y2; - first = FALSE; - } else { - if (x1 < extents.x2 && x2 > extents.x1 && - y1 < extents.y2 && y2 > extents.y1) - { - return TRUE; - } - - if (x1 < extents.x1) - extents.x1 = x1; - if (x2 > extents.x2) - extents.x2 = x2; - if (y1 < extents.y1) - extents.y1 = y1; - if (y2 > extents.y2) - extents.y2 = y2; - } - x += glyph->info.xOff; - y += glyph->info.yOff; - } - } - - return FALSE; -} - -#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0) - -/* exaGlyphs is a slight variation on miGlyphs, to support acceleration. The - * issue is that miGlyphs' use of ModifyPixmapHeader makes it impossible to - * migrate these pixmaps. So, instead we create a pixmap at the beginning of - * the loop and upload each glyph into the pixmap before compositing. - * - * This is now used even when Composite can't be accelerated for better - * migration control. - */ -void -exaGlyphs (CARD8 op, - PicturePtr pSrc, - PicturePtr pDst, - PictFormatPtr maskFormat, - INT16 xSrc, - INT16 ySrc, - int nlist, - GlyphListPtr list, - GlyphPtr *glyphs) -{ - ExaScreenPriv (pDst->pDrawable->pScreen); - PicturePtr pPicture; - PixmapPtr pMaskPixmap = NULL; - PicturePtr pMask; - ScreenPtr pScreen = pDst->pDrawable->pScreen; - int width = 0, height = 0; - int x, y, x1, y1; - int xDst = list->xOff, yDst = list->yOff; - int n; - int error; - BoxRec extents; - CARD32 component_alpha; - - /* If we have a mask format but it's the same as all the glyphs and - * the glyphs don't intersect, we can avoid accumulating the glyphs in the - * temporary picture. - */ - if (maskFormat != NULL) { - Bool sameFormat = TRUE; - int i; - - for (i = 0; i < nlist; i++) { - if (maskFormat->format != list[i].format->format) { - sameFormat = FALSE; - break; - } - } - if (sameFormat) { - if (!exaGlyphsIntersect(nlist, list, glyphs)) { - maskFormat = NULL; - } - } - } - - if (maskFormat) - { - GCPtr pGC; - xRectangle rect; - - miGlyphExtents (nlist, list, glyphs, &extents); - - extents.x1 = max(extents.x1, 0); - extents.y1 = max(extents.y1, 0); - extents.x2 = min(extents.x2, pDst->pDrawable->width); - extents.y2 = min(extents.y2, pDst->pDrawable->height); - - if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1) - return; - width = extents.x2 - extents.x1; - height = extents.y2 - extents.y1; - pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, - maskFormat->depth); - if (!pMaskPixmap) - return; - component_alpha = NeedsComponent(maskFormat->format); - pMask = CreatePicture (0, &pMaskPixmap->drawable, - maskFormat, CPComponentAlpha, &component_alpha, - serverClient, &error); - if (!pMask) - { - (*pScreen->DestroyPixmap) (pMaskPixmap); - return; - } - ValidatePicture(pMask); - pGC = GetScratchGC (pMaskPixmap->drawable.depth, pScreen); - ValidateGC (&pMaskPixmap->drawable, pGC); - rect.x = 0; - rect.y = 0; - rect.width = width; - rect.height = height; - ExaCheckPolyFillRect (&pMaskPixmap->drawable, pGC, 1, &rect); - if (pExaScr->info->PrepareComposite) - (*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect); - else - exaPixmapDirty(pMaskPixmap, 0, 0, width, height); - FreeScratchGC (pGC); - x = -extents.x1; - y = -extents.y1; - } - else - { - pMask = pDst; - x = 0; - y = 0; - } - - while (nlist--) - { - GCPtr pGC = NULL; - int maxwidth = 0, maxheight = 0, i; - - x += list->xOff; - y += list->yOff; - n = list->len; - for (i = 0; i < n; i++) { - if (glyphs[i]->info.width > maxwidth) - maxwidth = glyphs[i]->info.width; - if (glyphs[i]->info.height > maxheight) - maxheight = glyphs[i]->info.height; - } - if (maxwidth == 0 || maxheight == 0) { - while (n--) - { - GlyphPtr glyph; - - glyph = *glyphs++; - x += glyph->info.xOff; - y += glyph->info.yOff; - } - list++; - continue; - } - - while (n--) - { - GlyphPtr glyph = *glyphs++; - DrawablePtr pCmpDrw = (maskFormat ? pMask : pDst)->pDrawable; - - x1 = x - glyph->info.x; - y1 = y - glyph->info.y; - - if (x1 >= pCmpDrw->width || y1 >= pCmpDrw->height || - glyph->info.width == 0 || glyph->info.height == 0 || - (x1 + glyph->info.width) <= 0 || (y1 + glyph->info.height) <= 0) - goto nextglyph; - - /* The glyph already has a Picture ready for us to use. */ - pPicture = GlyphPicture (glyph)[pScreen->myNum]; - ValidatePicture(pPicture); - - if (maskFormat) - { - exaComposite (PictOpAdd, pPicture, NULL, pMask, 0, 0, 0, 0, - x1, y1, glyph->info.width, glyph->info.height); - exaPixmapDirty(pMaskPixmap, x1, y1, x1 + glyph->info.width, - y1 + glyph->info.height); - } - else - { - exaComposite (op, pSrc, pPicture, pDst, - xSrc + x1 - xDst, ySrc + y1 - yDst, - 0, 0, x1, y1, glyph->info.width, - glyph->info.height); - } - -nextglyph: - x += glyph->info.xOff; - y += glyph->info.yOff; - } - list++; - if (pGC != NULL) - FreeScratchGC (pGC); - } - if (maskFormat) - { - x = extents.x1; - y = extents.y1; - exaComposite (op, pSrc, pMask, pDst, xSrc + x - xDst, ySrc + y - yDst, - 0, 0, x, y, width, height); - FreePicture ((pointer) pMask, (XID) 0); - (*pScreen->DestroyPixmap) (pMaskPixmap); - } -} diff --git a/hw/xfree86/loader/misym.c b/hw/xfree86/loader/misym.c index 78ae10e02..025983b09 100644 --- a/hw/xfree86/loader/misym.c +++ b/hw/xfree86/loader/misym.c @@ -205,9 +205,6 @@ _X_HIDDEN void *miLookupTab[] = { SYMVAR(miPointerScreenIndex) SYMVAR(miInstalledMaps) SYMVAR(miInitVisualsProc) -#ifdef RENDER - SYMFUNC(miGlyphExtents) -#endif #ifdef DAMAGE SYMFUNC(DamageDamageRegion) #endif diff --git a/miext/cw/cw.h b/miext/cw/cw.h index 8e42ac256..a83949dc9 100644 --- a/miext/cw/cw.h +++ b/miext/cw/cw.h @@ -98,7 +98,6 @@ typedef struct { ValidatePictureProcPtr ValidatePicture; CompositeProcPtr Composite; - GlyphsProcPtr Glyphs; CompositeRectsProcPtr CompositeRects; TrapezoidsProcPtr Trapezoids; diff --git a/miext/cw/cw_render.c b/miext/cw/cw_render.c index 35416beb7..6e0c727c2 100644 --- a/miext/cw/cw_render.c +++ b/miext/cw/cw_render.c @@ -279,34 +279,6 @@ cwComposite (CARD8 op, cwPsWrap(Composite, cwComposite); } -static void -cwGlyphs (CARD8 op, - PicturePtr pSrcPicture, - PicturePtr pDstPicture, - PictFormatPtr maskFormat, - INT16 xSrc, - INT16 ySrc, - int nlists, - GlyphListPtr lists, - GlyphPtr *glyphs) -{ - ScreenPtr pScreen = pDstPicture->pDrawable->pScreen; - cwPsDecl(pScreen); - cwSrcPictureDecl; - cwDstPictureDecl; - - cwPsUnwrap(Glyphs); - if (nlists) - { - lists->xOff += dst_picture_x_off; - lists->yOff += dst_picture_y_off; - } - (*ps->Glyphs) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat, - xSrc + src_picture_x_off, ySrc + src_picture_y_off, - nlists, lists, glyphs); - cwPsWrap(Glyphs, cwGlyphs); -} - static void cwCompositeRects (CARD8 op, PicturePtr pDstPicture, @@ -470,7 +442,6 @@ cwInitializeRender (ScreenPtr pScreen) cwPsWrap(ChangePicture, cwChangePicture); cwPsWrap(ValidatePicture, cwValidatePicture); cwPsWrap(Composite, cwComposite); - cwPsWrap(Glyphs, cwGlyphs); cwPsWrap(CompositeRects, cwCompositeRects); cwPsWrap(Trapezoids, cwTrapezoids); cwPsWrap(Triangles, cwTriangles); @@ -491,7 +462,6 @@ cwFiniRender (ScreenPtr pScreen) cwPsUnwrap(ChangePicture); cwPsUnwrap(ValidatePicture); cwPsUnwrap(Composite); - cwPsUnwrap(Glyphs); cwPsUnwrap(CompositeRects); cwPsUnwrap(Trapezoids); cwPsUnwrap(Triangles); diff --git a/render/Makefile.am b/render/Makefile.am index 830778a92..e53c7c746 100644 --- a/render/Makefile.am +++ b/render/Makefile.am @@ -6,7 +6,6 @@ librender_la_SOURCES = \ animcur.c \ filter.c \ glyph.c \ - miglyph.c \ miindex.c \ mipict.c \ mirect.c \ diff --git a/render/glyph.c b/render/glyph.c index 975c62b77..5cd799226 100644 --- a/render/glyph.c +++ b/render/glyph.c @@ -43,6 +43,7 @@ #include "servermd.h" #include "picturestr.h" #include "glyphstr.h" +#include "mipict.h" /* * From Knuth -- a good choice for hash/rehash values is p, p-2 where @@ -845,3 +846,215 @@ FreeGlyphSet (pointer value, } return Success; } + +static void +GlyphExtents (int nlist, + GlyphListPtr list, + GlyphPtr *glyphs, + BoxPtr extents) +{ + int x1, x2, y1, y2; + int n; + GlyphPtr glyph; + int x, y; + + x = 0; + y = 0; + extents->x1 = MAXSHORT; + extents->x2 = MINSHORT; + extents->y1 = MAXSHORT; + extents->y2 = MINSHORT; + while (nlist--) + { + x += list->xOff; + y += list->yOff; + n = list->len; + list++; + while (n--) + { + glyph = *glyphs++; + x1 = x - glyph->info.x; + if (x1 < MINSHORT) + x1 = MINSHORT; + y1 = y - glyph->info.y; + if (y1 < MINSHORT) + y1 = MINSHORT; + x2 = x1 + glyph->info.width; + if (x2 > MAXSHORT) + x2 = MAXSHORT; + y2 = y1 + glyph->info.height; + if (y2 > MAXSHORT) + y2 = MAXSHORT; + if (x1 < extents->x1) + extents->x1 = x1; + if (x2 > extents->x2) + extents->x2 = x2; + if (y1 < extents->y1) + extents->y1 = y1; + if (y2 > extents->y2) + extents->y2 = y2; + x += glyph->info.xOff; + y += glyph->info.yOff; + } + } +} + +#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0) + +/* Stub ABI compatibility for mi*Glyph, should go away */ +_X_EXPORT void +miGlyphs (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int nlist, + GlyphListPtr list, + GlyphPtr *glyphs) +{ + CompositeGlyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, + glyphs); +} + +Bool +miRealizeGlyph (ScreenPtr pScreen, + GlyphPtr glyph) +{ + return TRUE; +} + +void +miUnrealizeGlyph (ScreenPtr pScreen, + GlyphPtr glyph) +{ +} + +_X_EXPORT void +CompositeGlyphs (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int nlist, + GlyphListPtr list, + GlyphPtr *glyphs) +{ + PicturePtr pPicture; + PixmapPtr pMaskPixmap = 0; + PicturePtr pMask; + ScreenPtr pScreen = pDst->pDrawable->pScreen; + int width = 0, height = 0; + int x, y; + int xDst = list->xOff, yDst = list->yOff; + int n; + GlyphPtr glyph; + int error; + BoxRec extents = {0, 0, 0, 0}; + CARD32 component_alpha; + + ValidatePicture (pSrc); + ValidatePicture (pDst); + + if (maskFormat) + { + GCPtr pGC; + xRectangle rect; + + GlyphExtents (nlist, list, glyphs, &extents); + + if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1) + return; + width = extents.x2 - extents.x1; + height = extents.y2 - extents.y1; + pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, + maskFormat->depth); + if (!pMaskPixmap) + return; + component_alpha = NeedsComponent(maskFormat->format); + pMask = CreatePicture (0, &pMaskPixmap->drawable, + maskFormat, CPComponentAlpha, &component_alpha, + serverClient, &error); + if (!pMask) + { + (*pScreen->DestroyPixmap) (pMaskPixmap); + return; + } + pGC = GetScratchGC (pMaskPixmap->drawable.depth, pScreen); + ValidateGC (&pMaskPixmap->drawable, pGC); + rect.x = 0; + rect.y = 0; + rect.width = width; + rect.height = height; + (*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect); + FreeScratchGC (pGC); + x = -extents.x1; + y = -extents.y1; + } + else + { + pMask = pDst; + x = 0; + y = 0; + } + while (nlist--) + { + x += list->xOff; + y += list->yOff; + n = list->len; + while (n--) + { + glyph = *glyphs++; + pPicture = GlyphPicture (glyph)[pScreen->myNum]; + + if (maskFormat) + { + CompositePicture (PictOpAdd, + pPicture, + None, + pMask, + 0, 0, + 0, 0, + x - glyph->info.x, + y - glyph->info.y, + glyph->info.width, + glyph->info.height); + } + else + { + CompositePicture (op, + pSrc, + pPicture, + pDst, + xSrc + (x - glyph->info.x) - xDst, + ySrc + (y - glyph->info.y) - yDst, + 0, 0, + x - glyph->info.x, + y - glyph->info.y, + glyph->info.width, + glyph->info.height); + } + + x += glyph->info.xOff; + y += glyph->info.yOff; + } + list++; + } + if (maskFormat) + { + x = extents.x1; + y = extents.y1; + CompositePicture (op, + pSrc, + pMask, + pDst, + xSrc + x - xDst, + ySrc + y - yDst, + 0, 0, + x, y, + width, height); + FreePicture ((pointer) pMask, (XID) 0); + (*pScreen->DestroyPixmap) (pMaskPixmap); + } +} diff --git a/render/miglyph.c b/render/miglyph.c deleted file mode 100644 index a52ea49d6..000000000 --- a/render/miglyph.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - * - * Copyright © 2000 SuSE, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of SuSE not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. SuSE makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE - * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Author: Keith Packard, SuSE, Inc. - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include "scrnintstr.h" -#include "gcstruct.h" -#include "pixmapstr.h" -#include "windowstr.h" -#include "mi.h" -#include "picturestr.h" -#include "mipict.h" - -Bool -miRealizeGlyph (ScreenPtr pScreen, - GlyphPtr glyph) -{ - return TRUE; -} - -void -miUnrealizeGlyph (ScreenPtr pScreen, - GlyphPtr glyph) -{ -} - -_X_EXPORT void -miGlyphExtents (int nlist, - GlyphListPtr list, - GlyphPtr *glyphs, - BoxPtr extents) -{ - int x1, x2, y1, y2; - int n; - GlyphPtr glyph; - int x, y; - - x = 0; - y = 0; - extents->x1 = MAXSHORT; - extents->x2 = MINSHORT; - extents->y1 = MAXSHORT; - extents->y2 = MINSHORT; - while (nlist--) - { - x += list->xOff; - y += list->yOff; - n = list->len; - list++; - while (n--) - { - glyph = *glyphs++; - x1 = x - glyph->info.x; - if (x1 < MINSHORT) - x1 = MINSHORT; - y1 = y - glyph->info.y; - if (y1 < MINSHORT) - y1 = MINSHORT; - x2 = x1 + glyph->info.width; - if (x2 > MAXSHORT) - x2 = MAXSHORT; - y2 = y1 + glyph->info.height; - if (y2 > MAXSHORT) - y2 = MAXSHORT; - if (x1 < extents->x1) - extents->x1 = x1; - if (x2 > extents->x2) - extents->x2 = x2; - if (y1 < extents->y1) - extents->y1 = y1; - if (y2 > extents->y2) - extents->y2 = y2; - x += glyph->info.xOff; - y += glyph->info.yOff; - } - } -} - -#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0) - -_X_EXPORT void -miGlyphs (CARD8 op, - PicturePtr pSrc, - PicturePtr pDst, - PictFormatPtr maskFormat, - INT16 xSrc, - INT16 ySrc, - int nlist, - GlyphListPtr list, - GlyphPtr *glyphs) -{ - PixmapPtr pPixmap; - PicturePtr pPicture; - PixmapPtr pMaskPixmap = 0; - PicturePtr pMask; - ScreenPtr pScreen = pDst->pDrawable->pScreen; - int width = 0, height = 0; - int x, y; - int xDst = list->xOff, yDst = list->yOff; - int n; - GlyphPtr glyph; - int error; - BoxRec extents; - CARD32 component_alpha; - - if (maskFormat) - { - GCPtr pGC; - xRectangle rect; - - miGlyphExtents (nlist, list, glyphs, &extents); - - if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1) - return; - width = extents.x2 - extents.x1; - height = extents.y2 - extents.y1; - pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, maskFormat->depth); - if (!pMaskPixmap) - return; - component_alpha = NeedsComponent(maskFormat->format); - pMask = CreatePicture (0, &pMaskPixmap->drawable, - maskFormat, CPComponentAlpha, &component_alpha, - serverClient, &error); - if (!pMask) - { - (*pScreen->DestroyPixmap) (pMaskPixmap); - return; - } - pGC = GetScratchGC (pMaskPixmap->drawable.depth, pScreen); - ValidateGC (&pMaskPixmap->drawable, pGC); - rect.x = 0; - rect.y = 0; - rect.width = width; - rect.height = height; - (*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect); - FreeScratchGC (pGC); - x = -extents.x1; - y = -extents.y1; - } - else - { - pMask = pDst; - x = 0; - y = 0; - } - while (nlist--) - { - x += list->xOff; - y += list->yOff; - n = list->len; - while (n--) - { - glyph = *glyphs++; - pPicture = GlyphPicture (glyph)[pScreen->myNum]; - - if (maskFormat) - { - CompositePicture (PictOpAdd, - pPicture, - None, - pMask, - 0, 0, - 0, 0, - x - glyph->info.x, - y - glyph->info.y, - glyph->info.width, - glyph->info.height); - } - else - { - CompositePicture (op, - pSrc, - pPicture, - pDst, - xSrc + (x - glyph->info.x) - xDst, - ySrc + (y - glyph->info.y) - yDst, - 0, 0, - x - glyph->info.x, - y - glyph->info.y, - glyph->info.width, - glyph->info.height); - } - - x += glyph->info.xOff; - y += glyph->info.yOff; - } - list++; - } - if (maskFormat) - { - x = extents.x1; - y = extents.y1; - CompositePicture (op, - pSrc, - pMask, - pDst, - xSrc + x - xDst, - ySrc + y - yDst, - 0, 0, - x, y, - width, height); - FreePicture ((pointer) pMask, (XID) 0); - (*pScreen->DestroyPixmap) (pMaskPixmap); - } -} diff --git a/render/mipict.c b/render/mipict.c index 87dccbbda..5aad676f5 100644 --- a/render/mipict.c +++ b/render/mipict.c @@ -636,7 +636,7 @@ miPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats) /* MI rendering routines */ ps->Composite = 0; /* requires DDX support */ - ps->Glyphs = miGlyphs; + ps->Glyphs = NULL; ps->CompositeRects = miCompositeRects; ps->Trapezoids = miTrapezoids; ps->Triangles = miTriangles; diff --git a/render/mipict.h b/render/mipict.h index bd7c23f4b..60baf7f66 100644 --- a/render/mipict.h +++ b/render/mipict.h @@ -119,12 +119,6 @@ void miUnrealizeGlyph (ScreenPtr pScreen, GlyphPtr glyph); -void -miGlyphExtents (int nlist, - GlyphListPtr list, - GlyphPtr *glyphs, - BoxPtr extents); - void miGlyphs (CARD8 op, PicturePtr pSrc, diff --git a/render/picture.c b/render/picture.c index ede865f28..a7e40f994 100644 --- a/render/picture.c +++ b/render/picture.c @@ -1767,24 +1767,6 @@ CompositePicture (CARD8 op, height); } -void -CompositeGlyphs (CARD8 op, - PicturePtr pSrc, - PicturePtr pDst, - PictFormatPtr maskFormat, - INT16 xSrc, - INT16 ySrc, - int nlist, - GlyphListPtr lists, - GlyphPtr *glyphs) -{ - PictureScreenPtr ps = GetPictureScreen(pDst->pDrawable->pScreen); - - ValidatePicture (pSrc); - ValidatePicture (pDst); - (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, lists, glyphs); -} - void CompositeRects (CARD8 op, PicturePtr pDst, diff --git a/render/picturestr.h b/render/picturestr.h index 09a713199..b2e180f11 100644 --- a/render/picturestr.h +++ b/render/picturestr.h @@ -345,7 +345,7 @@ typedef struct _PictureScreen { ValidatePictureProcPtr ValidatePicture; CompositeProcPtr Composite; - GlyphsProcPtr Glyphs; + GlyphsProcPtr Glyphs; /* unused */ CompositeRectsProcPtr CompositeRects; DestroyWindowProcPtr DestroyWindow; From 7f5e71fa7347fb4ec2657ccc453831c04a0f288d Mon Sep 17 00:00:00 2001 From: David Nusinow Date: Sun, 21 Oct 2007 23:41:49 -0400 Subject: [PATCH 23/33] Make PCI text file directory configurable --- configure.ac | 5 +++++ hw/xfree86/common/Makefile.am | 2 ++ hw/xfree86/common/xf86AutoConfig.c | 11 ++++++----- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index e7d229c4f..c8b2b7838 100644 --- a/configure.ac +++ b/configure.ac @@ -464,6 +464,10 @@ APPLE_APPLICATIONS_DIR="${bindir}/Applications" AC_ARG_WITH(apple-applications-dir,AS_HELP_STRING([--with-apple-applications-dir=PATH], [Path to the Applications directory (default: ${bindir}/Applications)]), [ APPLE_APPLICATIONS_DIR="${withval}" ]. [ APPLE_APPLICATIONS_DIR="${bindir}/Applications" ]) +AC_ARG_WITH(pci-txt-ids-dir, AS_HELP_STRING([--with-pci-txt-ids-dir=PATH], +[Path to pci id directory (default: ${datadir}/X11/pci)]), + [ PCI_TXT_IDS_DIR="$withval" ], + [ PCI_TXT_IDS_DIR="${datadir}/X11/pci" ]) AC_ARG_ENABLE(builddocs, AS_HELP_STRING([--enable-builddocs], [Build docs (default: disabled)]), [BUILDDOCS=$enableval], [BUILDDOCS=no]) @@ -1003,6 +1007,7 @@ fi AC_DEFINE_DIR(COMPILEDDEFAULTFONTPATH, FONTPATH, [Default font path]) AC_DEFINE_DIR(RGB_DB, RGBPATH, [Default RGB path]) +AC_DEFINE_DIR(PCI_TXT_IDS_PATH, PCI_TXT_IDS_DIR, [Default PCI text file ID path]) AC_DEFINE_DIR(SERVERCONFIGdir, SERVERCONFIG, [Server config path]) AC_DEFINE_DIR(BASE_FONT_PATH, FONTDIR, [Default base font path]) AC_DEFINE_DIR(DRI_DRIVER_PATH, DRI_DRIVER_PATH, [Default DRI driver path]) diff --git a/hw/xfree86/common/Makefile.am b/hw/xfree86/common/Makefile.am index db726fea1..05c088c96 100644 --- a/hw/xfree86/common/Makefile.am +++ b/hw/xfree86/common/Makefile.am @@ -94,4 +94,6 @@ if LNXACPI XORG_CFLAGS += -DHAVE_ACPI endif +XORG_CFLAGS += -DPCITXTIDSPATH=\"$(PCI_TXT_IDS_PATH)\" + AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) diff --git a/hw/xfree86/common/xf86AutoConfig.c b/hw/xfree86/common/xf86AutoConfig.c index 8117ace24..524e14eb5 100644 --- a/hw/xfree86/common/xf86AutoConfig.c +++ b/hw/xfree86/common/xf86AutoConfig.c @@ -342,9 +342,10 @@ matchDriverFromFiles (char** matches, uint16_t match_vendor, uint16_t match_chip char path_name[256], vendor_str[5], chip_str[5]; uint16_t vendor, chip; int i, j; - idsdir = opendir("/usr/share/xserver-xorg/pci"); + idsdir = opendir(PCITXTIDSPATH); if (idsdir) { + xf86Msg(X_INFO, "Scanning %s directory for additional PCI ID's supported by the drivers\n", PCITXTIDSPATH); direntry = readdir(idsdir); /* Read the directory */ while (direntry) { @@ -356,8 +357,9 @@ matchDriverFromFiles (char** matches, uint16_t match_vendor, uint16_t match_chip /* A tiny bit of sanity checking. We should probably do better */ if (strncmp(&(direntry->d_name[len-4]), ".ids", 4) == 0) { /* We need the full path name to open the file */ - strncpy(path_name, "/usr/share/xserver-xorg/pci/", 256); - strncat(path_name, direntry->d_name, (256 - strlen(path_name))); + strncpy(path_name, PCITXTIDSPATH, 256); + strncat(path_name, "/", 1); + strncat(path_name, direntry->d_name, (256 - strlen(path_name) - 1)); fp = fopen(path_name, "r"); if (fp == NULL) { xf86Msg(X_ERROR, "Could not open %s for reading. Exiting.\n", path_name); @@ -406,8 +408,7 @@ matchDriverFromFiles (char** matches, uint16_t match_vendor, uint16_t match_chip matches[i][j] = direntry->d_name[j]; } } - xf86Msg(X_INFO, "Matched %s from file name %s in autoconfig\n", matches[i], direntry->d_name); - + xf86Msg(X_INFO, "Matched %s from file name %s\n", matches[i], direntry->d_name); } } else { /* TODO Handle driver overrides here */ From b79b965bd9a96f79781e85c0428068caa1ba381b Mon Sep 17 00:00:00 2001 From: David Nusinow Date: Sun, 21 Oct 2007 23:46:54 -0400 Subject: [PATCH 24/33] Fix compilation issue on FreeBSD (bug #12841) Hide getline call by checking for glibc. If not, use fgetln instead. Even though this section is now #ifdef'ed for linux only, this should help make it more portable if non-linux folks end up wanting it. --- hw/xfree86/common/xf86AutoConfig.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hw/xfree86/common/xf86AutoConfig.c b/hw/xfree86/common/xf86AutoConfig.c index 524e14eb5..efaf45fb8 100644 --- a/hw/xfree86/common/xf86AutoConfig.c +++ b/hw/xfree86/common/xf86AutoConfig.c @@ -366,7 +366,11 @@ matchDriverFromFiles (char** matches, uint16_t match_vendor, uint16_t match_chip goto end; } /* Read the file */ + #ifdef __GLIBC__ while ((read = getline(&line, &len, fp)) != -1) { + #else + while ((line = fgetln(fp, &len)) != (char *)NULL) { + #endif /* __GLIBC __ */ xchomp(line); if (isdigit(line[0])) { strncpy(vendor_str, line, 4); From be9b0e558d6172ef01ed880d47da897d2ceb25fa Mon Sep 17 00:00:00 2001 From: David Nusinow Date: Sun, 21 Oct 2007 23:49:14 -0400 Subject: [PATCH 25/33] Add a note as to why the text file based PCI ID scheme is present at all --- hw/xfree86/common/xf86AutoConfig.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hw/xfree86/common/xf86AutoConfig.c b/hw/xfree86/common/xf86AutoConfig.c index efaf45fb8..29f1279fa 100644 --- a/hw/xfree86/common/xf86AutoConfig.c +++ b/hw/xfree86/common/xf86AutoConfig.c @@ -330,6 +330,10 @@ autoConfigDevice(GDevPtr preconf_device) } #ifdef __linux__ +/* This function is used to provide a workaround for binary drivers that + * don't export their PCI ID's properly. If distros don't end up using this + * feature it can and should be removed because the symbol-based resolution + * scheme should be the primary one */ static void matchDriverFromFiles (char** matches, uint16_t match_vendor, uint16_t match_chip) { From c6d36b1cee44a9cbb690dff62a4683d7f6fbf30c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 22 Oct 2007 18:28:03 +0200 Subject: [PATCH 26/33] GLX: Don't crash on unused client array members when switching to/from console. --- GL/glx/glxext.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GL/glx/glxext.c b/GL/glx/glxext.c index 4d6bfd7c6..546d87f01 100644 --- a/GL/glx/glxext.c +++ b/GL/glx/glxext.c @@ -393,7 +393,7 @@ void glxSuspendClients(void) int i; for (i = 1; i < currentMaxClients; i++) { - if (glxGetClient(clients[i])->inUse) + if (clients[i] && glxGetClient(clients[i])->inUse) IgnoreClient(clients[i]); } @@ -408,7 +408,7 @@ void glxResumeClients(void) glxBlockClients = FALSE; for (i = 1; i < currentMaxClients; i++) { - if (glxGetClient(clients[i])->inUse) + if (clients[i] && glxGetClient(clients[i])->inUse) AttendClient(clients[i]); } From fbe19c66c36acfb484809111cf02579a3baf2f0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 22 Oct 2007 18:28:03 +0200 Subject: [PATCH 27/33] GLX: Fix leak of X pixmaps associated with GLX pixmaps. --- GL/glx/glxcmds.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/GL/glx/glxcmds.c b/GL/glx/glxcmds.c index ac2393c3b..992ddbce5 100644 --- a/GL/glx/glxcmds.c +++ b/GL/glx/glxcmds.c @@ -1215,6 +1215,11 @@ static int DoDestroyDrawable(__GLXclientState *cl, XID glxdrawable, int type) return __glXError(GLXBadPbuffer); } } + + if (type == GLX_DRAWABLE_PIXMAP) { + ((PixmapPtr) pGlxDraw->pDraw)->refcnt--; + } + FreeResource(glxdrawable, FALSE); return Success; From 29e0e180729a4f0cc020985a4de4c8bc4b9c7f5f Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 22 Oct 2007 13:38:16 -0700 Subject: [PATCH 28/33] Leave hardware-specified preferred modes alone when user preference exists. Instead of removing the preference bit marking the hardware declared mode preference, leave it in place and just move the user preferred mode to the front of the list while marking it with the USERPREF bit which will cause it to be selected by the initial mode selection code. --- hw/xfree86/modes/xf86Crtc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c index 0a48d5bd3..bb416fddc 100644 --- a/hw/xfree86/modes/xf86Crtc.c +++ b/hw/xfree86/modes/xf86Crtc.c @@ -1417,9 +1417,8 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY) output->probed_modes = mode; } mode->type |= (M_T_PREFERRED|M_T_USERPREF); + break; } - else - mode->type &= ~M_T_PREFERRED; } } From d808d653d1fc16f1d5af76ab00fa862fb80fa3ba Mon Sep 17 00:00:00 2001 From: David Nusinow Date: Mon, 22 Oct 2007 21:30:04 -0400 Subject: [PATCH 29/33] Define PCI_TXT_IDS_DIR more cleanly --- hw/xfree86/common/Makefile.am | 2 -- hw/xfree86/common/xf86AutoConfig.c | 6 +++--- include/xorg-config.h.in | 3 +++ 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/hw/xfree86/common/Makefile.am b/hw/xfree86/common/Makefile.am index 05c088c96..db726fea1 100644 --- a/hw/xfree86/common/Makefile.am +++ b/hw/xfree86/common/Makefile.am @@ -94,6 +94,4 @@ if LNXACPI XORG_CFLAGS += -DHAVE_ACPI endif -XORG_CFLAGS += -DPCITXTIDSPATH=\"$(PCI_TXT_IDS_PATH)\" - AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) diff --git a/hw/xfree86/common/xf86AutoConfig.c b/hw/xfree86/common/xf86AutoConfig.c index 29f1279fa..c5998bfb8 100644 --- a/hw/xfree86/common/xf86AutoConfig.c +++ b/hw/xfree86/common/xf86AutoConfig.c @@ -347,9 +347,9 @@ matchDriverFromFiles (char** matches, uint16_t match_vendor, uint16_t match_chip uint16_t vendor, chip; int i, j; - idsdir = opendir(PCITXTIDSPATH); + idsdir = opendir(PCI_TXT_IDS_PATH); if (idsdir) { - xf86Msg(X_INFO, "Scanning %s directory for additional PCI ID's supported by the drivers\n", PCITXTIDSPATH); + xf86Msg(X_INFO, "Scanning %s directory for additional PCI ID's supported by the drivers\n", PCI_TXT_IDS_PATH); direntry = readdir(idsdir); /* Read the directory */ while (direntry) { @@ -361,7 +361,7 @@ matchDriverFromFiles (char** matches, uint16_t match_vendor, uint16_t match_chip /* A tiny bit of sanity checking. We should probably do better */ if (strncmp(&(direntry->d_name[len-4]), ".ids", 4) == 0) { /* We need the full path name to open the file */ - strncpy(path_name, PCITXTIDSPATH, 256); + strncpy(path_name, PCI_TXT_IDS_PATH, 256); strncat(path_name, "/", 1); strncat(path_name, direntry->d_name, (256 - strlen(path_name) - 1)); fp = fopen(path_name, "r"); diff --git a/include/xorg-config.h.in b/include/xorg-config.h.in index b9643a2a4..8e52ae106 100644 --- a/include/xorg-config.h.in +++ b/include/xorg-config.h.in @@ -115,4 +115,7 @@ /* Have execinfo.h */ #undef HAVE_EXECINFO_H +/* Path to text files containing PCI IDs */ +#undef PCI_TXT_IDS_PATH + #endif /* _XORG_CONFIG_H_ */ From 75f05086d04a90c3dcdcdd31bf79d7033708e3e0 Mon Sep 17 00:00:00 2001 From: Matthias Hopf Date: Tue, 23 Oct 2007 15:39:23 +0200 Subject: [PATCH 30/33] Get rid of unnecessary GNU extended variadic macro. --- include/os.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/os.h b/include/os.h index d91526786..597ecd742 100644 --- a/include/os.h +++ b/include/os.h @@ -517,7 +517,7 @@ __attribute((noreturn)) #ifdef DEBUG #define DebugF ErrorF #else -#define DebugF(x, ...) /* */ +#define DebugF(...) /* */ #endif extern void VErrorF(const char *f, va_list args); From a8a148919b84a293e3e7a49409ab833590357edb Mon Sep 17 00:00:00 2001 From: Matthias Hopf Date: Tue, 23 Oct 2007 16:23:28 +0200 Subject: [PATCH 31/33] Superfluous ','. --- render/picture.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/render/picture.h b/render/picture.h index 563a81b43..e8a098cd9 100644 --- a/render/picture.h +++ b/render/picture.h @@ -115,7 +115,7 @@ typedef enum _PictFormatShort { /* 1bpp formats */ PICT_a1 = PIXMAN_a1, - PICT_g1 = PIXMAN_g1, + PICT_g1 = PIXMAN_g1 } PictFormatShort; /* From d502521c3669f3f22b94c39a64ab63bfd92c6a97 Mon Sep 17 00:00:00 2001 From: Pierre Willenbrock Date: Tue, 23 Oct 2007 16:45:13 +0200 Subject: [PATCH 32/33] EXA: Fix off-by-one in polyline drawing. --- exa/exa_accel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exa/exa_accel.c b/exa/exa_accel.c index 52cc5c40a..5fb72d71b 100644 --- a/exa/exa_accel.c +++ b/exa/exa_accel.c @@ -658,7 +658,7 @@ exaPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, x1 = ppt[0].x; y1 = ppt[0].y; /* If we have any non-horizontal/vertical, fall back. */ - for (i = 0; i < npt; i++) { + for (i = 0; i < npt - 1; i++) { if (mode == CoordModePrevious) { x2 = x1 + ppt[i + 1].x; y2 = y1 + ppt[i + 1].y; From 48ca5961caee62f2980017a6bdc96a1b4c747727 Mon Sep 17 00:00:00 2001 From: Matthias Hopf Date: Wed, 24 Oct 2007 20:31:51 +0200 Subject: [PATCH 33/33] Prefer configured DisplaySize to probed DDC data, if available. Based on patch by Hong Liu . --- hw/xfree86/modes/xf86RandR12.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c index 38435c924..7169f74c8 100644 --- a/hw/xfree86/modes/xf86RandR12.c +++ b/hw/xfree86/modes/xf86RandR12.c @@ -426,8 +426,18 @@ xf86RandR12CreateScreenResources (ScreenPtr pScreen) xf86OutputPtr output = config->output[config->compat_output]; xf86CrtcPtr crtc = output->crtc; - if (crtc && crtc->mode.HDisplay && - output->mm_width && output->mm_height) + if (output->conf_monitor && + (output->conf_monitor->mon_width > 0 && + output->conf_monitor->mon_height > 0)) + { + /* + * Prefer user configured DisplaySize + */ + mmWidth = output->conf_monitor->mon_width; + mmHeight = output->conf_monitor->mon_height; + } + else if (crtc && crtc->mode.HDisplay && + output->mm_width && output->mm_height) { /* * If the output has a mode and a declared size, use that