Hi, I've been trying to hack X to mirror an output on axis, such that the left and right halves of the screen show the same thing.
My patch is attached to this email. The plan is to create a pixmap with half width and use it as a buffer for all dix operations, then copy it to another pixmap that is mapped to the front_bo in the dispatch loop. But it didn't work, for no apparent reason. Only the left of the screen is showing the client while the other halve is black. To my suprise, the same result was produced even when I commented out the call to copy to the left halve of the screen. I'd be very glad if anyone have an idea about what I missed. Thanks you. qwerjkl
diff --git a/dix/dispatch.c b/dix/dispatch.c index 176c7a0..0fc1244 100644 --- a/dix/dispatch.c +++ b/dix/dispatch.c @@ -399,6 +399,24 @@ DisableLimitedSchedulingLatency(void) SmartScheduleLatencyLimited = 0; } +/* EDIT function to copy pixmap twice */ +void +pixcopy(void) +{ + PixmapPtr p1 = (PixmapPtr) (screenInfo.screens[0]->devPrivate); + PixmapPtr p2 = (PixmapPtr) (screenInfo.screens[0]->devPrivate2); + uint32_t *pm1 = (uint32_t *) p1->devPrivate.ptr; + uint32_t *pm2 = (uint32_t *) p2->devPrivate.ptr; + int stride1 = (int) (p1->devKind) >> 2; + int stride2 = (int) (p2->devKind) >> 2; + int bpp1 = (int) (p1->drawable.bitsPerPixel); + int bpp2 = (int) (p2->drawable.bitsPerPixel); + int height = (int) p1->drawable.height; + int width = (int) p1->drawable.width; + pixman_blt (pm1, pm2, stride1, stride2, bpp1, bpp2, 0, 0, 0, 0, width, height); + pixman_blt (pm1, pm2, stride1, stride2, bpp1, bpp2, 0, 0, width, 0, width, height); +} + void Dispatch(void) { @@ -413,6 +431,7 @@ Dispatch(void) init_client_ready(); while (!dispatchException) { + pixcopy(); if (InputCheckPending()) { ProcessInputEvents(); FlushIfCriticalOutputPending(); diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c index 8d29b13..124cdff 100644 --- a/hw/xfree86/drivers/modesetting/driver.c +++ b/hw/xfree86/drivers/modesetting/driver.c @@ -1335,6 +1335,10 @@ CreateScreenResources(ScreenPtr pScreen) rrScrPrivPtr pScrPriv = rrGetScrPriv(pScreen); modesettingPtr ms = modesettingPTR(pScrn); PixmapPtr rootPixmap; + + /* EDIT add rootPixmap2 */ + PixmapPtr rootPixmap2; + Bool ret; void *pixels = NULL; int err; @@ -1360,7 +1364,10 @@ CreateScreenResources(ScreenPtr pScreen) return FALSE; } - rootPixmap = pScreen->GetScreenPixmap(pScreen); + rootPixmap = pScreen->GetScreenPixmap(pScreen); + + /* EDIT add rootPixmap2 as devPrivate2*/ + rootPixmap2 = (PixmapPtr) (pScreen->devPrivate2); if (ms->drmmode.shadow_enable) pixels = ms->drmmode.shadow_fb; @@ -1371,7 +1378,8 @@ CreateScreenResources(ScreenPtr pScreen) ms->drmmode.shadow_enable2 = FALSE; } - if (!pScreen->ModifyPixmapHeader(rootPixmap, -1, -1, -1, -1, -1, pixels)) + /* EDIT map BO to devPrivate2*/ + if (!pScreen->ModifyPixmapHeader(rootPixmap2, -1, -1, -1, -1, -1, pixels)) FatalError("Couldn't adjust screen pixmap\n"); if (ms->drmmode.shadow_enable) { diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c index 336f768..73e512c 100644 --- a/hw/xfree86/drivers/modesetting/drmmode_display.c +++ b/hw/xfree86/drivers/modesetting/drmmode_display.c @@ -3129,6 +3129,16 @@ drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height) xf86DrvMsg(scrn->scrnIndex, X_INFO, "Allocate new frame buffer %dx%d stride\n", width, height); + /* EDIT skip all if no change size + * XXX what about resolution really is changed?*/ + if (scrn->virtualX == (width << 1)) { + pitch = drmmode_bo_get_pitch(&drmmode->front_bo); + scrn->virtualX = width; + scrn->virtualY = height; + scrn->displayWidth = pitch / kcpp; + return TRUE; + } + old_width = scrn->virtualX; old_height = scrn->virtualY; old_pitch = drmmode_bo_get_pitch(&drmmode->front_bo); diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c index 34f2652..8c53e8b 100644 --- a/hw/xfree86/modes/xf86RandR12.c +++ b/hw/xfree86/modes/xf86RandR12.c @@ -823,6 +823,10 @@ xf86RandR12CreateScreenResources(ScreenPtr pScreen) * We have to pre-set it here, otherwise panning would be adapted * to the new screen size. */ + /* EDIT start halve width and mmWidth */ + width = width >> 1; + mmWidth = mmWidth >> 1; + pScreen->width = width; pScreen->height = height; xf86RandR12ScreenSetSize(pScreen, width, height, mmWidth, mmHeight); diff --git a/include/scrnintstr.h b/include/scrnintstr.h index 9b663fa..72c557b 100644 --- a/include/scrnintstr.h +++ b/include/scrnintstr.h @@ -513,6 +513,8 @@ typedef struct _Screen { */ PixmapPtr defaultStipple; void *devPrivate; + /* EDIT *ScreenPtr add devPrivate2 */ + void *devPrivate2; short numVisuals; VisualPtr visuals; WindowPtr root; diff --git a/mi/miscrinit.c b/mi/miscrinit.c index 9c6af0d..bb00bc3 100644 --- a/mi/miscrinit.c +++ b/mi/miscrinit.c @@ -137,6 +137,9 @@ miCreateScreenResources(ScreenPtr pScreen) miScreenInitParmsPtr pScrInitParms; void *value; + /* EDIT miCreateScreenResources value2 */ + void *value2; + pScrInitParms = (miScreenInitParmsPtr) pScreen->devPrivate; /* if width is non-zero, pScreen->devPrivate will be a pixmap @@ -145,11 +148,19 @@ miCreateScreenResources(ScreenPtr pScreen) if (pScrInitParms->width) { PixmapPtr pPixmap; + /* EDIT miCreateScreenResources pPixmap2 */ + PixmapPtr pPixmap2; + /* create a pixmap with no data, then redirect it to point to * the screen */ pPixmap = (*pScreen->CreatePixmap) (pScreen, 0, 0, pScreen->rootDepth, 0); + + /* EDIT miCreateScreenResources allocate pPixmap2 */ + pPixmap2 = + (*pScreen->CreatePixmap) (pScreen, (pScreen->width) >> 1, pScreen->height, pScreen->rootDepth, 0); + if (!pPixmap) return FALSE; @@ -159,15 +170,32 @@ miCreateScreenResources(ScreenPtr pScreen) BitsPerPixel(pScreen->rootDepth), PixmapBytePad(pScrInitParms->width, pScreen->rootDepth), - pScrInitParms->pbits)) + pScrInitParms->pbits) + + /* EDIT miCreateScreenResources init bpp pbp */ + && !(*pScreen->ModifyPixmapHeader) (pPixmap2, (pScreen->width) >> 1, + pScreen->height, + pScreen->rootDepth, + BitsPerPixel(pScreen->rootDepth), + PixmapBytePad((pScrInitParms->width) >> 1, + pScreen->rootDepth), + 0)) return FALSE; value = (void *) pPixmap; + + /* EDIT temp value2 store */ + value2 = (void *) pPixmap2; } else { value = pScrInitParms->pbits; } free(pScreen->devPrivate); /* freeing miScreenInitParmsRec */ - pScreen->devPrivate = value; /* pPixmap or pbits */ + + /* EDIT insert devPrivate allocated pixmap */ + pScreen->devPrivate = value2; /* pPixmap or pbits */ + + /* EDIT insert devPrivate2 empty pixmap */ + pScreen->devPrivate2 = value; return TRUE; }
_______________________________________________ xorg@lists.x.org: X.Org support Archives: http://lists.freedesktop.org/archives/xorg Info: https://lists.x.org/mailman/listinfo/xorg Your subscription address: %(user_address)s