From 95fadbd4022ec99f42ba78ec8a18a064903e8a7f Mon Sep 17 00:00:00 2001 From: Dodji Seketeli Date: Mon, 16 Jul 2007 17:37:21 +0200 Subject: Add basic Exa driver entry point validation. In exaDriverInit(), quickly check if the programmer forgot to set some mandadory driver hooks, in that case display a meaningful error message. --- exa/exa.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'exa') diff --git a/exa/exa.c b/exa/exa.c index 3e8054da9..fc1f419bc 100644 --- a/exa/exa.c +++ b/exa/exa.c @@ -722,6 +722,48 @@ exaDriverAlloc(void) return xcalloc(1, sizeof(ExaDriverRec)); } +static Bool +exaDriverValidateEntryPoints (ExaDriverPtr pExaDriver) +{ + Bool res=TRUE ; + + if (!pExaDriver) + return FALSE ; + + if (!pExaDriver->memoryBase) { + LogMessage(X_ERROR, + "Exa: Exa::memoryBase member " + "must be assigned to a value different from zero\n") ; + res = FALSE ; + } + if (!pExaDriver->memorySize) { + LogMessage(X_ERROR, + "Exa: Exa::memorySize member must be different from zero\n") ; + res = FALSE ; + } + if (pExaDriver->offScreenBase > pExaDriver->memorySize) { + LogMessage(X_ERROR, + "Exa: Exa::ffscreenBase must be <= pExaDriver->memorySize member\n") ; + res = FALSE ; + } + if (!pExaDriver->PrepareSolid) { + LogMessage(X_ERROR, + "Exa: Exa::PrepareSolid member is required to be non NULL\n") ; + res = FALSE ; + } + if (!pExaDriver->PrepareCopy) { + LogMessage(X_ERROR, + "Exa: Exa::PrepareCopy member is required to be non NULL\n") ; + res = FALSE ; + } + if (!pExaDriver->WaitMarker) { + LogMessage(X_ERROR, + "Exa: Exa::WaitWarker member is required to be non NULL\n") ; + res = FALSE ; + } + return res ; +} + /** * @param pScreen screen being initialized * @param pScreenInfo EXA driver record @@ -806,6 +848,12 @@ exaDriverInit (ScreenPtr pScreen, { pScreenInfo->maxPitchPixels = pScreenInfo->maxX; } + if (!exaDriverValidateEntryPoints(pScreenInfo)) + { + LogMessage(X_ERROR, "Exa(%d): EXA driver entry points validation failed\n", + pScreen->myNum) ; + return FALSE ; + } #ifdef RENDER ps = GetPictureScreenIfSet(pScreen); -- cgit v1.2.3 From 1df1fee82d3565f6d8cfb91ce25a81c23a10a4b5 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 3 Oct 2007 11:56:04 +1000 Subject: exa: make sure we set fb_ptr to NULL --- exa/exa.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'exa') diff --git a/exa/exa.c b/exa/exa.c index 3e8054da9..8a4b8c114 100644 --- a/exa/exa.c +++ b/exa/exa.c @@ -286,8 +286,9 @@ exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth) (*pScreen->ModifyPixmapHeader)(pPixmap, w, h, 0, 0, paddedWidth, NULL); - pExaPixmap->driverPriv = driver_priv; - pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED; + pExaPixmap->driverPriv = driver_priv; + pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED; + pExaPixmap->fb_ptr = NULL; } else { pExaPixmap->driverPriv = NULL; /* Glyphs have w/h equal to zero, and may not be migrated. See exaGlyphs. */ -- cgit v1.2.3 From 566dd3b7d789ba60d0adf33b3f729cfb02ff33cd Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 3 Oct 2007 11:59:52 +1000 Subject: exa: add new flags to denote driver handles all pixmap migration/hiding --- exa/exa.c | 7 +++---- exa/exa.h | 7 +++++++ exa/exa_migration.c | 3 +++ 3 files changed, 13 insertions(+), 4 deletions(-) (limited to 'exa') diff --git a/exa/exa.c b/exa/exa.c index 8a4b8c114..7ad226fba 100644 --- a/exa/exa.c +++ b/exa/exa.c @@ -410,7 +410,7 @@ exaPixmapIsOffscreen(PixmapPtr p) save_ptr = p->devPrivate.ptr; - if (!save_ptr && pExaPixmap) + if (!save_ptr && pExaPixmap && !(pExaScr->info->flags & EXA_HANDLES_PIXMAPS)) p->devPrivate.ptr = ExaGetPixmapAddress(p); if (pExaScr->info->PixmapIsOffscreen) @@ -460,7 +460,7 @@ ExaDoPrepareAccess(DrawablePtr pDrawable, int index) Bool offscreen = exaPixmapIsOffscreen(pPixmap); /* Unhide pixmap pointer */ - if (pPixmap->devPrivate.ptr == NULL) { + if (pPixmap->devPrivate.ptr == NULL && !(pExaScr->info->flags & EXA_HANDLES_PIXMAPS)) { pPixmap->devPrivate.ptr = ExaGetPixmapAddress(pPixmap); } @@ -521,8 +521,7 @@ exaFinishAccess(DrawablePtr pDrawable, int index) ExaPixmapPriv (pPixmap); /* Rehide pixmap pointer if we're doing that. */ - if (pExaPixmap) - { + if (pExaPixmap && !(pExaScr->info->flags & EXA_HANDLES_PIXMAPS)) { pPixmap->devPrivate.ptr = NULL; } diff --git a/exa/exa.h b/exa/exa.h index f852df482..1ff0518e4 100644 --- a/exa/exa.h +++ b/exa/exa.h @@ -733,6 +733,13 @@ typedef struct _ExaDriver { * (right-to-left, bottom-to-top). */ #define EXA_TWO_BITBLT_DIRECTIONS (1 << 2) + +/** + * EXA_HANDLES_PIXMAPS indicates to EXA that the driver can handle + * all pixmap addressing and migration. + */ +#define EXA_HANDLES_PIXMAPS (1 << 3) + /** @} */ ExaDriverPtr diff --git a/exa/exa_migration.c b/exa/exa_migration.c index c0e022ca7..7968521c5 100644 --- a/exa/exa_migration.c +++ b/exa/exa_migration.c @@ -553,6 +553,9 @@ exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel) ExaScreenPriv(pScreen); int i, j; + if (pExaScr->info->flags & EXA_HANDLES_PIXMAPS) + return; + /* If this debugging flag is set, check each pixmap for whether it is marked * as clean, and if so, actually check if that's the case. This should help * catch issues with failing to mark a drawable as dirty. While it will -- cgit v1.2.3 From 1365aeff5499a051375e43a9fcbf54733ac93929 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 3 Oct 2007 12:00:16 +1000 Subject: exa: direct access to the pixmap sys ptr is bad if the pixmap isn't mapped --- exa/exa_accel.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'exa') diff --git a/exa/exa_accel.c b/exa/exa_accel.c index abe5c204f..e10bf5cf2 100644 --- a/exa/exa_accel.c +++ b/exa/exa_accel.c @@ -1138,17 +1138,19 @@ exaFillRegionSolid (DrawablePtr pDrawable, pDrawable->bitsPerPixel != 24) { ExaPixmapPriv(pPixmap); + exaPrepareAccess(pDrawable, EXA_PREPARE_DEST); switch (pDrawable->bitsPerPixel) { case 32: - *(CARD32*)pExaPixmap->sys_ptr = pixel; + *(CARD32*)pPixmap->devPrivate.ptr = pixel; break; case 16: - *(CARD16*)pExaPixmap->sys_ptr = pixel; + *(CARD16*)pPixmap->devPrivate.ptr = pixel; break; case 8: - *(CARD8*)pExaPixmap->sys_ptr = pixel; + *(CARD8*)pPixmap->devPrivate.ptr = pixel; } + exaFinishAccess(pDrawable, EXA_PREPARE_DEST); REGION_UNION(pScreen, &pExaPixmap->validSys, &pExaPixmap->validSys, pRegion); } -- cgit v1.2.3 From 3549a1282365e69e70c7c2546cfa7d25923cce31 Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Thu, 4 Oct 2007 11:38:01 +0200 Subject: EXA: Disable 1x1 pixmap fill optimization for drivers that handle pixmaps. This reverts commit 1365aeff5499a051375e43a9fcbf54733ac93929. It defeated the optimization for drivers that don't provide a CreatePixmap hook. The optimization makes no sense for drivers that do anyway, so disable it for them completely. --- exa/exa_accel.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'exa') diff --git a/exa/exa_accel.c b/exa/exa_accel.c index e10bf5cf2..8bbf036e4 100644 --- a/exa/exa_accel.c +++ b/exa/exa_accel.c @@ -1134,23 +1134,22 @@ exaFillRegionSolid (DrawablePtr pDrawable, (*pExaScr->info->DoneSolid) (pPixmap); exaMarkSync(pDrawable->pScreen); - if (pDrawable->width == 1 && pDrawable->height == 1 && + if (!(pExaScr->info->flags & EXA_HANDLES_PIXMAPS) && + pDrawable->width == 1 && pDrawable->height == 1 && pDrawable->bitsPerPixel != 24) { ExaPixmapPriv(pPixmap); - exaPrepareAccess(pDrawable, EXA_PREPARE_DEST); switch (pDrawable->bitsPerPixel) { case 32: - *(CARD32*)pPixmap->devPrivate.ptr = pixel; + *(CARD32*)pExaPixmap->sys_ptr = pixel; break; case 16: - *(CARD16*)pPixmap->devPrivate.ptr = pixel; + *(CARD16*)pExaPixmap->sys_ptr = pixel; break; case 8: - *(CARD8*)pPixmap->devPrivate.ptr = pixel; + *(CARD8*)pExaPixmap->sys_ptr = pixel; } - exaFinishAccess(pDrawable, EXA_PREPARE_DEST); REGION_UNION(pScreen, &pExaPixmap->validSys, &pExaPixmap->validSys, pRegion); } -- cgit v1.2.3 From 6aab6a6e2ae0ef5fdedae09cf2cdc86f382e3a8a Mon Sep 17 00:00:00 2001 From: Dodji Seketeli Date: Mon, 8 Oct 2007 13:25:38 +0200 Subject: EXA: dude, don't validation driver hooks twice ! --- exa/exa.c | 48 ------------------------------------------------ 1 file changed, 48 deletions(-) (limited to 'exa') diff --git a/exa/exa.c b/exa/exa.c index 1403d4fa3..7ad226fba 100644 --- a/exa/exa.c +++ b/exa/exa.c @@ -722,48 +722,6 @@ exaDriverAlloc(void) return xcalloc(1, sizeof(ExaDriverRec)); } -static Bool -exaDriverValidateEntryPoints (ExaDriverPtr pExaDriver) -{ - Bool res=TRUE ; - - if (!pExaDriver) - return FALSE ; - - if (!pExaDriver->memoryBase) { - LogMessage(X_ERROR, - "Exa: Exa::memoryBase member " - "must be assigned to a value different from zero\n") ; - res = FALSE ; - } - if (!pExaDriver->memorySize) { - LogMessage(X_ERROR, - "Exa: Exa::memorySize member must be different from zero\n") ; - res = FALSE ; - } - if (pExaDriver->offScreenBase > pExaDriver->memorySize) { - LogMessage(X_ERROR, - "Exa: Exa::ffscreenBase must be <= pExaDriver->memorySize member\n") ; - res = FALSE ; - } - if (!pExaDriver->PrepareSolid) { - LogMessage(X_ERROR, - "Exa: Exa::PrepareSolid member is required to be non NULL\n") ; - res = FALSE ; - } - if (!pExaDriver->PrepareCopy) { - LogMessage(X_ERROR, - "Exa: Exa::PrepareCopy member is required to be non NULL\n") ; - res = FALSE ; - } - if (!pExaDriver->WaitMarker) { - LogMessage(X_ERROR, - "Exa: Exa::WaitWarker member is required to be non NULL\n") ; - res = FALSE ; - } - return res ; -} - /** * @param pScreen screen being initialized * @param pScreenInfo EXA driver record @@ -848,12 +806,6 @@ exaDriverInit (ScreenPtr pScreen, { pScreenInfo->maxPitchPixels = pScreenInfo->maxX; } - if (!exaDriverValidateEntryPoints(pScreenInfo)) - { - LogMessage(X_ERROR, "Exa(%d): EXA driver entry points validation failed\n", - pScreen->myNum) ; - return FALSE ; - } #ifdef RENDER ps = GetPictureScreenIfSet(pScreen); -- cgit v1.2.3 From 5d74416740de883b7ef0994afea4bbd4d3901be0 Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Thu, 18 Oct 2007 17:44:14 +0200 Subject: 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(-) (limited to 'exa') 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; -- cgit v1.2.3 From ce50bfd3369686cfecee5a138bd84ef1107a249d Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Thu, 18 Oct 2007 17:44:48 +0200 Subject: EXA: Skip empty glyphs. --- exa/exa_render.c | 1 + 1 file changed, 1 insertion(+) (limited to 'exa') 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; -- cgit v1.2.3