Renamed 'wlr_drm_display' to 'wlr_drm_output'
This commit is contained in:
		
							parent
							
								
									15d247bf34
								
							
						
					
					
						commit
						18387468bb
					
				|  | @ -23,8 +23,8 @@ struct wlr_drm_backend *wlr_drm_backend_init(struct wlr_session *session, | ||||||
| 
 | 
 | ||||||
| 	backend->session = session; | 	backend->session = session; | ||||||
| 
 | 
 | ||||||
| 	backend->displays = list_create(); | 	backend->outputs = list_create(); | ||||||
| 	if (!backend->displays) { | 	if (!backend->outputs) { | ||||||
| 		wlr_log(L_ERROR, "Failed to allocate list"); | 		wlr_log(L_ERROR, "Failed to allocate list"); | ||||||
| 		goto error_backend; | 		goto error_backend; | ||||||
| 	} | 	} | ||||||
|  | @ -51,16 +51,16 @@ struct wlr_drm_backend *wlr_drm_backend_init(struct wlr_session *session, | ||||||
| 		goto error_fd; | 		goto error_fd; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	wl_signal_init(&backend->signals.display_add); | 	wl_signal_init(&backend->signals.output_add); | ||||||
| 	wl_signal_init(&backend->signals.display_rem); | 	wl_signal_init(&backend->signals.output_rem); | ||||||
| 	wl_signal_init(&backend->signals.display_render); | 	wl_signal_init(&backend->signals.output_render); | ||||||
| 
 | 
 | ||||||
| 	if (add) | 	if (add) | ||||||
| 		wl_signal_add(&backend->signals.display_add, add); | 		wl_signal_add(&backend->signals.output_add, add); | ||||||
| 	if (rem) | 	if (rem) | ||||||
| 		wl_signal_add(&backend->signals.display_rem, rem); | 		wl_signal_add(&backend->signals.output_rem, rem); | ||||||
| 	if (render) | 	if (render) | ||||||
| 		wl_signal_add(&backend->signals.display_render, render); | 		wl_signal_add(&backend->signals.output_render, render); | ||||||
| 
 | 
 | ||||||
| 	wlr_drm_scan_connectors(backend); | 	wlr_drm_scan_connectors(backend); | ||||||
| 
 | 
 | ||||||
|  | @ -73,17 +73,17 @@ error_udev: | ||||||
| error_loop: | error_loop: | ||||||
| 	wl_event_loop_destroy(backend->event_loop); | 	wl_event_loop_destroy(backend->event_loop); | ||||||
| error_list: | error_list: | ||||||
| 	list_free(backend->displays); | 	list_free(backend->outputs); | ||||||
| error_backend: | error_backend: | ||||||
| 	free(backend); | 	free(backend); | ||||||
| 	return NULL; | 	return NULL; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void free_display(void *item) | static void free_output(void *item) | ||||||
| { | { | ||||||
| 	struct wlr_drm_display *disp = item; | 	struct wlr_drm_output *out = item; | ||||||
| 	wlr_drm_display_free(disp, true); | 	wlr_drm_output_free(out, true); | ||||||
| 	free(disp); | 	free(out); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void wlr_drm_backend_free(struct wlr_drm_backend *backend) | void wlr_drm_backend_free(struct wlr_drm_backend *backend) | ||||||
|  | @ -91,7 +91,7 @@ void wlr_drm_backend_free(struct wlr_drm_backend *backend) | ||||||
| 	if (!backend) | 	if (!backend) | ||||||
| 		return; | 		return; | ||||||
| 
 | 
 | ||||||
| 	list_foreach(backend->displays, free_display); | 	list_foreach(backend->outputs, free_output); | ||||||
| 
 | 
 | ||||||
| 	wlr_drm_renderer_free(&backend->renderer); | 	wlr_drm_renderer_free(&backend->renderer); | ||||||
| 	wlr_udev_free(&backend->udev); | 	wlr_udev_free(&backend->udev); | ||||||
|  | @ -102,7 +102,7 @@ void wlr_drm_backend_free(struct wlr_drm_backend *backend) | ||||||
| 	wl_event_source_remove(backend->event_src.udev); | 	wl_event_source_remove(backend->event_src.udev); | ||||||
| 	wl_event_loop_destroy(backend->event_loop); | 	wl_event_loop_destroy(backend->event_loop); | ||||||
| 
 | 
 | ||||||
| 	list_free(backend->displays); | 	list_free(backend->outputs); | ||||||
| 	free(backend); | 	free(backend); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -37,23 +37,19 @@ static const char *conn_name[] = { | ||||||
| 	[DRM_MODE_CONNECTOR_DSI]         = "DSI", | 	[DRM_MODE_CONNECTOR_DSI]         = "DSI", | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static void page_flip_handler(int fd, | static void page_flip_handler(int fd, unsigned seq, unsigned tv_sec, unsigned tv_usec, | ||||||
| 		unsigned seq, | 	void *user) { | ||||||
| 		unsigned tv_sec, |  | ||||||
| 		unsigned tv_usec, |  | ||||||
| 		void *user) |  | ||||||
| { |  | ||||||
| 	struct wlr_drm_display *disp = user; |  | ||||||
| 	struct wlr_drm_backend *backend = disp->renderer->backend; |  | ||||||
| 
 | 
 | ||||||
| 	disp->pageflip_pending = true; | 	struct wlr_drm_output *out = user; | ||||||
| 	if (!disp->cleanup) | 	struct wlr_drm_backend *backend = out->renderer->backend; | ||||||
| 		wl_signal_emit(&backend->signals.display_render, disp); | 
 | ||||||
|  | 	out->pageflip_pending = true; | ||||||
|  | 	if (!out->cleanup) { | ||||||
|  | 		wl_signal_emit(&backend->signals.output_render, out); | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | static int drm_event(int fd, uint32_t mask, void *data) { | ||||||
| static int drm_event(int fd, uint32_t mask, void *data) |  | ||||||
| { |  | ||||||
| 	drmEventContext event = { | 	drmEventContext event = { | ||||||
| 		.version = DRM_EVENT_CONTEXT_VERSION, | 		.version = DRM_EVENT_CONTEXT_VERSION, | ||||||
| 		.page_flip_handler = page_flip_handler, | 		.page_flip_handler = page_flip_handler, | ||||||
|  | @ -65,8 +61,8 @@ static int drm_event(int fd, uint32_t mask, void *data) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool wlr_drm_renderer_init(struct wlr_drm_renderer *renderer, | bool wlr_drm_renderer_init(struct wlr_drm_renderer *renderer, | ||||||
| 		struct wlr_drm_backend *backend, int fd) | 	struct wlr_drm_backend *backend, int fd) { | ||||||
| { | 
 | ||||||
| 	renderer->gbm = gbm_create_device(fd); | 	renderer->gbm = gbm_create_device(fd); | ||||||
| 	if (!renderer->gbm) { | 	if (!renderer->gbm) { | ||||||
| 		wlr_log(L_ERROR, "Failed to create GBM device: %s", strerror(errno)); | 		wlr_log(L_ERROR, "Failed to create GBM device: %s", strerror(errno)); | ||||||
|  | @ -98,30 +94,29 @@ error_gbm: | ||||||
| 	return false; | 	return false; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void wlr_drm_renderer_free(struct wlr_drm_renderer *renderer) | void wlr_drm_renderer_free(struct wlr_drm_renderer *renderer) { | ||||||
| { | 	if (!renderer) { | ||||||
| 	if (!renderer) |  | ||||||
| 		return; | 		return; | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	wlr_egl_free(&renderer->egl); | 	wlr_egl_free(&renderer->egl); | ||||||
| 	gbm_device_destroy(renderer->gbm); | 	gbm_device_destroy(renderer->gbm); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int find_id(const void *item, const void *cmp_to) | static int find_id(const void *item, const void *cmp_to) { | ||||||
| { | 	const struct wlr_drm_output *out = item; | ||||||
| 	const struct wlr_drm_display *disp = item; |  | ||||||
| 	const uint32_t *id = cmp_to; | 	const uint32_t *id = cmp_to; | ||||||
| 
 | 
 | ||||||
| 	if (disp->connector < *id) | 	if (out->connector < *id) { | ||||||
| 		return -1; | 		return -1; | ||||||
| 	else if (disp->connector > *id) | 	} else if (out->connector > *id) { | ||||||
| 		return 1; | 		return 1; | ||||||
| 	else | 	} else { | ||||||
| 		return 0; | 		return 0; | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void wlr_drm_scan_connectors(struct wlr_drm_backend *backend) | void wlr_drm_scan_connectors(struct wlr_drm_backend *backend) { | ||||||
| { |  | ||||||
| 	drmModeRes *res = drmModeGetResources(backend->fd); | 	drmModeRes *res = drmModeGetResources(backend->fd); | ||||||
| 	if (!res) { | 	if (!res) { | ||||||
| 		wlr_log(L_ERROR, "Failed to get DRM resources"); | 		wlr_log(L_ERROR, "Failed to get DRM resources"); | ||||||
|  | @ -137,42 +132,44 @@ void wlr_drm_scan_connectors(struct wlr_drm_backend *backend) | ||||||
| 			continue; | 			continue; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		struct wlr_drm_display *disp; | 		struct wlr_drm_output *out; | ||||||
| 		int index = list_seq_find(backend->displays, find_id, &id); | 		int index = list_seq_find(backend->outputs, find_id, &id); | ||||||
| 
 | 
 | ||||||
| 		if (index == -1) { | 		if (index == -1) { | ||||||
| 			disp = calloc(1, sizeof *disp); | 			out = calloc(1, sizeof *out); | ||||||
| 			if (!disp) { | 			if (!out) { | ||||||
| 				wlr_log(L_ERROR, "Allocation failed: %s", strerror(errno)); | 				wlr_log(L_ERROR, "Allocation failed: %s", strerror(errno)); | ||||||
| 				drmModeFreeConnector(conn); | 				drmModeFreeConnector(conn); | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			disp->renderer = &backend->renderer; | 			out->renderer = &backend->renderer; | ||||||
| 			disp->state = DRM_DISP_DISCONNECTED; | 			out->state = DRM_OUTPUT_DISCONNECTED; | ||||||
| 			disp->connector = res->connectors[i]; | 			out->connector = res->connectors[i]; | ||||||
| 			snprintf(disp->name, sizeof disp->name, "%s-%"PRIu32, | 			snprintf(out->name, sizeof out->name, "%s-%"PRIu32, | ||||||
| 				 conn_name[conn->connector_type], | 				 conn_name[conn->connector_type], | ||||||
| 				 conn->connector_type_id); | 				 conn->connector_type_id); | ||||||
| 
 | 
 | ||||||
| 			list_add(backend->displays, disp); | 			list_add(backend->outputs, out); | ||||||
| 			wlr_log(L_INFO, "Found display '%s'", disp->name); | 			wlr_log(L_INFO, "Found display '%s'", out->name); | ||||||
| 		} else { | 		} else { | ||||||
| 			disp = backend->displays->items[index]; | 			out = backend->outputs->items[index]; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (disp->state == DRM_DISP_DISCONNECTED && | 		if (out->state == DRM_OUTPUT_DISCONNECTED && | ||||||
| 		    conn->connection == DRM_MODE_CONNECTED) { | 			conn->connection == DRM_MODE_CONNECTED) { | ||||||
| 			disp->state = DRM_DISP_NEEDS_MODESET; |  | ||||||
| 			wlr_log(L_INFO, "Sending modesetting signal for '%s'", disp->name); |  | ||||||
| 			wl_signal_emit(&backend->signals.display_add, disp); |  | ||||||
| 
 | 
 | ||||||
| 		} else if (disp->state == DRM_DISP_CONNECTED && | 			out->state = DRM_OUTPUT_NEEDS_MODESET; | ||||||
| 		    conn->connection != DRM_MODE_CONNECTED) { | 			wlr_log(L_INFO, "Sending modesetting signal for '%s'", out->name); | ||||||
| 			disp->state = DRM_DISP_DISCONNECTED; | 			wl_signal_emit(&backend->signals.output_add, out); | ||||||
| 			wlr_drm_display_free(disp, false); | 
 | ||||||
| 			wlr_log(L_INFO, "Sending destruction signal for '%s'", disp->name); | 		} else if (out->state == DRM_OUTPUT_CONNECTED && | ||||||
| 			wl_signal_emit(&backend->signals.display_rem, disp); | 			conn->connection != DRM_MODE_CONNECTED) { | ||||||
|  | 
 | ||||||
|  | 			out->state = DRM_OUTPUT_DISCONNECTED; | ||||||
|  | 			wlr_drm_output_free(out, false); | ||||||
|  | 			wlr_log(L_INFO, "Sending destruction signal for '%s'", out->name); | ||||||
|  | 			wl_signal_emit(&backend->signals.output_rem, out); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		drmModeFreeConnector(conn); | 		drmModeFreeConnector(conn); | ||||||
|  | @ -181,22 +178,22 @@ void wlr_drm_scan_connectors(struct wlr_drm_backend *backend) | ||||||
| 	drmModeFreeResources(res); | 	drmModeFreeResources(res); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void free_fb(struct gbm_bo *bo, void *data) | static void free_fb(struct gbm_bo *bo, void *data) { | ||||||
| { |  | ||||||
| 	uint32_t *id = data; | 	uint32_t *id = data; | ||||||
| 
 | 
 | ||||||
| 	if (id && *id) | 	if (id && *id) { | ||||||
| 		drmModeRmFB(gbm_bo_get_fd(bo), *id); | 		drmModeRmFB(gbm_bo_get_fd(bo), *id); | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	free(id); | 	free(id); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static uint32_t get_fb_for_bo(int fd, struct gbm_bo *bo) | static uint32_t get_fb_for_bo(int fd, struct gbm_bo *bo) { | ||||||
| { |  | ||||||
| 	uint32_t *id = gbm_bo_get_user_data(bo); | 	uint32_t *id = gbm_bo_get_user_data(bo); | ||||||
| 
 | 
 | ||||||
| 	if (id) | 	if (id) { | ||||||
| 		return *id; | 		return *id; | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	id = calloc(1, sizeof *id); | 	id = calloc(1, sizeof *id); | ||||||
| 	if (!id) { | 	if (!id) { | ||||||
|  | @ -213,55 +210,52 @@ static uint32_t get_fb_for_bo(int fd, struct gbm_bo *bo) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static bool display_init_renderer(struct wlr_drm_renderer *renderer, | static bool display_init_renderer(struct wlr_drm_renderer *renderer, | ||||||
| 		struct wlr_drm_display *disp) | 	struct wlr_drm_output *out) { | ||||||
| { |  | ||||||
| 	disp->renderer = renderer; |  | ||||||
| 
 | 
 | ||||||
| 	disp->gbm = gbm_surface_create(renderer->gbm, | 	out->renderer = renderer; | ||||||
| 				       disp->width, disp->height, | 
 | ||||||
| 				       GBM_FORMAT_XRGB8888, | 	out->gbm = gbm_surface_create(renderer->gbm, out->width, out->height, | ||||||
| 				       GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); | 		GBM_FORMAT_XRGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); | ||||||
| 	if (!disp->gbm) { | 	if (!out->gbm) { | ||||||
| 		wlr_log(L_ERROR, "Failed to create GBM surface for %s: %s", disp->name, | 		wlr_log(L_ERROR, "Failed to create GBM surface for %s: %s", out->name, | ||||||
| 			strerror(errno)); | 			strerror(errno)); | ||||||
| 		return false; | 		return false; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	disp->egl = wlr_egl_create_surface(&renderer->egl, disp->gbm); | 	out->egl = wlr_egl_create_surface(&renderer->egl, out->gbm); | ||||||
| 	if (disp->egl == EGL_NO_SURFACE) { | 	if (out->egl == EGL_NO_SURFACE) { | ||||||
| 		wlr_log(L_ERROR, "Failed to create EGL surface for %s", disp->name); | 		wlr_log(L_ERROR, "Failed to create EGL surface for %s", out->name); | ||||||
| 		return false; | 		return false; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Render black frame
 | 	// Render black frame
 | ||||||
| 
 | 
 | ||||||
| 	eglMakeCurrent(renderer->egl.display, disp->egl, disp->egl, renderer->egl.context); | 	eglMakeCurrent(renderer->egl.display, out->egl, out->egl, renderer->egl.context); | ||||||
| 
 | 
 | ||||||
| 	glViewport(0, 0, disp->width, disp->height); | 	glViewport(0, 0, out->width, out->height); | ||||||
| 	glClearColor(0.0, 0.0, 0.0, 1.0); | 	glClearColor(0.0, 0.0, 0.0, 1.0); | ||||||
| 	glClear(GL_COLOR_BUFFER_BIT); | 	glClear(GL_COLOR_BUFFER_BIT); | ||||||
| 
 | 
 | ||||||
| 	eglSwapBuffers(renderer->egl.display, disp->egl); | 	eglSwapBuffers(renderer->egl.display, out->egl); | ||||||
| 
 | 
 | ||||||
| 	struct gbm_bo *bo = gbm_surface_lock_front_buffer(disp->gbm); | 	struct gbm_bo *bo = gbm_surface_lock_front_buffer(out->gbm); | ||||||
| 	uint32_t fb_id = get_fb_for_bo(renderer->fd, bo); | 	uint32_t fb_id = get_fb_for_bo(renderer->fd, bo); | ||||||
| 
 | 
 | ||||||
| 	drmModeSetCrtc(renderer->fd, disp->crtc, fb_id, 0, 0, | 	drmModeSetCrtc(renderer->fd, out->crtc, fb_id, 0, 0, | ||||||
| 		       &disp->connector, 1, disp->active_mode); | 		       &out->connector, 1, out->active_mode); | ||||||
| 	drmModePageFlip(renderer->fd, disp->crtc, fb_id, DRM_MODE_PAGE_FLIP_EVENT, disp); | 	drmModePageFlip(renderer->fd, out->crtc, fb_id, DRM_MODE_PAGE_FLIP_EVENT, out); | ||||||
| 
 | 
 | ||||||
| 	gbm_surface_release_buffer(disp->gbm, bo); | 	gbm_surface_release_buffer(out->gbm, bo); | ||||||
| 
 | 
 | ||||||
| 	return true; | 	return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static drmModeModeInfo *select_mode(size_t num_modes, | static drmModeModeInfo *select_mode(size_t num_modes, drmModeModeInfo modes[static num_modes], | ||||||
| 		drmModeModeInfo modes[static num_modes], | 	drmModeCrtc *old_crtc, const char *str) { | ||||||
| 		drmModeCrtc *old_crtc, | 
 | ||||||
| 		const char *str) | 	if (strcmp(str, "preferred") == 0) { | ||||||
| { |  | ||||||
| 	if (strcmp(str, "preferred") == 0) |  | ||||||
| 		return &modes[0]; | 		return &modes[0]; | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	if (strcmp(str, "current") == 0) { | 	if (strcmp(str, "current") == 0) { | ||||||
| 		if (!old_crtc) { | 		if (!old_crtc) { | ||||||
|  | @ -270,8 +264,9 @@ static drmModeModeInfo *select_mode(size_t num_modes, | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		for (size_t i = 0; i < num_modes; ++i) { | 		for (size_t i = 0; i < num_modes; ++i) { | ||||||
| 			if (memcmp(&modes[i], &old_crtc->mode, sizeof modes[0]) == 0) | 			if (memcmp(&modes[i], &old_crtc->mode, sizeof modes[0]) == 0) { | ||||||
| 				return &modes[i]; | 				return &modes[i]; | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		// We should never get here
 | 		// We should never get here
 | ||||||
|  | @ -289,55 +284,57 @@ static drmModeModeInfo *select_mode(size_t num_modes, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	for (size_t i = 0; i < num_modes; ++i) { | 	for (size_t i = 0; i < num_modes; ++i) { | ||||||
| 		if (modes[i].hdisplay == width && | 		if (modes[i].hdisplay == width && modes[i].vdisplay == height &&  | ||||||
| 		    modes[i].vdisplay == height && | 			(!rate || modes[i].vrefresh == rate)) { | ||||||
| 		    (!rate || modes[i].vrefresh == rate)) | 
 | ||||||
| 			return &modes[i]; | 			return &modes[i]; | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	wlr_log(L_ERROR, "Unable to find mode %ux%u@%u", width, height, rate); | 	wlr_log(L_ERROR, "Unable to find mode %ux%u@%u", width, height, rate); | ||||||
| 	return NULL; | 	return NULL; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool wlr_drm_display_modeset(struct wlr_drm_display *disp, const char *str) | bool wlr_drm_output_modeset(struct wlr_drm_output *out, const char *str) { | ||||||
| { | 	struct wlr_drm_backend *backend = out->renderer->backend; | ||||||
| 	struct wlr_drm_backend *backend = disp->renderer->backend; | 	wlr_log(L_INFO, "Modesetting %s with '%s'", out->name, str); | ||||||
| 	wlr_log(L_INFO, "Modesetting %s with '%s'", disp->name, str); |  | ||||||
| 
 | 
 | ||||||
| 	drmModeConnector *conn = drmModeGetConnector(backend->fd, disp->connector); | 	drmModeConnector *conn = drmModeGetConnector(backend->fd, out->connector); | ||||||
| 	if (!conn) { | 	if (!conn) { | ||||||
| 		wlr_log(L_ERROR, "Failed to get DRM connector"); | 		wlr_log(L_ERROR, "Failed to get DRM connector"); | ||||||
| 		goto error; | 		goto error; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (conn->connection != DRM_MODE_CONNECTED || conn->count_modes == 0) { | 	if (conn->connection != DRM_MODE_CONNECTED || conn->count_modes == 0) { | ||||||
| 		wlr_log(L_ERROR, "%s is not connected", disp->name); | 		wlr_log(L_ERROR, "%s is not connected", out->name); | ||||||
| 		goto error; | 		goto error; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	disp->num_modes = conn->count_modes; | 	out->num_modes = conn->count_modes; | ||||||
| 	disp->modes = malloc(sizeof *disp->modes * disp->num_modes); | 	out->modes = malloc(sizeof *out->modes * out->num_modes); | ||||||
| 	if (!disp->modes) { | 	if (!out->modes) { | ||||||
| 		wlr_log(L_ERROR, "Allocation failed: %s", strerror(errno)); | 		wlr_log(L_ERROR, "Allocation failed: %s", strerror(errno)); | ||||||
| 		goto error; | 		goto error; | ||||||
| 	} | 	} | ||||||
| 	memcpy(disp->modes, conn->modes, sizeof *disp->modes * disp->num_modes); | 	memcpy(out->modes, conn->modes, sizeof *out->modes * out->num_modes); | ||||||
| 
 | 
 | ||||||
| 	wlr_log(L_INFO, "Detected modes:"); | 	wlr_log(L_INFO, "Detected modes:"); | ||||||
| 	for (size_t i = 0; i < disp->num_modes; ++i) | 	for (size_t i = 0; i < out->num_modes; ++i) { | ||||||
| 		wlr_log(L_INFO, "  %"PRIu16"@%"PRIu16"@%"PRIu32, | 		wlr_log(L_INFO, "  %"PRIu16"@%"PRIu16"@%"PRIu32, | ||||||
| 			disp->modes[i].hdisplay, disp->modes[i].vdisplay, | 			out->modes[i].hdisplay, out->modes[i].vdisplay, | ||||||
| 			disp->modes[i].vrefresh); | 			out->modes[i].vrefresh); | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	drmModeEncoder *curr_enc = drmModeGetEncoder(backend->fd, conn->encoder_id); | 	drmModeEncoder *curr_enc = drmModeGetEncoder(backend->fd, conn->encoder_id); | ||||||
| 	if (curr_enc) { | 	if (curr_enc) { | ||||||
| 		disp->old_crtc = drmModeGetCrtc(backend->fd, curr_enc->crtc_id); | 		out->old_crtc = drmModeGetCrtc(backend->fd, curr_enc->crtc_id); | ||||||
| 		free(curr_enc); | 		free(curr_enc); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	disp->active_mode = select_mode(disp->num_modes, disp->modes, disp->old_crtc, str); | 	out->active_mode = select_mode(out->num_modes, out->modes, | ||||||
| 	if (!disp->active_mode) { | 		out->old_crtc, str); | ||||||
| 		wlr_log(L_ERROR, "Failed to configure %s", disp->name); | 	if (!out->active_mode) { | ||||||
|  | 		wlr_log(L_ERROR, "Failed to configure %s", out->name); | ||||||
| 		goto error; | 		goto error; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -354,12 +351,13 @@ bool wlr_drm_display_modeset(struct wlr_drm_display *disp, const char *str) | ||||||
| 			continue; | 			continue; | ||||||
| 
 | 
 | ||||||
| 		for (int j = 0; j < res->count_crtcs; ++j) { | 		for (int j = 0; j < res->count_crtcs; ++j) { | ||||||
| 			if ((enc->possible_crtcs & (1 << j)) == 0) | 			if ((enc->possible_crtcs & (1 << j)) == 0) { | ||||||
| 				continue; | 				continue; | ||||||
|  | 			} | ||||||
| 
 | 
 | ||||||
| 			if ((backend->taken_crtcs & (1 << j)) == 0) { | 			if ((backend->taken_crtcs & (1 << j)) == 0) { | ||||||
| 				backend->taken_crtcs |= 1 << j; | 				backend->taken_crtcs |= 1 << j; | ||||||
| 				disp->crtc = res->crtcs[j]; | 				out->crtc = res->crtcs[j]; | ||||||
| 
 | 
 | ||||||
| 				success = true; | 				success = true; | ||||||
| 				break; | 				break; | ||||||
|  | @ -372,55 +370,56 @@ bool wlr_drm_display_modeset(struct wlr_drm_display *disp, const char *str) | ||||||
| 	drmModeFreeResources(res); | 	drmModeFreeResources(res); | ||||||
| 
 | 
 | ||||||
| 	if (!success) { | 	if (!success) { | ||||||
| 		wlr_log(L_ERROR, "Failed to find CRTC for %s", disp->name); | 		wlr_log(L_ERROR, "Failed to find CRTC for %s", out->name); | ||||||
| 		goto error; | 		goto error; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	disp->state = DRM_DISP_CONNECTED; | 	out->state = DRM_OUTPUT_CONNECTED; | ||||||
| 
 | 
 | ||||||
| 	disp->width = disp->active_mode->hdisplay; | 	out->width = out->active_mode->hdisplay; | ||||||
| 	disp->height = disp->active_mode->vdisplay; | 	out->height = out->active_mode->vdisplay; | ||||||
| 
 | 
 | ||||||
| 	if (!display_init_renderer(&backend->renderer, disp)) { | 	if (!display_init_renderer(&backend->renderer, out)) { | ||||||
| 		wlr_log(L_ERROR, "Failed to initalise renderer for %s", disp->name); | 		wlr_log(L_ERROR, "Failed to initalise renderer for %s", out->name); | ||||||
| 		goto error; | 		goto error; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	drmModeFreeConnector(conn); | 	drmModeFreeConnector(conn); | ||||||
| 
 | 
 | ||||||
| 	wlr_log(L_INFO, "Configuring %s with mode %"PRIu16"x%"PRIu16"@%"PRIu32"", | 	wlr_log(L_INFO, "Configuring %s with mode %"PRIu16"x%"PRIu16"@%"PRIu32"", | ||||||
| 		disp->name, disp->active_mode->hdisplay, disp->active_mode->vdisplay, | 		out->name, out->active_mode->hdisplay, out->active_mode->vdisplay, | ||||||
| 		disp->active_mode->vrefresh); | 		out->active_mode->vrefresh); | ||||||
| 
 | 
 | ||||||
| 	return true; | 	return true; | ||||||
| 
 | 
 | ||||||
| error: | error: | ||||||
| 	disp->state = DRM_DISP_DISCONNECTED; | 	out->state = DRM_OUTPUT_DISCONNECTED; | ||||||
| 	drmModeFreeConnector(conn); | 	drmModeFreeConnector(conn); | ||||||
| 	free(disp->modes); | 	free(out->modes); | ||||||
| 
 | 
 | ||||||
| 	wl_signal_emit(&backend->signals.display_rem, disp); | 	wl_signal_emit(&backend->signals.output_rem, out); | ||||||
| 
 | 
 | ||||||
| 	return false; | 	return false; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void wlr_drm_display_free(struct wlr_drm_display *disp, bool restore) | void wlr_drm_output_free(struct wlr_drm_output *out, bool restore) { | ||||||
| { | 	if (!out || out->state != DRM_OUTPUT_CONNECTED) { | ||||||
| 	if (!disp || disp->state != DRM_DISP_CONNECTED) |  | ||||||
| 		return; | 		return; | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	struct wlr_drm_renderer *renderer = disp->renderer; | 	struct wlr_drm_renderer *renderer = out->renderer; | ||||||
| 
 | 
 | ||||||
| 	eglDestroySurface(renderer->egl.display, disp->egl); | 	eglDestroySurface(renderer->egl.display, out->egl); | ||||||
| 	gbm_surface_destroy(disp->gbm); | 	gbm_surface_destroy(out->gbm); | ||||||
| 
 | 
 | ||||||
| 	free(disp->modes); | 	free(out->modes); | ||||||
| 	disp->state = DRM_DISP_DISCONNECTED; | 	out->state = DRM_OUTPUT_DISCONNECTED; | ||||||
| 
 | 
 | ||||||
| 	if (!restore) | 	if (!restore) { | ||||||
| 		return; | 		return; | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	drmModeCrtc *crtc = disp->old_crtc; | 	drmModeCrtc *crtc = out->old_crtc; | ||||||
| 	if (crtc) { | 	if (crtc) { | ||||||
| 		// Wait for exising page flips to finish
 | 		// Wait for exising page flips to finish
 | ||||||
| 
 | 
 | ||||||
|  | @ -429,34 +428,32 @@ void wlr_drm_display_free(struct wlr_drm_display *disp, bool restore) | ||||||
| 			.page_flip_handler = page_flip_handler, | 			.page_flip_handler = page_flip_handler, | ||||||
| 		}; | 		}; | ||||||
| 
 | 
 | ||||||
| 		disp->cleanup = true; | 		out->cleanup = true; | ||||||
| 		while (disp->pageflip_pending) | 		while (out->pageflip_pending) | ||||||
| 			drmHandleEvent(renderer->fd, &event); | 			drmHandleEvent(renderer->fd, &event); | ||||||
| 
 | 
 | ||||||
| 		drmModeSetCrtc(renderer->fd, crtc->crtc_id, crtc->buffer_id, | 		drmModeSetCrtc(renderer->fd, crtc->crtc_id, crtc->buffer_id, | ||||||
| 			       crtc->x, crtc->y, &disp->connector, | 			       crtc->x, crtc->y, &out->connector, | ||||||
| 			       1, &crtc->mode); | 			       1, &crtc->mode); | ||||||
| 		drmModeFreeCrtc(crtc); | 		drmModeFreeCrtc(crtc); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void wlr_drm_display_begin(struct wlr_drm_display *disp) | void wlr_drm_output_begin(struct wlr_drm_output *out) { | ||||||
| { | 	struct wlr_drm_renderer *renderer = out->renderer; | ||||||
| 	struct wlr_drm_renderer *renderer = disp->renderer; | 	eglMakeCurrent(renderer->egl.display, out->egl, out->egl, renderer->egl.context); | ||||||
| 	eglMakeCurrent(renderer->egl.display, disp->egl, disp->egl, renderer->egl.context); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void wlr_drm_display_end(struct wlr_drm_display *disp) | void wlr_drm_output_end(struct wlr_drm_output *out) { | ||||||
| { | 	struct wlr_drm_renderer *renderer = out->renderer; | ||||||
| 	struct wlr_drm_renderer *renderer = disp->renderer; | 	eglSwapBuffers(renderer->egl.display, out->egl); | ||||||
| 	eglSwapBuffers(renderer->egl.display, disp->egl); |  | ||||||
| 
 | 
 | ||||||
| 	struct gbm_bo *bo = gbm_surface_lock_front_buffer(disp->gbm); | 	struct gbm_bo *bo = gbm_surface_lock_front_buffer(out->gbm); | ||||||
| 	uint32_t fb_id = get_fb_for_bo(renderer->fd, bo); | 	uint32_t fb_id = get_fb_for_bo(renderer->fd, bo); | ||||||
| 
 | 
 | ||||||
| 	drmModePageFlip(renderer->fd, disp->crtc, fb_id, DRM_MODE_PAGE_FLIP_EVENT, disp); | 	drmModePageFlip(renderer->fd, out->crtc, fb_id, DRM_MODE_PAGE_FLIP_EVENT, out); | ||||||
| 
 | 
 | ||||||
| 	gbm_surface_release_buffer(disp->gbm, bo); | 	gbm_surface_release_buffer(out->gbm, bo); | ||||||
| 
 | 
 | ||||||
| 	disp->pageflip_pending = false; | 	out->pageflip_pending = false; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -19,22 +19,22 @@ struct state { | ||||||
| 	struct wl_listener render; | 	struct wl_listener render; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| void display_add(struct wl_listener *listener, void *data) | void output_add(struct wl_listener *listener, void *data) | ||||||
| { | { | ||||||
| 	struct wlr_drm_display *disp = data; | 	struct wlr_drm_output *out = data; | ||||||
| 
 | 
 | ||||||
| 	fprintf(stderr, "Display added\n"); | 	fprintf(stderr, "Output added\n"); | ||||||
| 	wlr_drm_display_modeset(disp, "preferred"); | 	wlr_drm_output_modeset(out, "preferred"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void display_rem(struct wl_listener *listener, void *data) | void output_rem(struct wl_listener *listener, void *data) | ||||||
| { | { | ||||||
| 	fprintf(stderr, "Display removed\n"); | 	fprintf(stderr, "Output removed\n"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void display_render(struct wl_listener *listener, void *data) | void output_render(struct wl_listener *listener, void *data) | ||||||
| { | { | ||||||
| 	struct wlr_drm_display *disp = data; | 	struct wlr_drm_output *out = data; | ||||||
| 	struct state *s = wl_container_of(listener, s, render); | 	struct state *s = wl_container_of(listener, s, render); | ||||||
| 
 | 
 | ||||||
| 	struct timespec now; | 	struct timespec now; | ||||||
|  | @ -56,12 +56,12 @@ void display_render(struct wl_listener *listener, void *data) | ||||||
| 
 | 
 | ||||||
| 	s->last_frame = now; | 	s->last_frame = now; | ||||||
| 
 | 
 | ||||||
| 	wlr_drm_display_begin(disp); | 	wlr_drm_output_begin(out); | ||||||
| 
 | 
 | ||||||
| 	glClearColor(s->color[0], s->color[1], s->color[2], 1.0); | 	glClearColor(s->color[0], s->color[1], s->color[2], 1.0); | ||||||
| 	glClear(GL_COLOR_BUFFER_BIT); | 	glClear(GL_COLOR_BUFFER_BIT); | ||||||
| 
 | 
 | ||||||
| 	wlr_drm_display_end(disp); | 	wlr_drm_output_end(out); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int timer_done(void *data) | int timer_done(void *data) | ||||||
|  | @ -83,9 +83,9 @@ int main() | ||||||
| 	struct state state = { | 	struct state state = { | ||||||
| 		.color = { 1.0, 0.0, 0.0 }, | 		.color = { 1.0, 0.0, 0.0 }, | ||||||
| 		.dec = 0, | 		.dec = 0, | ||||||
| 		.add = { .notify = display_add }, | 		.add = { .notify = output_add }, | ||||||
| 		.rem = { .notify = display_rem }, | 		.rem = { .notify = output_rem }, | ||||||
| 		.render = { .notify = display_render }, | 		.render = { .notify = output_render }, | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	wl_list_init(&state.add.link); | 	wl_list_init(&state.add.link); | ||||||
|  |  | ||||||
|  | @ -28,12 +28,12 @@ struct wlr_drm_backend { | ||||||
| 	} event_src; | 	} event_src; | ||||||
| 
 | 
 | ||||||
| 	struct { | 	struct { | ||||||
| 		struct wl_signal display_add; | 		struct wl_signal output_add; | ||||||
| 		struct wl_signal display_rem; | 		struct wl_signal output_rem; | ||||||
| 		struct wl_signal display_render; | 		struct wl_signal output_render; | ||||||
| 	} signals; | 	} signals; | ||||||
| 
 | 
 | ||||||
| 	list_t *displays; | 	list_t *outputs; | ||||||
| 
 | 
 | ||||||
| 	uint32_t taken_crtcs; | 	uint32_t taken_crtcs; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -25,15 +25,15 @@ bool wlr_drm_renderer_init(struct wlr_drm_renderer *renderer, | ||||||
| 		struct wlr_drm_backend *backend, int fd); | 		struct wlr_drm_backend *backend, int fd); | ||||||
| void wlr_drm_renderer_free(struct wlr_drm_renderer *renderer); | void wlr_drm_renderer_free(struct wlr_drm_renderer *renderer); | ||||||
| 
 | 
 | ||||||
| enum wlr_drm_display_state { | enum wlr_drm_output_state { | ||||||
| 	DRM_DISP_INVALID, | 	DRM_OUTPUT_INVALID, | ||||||
| 	DRM_DISP_DISCONNECTED, | 	DRM_OUTPUT_DISCONNECTED, | ||||||
| 	DRM_DISP_NEEDS_MODESET, | 	DRM_OUTPUT_NEEDS_MODESET, | ||||||
| 	DRM_DISP_CONNECTED, | 	DRM_OUTPUT_CONNECTED, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct wlr_drm_display { | struct wlr_drm_output { | ||||||
| 	enum wlr_drm_display_state state; | 	enum wlr_drm_output_state state; | ||||||
| 	uint32_t connector; | 	uint32_t connector; | ||||||
| 	char name[16]; | 	char name[16]; | ||||||
| 
 | 
 | ||||||
|  | @ -55,11 +55,11 @@ struct wlr_drm_display { | ||||||
| 	bool cleanup; | 	bool cleanup; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| bool wlr_drm_display_modeset(struct wlr_drm_display *disp, const char *str); | bool wlr_drm_output_modeset(struct wlr_drm_output *out, const char *str); | ||||||
| void wlr_drm_display_free(struct wlr_drm_display *disp, bool restore); | void wlr_drm_output_free(struct wlr_drm_output *out, bool restore); | ||||||
| 
 | 
 | ||||||
| void wlr_drm_display_begin(struct wlr_drm_display *disp); | void wlr_drm_output_begin(struct wlr_drm_output *out); | ||||||
| void wlr_drm_display_end(struct wlr_drm_display *disp); | void wlr_drm_output_end(struct wlr_drm_output *out); | ||||||
| 
 | 
 | ||||||
| void wlr_drm_scan_connectors(struct wlr_drm_backend *backend); | void wlr_drm_scan_connectors(struct wlr_drm_backend *backend); | ||||||
| void wlr_drm_event(int fd); | void wlr_drm_event(int fd); | ||||||
|  |  | ||||||
|  | @ -5,7 +5,7 @@ | ||||||
| #include <wlr/session.h> | #include <wlr/session.h> | ||||||
| 
 | 
 | ||||||
| struct wlr_drm_backend; | struct wlr_drm_backend; | ||||||
| struct wlr_drm_display; | struct wlr_drm_output; | ||||||
| 
 | 
 | ||||||
| struct wlr_drm_backend *wlr_drm_backend_init(struct wlr_session *session, | struct wlr_drm_backend *wlr_drm_backend_init(struct wlr_session *session, | ||||||
| 	struct wl_listener *add, struct wl_listener *rem, struct wl_listener *render); | 	struct wl_listener *add, struct wl_listener *rem, struct wl_listener *render); | ||||||
|  | @ -13,8 +13,8 @@ void wlr_drm_backend_free(struct wlr_drm_backend *backend); | ||||||
| 
 | 
 | ||||||
| struct wl_event_loop *wlr_drm_backend_get_event_loop(struct wlr_drm_backend *backend); | struct wl_event_loop *wlr_drm_backend_get_event_loop(struct wlr_drm_backend *backend); | ||||||
| 
 | 
 | ||||||
| bool wlr_drm_display_modeset(struct wlr_drm_display *disp, const char *str); | bool wlr_drm_output_modeset(struct wlr_drm_output *out, const char *str); | ||||||
| void wlr_drm_display_begin(struct wlr_drm_display *disp); | void wlr_drm_output_begin(struct wlr_drm_output *out); | ||||||
| void wlr_drm_display_end(struct wlr_drm_display *disp); | void wlr_drm_output_end(struct wlr_drm_output *out); | ||||||
| 
 | 
 | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue