diff options
author | Miguel A. Vico | 2017-08-09 17:02:07 -0700 |
---|---|---|
committer | Miguel A. Vico | 2017-08-09 17:02:07 -0700 |
commit | 96452a48b8d31a9f48c7ece5d8d5a7935b2fa8b3 (patch) | |
tree | 5033b97899584014c8917eb2288fde0b044ecc47 /0006-compositor-drm-Add-support-for-EGLDevice-EGLOutput.patch | |
parent | 87ffac5fff77badfc6c0ecaa022ef7ca96278cd2 (diff) | |
download | aur-96452a48b8d31a9f48c7ece5d8d5a7935b2fa8b3.tar.gz |
Update to weston 3.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 | 524 |
1 files changed, 524 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..12d9e0121fc5 --- /dev/null +++ b/0006-compositor-drm-Add-support-for-EGLDevice-EGLOutput.patch @@ -0,0 +1,524 @@ +From a151d9d94a819673a4fa2cafef2a91dbedc17be4 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/9] 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 | 285 ++++++++++++++++++++++++++++++++------------- + libweston/compositor-drm.h | 4 + + libweston/gl-renderer.h | 1 + + shared/weston-egl-ext.h | 9 ++ + 5 files changed, 220 insertions(+), 81 deletions(-) + +diff --git a/compositor/main.c b/compositor/main.c +index f8a60e97..7abc8d1a 100644 +--- a/compositor/main.c ++++ b/compositor/main.c +@@ -566,6 +566,7 @@ usage(int error_code) + " --seat=SEAT\t\tThe seat that weston should run on\n" + " --tty=TTY\t\tThe tty to use\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 + +@@ -1227,6 +1228,7 @@ load_drm_backend(struct weston_compositor *c, + { WESTON_OPTION_INTEGER, "tty", 0, &config.tty }, + { WESTON_OPTION_BOOLEAN, "current-mode", 0, &wet->drm_use_current_mode }, + { WESTON_OPTION_BOOLEAN, "use-pixman", 0, &config.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 7120b578..1eed58a7 100644 +--- a/libweston/compositor-drm.c ++++ b/libweston/compositor-drm.c +@@ -95,7 +95,10 @@ struct drm_backend { + int fd; + char *filename; + } drm; ++ ++ EGLDeviceEXT egldevice; + struct gbm_device *gbm; ++ + struct wl_listener session_listener; + uint32_t gbm_format; + +@@ -114,6 +117,7 @@ struct drm_backend { + int cursors_are_broken; + + int use_pixman; ++ int use_egldevice; + + struct udev_input input; + +@@ -735,19 +739,23 @@ drm_output_render_gl(struct drm_output *output, 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; ++ } + +- ret = drm_fb_get_from_bo(bo, b, output->gbm_format, 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 = drm_fb_get_from_bo(bo, b, output->gbm_format, 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; + } +@@ -898,9 +906,14 @@ drm_output_repaint(struct weston_output *output_base, + output->state_invalid = false; + } + +- if (drmModePageFlip(backend->drm.fd, output->crtc_id, +- output->fb_pending->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, ++ output->fb_pending->fb_id, ++ DRM_MODE_PAGE_FLIP_EVENT, output); ++ ++ if (ret < 0) { + weston_log("queueing pageflip failed: %m\n"); + goto err_pageflip; + } +@@ -985,7 +998,6 @@ drm_output_start_repaint_loop(struct weston_output *output_base) + struct drm_output *output = to_drm_output(output_base); + struct drm_backend *backend = + to_drm_backend(output_base->compositor); +- uint32_t fb_id; + struct timespec ts, tnow; + struct timespec vbl2now; + int64_t refresh_nsec; +@@ -1047,13 +1059,17 @@ drm_output_start_repaint_loop(struct weston_output *output_base) + /* Immediate query succeeded, but didn't provide valid timestamp. + * Use pageflip fallback. + */ +- fb_id = output->fb_current->fb_id; +- + assert(!output->page_flip_pending); + assert(!output->fb_last); + +- if (drmModePageFlip(backend->drm.fd, output->crtc_id, 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, ++ output->fb_current->fb_id, ++ DRM_MODE_PAGE_FLIP_EVENT, output); ++ ++ if (ret < 0) { + weston_log("queueing pageflip failed: %m\n"); + goto finish_frame; + } +@@ -1761,11 +1777,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 +@@ -1778,6 +1789,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. + * +@@ -1804,38 +1849,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; + } + +@@ -2122,37 +2191,67 @@ 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; +- +- output->gbm_surface = gbm_surface_create(b->gbm, +- output->base.current_mode->width, +- output->base.current_mode->height, +- format[0], +- GBM_BO_USE_SCANOUT | +- GBM_BO_USE_RENDERING); +- if (!output->gbm_surface) { +- weston_log("failed to create gbm surface\n"); +- return -1; +- } ++ if (b->use_egldevice) { ++ int w = output->base.current_mode->width; ++ int h = output->base.current_mode->height; + +- 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); +- return -1; +- } ++ /* 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; ++ } ++ ++ /* 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; ++ ++ output->gbm_surface = gbm_surface_create( ++ b->gbm, ++ output->base.current_mode->width, ++ output->base.current_mode->height, ++ format[0], ++ GBM_BO_USE_SCANOUT | ++ GBM_BO_USE_RENDERING); ++ if (!output->gbm_surface) { ++ weston_log("failed to create gbm surface\n"); ++ return -1; ++ } + +- drm_output_init_cursor_egl(output, b); ++ 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); ++ return -1; ++ } ++ ++ drm_output_init_cursor_egl(output, b); ++ } + + return 0; + } +@@ -2161,7 +2260,15 @@ static void + drm_output_fini_egl(struct drm_output *output) + { + gl_renderer->output_destroy(&output->base); +- gbm_surface_destroy(output->gbm_surface); ++ ++ if (output->dumb[0]) { ++ drm_fb_destroy_dumb(output->dumb[0]); ++ output->dumb[0] = NULL; ++ } ++ ++ if (output->gbm_surface) ++ gbm_surface_destroy(output->gbm_surface); ++ + drm_output_fini_cursor_egl(output); + } + +@@ -3438,6 +3545,11 @@ recorder_binding(struct weston_keyboard *keyboard, uint32_t time, uint32_t key, + 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); + +@@ -3493,11 +3605,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) +@@ -3506,7 +3627,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); +@@ -3572,6 +3694,7 @@ drm_backend_create(struct weston_compositor *compositor, + b->compositor = compositor; + b->use_pixman = config->use_pixman; + b->pageflip_timeout = config->pageflip_timeout; ++ b->use_egldevice = config->use_egldevice; + + if (parse_gbm_format(config->gbm_format, GBM_FORMAT_XRGB8888, &b->gbm_format) < 0) + goto err_compositor; +diff --git a/libweston/compositor-drm.h b/libweston/compositor-drm.h +index 08707197..bb4ce8cb 100644 +--- a/libweston/compositor-drm.h ++++ b/libweston/compositor-drm.h +@@ -110,6 +110,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 NULL the default "seat0" will be used. The backend will +diff --git a/libweston/gl-renderer.h b/libweston/gl-renderer.h +index 39ea3b42..37252492 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 31096e64..778eae07 100644 +--- a/shared/weston-egl-ext.h ++++ b/shared/weston-egl-ext.h +@@ -180,6 +180,10 @@ typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC) (EGLD + #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 +@@ -228,6 +232,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.13.3 + |