[PATCH 4/9] exa: properly wrap GC functions

2009-02-03 Thread Maarten Maathuis
---
 exa/exa.c |  219 
 exa/exa_priv.h|   33 -
 exa/exa_unaccel.c |   98 +---
 3 files changed, 234 insertions(+), 116 deletions(-)

diff --git a/exa/exa.c b/exa/exa.c
index 496b898..42b664f 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -575,86 +575,164 @@ exaFinishAccess(DrawablePtr pDrawable, int index)
 }
 
 /**
- * exaValidateGC() sets the ops to EXA's implementations, which may be
- * accelerated or may sync the card and fall back to fb.
+ * Here begins EXA's GC code.
+ * Do not ever access the fb/mi layer directly.
  */
+
+static void
+exaValidateGC(GCPtr pGC,
+   unsigned long changes,
+   DrawablePtr pDrawable);
+
+static void
+exaDestroyGC(GCPtr pGC);
+
+static void
+exaChangeGC (GCPtr pGC,
+   unsigned long mask);
+
+static void
+exaCopyGC (GCPtr pGCSrc,
+ unsigned long mask,
+ GCPtr  pGCDst);
+
+static void
+exaChangeClip (GCPtr pGC,
+   int type,
+   pointer pvalue,
+   int nrects);
+
+static void
+exaCopyClip(GCPtr pGCDst, GCPtr pGCSrc);
+
+static void
+exaCopyClip(GCPtr pGCDst, GCPtr pGCSrc);
+
 static void
-exaValidateGC (GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
+exaDestroyClip(GCPtr pGC);
+
+const GCFuncs exaGCFuncs = {
+exaValidateGC,
+exaChangeGC,
+exaCopyGC,
+exaDestroyGC,
+exaChangeClip,
+exaDestroyClip,
+exaCopyClip
+};
+
+/*
+ * This wrapper exists to allow fbValidateGC to work.
+ */
+static PixmapPtr
+exaCreatePixmapWithPrepare(ScreenPtr pScreen, int w, int h, int depth,
+   unsigned usage_hint)
+{
+PixmapPtr pPixmap = exaCreatePixmap(pScreen, w, h, depth, usage_hint);
+
+if (!pPixmap)
+   return NULL;
+
+/* We use MASK, because SRC is already taken. */
+exaPrepareAccess(pPixmap-drawable, EXA_PREPARE_MASK);
+
+return pPixmap;
+}
+
+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.
+ * Do a few smart things so fbValidateGC can do it's work.
  */
-#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;
-   }
-   }
+ScreenPtr pScreen = pDrawable-pScreen;
+CreatePixmapProcPtr old_ptr = NULL;
+PixmapPtr pTile = NULL;
+EXA_GC_PROLOGUE(pGC);
+if (changes  GCTile) {
+   old_ptr = pScreen-CreatePixmap;
+   pScreen-CreatePixmap = exaCreatePixmapWithPrepare;
+   if (pGC-fillStyle == FillTiled)
+   pTile = pGC-tile.pixmap;
+   if (pTile)
+   exaPrepareAccess(pTile-drawable, EXA_PREPARE_SRC);
 }
-#endif
+exaPrepareAccessGC(pGC);
+(*pGC-funcs-ValidateGC)(pGC, changes, pDrawable);
+exaFinishAccessGC(pGC);
 if (changes  GCTile) {
-   if (!pGC-tileIsPixel  FbEvenTile (pGC-tile.pixmap-drawable.width *
-pDrawable-bitsPerPixel))
-   {
-   exaPrepareAccess(pGC-tile.pixmap-drawable, EXA_PREPARE_SRC);
-   fbPadPixmap (pGC-tile.pixmap);
-   exaFinishAccess(pGC-tile.pixmap-drawable, EXA_PREPARE_SRC);
+   pScreen-CreatePixmap = old_ptr;
+   if (pTile)
+   exaFinishAccess(pTile-drawable, EXA_PREPARE_SRC);
+
+   /* A new tile pixmap was created. */
+   if (pGC-tile.pixmap != pTile  pGC-fillStyle == FillTiled) {
+   

[PATCH 4/9] exa: properly wrap GC functions

2009-02-03 Thread Maarten Maathuis
---
 exa/exa.c |  233 +
 exa/exa_priv.h|   33 +++-
 exa/exa_unaccel.c |   98 ---
 3 files changed, 248 insertions(+), 116 deletions(-)

diff --git a/exa/exa.c b/exa/exa.c
index 496b898..58d1a7d 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -575,86 +575,178 @@ exaFinishAccess(DrawablePtr pDrawable, int index)
 }
 
 /**
- * exaValidateGC() sets the ops to EXA's implementations, which may be
- * accelerated or may sync the card and fall back to fb.
+ * Here begins EXA's GC code.
+ * Do not ever access the fb/mi layer directly.
  */
+
+static void
+exaValidateGC(GCPtr pGC,
+   unsigned long changes,
+   DrawablePtr pDrawable);
+
+static void
+exaDestroyGC(GCPtr pGC);
+
+static void
+exaChangeGC (GCPtr pGC,
+   unsigned long mask);
+
+static void
+exaCopyGC (GCPtr pGCSrc,
+ unsigned long mask,
+ GCPtr  pGCDst);
+
+static void
+exaChangeClip (GCPtr pGC,
+   int type,
+   pointer pvalue,
+   int nrects);
+
 static void
-exaValidateGC (GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
+exaCopyClip(GCPtr pGCDst, GCPtr pGCSrc);
+
+static void
+exaCopyClip(GCPtr pGCDst, GCPtr pGCSrc);
+
+static void
+exaDestroyClip(GCPtr pGC);
+
+const GCFuncs exaGCFuncs = {
+exaValidateGC,
+exaChangeGC,
+exaCopyGC,
+exaDestroyGC,
+exaChangeClip,
+exaDestroyClip,
+exaCopyClip
+};
+
+/*
+ * This wrapper exists to allow fbValidateGC to work.
+ */
+static PixmapPtr
+exaCreatePixmapWithPrepare(ScreenPtr pScreen, int w, int h, int depth,
+   unsigned usage_hint)
+{
+PixmapPtr pPixmap;
+ExaScreenPriv(pScreen);
+
+/* This swaps between this function and the real upper layer function.
+ * Normally this would swap to the fb layer pointer, this is a very 
special case.
+ */
+swap(pExaScr, pScreen, CreatePixmap);
+pPixmap = pScreen-CreatePixmap(pScreen, w, h, depth, usage_hint);
+swap(pExaScr, pScreen, CreatePixmap);
+
+if (!pPixmap)
+   return NULL;
+
+/* We use MASK, because SRC is already taken. */
+exaPrepareAccess(pPixmap-drawable, EXA_PREPARE_MASK);
+
+return pPixmap;
+}
+
+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.
+ * Do a few smart things so fbValidateGC can do it's work.
  */
-#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;
-   }
-   }
+ScreenPtr pScreen = pDrawable-pScreen;
+ExaScreenPriv(pScreen);
+CreatePixmapProcPtr old_ptr = NULL;
+PixmapPtr pTile = NULL;
+EXA_GC_PROLOGUE(pGC);
+if (changes  GCTile) {
+   /* save the fb pointer. */
+   old_ptr = pExaScr-SavedCreatePixmap;
+   /* create a new upper layer pointer. */
+   wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmapWithPrepare);
+   if (pGC-fillStyle == FillTiled)
+   pTile = pGC-tile.pixmap;
+   if (pTile)
+   exaPrepareAccess(pTile-drawable, EXA_PREPARE_SRC);
 }
-#endif
+exaPrepareAccessGC(pGC);
+(*pGC-funcs-ValidateGC)(pGC, changes, pDrawable);
+exaFinishAccessGC(pGC);
 if (changes  GCTile) {
-   if (!pGC-tileIsPixel  FbEvenTile (pGC-tile.pixmap-drawable.width *
-