intel_fb: re-evalute max resolution on unplug

On connector unplug the overall resolution of all available active connectors
can shrink and must be considered to potentially re-create the Capture
connection with smaller resolution size. Additionally, update the documentation.

Issue #4531
This commit is contained in:
Alexander Boettcher 2022-06-09 12:48:37 +02:00 committed by Christian Helmuth
parent 88118b133a
commit 80981dbefb
3 changed files with 46 additions and 23 deletions

View File

@ -20,9 +20,14 @@ Each of the connectors can be configured explicitly in terms of resolution and
whether it should be enabled or not. This looks like the following:
! <config>
! <connector name="LVDS-11" width="1280" height="800" hz="60" brightness="75" enabled="true"/>
! <connector name="eDP-1" width="1920" height="1080" hz="60" brightness="75" enabled="true"/>
! <connector name="DP-1" mode_id="2" enabled="true"/>
! </config>
The resolution can be configured exactly by the reported mode_id or by
the width/height/hz attributes. In the latter case the driver will take the
first matching mode out of multiple matching modes potentially.
When the configuration changes during runtime, the driver will adapt to it. In
this case, it will also change the current virtual resolution to the maximum of
the configured resolutions in width and height, and it will inform its client
@ -47,12 +52,18 @@ in the configuration as follows:
The exported report has the following format:
! <connectors>
! <connector name="LVDS-11" connected="1" brightness="50">
! <mode width="1280" height="800" hz="60"/>
! <connector name="eDP-1" connected="true" brightness="50">
! <mode width="1920" height="1080" hz="60" mode_id="1" preferred="true"/>
! ...
! </connector>
! <connector name="DP-1" connected="true">
! <mode width="1920" height="1200" hz="60" mode_id="1" preferred="true"/>
! <mode width="1920" height="1080" hz="60" mode_id="2"/>
! <mode width="1280" height="1024" hz="60" mode_id="3"/>
! <mode width="1024" height="768" hz="60" mode_id="4"/>
! ...
! </connector>
! <connector name="HDMI-A-1" connected="false"/>
! <connector name="DP-1" connected="false"/>
! </connectors>
The brightness attribute is reported only if the hardware supports it.

View File

@ -50,7 +50,25 @@ static void preferred_mode(struct drm_display_mode *prefer)
/* check for connector configuration on Genode side */
lx_emul_i915_connector_config(connector->name, &conf_mode);
if (!conf_mode.enabled || !conf_mode.width || !conf_mode.height)
if (!conf_mode.enabled)
continue;
if (conf_mode.id) {
unsigned mode_id = 0;
list_for_each_entry(mode, &connector->modes, head) {
mode_id ++;
if (!mode || conf_mode.id != mode_id)
continue;
conf_mode.width = mode->hdisplay;
conf_mode.height = mode->vdisplay;
break;
}
}
if (!conf_mode.width || !conf_mode.height)
continue;
if (conf_mode.width * conf_mode.height > prefer->hdisplay * prefer->vdisplay) {
@ -154,6 +172,10 @@ static bool reconfigure(void * data)
/* data is adjusted if virtual resolution is not same size as physical fb */
report_fb_info = *i915_fb()->fbdev;
if (mode_preferred.hdisplay && mode_preferred.vdisplay) {
report_fb_info.var.xres_virtual = mode_preferred.hdisplay;
report_fb_info.var.yres_virtual = mode_preferred.vdisplay;
}
drm_client_for_each_modeset(mode_set, &(i915_fb()->client)) {
struct drm_display_mode *mode_match = NULL;
@ -182,7 +204,10 @@ static bool reconfigure(void * data)
continue;
/* use mode id if configured and matches exactly */
if (conf_mode.id && (conf_mode.id == mode_id)) {
if (conf_mode.id) {
if (conf_mode.id != mode_id)
continue;
mode_match = mode;
break;
}
@ -225,16 +250,9 @@ static bool reconfigure(void * data)
if (!mode_match) {
/* use first mode */
mode_match = mode;
/* set up preferred resolution as virtual, if nothing is enforced */
if (!conf_mode.preferred &&
mode_preferred.hdisplay &&
mode_preferred.vdisplay) {
conf_mode.preferred = 1;
conf_mode.width = mode_preferred.hdisplay;
conf_mode.height = mode_preferred.vdisplay;
}
no_match = mode->hdisplay != conf_mode.width ||
mode->vdisplay != conf_mode.height;
if (conf_mode.enabled)
no_match = true;
}
if (mode_match != mode)
@ -267,12 +285,6 @@ static bool reconfigure(void * data)
retry = true;
else {
report_fb = true;
/* report forced resolution */
if (conf_mode.preferred) {
report_fb_info.var.xres_virtual = conf_mode.width;
report_fb_info.var.yres_virtual = conf_mode.height;
}
}
}

View File

@ -79,7 +79,7 @@ void Framebuffer_controller::_update_connector_config(Xml_generator & xml,
w = mode.attribute_value<unsigned long>("width", 0);
h = mode.attribute_value<unsigned long>("height", 0);
z = mode.attribute_value<unsigned long>("hz", 0);
if (w >= width) {
if (w * h >= width * height) {
width = w;
height = h;
if (z > hz)