summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Worth <cworth@cworth.org>2007-08-01 15:48:30 -0700
committerCarl Worth <cworth@cworth.org>2007-08-02 22:49:56 -0700
commita2af34d5a861982a03afad8e586bb0181b72bbd0 (patch)
tree0e423afde57f7d875c8a08f134bf1eb7e07276c0
parent19b3b1fd8feb343a690331cafe88ef10b34b9d98 (diff)
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).
-rw-r--r--exa/exa_priv.h1
-rw-r--r--exa/exa_render.c99
-rw-r--r--render/glyph.c55
-rw-r--r--render/glyphstr.h4
-rw-r--r--render/miglyph.c40
-rw-r--r--render/render.c67
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);