diff options
author | Miguel A. Vico | 2019-03-26 17:54:58 -0700 |
---|---|---|
committer | Miguel A. Vico | 2019-03-27 22:04:18 -0700 |
commit | 6270174bd71c83185112d299fbc842293b7ffb2c (patch) | |
tree | ca801657abff728d5f55c31b55db438fb686053b /0006-compositor-drm-Add-support-for-EGLDevice-EGLOutput.patch | |
parent | 1ec939fa1774fe9bfa98f601f90a1b0669b267ba (diff) | |
download | aur-6270174bd71c83185112d299fbc842293b7ffb2c.tar.gz |
Update to weston 6.0.0
Diffstat (limited to '0006-compositor-drm-Add-support-for-EGLDevice-EGLOutput.patch')
-rw-r--r-- | 0006-compositor-drm-Add-support-for-EGLDevice-EGLOutput.patch | 579 |
1 files changed, 579 insertions, 0 deletions
diff --git a/0006-compositor-drm-Add-support-for-EGLDevice-EGLOutput.patch b/0006-compositor-drm-Add-support-for-EGLDevice-EGLOutput.patch new file mode 100644 index 000000000000..84680572627b --- /dev/null +++ b/0006-compositor-drm-Add-support-for-EGLDevice-EGLOutput.patch @@ -0,0 +1,579 @@ +From 73bc85fbde7c65d3a667982301877238d3c02bf8 Mon Sep 17 00:00:00 2001 +From: "Miguel A. Vico" <mvicomoya@nvidia.com> +Date: Thu, 28 Jan 2016 19:37:10 +0100 +Subject: [PATCH 6/8] compositor-drm: Add support for EGLDevice+EGLOutput +X-NVConfidentiality: public + +As previously stated, EGLDevice and EGLOutput will provide means +to access native device objects and different portions of display +control hardware respectively. + +Whenever EGL_EXT_device_drm extension is present, EGLDevice can +be used to enumerate and access DRM KMS devices, and EGLOutputLayer +to enumerate and access DRM KMS crtcs and planes. + +By using EGLStreams and attaching an EGLOutputLayer consumer +(representing a DRM KMS crtc or plane) to it, compositor-drm can +produce final composition frames and present them on a DRM device. + +This change adds required logic to support presentation through +EGLDevice+EGLOutput+EGLStream. Whether GBM or EGLDevice should be +used can be controlled by --use-egldevice backend argument. + +Signed-off-by: Miguel A Vico Moya <mvicomoya@nvidia.com> +Reviewed-by: Andy Ritger <aritger@nvidia.com> +Reviewed-by: Adam Cheney <acheney@nvidia.com> +Reviewed-by: James Jones <jajones@nvidia.com> +--- + compositor/main.c | 2 + + libweston/compositor-drm.c | 336 +++++++++++++++++++++++++------------ + libweston/compositor-drm.h | 4 + + libweston/gl-renderer.h | 1 + + shared/weston-egl-ext.h | 9 + + 5 files changed, 245 insertions(+), 107 deletions(-) + +diff --git a/compositor/main.c b/compositor/main.c +index c3206783..103305e3 100644 +--- a/compositor/main.c ++++ b/compositor/main.c +@@ -664,6 +664,7 @@ usage(int error_code) + " --tty=TTY\t\tThe tty to use\n" + " --drm-device=CARD\tThe DRM device to use, e.g. \"card0\".\n" + " --use-pixman\t\tUse the pixman (CPU) renderer\n" ++ " --use-egldevice\tUse EGLDevice and EGLOutput with the GL renderer\n" + " --current-mode\tPrefer current KMS mode over EDID preferred mode\n\n"); + #endif + +@@ -2341,6 +2342,7 @@ load_drm_backend(struct weston_compositor *c, + { WESTON_OPTION_STRING, "drm-device", 0, &config.specific_device }, + { WESTON_OPTION_BOOLEAN, "current-mode", 0, &wet->drm_use_current_mode }, + { WESTON_OPTION_BOOLEAN, "use-pixman", 0, &use_pixman_ }, ++ { WESTON_OPTION_BOOLEAN, "use-egldevice", 0, &config.use_egldevice }, + }; + + parse_options(options, ARRAY_LENGTH(options), argc, argv); +diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c +index 77dbb077..100b3050 100644 +--- a/libweston/compositor-drm.c ++++ b/libweston/compositor-drm.c +@@ -310,7 +310,10 @@ struct drm_backend { + int fd; + char *filename; + } drm; ++ ++ EGLDeviceEXT egldevice; + struct gbm_device *gbm; ++ + struct wl_listener session_listener; + uint32_t gbm_format; + +@@ -340,6 +343,8 @@ struct drm_backend { + bool use_pixman; + bool use_pixman_shadow; + ++ int use_egldevice; ++ + struct udev_input input; + + int32_t cursor_width; +@@ -2109,20 +2114,24 @@ drm_output_render_gl(struct drm_output_state *state, pixman_region32_t *damage) + output->base.compositor->renderer->repaint_output(&output->base, + damage); + +- bo = gbm_surface_lock_front_buffer(output->gbm_surface); +- if (!bo) { +- weston_log("failed to lock front buffer: %m\n"); +- return NULL; +- } ++ if (b->use_egldevice) ++ ret = drm_fb_ref(output->dumb[0]); ++ else { ++ bo = gbm_surface_lock_front_buffer(output->gbm_surface); ++ if (!bo) { ++ weston_log("failed to lock front buffer: %m\n"); ++ return NULL; ++ } + +- /* The renderer always produces an opaque image. */ +- ret = drm_fb_get_from_bo(bo, b, true, BUFFER_GBM_SURFACE); +- if (!ret) { +- weston_log("failed to get drm_fb for bo\n"); +- gbm_surface_release_buffer(output->gbm_surface, bo); +- return NULL; ++ /* The renderer always produces an opaque image. */ ++ ret = drm_fb_get_from_bo(bo, b, true, BUFFER_GBM_SURFACE); ++ if (!ret) { ++ weston_log("failed to get drm_fb for bo\n"); ++ gbm_surface_release_buffer(output->gbm_surface, bo); ++ return NULL; ++ } ++ ret->gbm_surface = output->gbm_surface; + } +- ret->gbm_surface = output->gbm_surface; + + return ret; + } +@@ -2165,7 +2174,9 @@ drm_output_render(struct drm_output_state *state, pixman_region32_t *damage) + if (scanout_state->fb) + return; + +- if (!pixman_region32_not_empty(damage) && ++ /* XXX: Assume full damage when using streams */ ++ if (!b->use_egldevice && ++ !pixman_region32_not_empty(damage) && + scanout_plane->state_cur->fb && + (scanout_plane->state_cur->fb->type == BUFFER_GBM_SURFACE || + scanout_plane->state_cur->fb->type == BUFFER_PIXMAN_DUMB) && +@@ -2358,9 +2369,14 @@ drm_output_apply_state_legacy(struct drm_output_state *state) + output->crtc_id, scanout_state->plane->plane_id, + pinfo ? pinfo->drm_format_name : "UNKNOWN"); + +- if (drmModePageFlip(backend->drm.fd, output->crtc_id, +- scanout_state->fb->fb_id, +- DRM_MODE_PAGE_FLIP_EVENT, output) < 0) { ++ if (backend->use_egldevice) ++ ret = gl_renderer->output_stream_flip(&output->base, output); ++ else ++ ret = drmModePageFlip(backend->drm.fd, output->crtc_id, ++ scanout_state->fb->fb_id, ++ DRM_MODE_PAGE_FLIP_EVENT, output); ++ ++ if (ret < 0) { + weston_log("queueing pageflip failed: %m\n"); + goto err; + } +@@ -4174,7 +4190,8 @@ init_kms_caps(struct drm_backend *b) + b->universal_planes ? "supports" : "does not support"); + + #ifdef HAVE_DRM_ATOMIC +- if (b->universal_planes && !getenv("WESTON_DISABLE_ATOMIC")) { ++ /* FIXME: Atomic modeset is not yet fully supported with streams */ ++ if (b->universal_planes && !getenv("WESTON_DISABLE_ATOMIC") && !b->use_egldevice) { + ret = drmGetCap(b->drm.fd, DRM_CAP_CRTC_IN_VBLANK_EVENT, &cap); + if (ret != 0) + cap = 0; +@@ -4217,11 +4234,6 @@ create_gbm_device(int fd) + { + struct gbm_device *gbm; + +- gl_renderer = weston_load_module("gl-renderer.so", +- "gl_renderer_interface"); +- if (!gl_renderer) +- return NULL; +- + /* GBM will load a dri driver, but even though they need symbols from + * libglapi, in some version of Mesa they are not linked to it. Since + * only the gl-renderer module links to it, the call above won't make +@@ -4234,6 +4246,40 @@ create_gbm_device(int fd) + return gbm; + } + ++static EGLDeviceEXT ++find_egldevice(const char *filename) ++{ ++ EGLDeviceEXT egldevice = EGL_NO_DEVICE_EXT; ++ EGLDeviceEXT *devices; ++ EGLint num_devices; ++ const char *drm_path; ++ int i; ++ ++ if (gl_renderer->get_devices(0, NULL, &num_devices) < 0 || ++ num_devices < 1) ++ return EGL_NO_DEVICE_EXT; ++ ++ devices = zalloc(num_devices * sizeof *devices); ++ if (!devices) ++ return EGL_NO_DEVICE_EXT; ++ ++ if (gl_renderer->get_devices(num_devices, devices, &num_devices) < 0) { ++ free(devices); ++ return EGL_NO_DEVICE_EXT; ++ } ++ ++ for (i = 0; i < num_devices; i++) ++ if (gl_renderer->get_drm_device_file(devices[i], ++ &drm_path) == 0 && ++ strcmp(filename, drm_path) == 0) { ++ egldevice = devices[i]; ++ break; ++ } ++ ++ free(devices); ++ return egldevice; ++} ++ + /* When initializing EGL, if the preferred buffer format isn't available + * we may be able to substitute an ARGB format for an XRGB one. + * +@@ -4260,38 +4306,62 @@ fallback_format_for(uint32_t format) + static int + drm_backend_create_gl_renderer(struct drm_backend *b) + { +- EGLint format[3] = { +- b->gbm_format, +- fallback_format_for(b->gbm_format), +- 0, +- }; +- int n_formats = 2; ++ if (b->use_egldevice) { ++ EGLint device_platform_attribs[] = { ++ EGL_DRM_MASTER_FD_EXT, b->drm.fd, ++ EGL_NONE ++ }; + +- if (format[1]) +- n_formats = 3; +- if (gl_renderer->display_create(b->compositor, +- EGL_PLATFORM_GBM_KHR, +- (void *)b->gbm, ++ return gl_renderer->display_create( ++ b->compositor, ++ EGL_PLATFORM_DEVICE_EXT, ++ (void *)b->egldevice, ++ device_platform_attribs, ++ gl_renderer->opaque_stream_attribs, + NULL, +- gl_renderer->opaque_attribs, +- format, +- n_formats) < 0) { +- return -1; +- } ++ 0); ++ } else { ++ EGLint format[3] = { ++ b->gbm_format, ++ fallback_format_for(b->gbm_format), ++ 0, ++ }; ++ int n_formats = 2; + +- return 0; ++ if (format[1]) ++ n_formats = 3; ++ ++ return gl_renderer->display_create(b->compositor, ++ EGL_PLATFORM_GBM_KHR, ++ (void *)b->gbm, ++ NULL, ++ gl_renderer->opaque_attribs, ++ format, ++ n_formats); ++ } + } + + static int + init_egl(struct drm_backend *b) + { +- b->gbm = create_gbm_device(b->drm.fd); +- +- if (!b->gbm) ++ gl_renderer = weston_load_module("gl-renderer.so", ++ "gl_renderer_interface"); ++ if (!gl_renderer) + return -1; + ++ if (b->use_egldevice) { ++ b->egldevice = find_egldevice(b->drm.filename); ++ if (b->egldevice == EGL_NO_DEVICE_EXT) ++ return -1; ++ } else { ++ b->gbm = create_gbm_device(b->drm.fd); ++ if (!b->gbm) ++ return -1; ++ } ++ + if (drm_backend_create_gl_renderer(b) < 0) { +- gbm_device_destroy(b->gbm); ++ if (b->gbm) ++ gbm_device_destroy(b->gbm); + return -1; + } + +@@ -5058,71 +5128,98 @@ err: + static int + drm_output_init_egl(struct drm_output *output, struct drm_backend *b) + { +- EGLint format[2] = { +- output->gbm_format, +- fallback_format_for(output->gbm_format), +- }; +- int n_formats = 1; +- struct weston_mode *mode = output->base.current_mode; +- struct drm_plane *plane = output->scanout_plane; +- unsigned int i; ++ if (b->use_egldevice) { ++ int w = output->base.current_mode->width; ++ int h = output->base.current_mode->height; + +- assert(output->gbm_surface == NULL); ++ /* Create a black dumb fb for modesetting */ ++ output->dumb[0] = drm_fb_create_dumb(b, w, h, ++ DRM_FORMAT_XRGB8888); ++ if (!output->dumb[0]) { ++ weston_log("failed to create dumb framebuffer\n"); ++ return -1; ++ } ++ memset(output->dumb[0]->map, 0, output->dumb[0]->size); ++ ++ if (gl_renderer->output_stream_create(&output->base, ~0u, ++ output->crtc_id) < 0) { ++ weston_log("failed to create gl renderer output stream " ++ "state\n"); ++ drm_fb_destroy_dumb(output->dumb[0]); ++ output->dumb[0] = NULL; ++ return -1; ++ } + +- for (i = 0; i < plane->count_formats; i++) { +- if (plane->formats[i].format == output->gbm_format) +- break; +- } ++ /* FIXME: Add hw planes and cursors for EGL device when supported */ ++ b->sprites_are_broken = 1; ++ b->cursors_are_broken = 1; ++ } else { ++ EGLint format[2] = { ++ output->gbm_format, ++ fallback_format_for(output->gbm_format), ++ }; ++ int n_formats = 1; ++ struct weston_mode *mode = output->base.current_mode; ++ struct drm_plane *plane = output->scanout_plane; ++ unsigned int i; + +- if (i == plane->count_formats) { +- weston_log("format 0x%x not supported by output %s\n", +- output->gbm_format, output->base.name); +- return -1; +- } ++ assert(output->gbm_surface == NULL); ++ ++ for (i = 0; i < plane->count_formats; i++) { ++ if (plane->formats[i].format == output->gbm_format) ++ break; ++ } ++ ++ if (i == plane->count_formats) { ++ weston_log("format 0x%x not supported by output %s\n", ++ output->gbm_format, output->base.name); ++ return -1; ++ } + + #ifdef HAVE_GBM_MODIFIERS +- if (plane->formats[i].count_modifiers > 0) { +- output->gbm_surface = +- gbm_surface_create_with_modifiers(b->gbm, +- mode->width, +- mode->height, +- output->gbm_format, +- plane->formats[i].modifiers, +- plane->formats[i].count_modifiers); +- } +- +- /* If allocating with modifiers fails, try again without. This can +- * happen when the KMS display device supports modifiers but the +- * GBM driver does not, e.g. the old i915 Mesa driver. */ +- if (!output->gbm_surface) ++ if (plane->formats[i].count_modifiers > 0) { ++ output->gbm_surface = ++ gbm_surface_create_with_modifiers(b->gbm, ++ mode->width, ++ mode->height, ++ output->gbm_format, ++ plane->formats[i].modifiers, ++ plane->formats[i].count_modifiers); ++ } ++ ++ /* If allocating with modifiers fails, try again without. This can ++ * happen when the KMS display device supports modifiers but the ++ * GBM driver does not, e.g. the old i915 Mesa driver. */ ++ if (!output->gbm_surface) + #endif +- { +- output->gbm_surface = +- gbm_surface_create(b->gbm, mode->width, mode->height, +- output->gbm_format, +- output->gbm_bo_flags); +- } ++ { ++ output->gbm_surface = ++ gbm_surface_create(b->gbm, mode->width, mode->height, ++ output->gbm_format, ++ output->gbm_bo_flags); ++ } + +- if (!output->gbm_surface) { +- weston_log("failed to create gbm surface\n"); +- return -1; +- } ++ if (!output->gbm_surface) { ++ weston_log("failed to create gbm surface\n"); ++ return -1; ++ } + +- if (format[1]) +- n_formats = 2; +- if (gl_renderer->output_window_create(&output->base, +- (EGLNativeWindowType)output->gbm_surface, +- output->gbm_surface, +- gl_renderer->opaque_attribs, +- format, +- n_formats) < 0) { +- weston_log("failed to create gl renderer output state\n"); +- gbm_surface_destroy(output->gbm_surface); +- output->gbm_surface = NULL; +- return -1; +- } ++ if (format[1]) ++ n_formats = 2; ++ if (gl_renderer->output_window_create(&output->base, ++ (EGLNativeWindowType)output->gbm_surface, ++ output->gbm_surface, ++ gl_renderer->opaque_attribs, ++ format, ++ n_formats) < 0) { ++ weston_log("failed to create gl renderer output state\n"); ++ gbm_surface_destroy(output->gbm_surface); ++ output->gbm_surface = NULL; ++ return -1; ++ } + +- drm_output_init_cursor_egl(output, b); ++ drm_output_init_cursor_egl(output, b); ++ } + + return 0; + } +@@ -5144,8 +5241,17 @@ drm_output_fini_egl(struct drm_output *output) + } + + gl_renderer->output_destroy(&output->base); +- gbm_surface_destroy(output->gbm_surface); +- output->gbm_surface = NULL; ++ ++ if (output->dumb[0]) { ++ drm_fb_unref(output->dumb[0]); ++ output->dumb[0] = NULL; ++ } ++ ++ if (output->gbm_surface) { ++ gbm_surface_destroy(output->gbm_surface); ++ output->gbm_surface = NULL; ++ } ++ + drm_output_fini_cursor_egl(output); + } + +@@ -7050,6 +7156,11 @@ recorder_binding(struct weston_keyboard *keyboard, const struct timespec *time, + struct drm_output *output; + int width, height; + ++ if (b->use_egldevice) { ++ weston_log("recorder not supported with EGL device\n"); ++ return; ++ } ++ + output = container_of(b->compositor->output_list.next, + struct drm_output, base.link); + +@@ -7108,11 +7219,20 @@ switch_to_gl_renderer(struct drm_backend *b) + + weston_log("Switching to GL renderer\n"); + +- b->gbm = create_gbm_device(b->drm.fd); +- if (!b->gbm) { +- weston_log("Failed to create gbm device. " +- "Aborting renderer switch\n"); +- return; ++ if (b->use_egldevice) { ++ b->egldevice = find_egldevice(b->drm.filename); ++ if (b->egldevice == EGL_NO_DEVICE_EXT) { ++ weston_log("Failed to create EGL device. " ++ "Aborting renderer switch\n"); ++ return; ++ } ++ } else { ++ b->gbm = create_gbm_device(b->drm.fd); ++ if (!b->gbm) { ++ weston_log("Failed to create gbm device. " ++ "Aborting renderer switch\n"); ++ return; ++ } + } + + wl_list_for_each(output, &b->compositor->output_list, base.link) +@@ -7121,7 +7241,8 @@ switch_to_gl_renderer(struct drm_backend *b) + b->compositor->renderer->destroy(b->compositor); + + if (drm_backend_create_gl_renderer(b) < 0) { +- gbm_device_destroy(b->gbm); ++ if (b->gbm) ++ gbm_device_destroy(b->gbm); + weston_log("Failed to create GL renderer. Quitting.\n"); + /* FIXME: we need a function to shutdown cleanly */ + assert(0); +@@ -7451,6 +7572,7 @@ drm_backend_create(struct weston_compositor *compositor, + b->use_pixman = config->use_pixman; + b->pageflip_timeout = config->pageflip_timeout; + b->use_pixman_shadow = config->use_pixman_shadow; ++ b->use_egldevice = config->use_egldevice; + + b->debug = weston_compositor_add_debug_scope(compositor, "drm-backend", + "Debug messages from DRM/KMS backend\n", +diff --git a/libweston/compositor-drm.h b/libweston/compositor-drm.h +index 71a306fd..435581d9 100644 +--- a/libweston/compositor-drm.h ++++ b/libweston/compositor-drm.h +@@ -177,6 +177,10 @@ struct weston_drm_backend_config { + /** Whether to use the pixman renderer instead of the OpenGL ES renderer. */ + bool use_pixman; + ++ /** Whether to use the GL composition based off EGLDevice & friends instead ++ * of GBM. */ ++ bool use_egldevice; ++ + /** The seat to be used for input and output. + * + * If seat_id is NULL, the seat is taken from XDG_SEAT environment +diff --git a/libweston/gl-renderer.h b/libweston/gl-renderer.h +index 973097bf..233c9282 100644 +--- a/libweston/gl-renderer.h ++++ b/libweston/gl-renderer.h +@@ -45,6 +45,7 @@ typedef void *EGLConfig; + typedef intptr_t EGLNativeDisplayType; + typedef intptr_t EGLNativeWindowType; + #define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)0) ++#define EGL_NO_DEVICE_EXT ((EGLDeviceEXT)0) + + #endif /* ENABLE_EGL */ + +diff --git a/shared/weston-egl-ext.h b/shared/weston-egl-ext.h +index 96982e2d..e4e10ef9 100644 +--- a/shared/weston-egl-ext.h ++++ b/shared/weston-egl-ext.h +@@ -208,6 +208,10 @@ typedef EGLint (EGLAPIENTRYP PFNEGLDUPNATIVEFENCEFDANDROIDPROC) (EGLDisplay dpy, + #define EGL_PLATFORM_DEVICE_EXT 0x313F + #endif + ++#ifndef EGL_DRM_MASTER_FD_EXT ++#define EGL_DRM_MASTER_FD_EXT 0x333C ++#endif ++ + /* + * FIXME: Remove both EGL_EXT_stream_acquire_mode and + * EGL_NV_output_drm_flip_event definitions below once both extensions +@@ -256,6 +260,11 @@ EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerAcquireAttribEXT (EGLDisplay dpy, + #define EGL_PLATFORM_X11_KHR 0x31D5 + #define EGL_PLATFORM_DEVICE_EXT 0x313F + ++/* EGL_DRM_MASTER_FD_EXT and EGL_NONE enum values are also kept to allow ++ * compositor-drm.c to build with EGLDevice and EGLStream support */ ++#define EGL_DRM_MASTER_FD_EXT 0x333C ++#define EGL_NONE 0x3038 ++ + #endif /* ENABLE_EGL */ + + #endif +-- +2.21.0 + |