diff options
author | Ian Romanick <idr@us.ibm.com> | 2007-08-23 18:19:17 -0700 |
---|---|---|
committer | Ian Romanick <idr@us.ibm.com> | 2007-08-23 18:19:17 -0700 |
commit | 8b6b40b7271acd81a9548f502c18f46f3b640640 (patch) | |
tree | 1462cb63501a8bdd8845d7c62e038b6a86b78fd5 /exa | |
parent | ab7a6d860d4a275a810a64b1ba7b13726ed10575 (diff) | |
parent | 3305d17195e3a0a5555300555bd7703312fa489f (diff) |
Merge branch 'master' of git+ssh://git.freedesktop.org/git/xorg/xserver into pci-reworkpci-rework
Conflicts:
hw/xfree86/common/xf86.h
hw/xfree86/common/xf86Init.c
hw/xfree86/common/xf86pciBus.c
hw/xfree86/int10/generic.c
hw/xfree86/int10/helper_exec.c
hw/xfree86/loader/xf86sym.c
hw/xfree86/os-support/bus/Pci.c
hw/xfree86/os-support/bus/Pci.h
hw/xfree86/os-support/bus/linuxPci.c
hw/xfree86/os-support/linux/int10/linux.c
Diffstat (limited to 'exa')
-rw-r--r-- | exa/exa.c | 45 | ||||
-rw-r--r-- | exa/exa_accel.c | 27 | ||||
-rw-r--r-- | exa/exa_offscreen.c | 2 | ||||
-rw-r--r-- | exa/exa_priv.h | 6 | ||||
-rw-r--r-- | exa/exa_render.c | 126 | ||||
-rw-r--r-- | exa/exa_unaccel.c | 35 |
6 files changed, 212 insertions, 29 deletions
@@ -253,7 +253,7 @@ exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth) pExaScr->info->pixmapPitchAlign); pExaPixmap->fb_size = pExaPixmap->fb_pitch * h; - if (pExaPixmap->fb_pitch > 32767) { + if (pExaPixmap->fb_pitch > 131071) { fbDestroyPixmap(pPixmap); return NULL; } @@ -526,6 +526,7 @@ exaCloseScreen(int i, ScreenPtr pScreen) if (ps) { ps->Composite = pExaScr->SavedComposite; ps->Glyphs = pExaScr->SavedGlyphs; + ps->Trapezoids = pExaScr->SavedTrapezoids; } #endif @@ -569,6 +570,45 @@ exaDriverInit (ScreenPtr pScreen, PictureScreenPtr ps; #endif + if (!pScreenInfo) + return FALSE; + + if (!pScreenInfo->memoryBase) { + LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::memoryBase must be " + "non-zero\n", pScreen->myNum); + return FALSE; + } + + if (!pScreenInfo->memorySize) { + LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::memorySize must be " + "non-zero\n", pScreen->myNum); + return FALSE; + } + + if (pScreenInfo->offScreenBase > pScreenInfo->memorySize) { + LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::offScreenBase must be <= " + "ExaDriverRec::memorySize\n", pScreen->myNum); + return FALSE; + } + + if (!pScreenInfo->PrepareSolid) { + LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::PrepareSolid must be " + "non-NULL\n", pScreen->myNum); + return FALSE; + } + + if (!pScreenInfo->PrepareCopy) { + LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::PrepareCopy must be " + "non-NULL\n", pScreen->myNum); + return FALSE; + } + + if (!pScreenInfo->WaitMarker) { + LogMessage(X_ERROR, "EXA(%d): ExaDriverRec::WaitMarker must be " + "non-NULL\n", pScreen->myNum); + return FALSE; + } + if (pScreenInfo->exa_major != EXA_VERSION_MAJOR || pScreenInfo->exa_minor > EXA_VERSION_MINOR) { @@ -645,6 +685,9 @@ exaDriverInit (ScreenPtr pScreen, pExaScr->SavedGlyphs = ps->Glyphs; ps->Glyphs = exaGlyphs; + + pExaScr->SavedTrapezoids = ps->Trapezoids; + ps->Trapezoids = exaTrapezoids; } #endif diff --git a/exa/exa_accel.c b/exa/exa_accel.c index bf63f2c4f..cc383cca4 100644 --- a/exa/exa_accel.c +++ b/exa/exa_accel.c @@ -643,15 +643,13 @@ exaPolyFillRect(DrawablePtr pDrawable, int n; ExaMigrationRec pixmaps[2]; RegionPtr pReg = RECTS_TO_REGION(pScreen, nrect, prect, CT_UNSORTED); - RegionPtr pDamageReg = DamageRegion(ExaGetPixmapPriv(pPixmap)->pDamage); /* Compute intersection of rects and clip region */ REGION_TRANSLATE(pScreen, pReg, pDrawable->x, pDrawable->y); REGION_INTERSECT(pScreen, pReg, pClip, pReg); if (!REGION_NUM_RECTS(pReg)) { - REGION_DESTROY(pScreen, pReg); - return; + goto out; } pixmaps[0].as_dst = TRUE; @@ -680,7 +678,7 @@ exaPolyFillRect(DrawablePtr pDrawable, (pGC->fillStyle == FillTiled && !pGC->tileIsPixel && exaFillRegionTiled(pDrawable, pReg, pGC->tile.pixmap, &pGC->patOrg, pGC->planemask, pGC->alu))) { - goto damage; + goto out; } } @@ -709,13 +707,7 @@ fallback: } ExaCheckPolyFillRect (pDrawable, pGC, nrect, prect); - -damage: - REGION_TRANSLATE(pScreen, pReg, xoff, yoff); - REGION_UNION(pScreen, pDamageReg, pReg, pDamageReg); - REGION_DESTROY(pScreen, pReg); - - return; + goto out; } xorg = pDrawable->x; @@ -754,8 +746,6 @@ damage: (*pExaScr->info->Solid) (pPixmap, fullX1 + xoff, fullY1 + yoff, fullX2 + xoff, fullY2 + yoff); - exaPixmapDirty (pPixmap, fullX1 + xoff, fullY1 + yoff, - fullX2 + xoff, fullY2 + yoff); } else { @@ -786,14 +776,15 @@ damage: (*pExaScr->info->Solid) (pPixmap, partX1 + xoff, partY1 + yoff, partX2 + xoff, partY2 + yoff); - exaPixmapDirty (pPixmap, partX1 + xoff, partY1 + yoff, - partX2 + xoff, partY2 + yoff); } } } } (*pExaScr->info->DoneSolid) (pPixmap); exaMarkSync(pDrawable->pScreen); + +out: + REGION_DESTROY(pScreen, pReg); } static void @@ -1329,6 +1320,9 @@ exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h, int xoff, yoff; Bool ok; + if (pExaScr->swappedOut || (w == 1 && h == 1)) + goto fallback; + if (pExaScr->info->DownloadFromScreen == NULL) goto migrate_and_fallback; @@ -1342,9 +1336,6 @@ exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h, if (pDrawable->bitsPerPixel < 8) goto migrate_and_fallback; - if (pExaScr->swappedOut) - goto fallback; - pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff); if (pPix == NULL) goto fallback; diff --git a/exa/exa_offscreen.c b/exa/exa_offscreen.c index 6fe646a88..c666b001b 100644 --- a/exa/exa_offscreen.c +++ b/exa/exa_offscreen.c @@ -429,7 +429,7 @@ ExaOffscreenMarkUsed (PixmapPtr pPixmap) ExaScreenPriv (pPixmap->drawable.pScreen); static int iter = 0; - if (!pExaPixmap->area) + if (!pExaPixmap || !pExaPixmap->area) return; /* The numbers here are arbitrary. We may want to tune these. */ diff --git a/exa/exa_priv.h b/exa/exa_priv.h index a6d98cd2d..bab8aa23b 100644 --- a/exa/exa_priv.h +++ b/exa/exa_priv.h @@ -108,6 +108,7 @@ typedef struct { RasterizeTrapezoidProcPtr SavedRasterizeTrapezoid; AddTrianglesProcPtr SavedAddTriangles; GlyphsProcPtr SavedGlyphs; + TrapezoidsProcPtr SavedTrapezoids; #endif Bool swappedOut; enum ExaMigrationHeuristic migration; @@ -393,6 +394,11 @@ exaComposite(CARD8 op, CARD16 height); void +exaTrapezoids (CARD8 op, PicturePtr pSrc, PicturePtr pDst, + PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, + int ntrap, xTrapezoid *traps); + +void exaRasterizeTrapezoid (PicturePtr pPicture, xTrapezoid *trap, int x_off, int y_off); diff --git a/exa/exa_render.c b/exa/exa_render.c index 5e7c67feb..2dd3fc1ce 100644 --- a/exa/exa_render.c +++ b/exa/exa_render.c @@ -749,6 +749,132 @@ done: } #endif +/** + * Same as miCreateAlphaPicture, except it uses ExaCheckPolyFillRect instead + * of PolyFillRect to initialize the pixmap after creating it, to prevent + * the pixmap from being migrated. + * + * See the comments about exaTrapezoids. + */ +static PicturePtr +exaCreateAlphaPicture (ScreenPtr pScreen, + PicturePtr pDst, + PictFormatPtr pPictFormat, + CARD16 width, + CARD16 height) +{ + PixmapPtr pPixmap; + PicturePtr pPicture; + GCPtr pGC; + int error; + xRectangle rect; + + if (width > 32767 || height > 32767) + return 0; + + if (!pPictFormat) + { + if (pDst->polyEdge == PolyEdgeSharp) + pPictFormat = PictureMatchFormat (pScreen, 1, PICT_a1); + else + pPictFormat = PictureMatchFormat (pScreen, 8, PICT_a8); + if (!pPictFormat) + return 0; + } + + pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, + pPictFormat->depth); + if (!pPixmap) + return 0; + pGC = GetScratchGC (pPixmap->drawable.depth, pScreen); + if (!pGC) + { + (*pScreen->DestroyPixmap) (pPixmap); + return 0; + } + ValidateGC (&pPixmap->drawable, pGC); + rect.x = 0; + rect.y = 0; + rect.width = width; + rect.height = height; + ExaCheckPolyFillRect (&pPixmap->drawable, pGC, 1, &rect); + exaPixmapDirty (pPixmap, 0, 0, width, height); + FreeScratchGC (pGC); + pPicture = CreatePicture (0, &pPixmap->drawable, pPictFormat, + 0, 0, serverClient, &error); + (*pScreen->DestroyPixmap) (pPixmap); + return pPicture; +} + +/** + * exaTrapezoids is essentially a copy of miTrapezoids that uses + * exaCreateAlphaPicture instead of miCreateAlphaPicture. + * + * The problem with miCreateAlphaPicture is that it calls PolyFillRect + * to initialize the contents after creating the pixmap, which + * causes the pixmap to be moved in for acceleration. The subsequent + * call to RasterizeTrapezoid won't be accelerated however, which + * forces the pixmap to be moved out again. + * + * exaCreateAlphaPicture avoids this roundtrip by using ExaCheckPolyFillRect + * to initialize the contents. + */ +void +exaTrapezoids (CARD8 op, PicturePtr pSrc, PicturePtr pDst, + PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, + int ntrap, xTrapezoid *traps) +{ + ScreenPtr pScreen = pDst->pDrawable->pScreen; + PictureScreenPtr ps = GetPictureScreen(pScreen); + + /* + * Check for solid alpha add + */ + if (op == PictOpAdd && miIsSolidAlpha (pSrc)) + { + for (; ntrap; ntrap--, traps++) + (*ps->RasterizeTrapezoid) (pDst, traps, 0, 0); + } + else if (maskFormat) + { + PicturePtr pPicture; + BoxRec bounds; + INT16 xDst, yDst; + INT16 xRel, yRel; + + xDst = traps[0].left.p1.x >> 16; + yDst = traps[0].left.p1.y >> 16; + + miTrapezoidBounds (ntrap, traps, &bounds); + if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2) + return; + pPicture = exaCreateAlphaPicture (pScreen, pDst, maskFormat, + bounds.x2 - bounds.x1, + bounds.y2 - bounds.y1); + if (!pPicture) + return; + for (; ntrap; ntrap--, traps++) + (*ps->RasterizeTrapezoid) (pPicture, traps, + -bounds.x1, -bounds.y1); + xRel = bounds.x1 + xSrc - xDst; + yRel = bounds.y1 + ySrc - yDst; + CompositePicture (op, pSrc, pPicture, pDst, + xRel, yRel, 0, 0, bounds.x1, bounds.y1, + bounds.x2 - bounds.x1, + bounds.y2 - bounds.y1); + FreePicture (pPicture, 0); + } + else + { + if (pDst->polyEdge == PolyEdgeSharp) + maskFormat = PictureMatchFormat (pScreen, 1, PICT_a1); + else + maskFormat = PictureMatchFormat (pScreen, 8, PICT_a8); + for (; ntrap; ntrap--, traps++) + exaTrapezoids (op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, traps); + } +} + #define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0) /** diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c index 708d1eac6..a94648b47 100644 --- a/exa/exa_unaccel.c +++ b/exa/exa_unaccel.c @@ -369,31 +369,48 @@ ExaCheckComposite (CARD8 op, /** * Gets the 0,0 pixel of a pixmap. Used for doing solid fills of tiled pixmaps * that happen to be 1x1. Pixmap must be at least 8bpp. + * + * XXX This really belongs in fb, so it can be aware of tiling and etc. */ CARD32 exaGetPixmapFirstPixel (PixmapPtr pPixmap) { CARD32 pixel; + void *fb; + Bool need_finish = FALSE; + BoxRec box; ExaMigrationRec pixmaps[1]; + ExaPixmapPriv (pPixmap); - pixmaps[0].as_dst = FALSE; - pixmaps[0].as_src = TRUE; - pixmaps[0].pPix = pPixmap; - exaDoMigration (pixmaps, 1, FALSE); + fb = pExaPixmap->sys_ptr; + + /* Try to avoid framebuffer readbacks */ + if (exaPixmapIsOffscreen(pPixmap) && + miPointInRegion(DamageRegion(pExaPixmap->pDamage), 0, 0, &box)) + { + need_finish = TRUE; + pixmaps[0].as_dst = FALSE; + pixmaps[0].as_src = TRUE; + pixmaps[0].pPix = pPixmap; + exaDoMigration (pixmaps, 1, FALSE); + exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_SRC); + fb = pPixmap->devPrivate.ptr; + } - exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_SRC); switch (pPixmap->drawable.bitsPerPixel) { case 32: - pixel = *(CARD32 *)(pPixmap->devPrivate.ptr); + pixel = *(CARD32 *)fb; break; case 16: - pixel = *(CARD16 *)(pPixmap->devPrivate.ptr); + pixel = *(CARD16 *)fb; break; default: - pixel = *(CARD8 *)(pPixmap->devPrivate.ptr); + pixel = *(CARD8 *)fb; break; } - exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC); + + if (need_finish) + exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC); return pixel; } |