Module Name:    xsrc
Committed By:   macallan
Date:           Tue Feb 18 12:17:20 UTC 2025

Modified Files:
        xsrc/external/mit/xf86-video-ngle/dist/src: summit_accel.c

Log Message:
use the hardware to draw anti-aliased text
visible speedup
The problem is that HP didn't implement full alpha blending support on the FX4,
just what's needed to draw anti-aliased lines and edges, and no upper byte in
32bit buffers, which means we can't have anything with alpha in video memory
but we can apply alpha blending when scribbling into video memory using BINC,
therefore we do *not* want out glyph sources in VRAM...


To generate a diff of this commit:
cvs rdiff -u -r1.6 -r1.7 \
    xsrc/external/mit/xf86-video-ngle/dist/src/summit_accel.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: xsrc/external/mit/xf86-video-ngle/dist/src/summit_accel.c
diff -u xsrc/external/mit/xf86-video-ngle/dist/src/summit_accel.c:1.6 xsrc/external/mit/xf86-video-ngle/dist/src/summit_accel.c:1.7
--- xsrc/external/mit/xf86-video-ngle/dist/src/summit_accel.c:1.6	Sun Jan 26 05:38:38 2025
+++ xsrc/external/mit/xf86-video-ngle/dist/src/summit_accel.c	Tue Feb 18 12:17:20 2025
@@ -21,16 +21,23 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
-/* $NetBSD: summit_accel.c,v 1.6 2025/01/26 05:38:38 macallan Exp $ */
+/* $NetBSD: summit_accel.c,v 1.7 2025/02/18 12:17:20 macallan Exp $ */
 
 #include <sys/types.h>
 #include <dev/ic/summitreg.h>
 
 
 #include "ngle.h"
+#include "mipict.h"
 
 //#define DEBUG
 
+void
+ exaPrepareAccess(DrawablePtr pDrawable, int index);
+
+void
+ exaFinishAccess(DrawablePtr pDrawable, int index);
+
 #ifdef DEBUG
 #define ENTER xf86Msg(X_ERROR, "%s\n", __func__)
 #define LEAVE xf86Msg(X_ERROR, "%s done\n", __func__)
@@ -253,14 +260,18 @@ SummitUploadToScreen(PixmapPtr pDst, int
 	int	ofs =  exaGetPixmapOffset(pDst);
 	int i;
 	uint32_t *line, mode = OTC01 | BIN8F | BUFFL;
+	uint8_t *dst;
 
 	ENTER;
-
 	y += (ofs >> 13);	/* pitch is 8192 bytes in 24 bit */
 	if (y >= fPtr->fbi.fbi_height) {
 		mode = OTC01 | BIN8F | BUFBL;
 		y -= fPtr->fbi.fbi_height;
 	}
+
+	dst = fPtr->fbmem;
+	dst += (y << 13) + (x << 2);
+
 	SUMMIT_WRITE_MODE(mode);
 	NGLEWrite4(fPtr, VISFX_PLANE_MASK, 0xffffffff);
 	NGLEWrite4(fPtr, VISFX_FOE, 0);
@@ -277,9 +288,14 @@ SummitUploadToScreen(PixmapPtr pDst, int
 
 		for (i = 0; i < w; i++)
 			NGLEWrite4(fPtr, VISFX_VRAM_WRITE_DATA_INCRX, line[i]);
+		//memcpy(dst, src, w << 2);
 		src += src_pitch;
+		dst += 8192;
 		y++;
 	}
+
+	LEAVE;
+
 	return TRUE;
 }
 
@@ -294,6 +310,7 @@ SummitDownloadFromScreen(PixmapPtr pSrc,
 	uint32_t mode = OTC01 | BIN8F | BUFFL;
 
 	ENTER;
+
 	y += (ofs >> 13);
 	if (y >= fPtr->fbi.fbi_height) {
 		mode = OTC01 | BIN8F | BUFBL;
@@ -313,6 +330,8 @@ SummitDownloadFromScreen(PixmapPtr pSrc,
 		dst += dst_pitch;
 	}
 
+	LEAVE;
+
 	return TRUE;
 }
 
@@ -325,6 +344,7 @@ SummitPrepareAccess(PixmapPtr pPixmap, i
 	int	y;
 
 	ENTER;
+	//xf86Msg(X_ERROR, "%s %d\n", __func__, ofs);
 	if (ofs == 0) {
 		/* accessing the visible framebuffer */
 		SUMMIT_READ_MODE(OTC01 | BIN8F | BUFFL);
@@ -337,6 +357,7 @@ SummitPrepareAccess(PixmapPtr pPixmap, i
 		pPixmap->devPrivate.ptr = fPtr->fbmem + (y << 13);
 	}
 	NGLEWrite4(fPtr, VISFX_FOE, 0);
+	NGLEWrite4(fPtr, VISFX_RPH, VISFX_RPH_LTR);
 	//NGLEWrite4(fPtr, VISFX_CONTROL, 0x200);
 	SummitWait(fPtr);
 	LEAVE;
@@ -351,16 +372,231 @@ SummitFinishAccess(PixmapPtr pPixmap, in
 
 	ENTER;
 	//NGLEWrite4(fPtr, VISFX_CONTROL, 0);
+	//SummitWait(fPtr);
 	LEAVE;
 }
 
+PixmapPtr
+SummitGetDrawablePixmap(DrawablePtr pDrawable)
+{
+    if (pDrawable->type == DRAWABLE_WINDOW)
+        return pDrawable->pScreen->GetWindowPixmap((WindowPtr) pDrawable);
+    else
+        return (PixmapPtr) pDrawable;
+}
+
+static void
+SummitDrawGlyph8(NGLEPtr fPtr, int32_t fg, PixmapPtr mask, int p,
+    int xm, int ym, int xd, int yd, int w, int h)
+{
+	uint8_t *gdata = mask->devPrivate.ptr;
+	uint32_t msk;
+	int i, j;
+
+	gdata += xm;
+	gdata += (p * ym);
+	for (i = 0; i < h; i++) {
+		SummitWaitFifo(fPtr, w * 2);
+		NGLEWrite4(fPtr, VISFX_VRAM_WRITE_DEST, 
+		    ((yd + i) << 16) | xd);
+		for (j = 0; j < w; j++) {
+			msk = gdata[j];
+			msk = (msk << 24) | fg;
+			NGLEWrite4(fPtr,
+			    VISFX_VRAM_WRITE_DATA_INCRX, msk);	
+		}
+		gdata += p;
+	}
+}
+
+static void
+SummitDrawGlyph32(NGLEPtr fPtr, uint32_t fg, PixmapPtr mask, int p,
+    int xm, int ym, int xd, int yd, int w, int h)
+{
+	uint32_t *gdata = mask->devPrivate.ptr;
+	uint32_t msk;
+	int i, j;
+
+	gdata += xm;
+	gdata += (p * ym);
+
+	for (i = 0; i < h; i++) {
+		SummitWaitFifo(fPtr, w * 2);
+		NGLEWrite4(fPtr, VISFX_VRAM_WRITE_DEST, 
+		    ((yd + i) << 16) | xd);
+		for (j = 0; j < w; j++) {
+			msk = gdata[j];
+			msk = (msk & 0xff000000) | fg;
+			NGLEWrite4(fPtr,
+			    VISFX_VRAM_WRITE_DATA_INCRX, msk);	
+		}
+		gdata += p >> 2;
+	}
+}
+
+static void
+SummitGlyphs (CARD8	op,
+	  PicturePtr	pSrc,
+	  PicturePtr	pDst,
+	  PictFormatPtr	maskFormat,
+	  INT16		xSrc,
+	  INT16		ySrc,
+	  int		nlist,
+	  GlyphListPtr	list,
+	  GlyphPtr	*glyphs)
+{
+	ScreenPtr	pScreen = pDst->pDrawable->pScreen;
+	ScrnInfoPtr 	pScrn = xf86Screens[pScreen->myNum];
+	NGLEPtr 	fPtr = NGLEPTR(pScrn);
+	PicturePtr	pPicture;
+	PixmapPtr	mask, dst;
+	GlyphPtr	glyph;
+	int		xDst = list->xOff, yDst = list->yOff;
+	int		x = 0, y = 0, i, n, ofs, p, j, wi, he;
+	uint32_t fg = 0xffffffff, msk;
+
+	if (op != PictOpOver) goto fallback;
+
+	if (!exaDrawableIsOffscreen(pDst->pDrawable)) goto fallback;
+
+	dst = SummitGetDrawablePixmap(pDst->pDrawable);
+	ofs = exaGetPixmapOffset(dst);
+	ofs = ofs >> 13;
+
+	if (pDst->pDrawable->type == DRAWABLE_WINDOW) {
+		x += pDst->pDrawable->x;
+		y += pDst->pDrawable->y;
+	}
+
+	if (pSrc->pSourcePict != NULL) {
+		if (pSrc->pSourcePict->type == SourcePictTypeSolidFill) {
+			fg = pSrc->pSourcePict->solidFill.color;
+		}
+	}
+	fg &= 0x00ffffff;
+
+	if (ofs == 0) {
+		/* accessing the visible framebuffer */
+		SUMMIT_WRITE_MODE(OTC01 | BIN8F | BUFFL);
+	} else {
+		SUMMIT_WRITE_MODE(OTC01 | BIN8F | BUFBL);
+	}
+
+	SummitWaitFifo(fPtr, 4);
+	NGLEWrite4(fPtr, VISFX_FOE, FOE_BLEND_ROP);
+	NGLEWrite4(fPtr, VISFX_IBO,
+	    IBO_ADD | SRC(IBO_SRC) | DST(IBO_ONE_MINUS_SRC));
+
+	while (nlist--)     {
+		x += list->xOff;
+		y += list->yOff;
+		n = list->len;
+		while (n--) {
+			glyph = *glyphs++;
+			pPicture = GlyphPicture (glyph)[pScreen->myNum];
+			if (pPicture) {
+				int xd = x - glyph->info.x;
+				int yd = y - glyph->info.y;
+				RegionRec region;
+				BoxPtr pbox;
+				int nbox;
+
+				if (ofs == 0) {
+					/*
+					 * we're drawing to the visible screen,
+					 * so we must take care not to scribble
+					 * over other windows
+					 */
+					if (!miComputeCompositeRegion(&region,
+					  pSrc, pPicture, pDst,
+                        	          0, 0, 0, 0, xd, yd,
+                        	          glyph->info.width,
+                        	          glyph->info.height))
+						goto skip;
+
+					fbGetDrawablePixmap(pPicture->pDrawable,
+					    mask, wi, he);
+					exaPrepareAccess(pPicture->pDrawable,
+					    EXA_PREPARE_SRC);
+					p = exaGetPixmapPitch(mask);
+
+					nbox = RegionNumRects(&region);
+					pbox = RegionRects(&region);
+					while (nbox--) {
+						if (pPicture->format == PICT_a8) {
+							SummitDrawGlyph8(fPtr,
+							    fg, mask, p,
+							    pbox->x1 - xd,
+							    pbox->y1 - yd,
+							    pbox->x1, pbox->y1,
+							    pbox->x2 - pbox->x1,
+							    pbox->y2 - pbox->y1);
+						} else {
+							SummitDrawGlyph32(fPtr,
+							    fg, mask, p,
+							    pbox->x1 - xd,
+							    pbox->y1 - yd,
+							    pbox->x1, pbox->y1,
+							    pbox->x2 - pbox->x1,
+							    pbox->y2 - pbox->y1);
+						}
+        					pbox++;
+    					}
+					RegionUninit(&region);
+					exaFinishAccess(pPicture->pDrawable,
+					    EXA_PREPARE_SRC);
+				} else {
+					/*
+					 * drawing into off-screen memory, we
+					 * only need to clip to the destination
+					 * pixmap's boundaries
+					 */
+					yd += (ofs - fPtr->fbi.fbi_height);
+
+					fbGetDrawablePixmap(pPicture->pDrawable,
+					    mask, wi, he);
+					exaPrepareAccess(pPicture->pDrawable,
+					    EXA_PREPARE_SRC);
+					p = exaGetPixmapPitch(mask);
+
+					if (pPicture->format == PICT_a8) {
+						SummitDrawGlyph8(fPtr,
+						    fg, mask, p,
+						    0, 0,
+						    xd, yd, 
+						    glyph->info.width,
+						    glyph->info.height);
+					} else {
+						SummitDrawGlyph32(fPtr,
+						    fg, mask, p,
+						    0, 0,
+						    xd, yd, 
+						    glyph->info.width,
+						    glyph->info.height);
+					}
+					exaFinishAccess(pPicture->pDrawable,
+					    EXA_PREPARE_SRC);
+				}
+			}
+skip:
+			x += glyph->info.xOff;
+			y += glyph->info.yOff;
+		}
+		list++;
+	}
+	return;	
+fallback:
+	fPtr->glyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
+}
+
 Bool
 SummitInitAccel(ScreenPtr pScreen)
 {
 	ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+	PictureScreenPtr ps = GetPictureScreen(pScreen);
 	NGLEPtr fPtr = NGLEPTR(pScrn);
 	ExaDriverPtr pExa;
-	int bpp = pScrn->bitsPerPixel >> 3;
+	int bpp = pScrn->bitsPerPixel >> 3, ret;
 
 	pExa = exaDriverAlloc();
 	if (!pExa)
@@ -402,5 +638,9 @@ SummitInitAccel(ScreenPtr pScreen)
 	NGLEWrite4(fPtr, VISFX_IBO, GXcopy);
 	NGLEWrite4(fPtr, VISFX_CONTROL, 0);
 
-	return exaDriverInit(pScreen, pExa);
+	ret = exaDriverInit(pScreen, pExa);
+
+	fPtr->glyphs = ps->Glyphs;
+	ps->Glyphs = SummitGlyphs;
+	return ret;
 }

Reply via email to