mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	backend/drm: fix state for outputs loosing their CRTC
When there aren't enough CRTCs for all outputs, we try to move a CRTC from a disabled output to an enabled one. When this happens, the old output's state wasn't changed, so the compositor thought it was still enabled and rendering. This commit marks the old output as WLR_DRM_CONN_NEEDS_MODESET and sets its current mode to NULL.
This commit is contained in:
		
							parent
							
								
									3e21d0bd48
								
							
						
					
					
						commit
						d4ffa5b7a6
					
				
					 2 changed files with 20 additions and 5 deletions
				
			
		| 
						 | 
					@ -391,6 +391,8 @@ static void attempt_enable_needs_modeset(struct wlr_drm_backend *drm) {
 | 
				
			||||||
		if (conn->state == WLR_DRM_CONN_NEEDS_MODESET &&
 | 
							if (conn->state == WLR_DRM_CONN_NEEDS_MODESET &&
 | 
				
			||||||
				conn->crtc != NULL && conn->desired_mode != NULL &&
 | 
									conn->crtc != NULL && conn->desired_mode != NULL &&
 | 
				
			||||||
				conn->desired_enabled) {
 | 
									conn->desired_enabled) {
 | 
				
			||||||
 | 
								wlr_log(WLR_DEBUG, "Output %s has a desired mode and a CRTC, "
 | 
				
			||||||
 | 
									"attempting a modeset", conn->output.name);
 | 
				
			||||||
			drm_connector_set_mode(&conn->output, conn->desired_mode);
 | 
								drm_connector_set_mode(&conn->output, conn->desired_mode);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -637,7 +639,7 @@ static bool drm_connector_set_cursor(struct wlr_output *output,
 | 
				
			||||||
		plane->surf.height, output->transform);
 | 
							plane->surf.height, output->transform);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wlr_box hotspot = { .x = hotspot_x, .y = hotspot_y };
 | 
						struct wlr_box hotspot = { .x = hotspot_x, .y = hotspot_y };
 | 
				
			||||||
	wlr_box_transform(&hotspot, &hotspot, 
 | 
						wlr_box_transform(&hotspot, &hotspot,
 | 
				
			||||||
		wlr_output_transform_invert(output->transform),
 | 
							wlr_output_transform_invert(output->transform),
 | 
				
			||||||
		plane->surf.width, plane->surf.height);
 | 
							plane->surf.width, plane->surf.height);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -981,8 +983,17 @@ static void realloc_crtcs(struct wlr_drm_backend *drm, bool *changed_outputs) {
 | 
				
			||||||
		i++;
 | 
							i++;
 | 
				
			||||||
		struct wlr_output_mode *mode = conn->output.current_mode;
 | 
							struct wlr_output_mode *mode = conn->output.current_mode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (conn->state != WLR_DRM_CONN_CONNECTED || !changed_outputs[i]
 | 
							if (conn->state != WLR_DRM_CONN_CONNECTED || !changed_outputs[i]) {
 | 
				
			||||||
				|| conn->crtc == NULL) {
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (conn->crtc == NULL) {
 | 
				
			||||||
 | 
								wlr_log(WLR_DEBUG, "Output has %s lost its CRTC",
 | 
				
			||||||
 | 
									conn->output.name);
 | 
				
			||||||
 | 
								conn->state = WLR_DRM_CONN_NEEDS_MODESET;
 | 
				
			||||||
 | 
								wlr_output_update_enabled(&conn->output, false);
 | 
				
			||||||
 | 
								conn->desired_mode = conn->output.current_mode;
 | 
				
			||||||
 | 
								wlr_output_update_mode(&conn->output, NULL);
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -173,8 +173,12 @@ bool wlr_output_set_custom_mode(struct wlr_output *output, int32_t width,
 | 
				
			||||||
void wlr_output_update_mode(struct wlr_output *output,
 | 
					void wlr_output_update_mode(struct wlr_output *output,
 | 
				
			||||||
		struct wlr_output_mode *mode) {
 | 
							struct wlr_output_mode *mode) {
 | 
				
			||||||
	output->current_mode = mode;
 | 
						output->current_mode = mode;
 | 
				
			||||||
	wlr_output_update_custom_mode(output, mode->width, mode->height,
 | 
						if (mode != NULL) {
 | 
				
			||||||
		mode->refresh);
 | 
							wlr_output_update_custom_mode(output, mode->width, mode->height,
 | 
				
			||||||
 | 
								mode->refresh);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							wlr_output_update_custom_mode(output, 0, 0, 0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void wlr_output_update_custom_mode(struct wlr_output *output, int32_t width,
 | 
					void wlr_output_update_custom_mode(struct wlr_output *output, int32_t width,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue