static void fbSetFg(DrawablePtr drawable, GCPtr gc, Pixel fg) { if (fg != gc->fgPixel) { gc->fgPixel = fg; fbValidateGC(gc, GCForeground, drawable); } }
static void kaaValidateGC (GCPtr pGC, Mask changes, DrawablePtr pDrawable) { fbValidateGC (pGC, changes, pDrawable); if (kaaDrawableIsOffscreen (pDrawable)) pGC->ops = (GCOps *) &kaaOps; else pGC->ops = (GCOps *) &kdAsyncPixmapGCOps; }
/** * exaValidateGC() sets the ops to EXA's implementations, which may be * accelerated or may sync the card and fall back to fb. */ static void exaValidateGC (GCPtr pGC, unsigned long changes, DrawablePtr pDrawable) { /* fbValidateGC will do direct access to pixmaps if the tiling has changed. * Preempt fbValidateGC by doing its work and masking the change out, so * that we can do the Prepare/FinishAccess. */ #ifdef FB_24_32BIT if ((changes & GCTile) && fbGetRotatedPixmap(pGC)) { (*pGC->pScreen->DestroyPixmap) (fbGetRotatedPixmap(pGC)); fbGetRotatedPixmap(pGC) = 0; } if (pGC->fillStyle == FillTiled) { PixmapPtr pOldTile, pNewTile; pOldTile = pGC->tile.pixmap; if (pOldTile->drawable.bitsPerPixel != pDrawable->bitsPerPixel) { pNewTile = fbGetRotatedPixmap(pGC); if (!pNewTile || pNewTile ->drawable.bitsPerPixel != pDrawable->bitsPerPixel) { if (pNewTile) (*pGC->pScreen->DestroyPixmap) (pNewTile); /* fb24_32ReformatTile will do direct access of a newly- * allocated pixmap. This isn't a problem yet, since we don't * put pixmaps in FB until at least one accelerated EXA op. */ exaPrepareAccess(&pOldTile->drawable, EXA_PREPARE_SRC); pNewTile = fb24_32ReformatTile (pOldTile, pDrawable->bitsPerPixel); exaPixmapDirty(pNewTile, 0, 0, pNewTile->drawable.width, pNewTile->drawable.height); exaFinishAccess(&pOldTile->drawable, EXA_PREPARE_SRC); } if (pNewTile) { fbGetRotatedPixmap(pGC) = pOldTile; pGC->tile.pixmap = pNewTile; changes |= GCTile; } } } #endif if (changes & GCTile) { if (!pGC->tileIsPixel && FbEvenTile (pGC->tile.pixmap->drawable.width * pDrawable->bitsPerPixel)) { /* XXX This fixes corruption with tiled pixmaps, but may just be a * workaround for broken drivers */ exaMoveOutPixmap(pGC->tile.pixmap); fbPadPixmap (pGC->tile.pixmap); exaPixmapDirty(pGC->tile.pixmap, 0, 0, pGC->tile.pixmap->drawable.width, pGC->tile.pixmap->drawable.height); } /* Mask out the GCTile change notification, now that we've done FB's * job for it. */ changes &= ~GCTile; } fbValidateGC (pGC, changes, pDrawable); pGC->ops = (GCOps *) &exaOps; }
/** * uxa_validate_gc() sets the ops to UXA's implementations, which may be * accelerated or may sync the card and fall back to fb. */ static void uxa_validate_gc(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable) { /* fbValidateGC will do direct access to pixmaps if the tiling has * changed. * Preempt fbValidateGC by doing its work and masking the change out, so * that we can do the Prepare/finish_access. */ #ifdef FB_24_32BIT if ((changes & GCTile) && fbGetRotatedPixmap(pGC)) { (*pGC->pScreen->DestroyPixmap) (fbGetRotatedPixmap(pGC)); fbGetRotatedPixmap(pGC) = 0; } if (pGC->fillStyle == FillTiled) { PixmapPtr pOldTile, pNewTile; pOldTile = pGC->tile.pixmap; if (pOldTile->drawable.bitsPerPixel != pDrawable->bitsPerPixel) { pNewTile = fbGetRotatedPixmap(pGC); if (!pNewTile || pNewTile->drawable.bitsPerPixel != pDrawable->bitsPerPixel) { if (pNewTile) (*pGC->pScreen-> DestroyPixmap) (pNewTile); /* fb24_32ReformatTile will do direct access * of a newly-allocated pixmap. This isn't a * problem yet, since we don't put pixmaps in * FB until at least one accelerated UXA op. */ if (uxa_prepare_access (&pOldTile->drawable, NULL, UXA_ACCESS_RO)) { pNewTile = fb24_32ReformatTile(pOldTile, pDrawable-> bitsPerPixel); uxa_finish_access(&pOldTile->drawable); } } if (pNewTile) { fbGetRotatedPixmap(pGC) = pOldTile; pGC->tile.pixmap = pNewTile; changes |= GCTile; } } } #endif if (changes & GCTile) { if (!pGC->tileIsPixel && FbEvenTile(pGC->tile.pixmap->drawable.width * pDrawable->bitsPerPixel)) { if (uxa_prepare_access (&pGC->tile.pixmap->drawable, NULL, UXA_ACCESS_RW)) { fbPadPixmap(pGC->tile.pixmap); uxa_finish_access(&pGC->tile.pixmap->drawable); } } /* Mask out the GCTile change notification, now that we've * done FB's job for it. */ changes &= ~GCTile; } if (changes & GCStipple && pGC->stipple) { /* We can't inline stipple handling like we do for GCTile * because it sets fbgc privates. */ if (uxa_prepare_access(&pGC->stipple->drawable, NULL, UXA_ACCESS_RW)) { fbValidateGC(pGC, changes, pDrawable); uxa_finish_access(&pGC->stipple->drawable); } } else { fbValidateGC(pGC, changes, pDrawable); } pGC->ops = (GCOps *) & uxa_ops; }
/** * uxa_validate_gc() sets the ops to glamor's implementations, which may be * accelerated or may sync the card and fall back to fb. */ void glamor_validate_gc(GCPtr gc, unsigned long changes, DrawablePtr drawable) { /* fbValidateGC will do direct access to pixmaps if the tiling has changed. * Preempt fbValidateGC by doing its work and masking the change out, so * that we can do the Prepare/finish_access. */ #ifdef FB_24_32BIT if ((changes & GCTile) && fbGetRotatedPixmap(gc)) { gc->pScreen->DestroyPixmap(fbGetRotatedPixmap(gc)); fbGetRotatedPixmap(gc) = 0; } if (gc->fillStyle == FillTiled) { PixmapPtr old_tile, new_tile; old_tile = gc->tile.pixmap; if (old_tile->drawable.bitsPerPixel != drawable->bitsPerPixel) { new_tile = fbGetRotatedPixmap(gc); if (!new_tile || new_tile->drawable.bitsPerPixel != drawable->bitsPerPixel) { if (new_tile) gc->pScreen->DestroyPixmap(new_tile); /* fb24_32ReformatTile will do direct access of a newly- * allocated pixmap. */ glamor_fallback ("GC %p tile FB_24_32 transformat %p.\n", gc, old_tile); if (glamor_prepare_access (&old_tile->drawable, GLAMOR_ACCESS_RO)) { new_tile = fb24_32ReformatTile(old_tile, drawable->bitsPerPixel); glamor_finish_access(&old_tile->drawable, GLAMOR_ACCESS_RO); } } if (new_tile) { fbGetRotatedPixmap(gc) = old_tile; gc->tile.pixmap = new_tile; changes |= GCTile; } } } #endif if (changes & GCTile) { if (!gc->tileIsPixel) { glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(gc->tile.pixmap); if ((!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) && FbEvenTile(gc->tile.pixmap->drawable.width * drawable->bitsPerPixel)) { glamor_fallback ("GC %p tile changed %p.\n", gc, gc->tile.pixmap); if (glamor_prepare_access (&gc->tile.pixmap->drawable, GLAMOR_ACCESS_RW)) { fbPadPixmap(gc->tile.pixmap); glamor_finish_access (&gc->tile.pixmap->drawable, GLAMOR_ACCESS_RW); } } } /* Mask out the GCTile change notification, now that we've done FB's * job for it. */ changes &= ~GCTile; } if (changes & GCStipple && gc->stipple) { /* We can't inline stipple handling like we do for GCTile because * it sets fbgc privates. */ if (glamor_prepare_access(&gc->stipple->drawable, GLAMOR_ACCESS_RW)) { fbValidateGC(gc, changes, drawable); glamor_finish_access(&gc->stipple->drawable, GLAMOR_ACCESS_RW); } } else { fbValidateGC(gc, changes, drawable); } gc->ops = &glamor_gc_ops; }
void s3ValidateGC (GCPtr pGC, Mask changes, DrawablePtr pDrawable) { int new_type; /* drawable type has changed */ int new_origin; /* flags for changing the proc vector */ FbGCPrivPtr fbPriv; s3PrivGCPtr s3Priv; int oneRect; GCOps *newops; fbPriv = fbGetGCPrivate(pGC); s3Priv = s3GetGCPrivate(pGC); new_type = FALSE; new_origin = FALSE; /* * If the type of drawable has changed, fix up accelerated functions */ if (s3Priv->type != pDrawable->type) { new_type = TRUE; s3Priv->type = pDrawable->type; } /* * Check tile/stipple origin */ if (pGC->lastWinOrg.x != pDrawable->x || pGC->lastWinOrg.y != pDrawable->y) new_origin = TRUE; /* * Call down to FB to set clip list and rrop values */ fbValidateGC (pGC, changes, pDrawable); /* * Check accelerated pattern if necessary */ if (changes & (GCFillStyle|GCStipple|GCTile)) s3CheckGCFill (pGC); else if (s3Priv->pPattern && (new_origin || changes & (GCTileStipXOrigin|GCTileStipYOrigin))) s3MoveGCFill (pGC); /* * Try to match common vector */ if (newops = s3MatchCommon (pDrawable, pGC, fbPriv)) { if (pGC->ops->devPrivate.val) miDestroyGCOps (pGC->ops); pGC->ops = newops; return; } /* * No common vector matched, create private ops vector and * fill it in */ if (!pGC->ops->devPrivate.val) { /* * Switch from noop vector by first switching to fb * vector and fixing it up */ if (pGC->ops == &kdNoopOps) { pGC->ops = (GCOps *) &kdAsyncPixmapGCOps; new_type = TRUE; } pGC->ops = miCreateGCOps (pGC->ops); pGC->ops->devPrivate.val = 1; } /* * Fills */ if (new_type || (changes & (GCFillStyle|GCTile|GCStipple))) { pGC->ops->FillSpans = KdCheckFillSpans; pGC->ops->PolyFillRect = KdCheckPolyFillRect; if (s3Priv->type == DRAWABLE_WINDOW && (pGC->fillStyle != FillTiled || s3Priv->pPattern)) { pGC->ops->FillSpans = s3FillSpans; pGC->ops->PolyFillRect = s3PolyFillRect; } } /* * Blt */ if (new_type) { pGC->ops->CopyArea = s3CopyArea; pGC->ops->CopyPlane = s3CopyPlane; pGC->ops->PushPixels = s3PushPixels; } /* * Lines */ if (new_type || (changes & (GCLineStyle|GCLineWidth|GCFillStyle))) { pGC->ops->Polylines = KdCheckPolylines; pGC->ops->PolySegment = KdCheckPolySegment; if (pGC->lineStyle == LineSolid && pGC->lineWidth == 0 && pGC->fillStyle == FillSolid && s3Priv->type == DRAWABLE_WINDOW) { pGC->ops->Polylines = s3Polylines; pGC->ops->PolySegment = s3PolySegment; } } /* * Polygons */ if (new_type || (changes & (GCFillStyle))) { pGC->ops->FillPolygon = KdCheckFillPolygon; if (s3Priv->type == DRAWABLE_WINDOW && pGC->fillStyle == FillSolid) { pGC->ops->FillPolygon = s3FillPoly; } } /* * Filled arcs */ if (new_type || (changes & GCFillStyle)) { pGC->ops->PolyFillArc = KdCheckPolyFillArc; if (s3Priv->type == DRAWABLE_WINDOW && pGC->fillStyle == FillSolid) { pGC->ops->PolyFillArc = s3PolyFillArcSolid; } } /* * Text */ if (new_type || (changes & (GCFont|GCFillStyle))) { pGC->ops->PolyGlyphBlt = KdCheckPolyGlyphBlt; pGC->ops->ImageGlyphBlt = KdCheckImageGlyphBlt; if (s3Priv->type == DRAWABLE_WINDOW && pGC->font) { if (pGC->fillStyle == FillSolid) { if (TERMINALFONT(pGC->font)) pGC->ops->PolyGlyphBlt = s3PolyTEGlyphBlt; else pGC->ops->PolyGlyphBlt = s3PolyGlyphBlt; } if (TERMINALFONT(pGC->font)) pGC->ops->ImageGlyphBlt = s3ImageTEGlyphBlt; else pGC->ops->ImageGlyphBlt = s3ImageGlyphBlt; } } }