Module Name: xsrc
Committed By: martin
Date: Sat Feb 3 11:49:31 UTC 2024
Modified Files:
xsrc/external/mit/xf86-video-wsfb/dist/src [netbsd-10]: wsfb.h
wsfb_driver.c
Log Message:
Pull up following revision(s) (requested by jmcneill in ticket #562):
external/mit/xf86-video-wsfb/dist/src/wsfb_driver.c: revision 1.48
external/mit/xf86-video-wsfb/dist/src/wsfb.h: revision 1.11
xf86-video-wsfb: Add support for Nintendo Wii
The Wii's framebuffer is YUY2, so add a custom shadowproc that converts
from RGB565 to YUY2 on the fly.
To generate a diff of this commit:
cvs rdiff -u -r1.10 -r1.10.2.1 \
xsrc/external/mit/xf86-video-wsfb/dist/src/wsfb.h
cvs rdiff -u -r1.47 -r1.47.2.1 \
xsrc/external/mit/xf86-video-wsfb/dist/src/wsfb_driver.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-wsfb/dist/src/wsfb.h
diff -u xsrc/external/mit/xf86-video-wsfb/dist/src/wsfb.h:1.10 xsrc/external/mit/xf86-video-wsfb/dist/src/wsfb.h:1.10.2.1
--- xsrc/external/mit/xf86-video-wsfb/dist/src/wsfb.h:1.10 Sat Sep 10 19:23:03 2022
+++ xsrc/external/mit/xf86-video-wsfb/dist/src/wsfb.h Sat Feb 3 11:49:31 2024
@@ -73,6 +73,7 @@ typedef struct {
void * shadow;
Bool HWCursor;
Bool useSwap32;
+ Bool useRGB16ToYUY2;
#ifdef HAVE_SHADOW_AFB
Bool planarAfb;
#endif
Index: xsrc/external/mit/xf86-video-wsfb/dist/src/wsfb_driver.c
diff -u xsrc/external/mit/xf86-video-wsfb/dist/src/wsfb_driver.c:1.47 xsrc/external/mit/xf86-video-wsfb/dist/src/wsfb_driver.c:1.47.2.1
--- xsrc/external/mit/xf86-video-wsfb/dist/src/wsfb_driver.c:1.47 Sat Sep 10 19:25:44 2022
+++ xsrc/external/mit/xf86-video-wsfb/dist/src/wsfb_driver.c Sat Feb 3 11:49:31 2024
@@ -133,6 +133,7 @@ static void WsfbDGASetViewport(ScrnInfoP
static Bool WsfbDGAInit(ScrnInfoPtr, ScreenPtr);
#endif
+static void WsfbShadowUpdateRGB16ToYUY2(ScreenPtr, shadowBufPtr);
static void WsfbShadowUpdateSwap32(ScreenPtr, shadowBufPtr);
static void WsfbShadowUpdateSplit(ScreenPtr, shadowBufPtr);
@@ -154,6 +155,13 @@ enum { WSFB_ROTATE_NONE = 0,
*/
static int pix24bpp = 0;
+/*
+ * Screen-independent lookup table for RGB16 to YUV conversions.
+ */
+static unsigned char *mapRGB16ToY = NULL;
+static unsigned char *mapRGB16ToU = NULL;
+static unsigned char *mapRGB16ToV = NULL;
+
#define WSFB_VERSION 4000
#define WSFB_NAME "wsfb"
#define WSFB_DRIVER_NAME "wsfb"
@@ -610,6 +618,25 @@ WsfbPreInit(ScrnInfoPtr pScrn, int flags
fPtr->shadowFB = TRUE;
}
}
+
+ fPtr->useRGB16ToYUY2 = FALSE;
+#ifdef WSDISPLAY_TYPE_HOLLYWOOD
+ if (wstype == WSDISPLAY_TYPE_HOLLYWOOD) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Enabling RGB16->YUY2 conversion for Hollywood\n");
+ fPtr->useRGB16ToYUY2 = TRUE;
+ if (!fPtr->shadowFB) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Shadow FB forced on for RGB16->YUY2 conversion\n");
+ fPtr->shadowFB = TRUE;
+ }
+ /*
+ * Hollywood has a YUY2 framebuffer, but we treat it as
+ * RGB565 and convert with a custom shadowproc.
+ */
+ fPtr->fbi.fbi_pixeltype = WSFB_RGB;
+ }
+#endif
/* Rotation */
fPtr->rotate = WSFB_ROTATE_NONE;
if ((s = xf86GetOptValString(fPtr->Options, OPTION_ROTATE))) {
@@ -823,6 +850,35 @@ WsfbCreateScreenResources(ScreenPtr pScr
pPixmap = pScreen->GetScreenPixmap(pScreen);
if (fPtr->fbi.fbi_flags & WSFB_VRAM_IS_SPLIT) {
shadowproc = WsfbShadowUpdateSplit;
+ } else if (fPtr->useRGB16ToYUY2) {
+ /* Build RGB16 to Y, U, and V lookup tables */
+ if (mapRGB16ToY == NULL) {
+ mapRGB16ToY = malloc(0x30000);
+ if (mapRGB16ToY == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Cannot malloc %d bytes for RGB16->YUY2\n",
+ 0x30000);
+ return FALSE;
+ }
+ mapRGB16ToU = mapRGB16ToY + 0x10000;
+ mapRGB16ToV = mapRGB16ToY + 0x20000;
+ for (unsigned int n = 0; n < 0x10000; n++) {
+ /* RGB565 values, scaled to 8 bits */
+ const double R = (((n >> 11) & 0x1f) * 255) / 31;
+ const double G = (((n >> 5) & 0x3f) * 255) / 63;
+ const double B = (((n >> 0) & 0x1f) * 255) / 31;
+
+ /* Convert to YUV */
+ mapRGB16ToY[n] =
+ 0.257 * R + 0.504 * G + 0.098 * B + 16;
+ mapRGB16ToU[n] =
+ -0.148 * R - 0.291 * G + 0.439 * B + 128;
+ mapRGB16ToV[n] =
+ 0.439 * R - 0.368 * G - 0.071 * B + 128;
+ }
+ }
+
+ shadowproc = WsfbShadowUpdateRGB16ToYUY2;
} else if (fPtr->useSwap32) {
shadowproc = WsfbShadowUpdateSwap32;
} else if (fPtr->rotate) {
@@ -1682,6 +1738,101 @@ WsfbDriverFunc(ScrnInfoPtr pScrn, xorgDr
}
static inline void
+WsfbCopyRGB16ToYUY2(void *dest, void *src, int len)
+{
+ uint16_t *src16 = src;
+ uint32_t *dest32 = dest;
+
+ while (len > 0) {
+ const uint16_t rgb0 = src16[0];
+ const uint16_t rgb1 = src16[1];
+ const uint16_t rgb = ((rgb0 >> 1) & ~0x8410) +
+ ((rgb1 >> 1) & ~0x8410) +
+ ((rgb0 & rgb1) & 0x0841);
+ const uint32_t y0 = mapRGB16ToY[rgb0];
+ const uint32_t y1 = mapRGB16ToY[rgb1];
+ const uint32_t u = mapRGB16ToU[rgb];
+ const uint32_t v = mapRGB16ToV[rgb];
+
+ *dest32 = (y0 << 24) | (u << 16) | (y1 << 8) | v;
+
+ dest32++;
+ src16 += 2;
+ len -= 4;
+ }
+}
+
+void
+WsfbShadowUpdateRGB16ToYUY2(ScreenPtr pScreen, shadowBufPtr pBuf)
+{
+ RegionPtr damage = DamageRegion (pBuf->pDamage);
+ PixmapPtr pShadow = pBuf->pPixmap;
+ int nbox = RegionNumRects (damage);
+ BoxPtr pbox = RegionRects (damage);
+ FbBits *shaBase, *shaLine, *sha;
+ FbStride shaStride;
+ int scrBase, scrLine, scr;
+ int shaBpp;
+ int shaXoff, shaYoff; /* XXX assumed to be zero */
+ int x, y, w, h, width;
+ int i;
+ FbBits *winBase = NULL, *win;
+ CARD32 winSize;
+
+ fbGetDrawable (&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff, shaYoff);
+ while (nbox--)
+ {
+ x = pbox->x1 * shaBpp;
+ y = pbox->y1;
+ w = (pbox->x2 - pbox->x1) * shaBpp;
+ h = pbox->y2 - pbox->y1;
+
+ scrLine = (x >> FB_SHIFT);
+ shaLine = shaBase + y * shaStride + (x >> FB_SHIFT);
+
+ x &= FB_MASK;
+ w = (w + x + FB_MASK) >> FB_SHIFT;
+
+ while (h--)
+ {
+ winSize = 0;
+ scrBase = 0;
+ width = w;
+ scr = scrLine;
+ sha = shaLine;
+ while (width) {
+ /* how much remains in this window */
+ i = scrBase + winSize - scr;
+ if (i <= 0 || scr < scrBase)
+ {
+ winBase = (FbBits *) (*pBuf->window) (pScreen,
+ y,
+ scr * sizeof (FbBits),
+ SHADOW_WINDOW_WRITE,
+ &winSize,
+ pBuf->closure);
+ if(!winBase)
+ return;
+ scrBase = scr;
+ winSize /= sizeof (FbBits);
+ i = winSize;
+ }
+ win = winBase + (scr - scrBase);
+ if (i > width)
+ i = width;
+ width -= i;
+ scr += i;
+ WsfbCopyRGB16ToYUY2(win, sha, i * sizeof(FbBits));
+ sha += i;
+ }
+ shaLine += shaStride;
+ y++;
+ }
+ pbox++;
+ }
+}
+
+static inline void
memcpy32sw(void *dest, void *src, int len)
{
uint32_t *d = dest, *s = src;