mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	Merge pull request #1168 from manio/multi-gpu
Fix support for multiple GPU
This commit is contained in:
		
						commit
						e8fa25e027
					
				
					 7 changed files with 40 additions and 42 deletions
				
			
		| 
						 | 
					@ -51,8 +51,13 @@ static void backend_destroy(struct wlr_backend *backend) {
 | 
				
			||||||
static struct wlr_renderer *backend_get_renderer(
 | 
					static struct wlr_renderer *backend_get_renderer(
 | 
				
			||||||
		struct wlr_backend *backend) {
 | 
							struct wlr_backend *backend) {
 | 
				
			||||||
	struct wlr_drm_backend *drm = (struct wlr_drm_backend *)backend;
 | 
						struct wlr_drm_backend *drm = (struct wlr_drm_backend *)backend;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (drm->parent) {
 | 
				
			||||||
 | 
							return drm->parent->renderer.wlr_rend;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
		return drm->renderer.wlr_rend;
 | 
							return drm->renderer.wlr_rend;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct wlr_backend_impl backend_impl = {
 | 
					static struct wlr_backend_impl backend_impl = {
 | 
				
			||||||
	.start = backend_start,
 | 
						.start = backend_start,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -628,7 +628,6 @@ static bool drm_connector_set_cursor(struct wlr_output *output,
 | 
				
			||||||
		bool update_texture) {
 | 
							bool update_texture) {
 | 
				
			||||||
	struct wlr_drm_connector *conn = (struct wlr_drm_connector *)output;
 | 
						struct wlr_drm_connector *conn = (struct wlr_drm_connector *)output;
 | 
				
			||||||
	struct wlr_drm_backend *drm = (struct wlr_drm_backend *)output->backend;
 | 
						struct wlr_drm_backend *drm = (struct wlr_drm_backend *)output->backend;
 | 
				
			||||||
	struct wlr_drm_renderer *renderer = &drm->renderer;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wlr_drm_crtc *crtc = conn->crtc;
 | 
						struct wlr_drm_crtc *crtc = conn->crtc;
 | 
				
			||||||
	if (!crtc) {
 | 
						if (!crtc) {
 | 
				
			||||||
| 
						 | 
					@ -654,13 +653,16 @@ static bool drm_connector_set_cursor(struct wlr_output *output,
 | 
				
			||||||
		ret = drmGetCap(drm->fd, DRM_CAP_CURSOR_HEIGHT, &h);
 | 
							ret = drmGetCap(drm->fd, DRM_CAP_CURSOR_HEIGHT, &h);
 | 
				
			||||||
		h = ret ? 64 : h;
 | 
							h = ret ? 64 : h;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							struct wlr_drm_renderer *renderer =
 | 
				
			||||||
 | 
								drm->parent ? &drm->parent->renderer : &drm->renderer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!init_drm_surface(&plane->surf, renderer, w, h,
 | 
							if (!init_drm_surface(&plane->surf, renderer, w, h,
 | 
				
			||||||
				GBM_FORMAT_ARGB8888, 0)) {
 | 
									GBM_FORMAT_ARGB8888, 0)) {
 | 
				
			||||||
			wlr_log(WLR_ERROR, "Cannot allocate cursor resources");
 | 
								wlr_log(WLR_ERROR, "Cannot allocate cursor resources");
 | 
				
			||||||
			return false;
 | 
								return false;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		plane->cursor_bo = gbm_bo_create(renderer->gbm, w, h,
 | 
							plane->cursor_bo = gbm_bo_create(drm->renderer.gbm, w, h,
 | 
				
			||||||
			GBM_FORMAT_ARGB8888, GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE);
 | 
								GBM_FORMAT_ARGB8888, GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE);
 | 
				
			||||||
		if (!plane->cursor_bo) {
 | 
							if (!plane->cursor_bo) {
 | 
				
			||||||
			wlr_log_errno(WLR_ERROR, "Failed to create cursor bo");
 | 
								wlr_log_errno(WLR_ERROR, "Failed to create cursor bo");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -188,46 +188,29 @@ bool export_drm_bo(struct gbm_bo *bo, struct wlr_dmabuf_attributes *attribs) {
 | 
				
			||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct tex {
 | 
					static void free_tex(struct gbm_bo *bo, void *data) {
 | 
				
			||||||
	struct wlr_egl *egl;
 | 
						struct wlr_texture *tex = data;
 | 
				
			||||||
	EGLImageKHR img;
 | 
						wlr_texture_destroy(tex);
 | 
				
			||||||
	struct wlr_texture *tex;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void free_eglimage(struct gbm_bo *bo, void *data) {
 | 
					 | 
				
			||||||
	struct tex *tex = data;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	wlr_egl_destroy_image(tex->egl, tex->img);
 | 
					 | 
				
			||||||
	wlr_texture_destroy(tex->tex);
 | 
					 | 
				
			||||||
	free(tex);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct wlr_texture *get_tex_for_bo(struct wlr_drm_renderer *renderer,
 | 
					static struct wlr_texture *get_tex_for_bo(struct wlr_drm_renderer *renderer,
 | 
				
			||||||
		struct gbm_bo *bo) {
 | 
							struct gbm_bo *bo) {
 | 
				
			||||||
	struct tex *tex = gbm_bo_get_user_data(bo);
 | 
						struct wlr_texture *tex = gbm_bo_get_user_data(bo);
 | 
				
			||||||
	if (tex != NULL) {
 | 
						if (tex) {
 | 
				
			||||||
		return tex->tex;
 | 
							return tex;
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	tex = calloc(1, sizeof(struct tex));
 | 
					 | 
				
			||||||
	if (tex == NULL) {
 | 
					 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wlr_dmabuf_attributes attribs;
 | 
						struct wlr_dmabuf_attributes attribs;
 | 
				
			||||||
	if (!export_drm_bo(bo, &attribs)) {
 | 
						if (!export_drm_bo(bo, &attribs)) {
 | 
				
			||||||
		free(tex);
 | 
					 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tex->tex = wlr_texture_from_dmabuf(renderer->wlr_rend, &attribs);
 | 
						tex = wlr_texture_from_dmabuf(renderer->wlr_rend, &attribs);
 | 
				
			||||||
	if (tex->tex == NULL) {
 | 
						if (tex) {
 | 
				
			||||||
		free(tex);
 | 
							gbm_bo_set_user_data(bo, tex, free_tex);
 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	gbm_bo_set_user_data(bo, tex, free_eglimage);
 | 
						return tex;
 | 
				
			||||||
	return tex->tex;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct gbm_bo *copy_drm_surface_mgpu(struct wlr_drm_surface *dest,
 | 
					struct gbm_bo *copy_drm_surface_mgpu(struct wlr_drm_surface *dest,
 | 
				
			||||||
| 
						 | 
					@ -238,7 +221,7 @@ struct gbm_bo *copy_drm_surface_mgpu(struct wlr_drm_surface *dest,
 | 
				
			||||||
	assert(tex);
 | 
						assert(tex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	float mat[9];
 | 
						float mat[9];
 | 
				
			||||||
	wlr_matrix_projection(mat, 1, 1, WL_OUTPUT_TRANSFORM_FLIPPED_180);
 | 
						wlr_matrix_projection(mat, 1, 1, WL_OUTPUT_TRANSFORM_NORMAL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wlr_renderer *renderer = dest->renderer->wlr_rend;
 | 
						struct wlr_renderer *renderer = dest->renderer->wlr_rend;
 | 
				
			||||||
	wlr_renderer_begin(renderer, dest->width, dest->height);
 | 
						wlr_renderer_begin(renderer, dest->width, dest->height);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -143,7 +143,7 @@ bool wlr_multi_backend_add(struct wlr_backend *_multi,
 | 
				
			||||||
	struct wlr_renderer *multi_renderer =
 | 
						struct wlr_renderer *multi_renderer =
 | 
				
			||||||
		multi_backend_get_renderer(&multi->backend);
 | 
							multi_backend_get_renderer(&multi->backend);
 | 
				
			||||||
	struct wlr_renderer *backend_renderer = wlr_backend_get_renderer(backend);
 | 
						struct wlr_renderer *backend_renderer = wlr_backend_get_renderer(backend);
 | 
				
			||||||
	if (multi_renderer != NULL && backend_renderer != NULL) {
 | 
						if (multi_renderer != NULL && backend_renderer != NULL && multi_renderer != backend_renderer) {
 | 
				
			||||||
		wlr_log(WLR_ERROR, "Could not add backend: multiple renderers at the "
 | 
							wlr_log(WLR_ERROR, "Could not add backend: multiple renderers at the "
 | 
				
			||||||
			"same time aren't supported");
 | 
								"same time aren't supported");
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -88,7 +88,7 @@ const struct wlr_gles2_pixel_format *get_gles2_format_from_wl(
 | 
				
			||||||
	enum wl_shm_format fmt);
 | 
						enum wl_shm_format fmt);
 | 
				
			||||||
const enum wl_shm_format *get_gles2_formats(size_t *len);
 | 
					const enum wl_shm_format *get_gles2_formats(size_t *len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wlr_gles2_texture *get_gles2_texture_in_context(
 | 
					struct wlr_gles2_texture *gles2_get_texture(
 | 
				
			||||||
	struct wlr_texture *wlr_texture);
 | 
						struct wlr_texture *wlr_texture);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void push_gles2_marker(const char *file, const char *func);
 | 
					void push_gles2_marker(const char *file, const char *func);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -116,7 +116,7 @@ static bool gles2_render_texture_with_matrix(struct wlr_renderer *wlr_renderer,
 | 
				
			||||||
	struct wlr_gles2_renderer *renderer =
 | 
						struct wlr_gles2_renderer *renderer =
 | 
				
			||||||
		gles2_get_renderer_in_context(wlr_renderer);
 | 
							gles2_get_renderer_in_context(wlr_renderer);
 | 
				
			||||||
	struct wlr_gles2_texture *texture =
 | 
						struct wlr_gles2_texture *texture =
 | 
				
			||||||
		get_gles2_texture_in_context(wlr_texture);
 | 
							gles2_get_texture(wlr_texture);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct wlr_gles2_tex_shader *shader = NULL;
 | 
						struct wlr_gles2_tex_shader *shader = NULL;
 | 
				
			||||||
	GLenum target = 0;
 | 
						GLenum target = 0;
 | 
				
			||||||
| 
						 | 
					@ -213,7 +213,7 @@ static const enum wl_shm_format *gles2_renderer_formats(
 | 
				
			||||||
static bool gles2_resource_is_wl_drm_buffer(struct wlr_renderer *wlr_renderer,
 | 
					static bool gles2_resource_is_wl_drm_buffer(struct wlr_renderer *wlr_renderer,
 | 
				
			||||||
		struct wl_resource *resource) {
 | 
							struct wl_resource *resource) {
 | 
				
			||||||
	struct wlr_gles2_renderer *renderer =
 | 
						struct wlr_gles2_renderer *renderer =
 | 
				
			||||||
		gles2_get_renderer_in_context(wlr_renderer);
 | 
							gles2_get_renderer(wlr_renderer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!eglQueryWaylandBufferWL) {
 | 
						if (!eglQueryWaylandBufferWL) {
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
| 
						 | 
					@ -227,7 +227,7 @@ static bool gles2_resource_is_wl_drm_buffer(struct wlr_renderer *wlr_renderer,
 | 
				
			||||||
static void gles2_wl_drm_buffer_get_size(struct wlr_renderer *wlr_renderer,
 | 
					static void gles2_wl_drm_buffer_get_size(struct wlr_renderer *wlr_renderer,
 | 
				
			||||||
		struct wl_resource *buffer, int *width, int *height) {
 | 
							struct wl_resource *buffer, int *width, int *height) {
 | 
				
			||||||
	struct wlr_gles2_renderer *renderer =
 | 
						struct wlr_gles2_renderer *renderer =
 | 
				
			||||||
		gles2_get_renderer_in_context(wlr_renderer);
 | 
							gles2_get_renderer(wlr_renderer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!eglQueryWaylandBufferWL) {
 | 
						if (!eglQueryWaylandBufferWL) {
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
| 
						 | 
					@ -323,7 +323,7 @@ static struct wlr_texture *gles2_texture_from_dmabuf(
 | 
				
			||||||
static void gles2_init_wl_display(struct wlr_renderer *wlr_renderer,
 | 
					static void gles2_init_wl_display(struct wlr_renderer *wlr_renderer,
 | 
				
			||||||
		struct wl_display *wl_display) {
 | 
							struct wl_display *wl_display) {
 | 
				
			||||||
	struct wlr_gles2_renderer *renderer =
 | 
						struct wlr_gles2_renderer *renderer =
 | 
				
			||||||
		gles2_get_renderer_in_context(wlr_renderer);
 | 
							gles2_get_renderer(wlr_renderer);
 | 
				
			||||||
	if (!wlr_egl_bind_display(renderer->egl, wl_display)) {
 | 
						if (!wlr_egl_bind_display(renderer->egl, wl_display)) {
 | 
				
			||||||
		wlr_log(WLR_INFO, "failed to bind wl_display to EGL");
 | 
							wlr_log(WLR_INFO, "failed to bind wl_display to EGL");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,7 +16,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct wlr_texture_impl texture_impl;
 | 
					static const struct wlr_texture_impl texture_impl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct wlr_gles2_texture *gles2_get_texture(
 | 
					struct wlr_gles2_texture *gles2_get_texture(
 | 
				
			||||||
		struct wlr_texture *wlr_texture) {
 | 
							struct wlr_texture *wlr_texture) {
 | 
				
			||||||
	assert(wlr_texture->impl == &texture_impl);
 | 
						assert(wlr_texture->impl == &texture_impl);
 | 
				
			||||||
	return (struct wlr_gles2_texture *)wlr_texture;
 | 
						return (struct wlr_gles2_texture *)wlr_texture;
 | 
				
			||||||
| 
						 | 
					@ -25,7 +25,9 @@ static struct wlr_gles2_texture *gles2_get_texture(
 | 
				
			||||||
struct wlr_gles2_texture *get_gles2_texture_in_context(
 | 
					struct wlr_gles2_texture *get_gles2_texture_in_context(
 | 
				
			||||||
		struct wlr_texture *wlr_texture) {
 | 
							struct wlr_texture *wlr_texture) {
 | 
				
			||||||
	struct wlr_gles2_texture *texture = gles2_get_texture(wlr_texture);
 | 
						struct wlr_gles2_texture *texture = gles2_get_texture(wlr_texture);
 | 
				
			||||||
	assert(wlr_egl_is_current(texture->egl));
 | 
						if (!wlr_egl_is_current(texture->egl)) {
 | 
				
			||||||
 | 
							wlr_egl_make_current(texture->egl, EGL_NO_SURFACE, NULL);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return texture;
 | 
						return texture;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -143,7 +145,9 @@ static const struct wlr_texture_impl texture_impl = {
 | 
				
			||||||
struct wlr_texture *wlr_gles2_texture_from_pixels(struct wlr_egl *egl,
 | 
					struct wlr_texture *wlr_gles2_texture_from_pixels(struct wlr_egl *egl,
 | 
				
			||||||
		enum wl_shm_format wl_fmt, uint32_t stride, uint32_t width,
 | 
							enum wl_shm_format wl_fmt, uint32_t stride, uint32_t width,
 | 
				
			||||||
		uint32_t height, const void *data) {
 | 
							uint32_t height, const void *data) {
 | 
				
			||||||
	assert(wlr_egl_is_current(egl));
 | 
						if (!wlr_egl_is_current(egl)) {
 | 
				
			||||||
 | 
							wlr_egl_make_current(egl, EGL_NO_SURFACE, NULL);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const struct wlr_gles2_pixel_format *fmt = get_gles2_format_from_wl(wl_fmt);
 | 
						const struct wlr_gles2_pixel_format *fmt = get_gles2_format_from_wl(wl_fmt);
 | 
				
			||||||
	if (fmt == NULL) {
 | 
						if (fmt == NULL) {
 | 
				
			||||||
| 
						 | 
					@ -180,7 +184,9 @@ struct wlr_texture *wlr_gles2_texture_from_pixels(struct wlr_egl *egl,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wlr_texture *wlr_gles2_texture_from_wl_drm(struct wlr_egl *egl,
 | 
					struct wlr_texture *wlr_gles2_texture_from_wl_drm(struct wlr_egl *egl,
 | 
				
			||||||
		struct wl_resource *data) {
 | 
							struct wl_resource *data) {
 | 
				
			||||||
	assert(wlr_egl_is_current(egl));
 | 
						if (!wlr_egl_is_current(egl)) {
 | 
				
			||||||
 | 
							wlr_egl_make_current(egl, EGL_NO_SURFACE, NULL);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!glEGLImageTargetTexture2DOES) {
 | 
						if (!glEGLImageTargetTexture2DOES) {
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
| 
						 | 
					@ -239,7 +245,9 @@ struct wlr_texture *wlr_gles2_texture_from_wl_drm(struct wlr_egl *egl,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct wlr_texture *wlr_gles2_texture_from_dmabuf(struct wlr_egl *egl,
 | 
					struct wlr_texture *wlr_gles2_texture_from_dmabuf(struct wlr_egl *egl,
 | 
				
			||||||
		struct wlr_dmabuf_attributes *attribs) {
 | 
							struct wlr_dmabuf_attributes *attribs) {
 | 
				
			||||||
	assert(wlr_egl_is_current(egl));
 | 
						if (!wlr_egl_is_current(egl)) {
 | 
				
			||||||
 | 
							wlr_egl_make_current(egl, EGL_NO_SURFACE, NULL);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!glEGLImageTargetTexture2DOES) {
 | 
						if (!glEGLImageTargetTexture2DOES) {
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue