backend/drm: use wlr_swapchain
This commit is contained in:
		
							parent
							
								
									1245730ea2
								
							
						
					
					
						commit
						ef846a8839
					
				|  | @ -593,8 +593,8 @@ static bool drm_connector_commit(struct wlr_output *output) { | |||
| } | ||||
| 
 | ||||
| static void drm_connector_rollback_render(struct wlr_output *output) { | ||||
| 	struct wlr_drm_backend *drm = get_drm_backend_from_backend(output->backend); | ||||
| 	wlr_egl_unset_current(&drm->renderer.egl); | ||||
| 	struct wlr_drm_connector *conn = get_drm_connector_from_output(output); | ||||
| 	return drm_surface_unset_current(&conn->crtc->primary->surf); | ||||
| } | ||||
| 
 | ||||
| size_t drm_crtc_get_gamma_lut_size(struct wlr_drm_backend *drm, | ||||
|  | @ -883,7 +883,7 @@ static bool drm_connector_set_cursor(struct wlr_output *output, | |||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!plane->surf.gbm) { | ||||
| 	if (!plane->surf.swapchain) { | ||||
| 		int ret; | ||||
| 		uint64_t w, h; | ||||
| 		ret = drmGetCap(drm->fd, DRM_CAP_CURSOR_WIDTH, &w); | ||||
|  |  | |||
|  | @ -12,9 +12,13 @@ | |||
| #include <wlr/types/wlr_matrix.h> | ||||
| #include <wlr/util/log.h> | ||||
| #include "backend/drm/drm.h" | ||||
| #include "render/gbm_allocator.h" | ||||
| #include "render/swapchain.h" | ||||
| #include "render/wlr_renderer.h" | ||||
| 
 | ||||
| bool init_drm_renderer(struct wlr_drm_backend *drm, | ||||
| 		struct wlr_drm_renderer *renderer, wlr_renderer_create_func_t create_renderer_func) { | ||||
| 	// TODO: get rid of renderer->gbm
 | ||||
| 	renderer->gbm = gbm_create_device(drm->fd); | ||||
| 	if (!renderer->gbm) { | ||||
| 		wlr_log(WLR_ERROR, "Failed to create GBM device"); | ||||
|  | @ -44,9 +48,17 @@ bool init_drm_renderer(struct wlr_drm_backend *drm, | |||
| 		goto error_gbm; | ||||
| 	} | ||||
| 
 | ||||
| 	renderer->allocator = wlr_gbm_allocator_create(drm->fd); | ||||
| 	if (renderer->allocator == NULL) { | ||||
| 		wlr_log(WLR_ERROR, "Failed to create allocator"); | ||||
| 		goto error_wlr_rend; | ||||
| 	} | ||||
| 
 | ||||
| 	renderer->fd = drm->fd; | ||||
| 	return true; | ||||
| 
 | ||||
| error_wlr_rend: | ||||
| 	wlr_renderer_destroy(renderer->wlr_rend); | ||||
| error_gbm: | ||||
| 	gbm_device_destroy(renderer->gbm); | ||||
| 	return false; | ||||
|  | @ -57,6 +69,7 @@ void finish_drm_renderer(struct wlr_drm_renderer *renderer) { | |||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	wlr_allocator_destroy(&renderer->allocator->base); | ||||
| 	wlr_renderer_destroy(renderer->wlr_rend); | ||||
| 	wlr_egl_finish(&renderer->egl); | ||||
| 	gbm_device_destroy(renderer->gbm); | ||||
|  | @ -64,7 +77,7 @@ void finish_drm_renderer(struct wlr_drm_renderer *renderer) { | |||
| 
 | ||||
| static bool init_drm_surface(struct wlr_drm_surface *surf, | ||||
| 		struct wlr_drm_renderer *renderer, uint32_t width, uint32_t height, | ||||
| 		uint32_t format, struct wlr_drm_format_set *set, uint32_t flags) { | ||||
| 		uint32_t format, const struct wlr_drm_format_set *set, uint32_t flags) { | ||||
| 	if (surf->width == width && surf->height == height) { | ||||
| 		return true; | ||||
| 	} | ||||
|  | @ -73,43 +86,41 @@ static bool init_drm_surface(struct wlr_drm_surface *surf, | |||
| 	surf->width = width; | ||||
| 	surf->height = height; | ||||
| 
 | ||||
| 	if (surf->gbm) { | ||||
| 		gbm_surface_destroy(surf->gbm); | ||||
| 		surf->gbm = NULL; | ||||
| 	} | ||||
| 	wlr_egl_destroy_surface(&surf->renderer->egl, surf->egl); | ||||
| 	wlr_buffer_unlock(surf->back_buffer); | ||||
| 	surf->back_buffer = NULL; | ||||
| 	wlr_swapchain_destroy(surf->swapchain); | ||||
| 	surf->swapchain = NULL; | ||||
| 
 | ||||
| 	if (!(flags & GBM_BO_USE_LINEAR) && set != NULL) { | ||||
| 		const struct wlr_drm_format *drm_format = | ||||
| 			wlr_drm_format_set_get(set, format); | ||||
| 		if (drm_format != NULL) { | ||||
| 			surf->gbm = gbm_surface_create_with_modifiers(renderer->gbm, | ||||
| 				width, height, format, drm_format->modifiers, drm_format->len); | ||||
| 	const struct wlr_drm_format *drm_format = NULL; | ||||
| 	const struct wlr_drm_format format_no_modifiers = { .format = format }; | ||||
| 	if (set != NULL) { | ||||
| 		drm_format = wlr_drm_format_set_get(set, format); | ||||
| 	} else { | ||||
| 		drm_format = &format_no_modifiers; | ||||
| 	} | ||||
| 
 | ||||
| 	struct wlr_drm_format *format_linear = NULL; | ||||
| 	if (flags & GBM_BO_USE_LINEAR) { | ||||
| 		format_linear = calloc(1, sizeof(struct wlr_drm_format) + sizeof(uint64_t)); | ||||
| 		if (format_linear == NULL) { | ||||
| 			return false; | ||||
| 		} | ||||
| 		format_linear->format = format; | ||||
| 		format_linear->len = 1; | ||||
| 		format_linear->modifiers[0] = DRM_FORMAT_MOD_LINEAR; | ||||
| 		drm_format = format_linear; | ||||
| 	} | ||||
| 
 | ||||
| 	if (surf->gbm == NULL) { | ||||
| 		surf->gbm = gbm_surface_create(renderer->gbm, width, height, | ||||
| 			format, GBM_BO_USE_RENDERING | flags); | ||||
| 	} | ||||
| 	if (!surf->gbm) { | ||||
| 		wlr_log_errno(WLR_ERROR, "Failed to create GBM surface"); | ||||
| 		goto error_zero; | ||||
| 	} | ||||
| 
 | ||||
| 	surf->egl = wlr_egl_create_surface(&renderer->egl, surf->gbm); | ||||
| 	if (surf->egl == EGL_NO_SURFACE) { | ||||
| 		wlr_log(WLR_ERROR, "Failed to create EGL surface"); | ||||
| 		goto error_gbm; | ||||
| 	surf->swapchain = wlr_swapchain_create(&renderer->allocator->base, | ||||
| 		width, height, drm_format); | ||||
| 	free(format_linear); | ||||
| 	if (surf->swapchain == NULL) { | ||||
| 		wlr_log(WLR_ERROR, "Failed to create swapchain"); | ||||
| 		memset(surf, 0, sizeof(*surf)); | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	return true; | ||||
| 
 | ||||
| error_gbm: | ||||
| 	gbm_surface_destroy(surf->gbm); | ||||
| error_zero: | ||||
| 	memset(surf, 0, sizeof(*surf)); | ||||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| static void finish_drm_surface(struct wlr_drm_surface *surf) { | ||||
|  | @ -117,17 +128,44 @@ static void finish_drm_surface(struct wlr_drm_surface *surf) { | |||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	wlr_egl_destroy_surface(&surf->renderer->egl, surf->egl); | ||||
| 	if (surf->gbm) { | ||||
| 		gbm_surface_destroy(surf->gbm); | ||||
| 	} | ||||
| 	wlr_buffer_unlock(surf->back_buffer); | ||||
| 	wlr_swapchain_destroy(surf->swapchain); | ||||
| 
 | ||||
| 	memset(surf, 0, sizeof(*surf)); | ||||
| } | ||||
| 
 | ||||
| bool drm_surface_make_current(struct wlr_drm_surface *surf, | ||||
| 		int *buffer_age) { | ||||
| 	return wlr_egl_make_current(&surf->renderer->egl, surf->egl, buffer_age); | ||||
| 	wlr_buffer_unlock(surf->back_buffer); | ||||
| 	surf->back_buffer = wlr_swapchain_acquire(surf->swapchain); | ||||
| 	if (surf->back_buffer == NULL) { | ||||
| 		wlr_log(WLR_ERROR, "Failed to acquire swapchain buffer"); | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!wlr_egl_make_current(&surf->renderer->egl, EGL_NO_SURFACE, NULL)) { | ||||
| 		return false; | ||||
| 	} | ||||
| 	if (!wlr_renderer_bind_buffer(surf->renderer->wlr_rend, surf->back_buffer)) { | ||||
| 		wlr_log(WLR_ERROR, "Failed to attach buffer to renderer"); | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	// TODO: damage tracking
 | ||||
| 	if (buffer_age != NULL) { | ||||
| 		*buffer_age = -1; | ||||
| 	} | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| void drm_surface_unset_current(struct wlr_drm_surface *surf) { | ||||
| 	assert(surf->back_buffer != NULL); | ||||
| 
 | ||||
| 	wlr_renderer_bind_buffer(surf->renderer->wlr_rend, NULL); | ||||
| 	wlr_egl_unset_current(&surf->renderer->egl); | ||||
| 
 | ||||
| 	wlr_buffer_unlock(surf->back_buffer); | ||||
| 	surf->back_buffer = NULL; | ||||
| } | ||||
| 
 | ||||
| bool export_drm_bo(struct gbm_bo *bo, struct wlr_dmabuf_attributes *attribs) { | ||||
|  | @ -251,7 +289,7 @@ void drm_fb_clear(struct wlr_drm_fb *fb) { | |||
| 		assert(!fb->bo); | ||||
| 		break; | ||||
| 	case WLR_DRM_FB_TYPE_SURFACE: | ||||
| 		gbm_surface_release_buffer(fb->surf->gbm, fb->bo); | ||||
| 		abort(); // TODO: remove this case entirely
 | ||||
| 		break; | ||||
| 	case WLR_DRM_FB_TYPE_WLR_BUFFER: | ||||
| 		gbm_bo_destroy(fb->bo); | ||||
|  | @ -264,29 +302,22 @@ void drm_fb_clear(struct wlr_drm_fb *fb) { | |||
| 	fb->bo = NULL; | ||||
| 
 | ||||
| 	if (fb->mgpu_bo) { | ||||
| 		assert(fb->mgpu_surf); | ||||
| 		// TODO
 | ||||
| 		/*assert(fb->mgpu_surf);
 | ||||
| 		gbm_surface_release_buffer(fb->mgpu_surf->gbm, fb->mgpu_bo); | ||||
| 		fb->mgpu_bo = NULL; | ||||
| 		fb->mgpu_surf = NULL; | ||||
| 		fb->mgpu_surf = NULL;*/ | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| bool drm_fb_lock_surface(struct wlr_drm_fb *fb, struct wlr_drm_surface *surf) { | ||||
| 	drm_fb_clear(fb); | ||||
| 	assert(surf->back_buffer != NULL); | ||||
| 
 | ||||
| 	if (!wlr_egl_swap_buffers(&surf->renderer->egl, surf->egl, NULL)) { | ||||
| 		wlr_log(WLR_ERROR, "Failed to swap buffers"); | ||||
| 	if (!drm_fb_import_wlr(fb, surf->renderer, surf->back_buffer, NULL)) { | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	fb->bo = gbm_surface_lock_front_buffer(surf->gbm); | ||||
| 	if (!fb->bo) { | ||||
| 		wlr_log(WLR_ERROR, "Failed to lock front buffer"); | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	fb->type = WLR_DRM_FB_TYPE_SURFACE; | ||||
| 	fb->surf = surf; | ||||
| 	drm_surface_unset_current(surf); | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
|  | @ -299,7 +330,7 @@ bool drm_fb_import_wlr(struct wlr_drm_fb *fb, struct wlr_drm_renderer *renderer, | |||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!wlr_drm_format_set_has(set, attribs.format, attribs.modifier)) { | ||||
| 	if (set && !wlr_drm_format_set_has(set, attribs.format, attribs.modifier)) { | ||||
| 		// The format isn't supported by the plane. Try stripping the alpha
 | ||||
| 		// channel, if any.
 | ||||
| 		uint32_t format = strip_alpha_channel(attribs.format); | ||||
|  | @ -410,7 +441,8 @@ struct gbm_bo *drm_fb_acquire(struct wlr_drm_fb *fb, struct wlr_drm_backend *drm | |||
| 	wlr_render_texture_with_matrix(renderer, tex, mat, 1.0f); | ||||
| 	wlr_renderer_end(renderer); | ||||
| 
 | ||||
| 	if (!wlr_egl_swap_buffers(&mgpu->renderer->egl, mgpu->egl, NULL)) { | ||||
| 	// TODO
 | ||||
| 	/*if (!wlr_egl_swap_buffers(&mgpu->renderer->egl, mgpu->egl, NULL)) {
 | ||||
| 		wlr_log(WLR_ERROR, "Failed to swap buffers"); | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | @ -421,6 +453,6 @@ struct gbm_bo *drm_fb_acquire(struct wlr_drm_fb *fb, struct wlr_drm_backend *drm | |||
| 		return NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	fb->mgpu_surf = mgpu; | ||||
| 	fb->mgpu_surf = mgpu;*/ | ||||
| 	return fb->mgpu_bo; | ||||
| } | ||||
|  |  | |||
|  | @ -20,6 +20,7 @@ struct wlr_drm_renderer { | |||
| 	uint32_t gbm_format; | ||||
| 
 | ||||
| 	struct wlr_renderer *wlr_rend; | ||||
| 	struct wlr_gbm_allocator *allocator; | ||||
| }; | ||||
| 
 | ||||
| struct wlr_drm_surface { | ||||
|  | @ -28,8 +29,8 @@ struct wlr_drm_surface { | |||
| 	uint32_t width; | ||||
| 	uint32_t height; | ||||
| 
 | ||||
| 	struct gbm_surface *gbm; | ||||
| 	EGLSurface egl; | ||||
| 	struct wlr_swapchain *swapchain; | ||||
| 	struct wlr_buffer *back_buffer; | ||||
| }; | ||||
| 
 | ||||
| enum wlr_drm_fb_type { | ||||
|  | @ -45,10 +46,7 @@ struct wlr_drm_fb { | |||
| 	struct wlr_drm_surface *mgpu_surf; | ||||
| 	struct gbm_bo *mgpu_bo; | ||||
| 
 | ||||
| 	union { | ||||
| 		struct wlr_drm_surface *surf; | ||||
| 		struct wlr_buffer *wlr_buf; | ||||
| 	}; | ||||
| 	struct wlr_buffer *wlr_buf; | ||||
| }; | ||||
| 
 | ||||
| bool init_drm_renderer(struct wlr_drm_backend *drm, | ||||
|  | @ -56,6 +54,7 @@ bool init_drm_renderer(struct wlr_drm_backend *drm, | |||
| void finish_drm_renderer(struct wlr_drm_renderer *renderer); | ||||
| 
 | ||||
| bool drm_surface_make_current(struct wlr_drm_surface *surf, int *buffer_age); | ||||
| void drm_surface_unset_current(struct wlr_drm_surface *surf); | ||||
| bool export_drm_bo(struct gbm_bo *bo, struct wlr_dmabuf_attributes *attribs); | ||||
| 
 | ||||
| void drm_fb_clear(struct wlr_drm_fb *fb); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue