mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	backend/drm: init wlr_drm_plane for all plane types
This commit is contained in:
		
							parent
							
								
									c3d969d2d4
								
							
						
					
					
						commit
						b4e9487312
					
				
					 2 changed files with 50 additions and 71 deletions
				
			
		| 
						 | 
					@ -104,21 +104,23 @@ bool check_drm_features(struct wlr_drm_backend *drm) {
 | 
				
			||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool add_plane(struct wlr_drm_backend *drm,
 | 
					static bool init_plane(struct wlr_drm_backend *drm,
 | 
				
			||||||
		struct wlr_drm_crtc *crtc, const drmModePlane *drm_plane,
 | 
							struct wlr_drm_plane *p, const drmModePlane *drm_plane) {
 | 
				
			||||||
		uint32_t type, union wlr_drm_plane_props *props) {
 | 
						uint32_t id = drm_plane->plane_id;
 | 
				
			||||||
	assert(!(type == DRM_PLANE_TYPE_PRIMARY && crtc->primary));
 | 
					 | 
				
			||||||
	assert(!(type == DRM_PLANE_TYPE_CURSOR && crtc->cursor));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wlr_drm_plane *p = calloc(1, sizeof(*p));
 | 
						union wlr_drm_plane_props props = {0};
 | 
				
			||||||
	if (!p) {
 | 
						if (!get_drm_plane_props(drm->fd, id, &props)) {
 | 
				
			||||||
		wlr_log_errno(WLR_ERROR, "Allocation failed");
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint64_t type;
 | 
				
			||||||
 | 
						if (!get_drm_prop(drm->fd, id, props.type, &type)) {
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	p->type = type;
 | 
						p->type = type;
 | 
				
			||||||
	p->id = drm_plane->plane_id;
 | 
						p->id = drm_plane->plane_id;
 | 
				
			||||||
	p->props = *props;
 | 
						p->props = props;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (size_t i = 0; i < drm_plane->count_formats; ++i) {
 | 
						for (size_t i = 0; i < drm_plane->count_formats; ++i) {
 | 
				
			||||||
		// Force a LINEAR layout for the cursor if the driver doesn't support
 | 
							// Force a LINEAR layout for the cursor if the driver doesn't support
 | 
				
			||||||
| 
						 | 
					@ -152,15 +154,22 @@ static bool add_plane(struct wlr_drm_backend *drm,
 | 
				
			||||||
		drmModeFreePropertyBlob(blob);
 | 
							drmModeFreePropertyBlob(blob);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (type) {
 | 
						assert(drm->num_crtcs <= 32);
 | 
				
			||||||
	case DRM_PLANE_TYPE_PRIMARY:
 | 
						for (size_t j = 0; j < drm->num_crtcs; j++) {
 | 
				
			||||||
 | 
							uint32_t crtc_bit = 1 << j;
 | 
				
			||||||
 | 
							if ((drm_plane->possible_crtcs & crtc_bit) == 0) {
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							struct wlr_drm_crtc *crtc = &drm->crtcs[j];
 | 
				
			||||||
 | 
							if (type == DRM_PLANE_TYPE_PRIMARY && !crtc->primary) {
 | 
				
			||||||
			crtc->primary = p;
 | 
								crtc->primary = p;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
	case DRM_PLANE_TYPE_CURSOR:
 | 
							}
 | 
				
			||||||
 | 
							if (type == DRM_PLANE_TYPE_CURSOR && !crtc->cursor) {
 | 
				
			||||||
			crtc->cursor = p;
 | 
								crtc->cursor = p;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
	default:
 | 
							}
 | 
				
			||||||
		abort();
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return true;
 | 
						return true;
 | 
				
			||||||
| 
						 | 
					@ -179,66 +188,35 @@ static bool init_planes(struct wlr_drm_backend *drm) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wlr_log(WLR_INFO, "Found %"PRIu32" DRM planes", plane_res->count_planes);
 | 
						wlr_log(WLR_INFO, "Found %"PRIu32" DRM planes", plane_res->count_planes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						drm->num_planes = plane_res->count_planes;
 | 
				
			||||||
 | 
						drm->planes = calloc(drm->num_planes, sizeof(*drm->planes));
 | 
				
			||||||
 | 
						if (drm->planes == NULL) {
 | 
				
			||||||
 | 
							wlr_log_errno(WLR_ERROR, "Allocation failed");
 | 
				
			||||||
 | 
							goto error;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (uint32_t i = 0; i < plane_res->count_planes; ++i) {
 | 
						for (uint32_t i = 0; i < plane_res->count_planes; ++i) {
 | 
				
			||||||
		uint32_t id = plane_res->planes[i];
 | 
							uint32_t id = plane_res->planes[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		drmModePlane *plane = drmModeGetPlane(drm->fd, id);
 | 
							drmModePlane *drm_plane = drmModeGetPlane(drm->fd, id);
 | 
				
			||||||
		if (!plane) {
 | 
							if (!drm_plane) {
 | 
				
			||||||
			wlr_log_errno(WLR_ERROR, "Failed to get DRM plane");
 | 
								wlr_log_errno(WLR_ERROR, "Failed to get DRM plane");
 | 
				
			||||||
			goto error;
 | 
								goto error;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		union wlr_drm_plane_props props = {0};
 | 
							struct wlr_drm_plane *plane = &drm->planes[i];
 | 
				
			||||||
		if (!get_drm_plane_props(drm->fd, id, &props)) {
 | 
							if (!init_plane(drm, plane, drm_plane)) {
 | 
				
			||||||
			drmModeFreePlane(plane);
 | 
					 | 
				
			||||||
			goto error;
 | 
								goto error;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		uint64_t type;
 | 
							drmModeFreePlane(drm_plane);
 | 
				
			||||||
		if (!get_drm_prop(drm->fd, id, props.type, &type)) {
 | 
					 | 
				
			||||||
			drmModeFreePlane(plane);
 | 
					 | 
				
			||||||
			goto error;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// We don't really care about overlay planes, as we don't support them
 | 
					 | 
				
			||||||
		// yet.
 | 
					 | 
				
			||||||
		if (type == DRM_PLANE_TYPE_OVERLAY) {
 | 
					 | 
				
			||||||
			drmModeFreePlane(plane);
 | 
					 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		assert(drm->num_crtcs <= 32);
 | 
					 | 
				
			||||||
		struct wlr_drm_crtc *crtc = NULL;
 | 
					 | 
				
			||||||
		for (size_t j = 0; j < drm->num_crtcs ; j++) {
 | 
					 | 
				
			||||||
			uint32_t crtc_bit = 1 << j;
 | 
					 | 
				
			||||||
			if ((plane->possible_crtcs & crtc_bit) == 0) {
 | 
					 | 
				
			||||||
				continue;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			struct wlr_drm_crtc *candidate = &drm->crtcs[j];
 | 
					 | 
				
			||||||
			if ((type == DRM_PLANE_TYPE_PRIMARY && !candidate->primary) ||
 | 
					 | 
				
			||||||
					(type == DRM_PLANE_TYPE_CURSOR && !candidate->cursor)) {
 | 
					 | 
				
			||||||
				crtc = candidate;
 | 
					 | 
				
			||||||
				break;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (!crtc) {
 | 
					 | 
				
			||||||
			drmModeFreePlane(plane);
 | 
					 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (!add_plane(drm, crtc, plane, type, &props)) {
 | 
					 | 
				
			||||||
			drmModeFreePlane(plane);
 | 
					 | 
				
			||||||
			goto error;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		drmModeFreePlane(plane);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	drmModeFreePlaneResources(plane_res);
 | 
						drmModeFreePlaneResources(plane_res);
 | 
				
			||||||
	return true;
 | 
						return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
error:
 | 
					error:
 | 
				
			||||||
 | 
						free(drm->planes);
 | 
				
			||||||
	drmModeFreePlaneResources(plane_res);
 | 
						drmModeFreePlaneResources(plane_res);
 | 
				
			||||||
	return false;
 | 
						return false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -310,18 +288,16 @@ void finish_drm_resources(struct wlr_drm_backend *drm) {
 | 
				
			||||||
		if (crtc->gamma_lut) {
 | 
							if (crtc->gamma_lut) {
 | 
				
			||||||
			drmModeDestroyPropertyBlob(drm->fd, crtc->gamma_lut);
 | 
								drmModeDestroyPropertyBlob(drm->fd, crtc->gamma_lut);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (crtc->primary) {
 | 
					 | 
				
			||||||
			wlr_drm_format_set_finish(&crtc->primary->formats);
 | 
					 | 
				
			||||||
			free(crtc->primary);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (crtc->cursor) {
 | 
					 | 
				
			||||||
			wlr_drm_format_set_finish(&crtc->cursor->formats);
 | 
					 | 
				
			||||||
			free(crtc->cursor);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	free(drm->crtcs);
 | 
						free(drm->crtcs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (size_t i = 0; i < drm->num_planes; ++i) {
 | 
				
			||||||
 | 
							struct wlr_drm_plane *plane = &drm->planes[i];
 | 
				
			||||||
 | 
							wlr_drm_format_set_finish(&plane->formats);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						free(drm->planes);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct wlr_drm_connector *get_drm_connector_from_output(
 | 
					static struct wlr_drm_connector *get_drm_connector_from_output(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -64,6 +64,9 @@ struct wlr_drm_backend {
 | 
				
			||||||
	size_t num_crtcs;
 | 
						size_t num_crtcs;
 | 
				
			||||||
	struct wlr_drm_crtc *crtcs;
 | 
						struct wlr_drm_crtc *crtcs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						size_t num_planes;
 | 
				
			||||||
 | 
						struct wlr_drm_plane *planes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wl_display *display;
 | 
						struct wl_display *display;
 | 
				
			||||||
	struct wl_event_source *drm_event;
 | 
						struct wl_event_source *drm_event;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue