xwayland: Use libxcvt
Xwayland is using a copy of the CVT generator found in Xorg. Rather than duplicating the code within the xserver tree, use the libxcvt implementation instead. Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1142 Signed-off-by: Olivier Fourdan <ofourdan@redhat.com> Reviewed-by: Matt Turner <mattst88@gmail.com>
This commit is contained in:
		
							parent
							
								
									a4ab57cb74
								
							
						
					
					
						commit
						6ea2c001f9
					
				|  | @ -12,7 +12,8 @@ Xwayland_CFLAGS =				\ | |||
| 	$(XWAYLANDMODULES_CFLAGS)		\
 | ||||
| 	$(DIX_CFLAGS)				\
 | ||||
| 	$(GLAMOR_CFLAGS)			\
 | ||||
| 	$(GBM_CFLAGS) | ||||
| 	$(GBM_CFLAGS)				\
 | ||||
| 	$(LIBXCVT_CFLAGS) | ||||
| 
 | ||||
| Xwayland_SOURCES =				\
 | ||||
| 	xwayland.c				\
 | ||||
|  | @ -60,7 +61,8 @@ Xwayland_LDADD =				\ | |||
| 	$(GLXVND_LIB)				\
 | ||||
| 	$(XWAYLAND_SYS_LIBS)			\
 | ||||
| 	$(top_builddir)/Xext/libXvidmode.la	\
 | ||||
| 	$(XSERVER_SYS_LIBS) | ||||
| 	$(XSERVER_SYS_LIBS)			\
 | ||||
| 	$(LIBXCVT_LIBS) | ||||
| Xwayland_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG) | ||||
| 
 | ||||
| Xwayland_built_sources = | ||||
|  |  | |||
|  | @ -1,8 +1,6 @@ | |||
| /* Copied from hw/xfree86/modes/xf86cvt.c into xwayland DDX and
 | ||||
|  * changed to generate an RRMode */ | ||||
| 
 | ||||
| /*
 | ||||
|  * Copyright 2005-2006 Luc Verhaegen. | ||||
|  * Copyright © 2021 Red Hat, Inc. | ||||
|  * | ||||
|  * Permission is hereby granted, free of charge, to any person obtaining a | ||||
|  * copy of this software and associated documentation files (the "Software"), | ||||
|  | @ -23,284 +21,38 @@ | |||
|  * OTHER DEALINGS IN THE SOFTWARE. | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  * The reason for having this function in a file of its own is | ||||
|  * so that ../utils/cvt/cvt can link to it, and that xf86CVTMode | ||||
|  * code is shared directly. | ||||
|  */ | ||||
| 
 | ||||
| #include <xwayland-config.h> | ||||
| 
 | ||||
| #include <string.h> | ||||
| #include <randrstr.h> | ||||
| #include <libxcvt/libxcvt.h> | ||||
| 
 | ||||
| #include "xwayland-cvt.h" | ||||
| 
 | ||||
| /*
 | ||||
|  * Generate a CVT standard mode from HDisplay, VDisplay and VRefresh. | ||||
|  * | ||||
|  * These calculations are stolen from the CVT calculation spreadsheet written | ||||
|  * by Graham Loveridge. He seems to be claiming no copyright and there seems to | ||||
|  * be no license attached to this. He apparently just wants to see his name | ||||
|  * mentioned. | ||||
|  * | ||||
|  * This file can be found at http://www.vesa.org/Public/CVT/CVTd6r1.xls
 | ||||
|  * | ||||
|  * Comments and structure corresponds to the comments and structure of the xls. | ||||
|  * This should ease importing of future changes to the standard (not very | ||||
|  * likely though). | ||||
|  * | ||||
|  * About margins; i'm sure that they are to be the bit between HDisplay and | ||||
|  * HBlankStart, HBlankEnd and HTotal, VDisplay and VBlankStart, VBlankEnd and | ||||
|  * VTotal, where the overscan colour is shown. FB seems to call _all_ blanking | ||||
|  * outside sync "margin" for some reason. Since we prefer seeing proper | ||||
|  * blanking instead of the overscan colour, and since the Crtc* values will | ||||
|  * probably get altered after us, we will disable margins altogether. With | ||||
|  * these calculations, Margins will plainly expand H/VDisplay, and we don't | ||||
|  * want that. -- libv | ||||
|  * | ||||
|  */ | ||||
| RRModePtr | ||||
| xwayland_cvt(int HDisplay, int VDisplay, float VRefresh, Bool Reduced, | ||||
|              Bool Interlaced) | ||||
| xwayland_cvt(int hdisplay, int vdisplay, float vrefresh, Bool reduced, | ||||
|              Bool interlaced) | ||||
| { | ||||
|     /* 1) top/bottom margin size (% of height) - default: 1.8 */ | ||||
| #define CVT_MARGIN_PERCENTAGE 1.8 | ||||
| 
 | ||||
|     /* 2) character cell horizontal granularity (pixels) - default 8 */ | ||||
| #define CVT_H_GRANULARITY 8 | ||||
| 
 | ||||
|     /* 4) Minimum vertical porch (lines) - default 3 */ | ||||
| #define CVT_MIN_V_PORCH 3 | ||||
| 
 | ||||
|     /* 4) Minimum number of vertical back porch lines - default 6 */ | ||||
| #define CVT_MIN_V_BPORCH 6 | ||||
| 
 | ||||
|     /* Pixel Clock step (kHz) */ | ||||
| #define CVT_CLOCK_STEP 250 | ||||
| 
 | ||||
|     Bool Margins = FALSE; | ||||
|     float VFieldRate, HPeriod; | ||||
|     int HDisplayRnd, HMargin; | ||||
|     int VDisplayRnd, VMargin, VSync; | ||||
|     float Interlace;            /* Please rename this */ | ||||
|     struct libxcvt_mode_info *libxcvt_mode_info; | ||||
|     char name[128]; | ||||
|     xRRModeInfo modeinfo; | ||||
| 
 | ||||
|     libxcvt_mode_info = | ||||
|         libxcvt_gen_mode_info(hdisplay, vdisplay, vrefresh, reduced, interlaced); | ||||
| 
 | ||||
|     memset(&modeinfo, 0, sizeof modeinfo); | ||||
|     modeinfo.width      = libxcvt_mode_info->hdisplay; | ||||
|     modeinfo.height     = libxcvt_mode_info->vdisplay; | ||||
|     modeinfo.dotClock   = libxcvt_mode_info->dot_clock * 1000.0; | ||||
|     modeinfo.hSyncStart = libxcvt_mode_info->hsync_start; | ||||
|     modeinfo.hSyncEnd   = libxcvt_mode_info->hsync_end; | ||||
|     modeinfo.hTotal     = libxcvt_mode_info->htotal; | ||||
|     modeinfo.vSyncStart = libxcvt_mode_info->vsync_start; | ||||
|     modeinfo.vSyncEnd   = libxcvt_mode_info->vsync_end; | ||||
|     modeinfo.vTotal     = libxcvt_mode_info->vtotal; | ||||
|     modeinfo.modeFlags  = libxcvt_mode_info->mode_flags; | ||||
| 
 | ||||
|     /* CVT default is 60.0Hz */ | ||||
|     if (!VRefresh) | ||||
|         VRefresh = 60.0; | ||||
| 
 | ||||
|     /* 1. Required field rate */ | ||||
|     if (Interlaced) | ||||
|         VFieldRate = VRefresh * 2; | ||||
|     else | ||||
|         VFieldRate = VRefresh; | ||||
| 
 | ||||
|     /* 2. Horizontal pixels */ | ||||
|     HDisplayRnd = HDisplay - (HDisplay % CVT_H_GRANULARITY); | ||||
| 
 | ||||
|     /* 3. Determine left and right borders */ | ||||
|     if (Margins) { | ||||
|         /* right margin is actually exactly the same as left */ | ||||
|         HMargin = (((float) HDisplayRnd) * CVT_MARGIN_PERCENTAGE / 100.0); | ||||
|         HMargin -= HMargin % CVT_H_GRANULARITY; | ||||
|     } | ||||
|     else | ||||
|         HMargin = 0; | ||||
| 
 | ||||
|     /* 4. Find total active pixels */ | ||||
|     modeinfo.width = HDisplayRnd + 2 * HMargin; | ||||
| 
 | ||||
|     /* 5. Find number of lines per field */ | ||||
|     if (Interlaced) | ||||
|         VDisplayRnd = VDisplay / 2; | ||||
|     else | ||||
|         VDisplayRnd = VDisplay; | ||||
| 
 | ||||
|     /* 6. Find top and bottom margins */ | ||||
|     /* nope. */ | ||||
|     if (Margins) | ||||
|         /* top and bottom margins are equal again. */ | ||||
|         VMargin = (((float) VDisplayRnd) * CVT_MARGIN_PERCENTAGE / 100.0); | ||||
|     else | ||||
|         VMargin = 0; | ||||
| 
 | ||||
|     modeinfo.height = VDisplay + 2 * VMargin; | ||||
| 
 | ||||
|     /* 7. Interlace */ | ||||
|     if (Interlaced) | ||||
|         Interlace = 0.5; | ||||
|     else | ||||
|         Interlace = 0.0; | ||||
| 
 | ||||
|     /* Determine VSync Width from aspect ratio */ | ||||
|     if (!(VDisplay % 3) && ((VDisplay * 4 / 3) == HDisplay)) | ||||
|         VSync = 4; | ||||
|     else if (!(VDisplay % 9) && ((VDisplay * 16 / 9) == HDisplay)) | ||||
|         VSync = 5; | ||||
|     else if (!(VDisplay % 10) && ((VDisplay * 16 / 10) == HDisplay)) | ||||
|         VSync = 6; | ||||
|     else if (!(VDisplay % 4) && ((VDisplay * 5 / 4) == HDisplay)) | ||||
|         VSync = 7; | ||||
|     else if (!(VDisplay % 9) && ((VDisplay * 15 / 9) == HDisplay)) | ||||
|         VSync = 7; | ||||
|     else                        /* Custom */ | ||||
|         VSync = 10; | ||||
| 
 | ||||
|     if (!Reduced) {             /* simplified GTF calculation */ | ||||
| 
 | ||||
|         /* 4) Minimum time of vertical sync + back porch interval (µs)
 | ||||
|          * default 550.0 */ | ||||
| #define CVT_MIN_VSYNC_BP 550.0 | ||||
| 
 | ||||
|         /* 3) Nominal HSync width (% of line period) - default 8 */ | ||||
| #define CVT_HSYNC_PERCENTAGE 8 | ||||
| 
 | ||||
|         float HBlankPercentage; | ||||
|         int VSyncAndBackPorch, VBackPorch; | ||||
|         int HBlank; | ||||
| 
 | ||||
|         /* 8. Estimated Horizontal period */ | ||||
|         HPeriod = ((float) (1000000.0 / VFieldRate - CVT_MIN_VSYNC_BP)) / | ||||
|             (VDisplayRnd + 2 * VMargin + CVT_MIN_V_PORCH + Interlace); | ||||
| 
 | ||||
|         /* 9. Find number of lines in sync + backporch */ | ||||
|         if (((int) (CVT_MIN_VSYNC_BP / HPeriod) + 1) < | ||||
|             (VSync + CVT_MIN_V_PORCH)) | ||||
|             VSyncAndBackPorch = VSync + CVT_MIN_V_PORCH; | ||||
|         else | ||||
|             VSyncAndBackPorch = (int) (CVT_MIN_VSYNC_BP / HPeriod) + 1; | ||||
| 
 | ||||
|         /* 10. Find number of lines in back porch */ | ||||
|         VBackPorch = VSyncAndBackPorch - VSync; | ||||
|         (void) VBackPorch; | ||||
| 
 | ||||
|         /* 11. Find total number of lines in vertical field */ | ||||
|         modeinfo.vTotal = | ||||
|             VDisplayRnd + 2 * VMargin + VSyncAndBackPorch + Interlace + | ||||
|             CVT_MIN_V_PORCH; | ||||
| 
 | ||||
|         /* 5) Definition of Horizontal blanking time limitation */ | ||||
|         /* Gradient (%/kHz) - default 600 */ | ||||
| #define CVT_M_FACTOR 600 | ||||
| 
 | ||||
|         /* Offset (%) - default 40 */ | ||||
| #define CVT_C_FACTOR 40 | ||||
| 
 | ||||
|         /* Blanking time scaling factor - default 128 */ | ||||
| #define CVT_K_FACTOR 128 | ||||
| 
 | ||||
|         /* Scaling factor weighting - default 20 */ | ||||
| #define CVT_J_FACTOR 20 | ||||
| 
 | ||||
| #define CVT_M_PRIME CVT_M_FACTOR * CVT_K_FACTOR / 256 | ||||
| #define CVT_C_PRIME (CVT_C_FACTOR - CVT_J_FACTOR) * CVT_K_FACTOR / 256 + \ | ||||
|         CVT_J_FACTOR | ||||
| 
 | ||||
|         /* 12. Find ideal blanking duty cycle from formula */ | ||||
|         HBlankPercentage = CVT_C_PRIME - CVT_M_PRIME * HPeriod / 1000.0; | ||||
| 
 | ||||
|         /* 13. Blanking time */ | ||||
|         if (HBlankPercentage < 20) | ||||
|             HBlankPercentage = 20; | ||||
| 
 | ||||
|         HBlank = modeinfo.width * HBlankPercentage / (100.0 - HBlankPercentage); | ||||
|         HBlank -= HBlank % (2 * CVT_H_GRANULARITY); | ||||
| 
 | ||||
|         /* 14. Find total number of pixels in a line. */ | ||||
|         modeinfo.hTotal = modeinfo.width + HBlank; | ||||
| 
 | ||||
|         /* Fill in HSync values */ | ||||
|         modeinfo.hSyncEnd = modeinfo.width + HBlank / 2; | ||||
| 
 | ||||
|         modeinfo.hSyncStart = modeinfo.hSyncEnd - | ||||
|             (modeinfo.hTotal * CVT_HSYNC_PERCENTAGE) / 100; | ||||
|         modeinfo.hSyncStart += CVT_H_GRANULARITY - | ||||
|             modeinfo.hSyncStart % CVT_H_GRANULARITY; | ||||
| 
 | ||||
|         /* Fill in VSync values */ | ||||
|         modeinfo.vSyncStart = modeinfo.height + CVT_MIN_V_PORCH; | ||||
|         modeinfo.vSyncEnd = modeinfo.vSyncStart + VSync; | ||||
| 
 | ||||
|     } | ||||
|     else {                      /* Reduced blanking */ | ||||
|         /* Minimum vertical blanking interval time (µs) - default 460 */ | ||||
| #define CVT_RB_MIN_VBLANK 460.0 | ||||
| 
 | ||||
|         /* Fixed number of clocks for horizontal sync */ | ||||
| #define CVT_RB_H_SYNC 32.0 | ||||
| 
 | ||||
|         /* Fixed number of clocks for horizontal blanking */ | ||||
| #define CVT_RB_H_BLANK 160.0 | ||||
| 
 | ||||
|         /* Fixed number of lines for vertical front porch - default 3 */ | ||||
| #define CVT_RB_VFPORCH 3 | ||||
| 
 | ||||
|         int VBILines; | ||||
| 
 | ||||
|         /* 8. Estimate Horizontal period. */ | ||||
|         HPeriod = ((float) (1000000.0 / VFieldRate - CVT_RB_MIN_VBLANK)) / | ||||
|             (VDisplayRnd + 2 * VMargin); | ||||
| 
 | ||||
|         /* 9. Find number of lines in vertical blanking */ | ||||
|         VBILines = ((float) CVT_RB_MIN_VBLANK) / HPeriod + 1; | ||||
| 
 | ||||
|         /* 10. Check if vertical blanking is sufficient */ | ||||
|         if (VBILines < (CVT_RB_VFPORCH + VSync + CVT_MIN_V_BPORCH)) | ||||
|             VBILines = CVT_RB_VFPORCH + VSync + CVT_MIN_V_BPORCH; | ||||
| 
 | ||||
|         /* 11. Find total number of lines in vertical field */ | ||||
|         modeinfo.vTotal = VDisplayRnd + 2 * VMargin + Interlace + VBILines; | ||||
| 
 | ||||
|         /* 12. Find total number of pixels in a line */ | ||||
|         modeinfo.hTotal = modeinfo.width + CVT_RB_H_BLANK; | ||||
| 
 | ||||
|         /* Fill in HSync values */ | ||||
|         modeinfo.hSyncEnd = modeinfo.width + CVT_RB_H_BLANK / 2; | ||||
|         modeinfo.hSyncStart = modeinfo.hSyncEnd - CVT_RB_H_SYNC; | ||||
| 
 | ||||
|         /* Fill in VSync values */ | ||||
|         modeinfo.vSyncStart = modeinfo.height + CVT_RB_VFPORCH; | ||||
|         modeinfo.vSyncEnd = modeinfo.vSyncStart + VSync; | ||||
|     } | ||||
| 
 | ||||
|     /* 15/13. Find pixel clock frequency (kHz for xf86) */ | ||||
|     modeinfo.dotClock = modeinfo.hTotal * 1000.0 / HPeriod; | ||||
|     modeinfo.dotClock -= modeinfo.dotClock % CVT_CLOCK_STEP; | ||||
|     modeinfo.dotClock *= 1000.0; | ||||
| #if 0 | ||||
|     /* 16/14. Find actual Horizontal Frequency (kHz) */ | ||||
|     modeinfo.hSync = ((float) modeinfo.dotClock) / ((float) modeinfo.hTotal); | ||||
| #endif | ||||
| 
 | ||||
| #if 0 | ||||
|     /* 17/15. Find actual Field rate */ | ||||
|     modeinfo.vRefresh = (1000.0 * ((float) modeinfo.dotClock)) / | ||||
|         ((float) (modeinfo.hTotal * modeinfo.vTotal)); | ||||
| #endif | ||||
| 
 | ||||
|     /* 18/16. Find actual vertical frame frequency */ | ||||
|     /* ignore - just set the mode flag for interlaced */ | ||||
|     if (Interlaced) | ||||
|         modeinfo.vTotal *= 2; | ||||
| 
 | ||||
|     if (Reduced) | ||||
|         modeinfo.modeFlags |= RR_HSyncPositive | RR_VSyncNegative; | ||||
|     else | ||||
|         modeinfo.modeFlags |= RR_HSyncNegative | RR_VSyncPositive; | ||||
| 
 | ||||
|     if (Interlaced) | ||||
|         modeinfo.modeFlags |= RR_Interlace; | ||||
| 
 | ||||
|     /* FWXGA hack adapted from hw/xfree86/modes/xf86EdidModes.c, because you can't say 1366 */ | ||||
|     if (HDisplay == 1366 && VDisplay == 768) { | ||||
|          modeinfo.width = 1366; | ||||
|          modeinfo.hSyncStart--; | ||||
|          modeinfo.hSyncEnd--; | ||||
|     } | ||||
|     free(libxcvt_mode_info); | ||||
| 
 | ||||
|     snprintf(name, sizeof name, "%dx%d", | ||||
|              modeinfo.width, modeinfo.height); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue