Files
mutter/src/backends/native/gen-default-modes.py
Kai-Heng Feng 8e58aa46ac gen_default_modes: Consider reduced blanking with lower pixelclock
Some panels only support fixed resolutions and fixed refresh rate with reduced blanking:
  Established Timings I & II: none
  Standard Timings: none
  Detailed Timing Descriptors:
    DTD 1:  2560x1600  120.001823 Hz   8:5    203.283 kHz    552.930000 MHz (345 mm x 215 mm)
                 Hfront   48 Hsync  32 Hback   80 Hpol P
                 Vfront    3 Vsync   6 Vback   85 Vpol N
    DTD 2:  2560x1600   48.000295 Hz   8:5     81.312 kHz    221.170000 MHz (345 mm x 215 mm)
                 Hfront   48 Hsync  32 Hback   80 Hpol P
                 Vfront    3 Vsync   6 Vback   85 Vpol N
...
    Minimum Pixel Clock: 552922 kHz
    Maximum Pixel Clock: 552922 kHz

When using mirror mode, resolutions like 2560x1440 120Hz can be too high
to meet the pixelclock limitation, so 2560x1440 90Hz is selected
instead. However, the panel only supports 120Hz so using 90Hz result to
failed mode set.

So add reduced blanking to fallback mode, so correct refresh rate can be
used.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3449>
2024-01-18 12:12:06 +08:00

156 lines
4.4 KiB
Python
Executable File

#!/usr/bin/env python3
# Copyright (C) 2016 Red Hat Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
import os
import sys
import re
if len(sys.argv) != 2:
print("Usage: %s [output file]"%sys.argv[0])
exit(1)
common_resolutions = [
# 4:3
(800, 600),
(1024, 768),
(1152, 864),
(1280, 960),
(1400, 1050),
(1440, 1080),
(1600, 1200),
(1920, 1440),
(2048, 1536),
# 16:10
(1280, 800),
(1440, 900),
(1680, 1050),
(1920, 1200),
(2560, 1600),
# 16:9
(1280, 720),
(1366, 768),
(1600, 900),
(1920, 1080),
(2048, 1152),
(2560, 1440),
(2880, 1620),
(3200, 1800),
(3840, 2160),
(4096, 2304),
(5120, 2880),
]
common_refresh_rates = [
60,
90,
120,
144,
165,
240,
]
output_lines = [
"/* Generated by gen-default-modes.py */\n",
"static const drmModeModeInfo meta_default_landscape_drm_mode_infos[] = {",
]
def sync_flags(hsync, vsync):
flags = "DRM_MODE_FLAG_"
flags += "NHSYNC" if hsync[0] == '-' else "PHSYNC"
flags += " | DRM_MODE_FLAG_"
flags += "NVSYNC" if vsync[0] == '-' else "PVSYNC"
return flags
def drm_mode_info_from_modeline(line):
sline = line.split()
return "{ %d, %d, %d, %d, %d, 0, %d, %d, %d, %d, 0, 0, %s, DRM_MODE_TYPE_DEFAULT, %s }," % \
(int(float(sline[2]) * 1000),
int(sline[3]),
int(sline[4]),
int(sline[5]),
int(sline[6]),
int(sline[7]),
int(sline[8]),
int(sline[9]),
int(sline[10]),
sync_flags(sline[11], sline[12]),
sline[1])
def portrait_drm_mode_info_from_modeline(line):
sline = line.split()
return "{ %d, %d, %d, %d, %d, 0, %d, %d, %d, %d, 0, 0, %s, DRM_MODE_TYPE_DEFAULT, \"%dx%d%s\" }," % \
(int(float(sline[2]) * 1000),
int(sline[7]),
int(sline[8]),
int(sline[9]),
int(sline[10]),
int(sline[3]),
int(sline[4]),
int(sline[5]),
int(sline[6]),
sync_flags(sline[12], sline[11]),
int(sline[7]), int(sline[3]), re.match(r'^"[0-9]+x[0-9]+(.*)"$', sline[1]).group(1))
for resolution in common_resolutions:
for refresh_rate in common_refresh_rates:
cvt = os.popen("%s %s %s %s" % ('cvt', resolution[0], resolution[1], refresh_rate))
cvt.readline() # discard comment line
line = cvt.readline()
cvt.close()
if refresh_rate % 60 == 0:
cvt_rb = os.popen("%s %s %s %s %s" % ('cvt', '-r', resolution[0], resolution[1], refresh_rate))
cvt_rb.readline() # discard comment line
line_rb = cvt_rb.readline()
output_lines.append(drm_mode_info_from_modeline(line_rb))
cvt_rb.close()
output_lines.append(drm_mode_info_from_modeline(line))
output_lines.append("};")
output_lines.append("")
output_lines.append("static const drmModeModeInfo meta_default_portrait_drm_mode_infos[] = {")
for resolution in common_resolutions:
for refresh_rate in common_refresh_rates:
cvt = os.popen("%s %s %s %s" % ('cvt', resolution[0], resolution[1], refresh_rate))
cvt.readline() # discard comment line
line = cvt.readline()
cvt.close()
if refresh_rate % 60 == 0:
cvt_rb = os.popen("%s %s %s %s %s" % ('cvt', '-r', resolution[0], resolution[1], refresh_rate))
cvt_rb.readline() # discard comment line
line_rb = cvt_rb.readline()
output_lines.append(portrait_drm_mode_info_from_modeline(line_rb))
cvt_rb.close()
output_lines.append(portrait_drm_mode_info_from_modeline(line))
output_lines.append("};")
try:
output_file = open(sys.argv[1], 'w')
for line in output_lines:
output_file.write(line + "\n")
output_file.flush()
output_file.close()
except:
print("Failed to generate modelines:", sys.exc_info()[0])
exit(1)