[PATCH xf86-video-dummy 6/6] Support RandR 1.2

Aaron Plattner aplattner at nvidia.com
Sat Jan 24 17:08:13 PST 2015


Don't bother creating RandR outputs or creating or validating modes.
Instead, just invent a dummy DisplayModeRec for the current screen
size.

Plug in a RandR framebuffer resize hook to allow resizing the screen.
Update the screen pixmap, ScrnInfo structure, and dummy mode when that
happens.

Dispense with the pScrn->videoRam field.  Instead, use the Virtual
size from the Display subsection of the Screen section.  If that's not
set, default to something reasonable by today's standards.

Based on an idea by Nicolas Boichat <drinkcat at chromium.org>
(http://lists.x.org/archives/xorg-devel/2014-November/044580.html)

Signed-off-by: Aaron Plattner <aplattner at nvidia.com>
---
 src/dummy_driver.c | 166 ++++++++++++++++++++++-------------------------------
 1 file changed, 70 insertions(+), 96 deletions(-)

diff --git a/src/dummy_driver.c b/src/dummy_driver.c
index 8262f39f2563..48956ef72b50 100644
--- a/src/dummy_driver.c
+++ b/src/dummy_driver.c
@@ -22,8 +22,7 @@
 #include "property.h"
 
 #include "xf86cmap.h"
-
-#include "xf86fbman.h"
+#include "xf86Crtc.h"
 
 #include "fb.h"
 
@@ -71,9 +70,6 @@ static Bool	dummyDriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op,
 #define DUMMY_MINOR_VERSION PACKAGE_VERSION_MINOR
 #define DUMMY_PATCHLEVEL PACKAGE_VERSION_PATCHLEVEL
 
-#define DUMMY_MAX_WIDTH 32767
-#define DUMMY_MAX_HEIGHT 32767
-
 /*
  * This is intentionally screen-independent.  It indicates the binding
  * choice made in the first PreInit.
@@ -165,6 +161,55 @@ dummySetup(pointer module, pointer opts, int *errmaj, int *errmin)
 
 #endif /* XFree86LOADER */
 
+/*
+ * Build a DisplayModeRec that matches the screen's dimensions.
+ *
+ * Make up a fake pixel clock so that applications that use the VidMode
+ * extension to query the "refresh rate" get 60 Hz.
+ */
+static void ConstructFakeDisplayMode(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+    mode->HDisplay = mode->HSyncStart = mode->HSyncEnd = mode->HTotal =
+        pScrn->virtualX;
+    mode->VDisplay = mode->VSyncStart = mode->VSyncEnd = mode->VTotal =
+        pScrn->virtualY;
+    mode->Clock = mode->HTotal * mode->VTotal * 60 / 1000;
+
+    xf86SetCrtcForModes(pScrn, 0);
+}
+
+static Bool
+dummy_xf86crtc_resize(ScrnInfoPtr pScrn, int width, int height)
+{
+    ScreenPtr pScreen = pScrn->pScreen;
+    PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
+    int newPitch = width * (pScrn->bitsPerPixel / 8);
+    void *oldScreen = rootPixmap->devPrivate.ptr;
+    void *newScreen = calloc(newPitch, height);
+
+    if (!newScreen)
+        return FALSE;
+
+    if (!pScreen->ModifyPixmapHeader(rootPixmap, width, height,
+                                     -1, -1, newPitch, newScreen)) {
+        free(newScreen);
+        return FALSE;
+    }
+
+    free(oldScreen);
+
+    pScrn->virtualX = width;
+    pScrn->virtualY = height;
+    pScrn->displayWidth = width;
+    ConstructFakeDisplayMode(pScrn, pScrn->modes);
+
+    return TRUE;
+}
+
+static const xf86CrtcConfigFuncsRec dummy_xf86crtc_config_funcs = {
+    dummy_xf86crtc_resize
+};
+
 static Bool
 DUMMYGetRec(ScrnInfoPtr pScrn)
 {
@@ -266,10 +311,7 @@ DUMMYProbe(DriverPtr drv, int flags)
 Bool
 DUMMYPreInit(ScrnInfoPtr pScrn, int flags)
 {
-    ClockRangePtr clockRanges;
-    int i;
     DUMMYPtr dPtr;
-    int maxClock = 230000;
     GDevPtr device = xf86GetEntityInfo(pScrn->entityList[0])->device;
 
     if (flags & PROBE_DETECT) 
@@ -351,80 +393,26 @@ DUMMYPreInit(ScrnInfoPtr pScrn, int flags)
 
     xf86GetOptValBool(dPtr->Options, OPTION_SW_CURSOR,&dPtr->swCursor);
 
-    if (device->videoRam != 0) {
-	pScrn->videoRam = device->videoRam;
-	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "VideoRAM: %d kByte\n",
-		   pScrn->videoRam);
-    } else {
-	pScrn->videoRam = 4096;
-	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VideoRAM: %d kByte\n",
-		   pScrn->videoRam);
-    }
-    
-    if (device->dacSpeeds[0] != 0) {
-	maxClock = device->dacSpeeds[0];
-	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Max Clock: %d kHz\n",
-		   maxClock);
-    } else {
-	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Max Clock: %d kHz\n",
-		   maxClock);
-    }
-
-    pScrn->progClock = TRUE;
-    /*
-     * Setup the ClockRanges, which describe what clock ranges are available,
-     * and what sort of modes they can be used for.
-     */
-    clockRanges = (ClockRangePtr)xnfcalloc(sizeof(ClockRange), 1);
-    clockRanges->next = NULL;
-    clockRanges->ClockMulFactor = 1;
-    clockRanges->minClock = 11000;   /* guessed ยงยงยง */
-    clockRanges->maxClock = 300000;
-    clockRanges->clockIndex = -1;		/* programmable */
-    clockRanges->interlaceAllowed = TRUE; 
-    clockRanges->doubleScanAllowed = TRUE;
-
-    /* Subtract memory for HW cursor */
-
-
-    {
-	int apertureSize = (pScrn->videoRam * 1024);
-	i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
-			      pScrn->display->modes, clockRanges,
-			      NULL, 256, DUMMY_MAX_WIDTH,
-			      (8 * pScrn->bitsPerPixel),
-			      128, DUMMY_MAX_HEIGHT, pScrn->display->virtualX,
-			      pScrn->display->virtualY, apertureSize,
-			      LOOKUP_BEST_REFRESH);
-
-       if (i == -1)
-           RETURN;
-    }
-
-    /* Prune the modes marked as invalid */
-    xf86PruneDriverModes(pScrn);
+    xf86CrtcConfigInit(pScrn, &dummy_xf86crtc_config_funcs);
+    xf86CrtcSetSizeRange(pScrn, 8, 8, SHRT_MAX, SHRT_MAX);
 
-    if (i == 0 || pScrn->modes == NULL) {
-	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
-	RETURN;
+    /* Pick up size from the "Display" subsection if it exists */
+    if (pScrn->display->virtualX) {
+        pScrn->virtualX = pScrn->display->virtualX;
+        pScrn->virtualY = pScrn->display->virtualY;
+    } else {
+        /* Pick a "modern" screen resolution */
+        pScrn->virtualX = 3840;
+        pScrn->virtualY = 2160;
     }
+    pScrn->displayWidth = pScrn->virtualX;
 
-    /*
-     * Set the CRTC parameters for all of the modes based on the type
-     * of mode, and the chipset's interlace requirements.
-     *
-     * Calling this is required if the mode->Crtc* values are used by the
-     * driver and if the driver doesn't provide code to set them.  They
-     * are not pre-initialised at all.
-     */
-    xf86SetCrtcForModes(pScrn, 0); 
- 
-    /* Set the current mode to the first in the list */
+    /* Construct a mode with the screen's initial dimensions */
+    pScrn->modes = calloc(sizeof(DisplayModeRec), 1);
+    ConstructFakeDisplayMode(pScrn, pScrn->modes);
+    pScrn->modes->next = pScrn->modes->prev = pScrn->modes;
     pScrn->currentMode = pScrn->modes;
 
-    /* Print the list of modes being used */
-    xf86PrintModes(pScrn);
-
     /* If monitor resolution is set on the command line, use it */
     xf86SetDpi(pScrn, 0, 0);
 
@@ -515,8 +503,8 @@ DUMMYScreenInit(SCREEN_INIT_ARGS_DECL)
     dPtr = DUMMYPTR(pScrn);
     DUMMYScrn = pScrn;
 
-
-    if (!(pixels = malloc(pScrn->videoRam * 1024)))
+    if (!(pixels = malloc(pScrn->displayWidth * pScrn->bitsPerPixel * 8 *
+                          pScrn->virtualY)))
 	return FALSE;
     
     DUMMYAdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0));
@@ -569,23 +557,6 @@ DUMMYScreenInit(SCREEN_INIT_ARGS_DECL)
     if (dPtr->swCursor)
 	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using Software Cursor.\n");
 
-    {
-
-	 
-	BoxRec AvailFBArea;
-	int lines = pScrn->videoRam * 1024 /
-	    (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3));
-	AvailFBArea.x1 = 0;
-	AvailFBArea.y1 = 0;
-	AvailFBArea.x2 = pScrn->displayWidth;
-	AvailFBArea.y2 = lines;
-	xf86InitFBManager(pScreen, &AvailFBArea); 
-	
-	xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
-		   "Using %i scanlines of offscreen memory \n"
-		   , lines - pScrn->virtualY);
-    }
-
     xf86SetBackingStore(pScreen);
     xf86SetSilkenMouse(pScreen);
 	
@@ -612,6 +583,9 @@ DUMMYScreenInit(SCREEN_INIT_ARGS_DECL)
 			     | CMAP_RELOAD_ON_MODE_SWITCH))
 	return FALSE;
 
+    if (!xf86CrtcScreenInit(pScreen))
+        return FALSE;
+
     pScreen->SaveScreen = DUMMYSaveScreen;
 
     
-- 
2.2.2



More information about the xorg-devel mailing list