diff --git a/src/backends/native/meta-onscreen-native.c b/src/backends/native/meta-onscreen-native.c index 3ff250415..8462d9ee3 100644 --- a/src/backends/native/meta-onscreen-native.c +++ b/src/backends/native/meta-onscreen-native.c @@ -43,6 +43,8 @@ #include "backends/native/meta-kms-utils.h" #include "backends/native/meta-kms.h" #include "backends/native/meta-output-kms.h" +#include "backends/native/meta-render-device-gbm.h" +#include "backends/native/meta-render-device.h" #include "backends/native/meta-renderer-native-gles3.h" #include "backends/native/meta-renderer-native-private.h" @@ -369,6 +371,7 @@ custom_egl_stream_page_flip (gpointer custom_page_flip_data, MetaRendererView *view = user_data; MetaEgl *egl = meta_onscreen_native_get_egl (onscreen_native); MetaRendererNativeGpuData *renderer_gpu_data; + MetaRenderDevice *render_device; EGLDisplay *egl_display; EGLAttrib *acquire_attribs; g_autoptr (GError) error = NULL; @@ -382,8 +385,9 @@ custom_egl_stream_page_flip (gpointer custom_page_flip_data, renderer_gpu_data = meta_renderer_native_get_gpu_data (onscreen_native->renderer_native, onscreen_native->render_gpu); + render_device = renderer_gpu_data->render_device; - egl_display = renderer_gpu_data->egl_display; + egl_display = meta_render_device_get_egl_display (render_device); if (!meta_egl_stream_consumer_acquire_attrib (egl, egl_display, onscreen_native->egl.stream, @@ -548,10 +552,14 @@ secondary_gpu_state_free (MetaOnscreenNativeSecondaryGpuState *secondary_gpu_sta if (secondary_gpu_state->egl_surface != EGL_NO_SURFACE) { MetaRendererNativeGpuData *renderer_gpu_data; + MetaRenderDevice *render_device; + EGLDisplay egl_display; renderer_gpu_data = secondary_gpu_state->renderer_gpu_data; + render_device = renderer_gpu_data->render_device; + egl_display = meta_render_device_get_egl_display (render_device); meta_egl_destroy_surface (egl, - renderer_gpu_data->egl_display, + egl_display, secondary_gpu_state->egl_surface, NULL); } @@ -570,28 +578,21 @@ import_shared_framebuffer (CoglOnscreen *onscreen, MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state) { MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen); - MetaGpuKms *gpu_kms; - MetaDeviceFile *device_file; - struct gbm_device *gbm_device; - MetaDrmBufferGbm *buffer_gbm; - MetaDrmBufferImport *buffer_import; + MetaRenderDevice *render_device; g_autoptr (GError) error = NULL; + MetaDrmBuffer *imported_buffer; - buffer_gbm = META_DRM_BUFFER_GBM (onscreen_native->gbm.next_fb); - - gpu_kms = secondary_gpu_state->gpu_kms; - device_file = secondary_gpu_state->renderer_gpu_data->device_file; - gbm_device = meta_gbm_device_from_gpu (gpu_kms); - buffer_import = meta_drm_buffer_import_new (device_file, - gbm_device, - buffer_gbm, - &error); - if (!buffer_import) + render_device = secondary_gpu_state->renderer_gpu_data->render_device; + imported_buffer = + meta_render_device_import_dma_buf (render_device, + onscreen_native->gbm.next_fb, + &error); + if (!imported_buffer) { meta_topic (META_DEBUG_KMS, "Zero-copy disabled for %s, " "meta_drm_buffer_import_new failed: %s", - meta_device_file_get_path (device_file), + meta_render_device_get_name (render_device), error->message); g_warn_if_fail (secondary_gpu_state->import_status == @@ -620,7 +621,7 @@ import_shared_framebuffer (CoglOnscreen *onscreen, * when we are sure to succeed. */ g_clear_object (&secondary_gpu_state->gbm.next_fb); - secondary_gpu_state->gbm.next_fb = META_DRM_BUFFER (buffer_import); + secondary_gpu_state->gbm.next_fb = imported_buffer; if (secondary_gpu_state->import_status == META_SHARED_FRAMEBUFFER_IMPORT_STATUS_NONE) @@ -633,7 +634,7 @@ import_shared_framebuffer (CoglOnscreen *onscreen, meta_topic (META_DEBUG_KMS, "Using zero-copy for %s succeeded once.", - meta_device_file_get_path (device_file)); + meta_render_device_get_name (render_device)); } secondary_gpu_state->import_status = @@ -651,6 +652,8 @@ copy_shared_framebuffer_gpu (CoglOnscreen *onscreen, MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native; MetaEgl *egl = meta_renderer_native_get_egl (renderer_native); MetaGles3 *gles3 = meta_renderer_native_get_gles3 (renderer_native); + MetaRenderDevice *render_device; + EGLDisplay egl_display; GError *error = NULL; gboolean use_modifiers; MetaDeviceFile *device_file; @@ -664,8 +667,11 @@ copy_shared_framebuffer_gpu (CoglOnscreen *onscreen, g_warn_if_fail (secondary_gpu_state->gbm.next_fb == NULL); g_clear_object (&secondary_gpu_state->gbm.next_fb); + render_device = renderer_gpu_data->render_device; + egl_display = meta_render_device_get_egl_display (render_device); + if (!meta_egl_make_current (egl, - renderer_gpu_data->egl_display, + egl_display, secondary_gpu_state->egl_surface, secondary_gpu_state->egl_surface, renderer_gpu_data->secondary.egl_context, @@ -683,7 +689,7 @@ copy_shared_framebuffer_gpu (CoglOnscreen *onscreen, bo = meta_drm_buffer_gbm_get_bo (buffer_gbm); if (!meta_renderer_native_gles3_blit_shared_bo (egl, gles3, - renderer_gpu_data->egl_display, + egl_display, renderer_gpu_data->secondary.egl_context, secondary_gpu_state->egl_surface, bo, @@ -695,7 +701,7 @@ copy_shared_framebuffer_gpu (CoglOnscreen *onscreen, } if (!meta_egl_swap_buffers (egl, - renderer_gpu_data->egl_display, + egl_display, secondary_gpu_state->egl_surface, &error)) { @@ -705,7 +711,7 @@ copy_shared_framebuffer_gpu (CoglOnscreen *onscreen, } use_modifiers = meta_renderer_native_use_modifiers (renderer_native); - device_file = secondary_gpu_state->renderer_gpu_data->device_file; + device_file = meta_render_device_get_device_file (render_device); flags = META_DRM_BUFFER_FLAG_NONE; if (!use_modifiers) @@ -896,10 +902,10 @@ update_secondary_gpu_state_pre_swap_buffers (CoglOnscreen *onscreen) if (secondary_gpu_state) { MetaRendererNativeGpuData *renderer_gpu_data; - MetaDeviceFile *device_file; + MetaRenderDevice *render_device; renderer_gpu_data = secondary_gpu_state->renderer_gpu_data; - device_file = renderer_gpu_data->device_file; + render_device = renderer_gpu_data->render_device; switch (renderer_gpu_data->secondary.copy_mode) { case META_SHARED_FRAMEBUFFER_COPY_MODE_SECONDARY_GPU: @@ -920,7 +926,7 @@ update_secondary_gpu_state_pre_swap_buffers (CoglOnscreen *onscreen) { meta_topic (META_DEBUG_KMS, "Using primary GPU to copy for %s failed once.", - meta_device_file_get_path (device_file)); + meta_render_device_get_name (render_device)); secondary_gpu_state->noted_primary_gpu_copy_failed = TRUE; } @@ -932,7 +938,7 @@ update_secondary_gpu_state_pre_swap_buffers (CoglOnscreen *onscreen) { meta_topic (META_DEBUG_KMS, "Using primary GPU to copy for %s succeeded once.", - meta_device_file_get_path (device_file)); + meta_render_device_get_name (render_device)); secondary_gpu_state->noted_primary_gpu_copy_ok = TRUE; } break; @@ -1046,7 +1052,8 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, renderer_gpu_data = meta_renderer_native_get_gpu_data (renderer_native, render_gpu); - render_device_file = renderer_gpu_data->device_file; + render_device_file = + meta_render_device_get_device_file (renderer_gpu_data->render_device); switch (renderer_gpu_data->mode) { case META_RENDERER_NATIVE_MODE_GBM: @@ -1499,6 +1506,8 @@ get_supported_egl_modifiers (CoglOnscreen *onscreen, MetaEgl *egl = meta_onscreen_native_get_egl (onscreen_native); MetaGpu *gpu; MetaRendererNativeGpuData *renderer_gpu_data; + MetaRenderDevice *render_device; + EGLDisplay egl_display; EGLint num_modifiers; GArray *modifiers; GError *error = NULL; @@ -1507,13 +1516,15 @@ get_supported_egl_modifiers (CoglOnscreen *onscreen, gpu = meta_crtc_get_gpu (META_CRTC (crtc_kms)); renderer_gpu_data = meta_renderer_native_get_gpu_data (renderer_native, META_GPU_KMS (gpu)); + render_device = renderer_gpu_data->render_device; + egl_display = meta_render_device_get_egl_display (render_device); - if (!meta_egl_has_extensions (egl, renderer_gpu_data->egl_display, NULL, + if (!meta_egl_has_extensions (egl, egl_display, NULL, "EGL_EXT_image_dma_buf_import_modifiers", NULL)) return NULL; - ret = meta_egl_query_dma_buf_modifiers (egl, renderer_gpu_data->egl_display, + ret = meta_egl_query_dma_buf_modifiers (egl, egl_display, format, 0, NULL, NULL, &num_modifiers, NULL); if (!ret || num_modifiers == 0) @@ -1521,7 +1532,7 @@ get_supported_egl_modifiers (CoglOnscreen *onscreen, modifiers = g_array_sized_new (FALSE, FALSE, sizeof (uint64_t), num_modifiers); - ret = meta_egl_query_dma_buf_modifiers (egl, renderer_gpu_data->egl_display, + ret = meta_egl_query_dma_buf_modifiers (egl, egl_display, format, num_modifiers, (EGLuint64KHR *) modifiers->data, NULL, &num_modifiers, &error); @@ -1582,6 +1593,8 @@ create_surfaces_gbm (CoglOnscreen *onscreen, CoglRenderer *cogl_renderer = cogl_display->renderer; CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys; MetaRendererNativeGpuData *renderer_gpu_data = cogl_renderer_egl->platform; + MetaRenderDeviceGbm *render_device_gbm; + struct gbm_device *gbm_device; struct gbm_surface *new_gbm_surface = NULL; EGLNativeWindowType egl_native_window; EGLSurface new_egl_surface; @@ -1591,6 +1604,8 @@ create_surfaces_gbm (CoglOnscreen *onscreen, renderer_gpu_data = meta_renderer_native_get_gpu_data (renderer_native, onscreen_native->render_gpu); + render_device_gbm = META_RENDER_DEVICE_GBM (renderer_gpu_data->render_device); + gbm_device = meta_render_device_gbm_get_gbm_device (render_device_gbm); format = get_gbm_format_from_egl (egl, cogl_renderer_egl->edpy, @@ -1604,7 +1619,7 @@ create_surfaces_gbm (CoglOnscreen *onscreen, if (modifiers) { new_gbm_surface = - gbm_surface_create_with_modifiers (renderer_gpu_data->gbm.device, + gbm_surface_create_with_modifiers (gbm_device, width, height, format, (uint64_t *) modifiers->data, modifiers->len); @@ -1618,7 +1633,7 @@ create_surfaces_gbm (CoglOnscreen *onscreen, if (should_surface_be_sharable (onscreen)) flags |= GBM_BO_USE_LINEAR; - new_gbm_surface = gbm_surface_create (renderer_gpu_data->gbm.device, + new_gbm_surface = gbm_surface_create (gbm_device, width, height, format, flags); @@ -1669,9 +1684,10 @@ create_surfaces_egl_device (CoglOnscreen *onscreen, CoglRenderer *cogl_renderer = cogl_display->renderer; CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys; MetaRendererNativeGpuData *renderer_gpu_data = cogl_renderer_egl->platform; + MetaRenderDevice *render_device; MetaEgl *egl = meta_renderer_native_get_egl (renderer_gpu_data->renderer_native); - EGLDisplay egl_display = renderer_gpu_data->egl_display; + EGLDisplay egl_display; EGLConfig egl_config; EGLStreamKHR egl_stream; EGLSurface egl_surface; @@ -1689,6 +1705,8 @@ create_surfaces_egl_device (CoglOnscreen *onscreen, EGL_NONE }; + render_device = renderer_gpu_data->render_device; + egl_display = meta_render_device_get_egl_display (render_device); egl_stream = meta_egl_create_stream (egl, egl_display, stream_attribs, error); if (egl_stream == EGL_NO_STREAM_KHR) return FALSE; @@ -1764,7 +1782,8 @@ meta_onscreen_native_allocate (CoglFramebuffer *framebuffer, int width; int height; #ifdef HAVE_EGL_DEVICE - MetaDeviceFile *render_device_file; + MetaRenderDevice *render_device; + MetaDrmBuffer *dumb_buffer; EGLStreamKHR egl_stream; #endif CoglFramebufferClass *parent_class; @@ -1801,15 +1820,16 @@ meta_onscreen_native_allocate (CoglFramebuffer *framebuffer, break; #ifdef HAVE_EGL_DEVICE case META_RENDERER_NATIVE_MODE_EGL_DEVICE: - render_device_file = renderer_gpu_data->device_file; - onscreen_native->egl.dumb_fb = - meta_drm_buffer_dumb_new (render_device_file, - width, height, - DRM_FORMAT_XRGB8888, - error); - if (!onscreen_native->egl.dumb_fb) + render_device = renderer_gpu_data->render_device; + dumb_buffer = meta_render_device_allocate_dumb_buf (render_device, + width, height, + DRM_FORMAT_XRGB8888, + error); + if (!dumb_buffer) return FALSE; + onscreen_native->egl.dumb_fb = META_DRM_BUFFER_DUMB (dumb_buffer); + if (!create_surfaces_egl_device (onscreen, width, height, &egl_stream, @@ -1836,6 +1856,10 @@ init_secondary_gpu_state_gpu_copy_mode (MetaRendererNative *renderer_nat CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen); MetaEgl *egl = meta_onscreen_native_get_egl (onscreen_native); + MetaRenderDevice *render_device; + MetaRenderDeviceGbm *render_device_gbm; + struct gbm_device *gbm_device; + EGLDisplay egl_display; int width, height; EGLNativeWindowType egl_native_window; struct gbm_surface *gbm_surface; @@ -1844,13 +1868,17 @@ init_secondary_gpu_state_gpu_copy_mode (MetaRendererNative *renderer_nat MetaGpuKms *gpu_kms; uint32_t format; + render_device = renderer_gpu_data->render_device; + egl_display = meta_render_device_get_egl_display (render_device); width = cogl_framebuffer_get_width (framebuffer); height = cogl_framebuffer_get_height (framebuffer); format = get_gbm_format_from_egl (egl, - renderer_gpu_data->egl_display, + egl_display, renderer_gpu_data->secondary.egl_config); - gbm_surface = gbm_surface_create (renderer_gpu_data->gbm.device, + render_device_gbm = META_RENDER_DEVICE_GBM (render_device); + gbm_device = meta_render_device_gbm_get_gbm_device (render_device_gbm); + gbm_surface = gbm_surface_create (gbm_device, width, height, format, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); @@ -1864,7 +1892,7 @@ init_secondary_gpu_state_gpu_copy_mode (MetaRendererNative *renderer_nat egl_native_window = (EGLNativeWindowType) gbm_surface; egl_surface = meta_egl_create_window_surface (egl, - renderer_gpu_data->egl_display, + egl_display, renderer_gpu_data->secondary.egl_config, egl_native_window, NULL, @@ -1958,8 +1986,8 @@ init_secondary_gpu_state_cpu_copy_mode (MetaRendererNative *renderer_nat CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen); MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state; + MetaRenderDevice *render_device; MetaGpuKms *gpu_kms; - MetaDeviceFile *device_file; int width, height; unsigned int i; uint32_t drm_format; @@ -1977,10 +2005,10 @@ init_secondary_gpu_state_cpu_copy_mode (MetaRendererNative *renderer_nat height = cogl_framebuffer_get_height (framebuffer); gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (onscreen_native->crtc)); - device_file = renderer_gpu_data->device_file; + render_device = renderer_gpu_data->render_device; meta_topic (META_DEBUG_KMS, "Secondary GPU %s using DRM format '%s' (0x%x) for a %dx%d output.", - meta_device_file_get_path (device_file), + meta_render_device_get_name (render_device), meta_drm_format_to_string (&tmp, drm_format), drm_format, width, height); @@ -1992,16 +2020,19 @@ init_secondary_gpu_state_cpu_copy_mode (MetaRendererNative *renderer_nat for (i = 0; i < G_N_ELEMENTS (secondary_gpu_state->cpu.dumb_fbs); i++) { - secondary_gpu_state->cpu.dumb_fbs[i] = - meta_drm_buffer_dumb_new (device_file, - width, height, - drm_format, - error); - if (!secondary_gpu_state->cpu.dumb_fbs[i]) + MetaDrmBuffer *dumb_buffer; + + dumb_buffer = meta_render_device_allocate_dumb_buf (render_device, + width, height, + drm_format, + error); + if (!dumb_buffer) { secondary_gpu_state_free (secondary_gpu_state); return FALSE; } + + secondary_gpu_state->cpu.dumb_fbs[i] = META_DRM_BUFFER_DUMB (dumb_buffer); } /* diff --git a/src/backends/native/meta-renderer-native-private.h b/src/backends/native/meta-renderer-native-private.h index acadb3fff..0364fd779 100644 --- a/src/backends/native/meta-renderer-native-private.h +++ b/src/backends/native/meta-renderer-native-private.h @@ -29,6 +29,7 @@ #define META_RENDERER_NATIVE_PRIVATE_H #include "backends/meta-gles3.h" +#include "backends/native/meta-backend-native-types.h" #include "backends/native/meta-renderer-native.h" typedef enum _MetaSharedFramebufferCopyMode @@ -49,28 +50,15 @@ typedef struct _MetaRendererNativeGpuData { MetaRendererNative *renderer_native; - MetaDeviceFile *device_file; - - struct { - struct gbm_device *device; - } gbm; - -#ifdef HAVE_EGL_DEVICE - struct { - EGLDeviceEXT device; - } egl; -#endif + MetaRenderDevice *render_device; MetaRendererNativeMode mode; - EGLDisplay egl_display; - /* * Fields used for blitting iGPU framebuffer content onto dGPU framebuffers. */ struct { MetaSharedFramebufferCopyMode copy_mode; - gboolean is_hardware_rendering; gboolean has_EGL_EXT_image_dma_buf_import_modifiers; /* For GPU blit mode */ diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c index 70fd51a9f..752c92474 100644 --- a/src/backends/native/meta-renderer-native.c +++ b/src/backends/native/meta-renderer-native.c @@ -56,10 +56,16 @@ #include "backends/native/meta-kms-device.h" #include "backends/native/meta-kms.h" #include "backends/native/meta-onscreen-native.h" +#include "backends/native/meta-render-device-gbm.h" +#include "backends/native/meta-render-device-surfaceless.h" #include "backends/native/meta-renderer-native-private.h" #include "cogl/cogl.h" #include "core/boxes-private.h" +#ifdef HAVE_EGL_DEVICE +#include "backends/native/meta-render-device-egl-stream.h" +#endif + #ifndef EGL_DRM_MASTER_FD_EXT #define EGL_DRM_MASTER_FD_EXT 0x333C #endif @@ -119,22 +125,21 @@ meta_get_renderer_native_parent_vtable (void) static void meta_renderer_native_gpu_data_free (MetaRendererNativeGpuData *renderer_gpu_data) { - MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native; - MetaEgl *egl = meta_renderer_native_get_egl (renderer_native); - if (renderer_gpu_data->secondary.egl_context != EGL_NO_CONTEXT) { + MetaRenderDevice *render_device = renderer_gpu_data->render_device; + EGLDisplay egl_display = + meta_render_device_get_egl_display (render_device); + MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native; + MetaEgl *egl = meta_renderer_native_get_egl (renderer_native); + meta_egl_destroy_context (egl, - renderer_gpu_data->egl_display, + egl_display, renderer_gpu_data->secondary.egl_context, NULL); } - if (renderer_gpu_data->egl_display != EGL_NO_DISPLAY) - meta_egl_terminate (egl, renderer_gpu_data->egl_display, NULL); - - g_clear_pointer (&renderer_gpu_data->gbm.device, gbm_device_destroy); - g_clear_pointer (&renderer_gpu_data->device_file, meta_device_file_release); + g_clear_pointer (&renderer_gpu_data->render_device, g_object_unref); g_free (renderer_gpu_data); } @@ -158,11 +163,18 @@ meta_gbm_device_from_gpu (MetaGpuKms *gpu_kms) { MetaRendererNative *renderer_native = meta_renderer_native_from_gpu (gpu_kms); MetaRendererNativeGpuData *renderer_gpu_data; + MetaRenderDevice *render_device; + MetaRenderDeviceGbm *render_device_gbm; renderer_gpu_data = meta_renderer_native_get_gpu_data (renderer_native, gpu_kms); + render_device = renderer_gpu_data->render_device; - return renderer_gpu_data->gbm.device; + if (!META_IS_RENDER_DEVICE_GBM (render_device)) + return NULL; + + render_device_gbm = META_RENDER_DEVICE_GBM (render_device); + return meta_render_device_gbm_get_gbm_device (render_device_gbm); } MetaGpuKms * @@ -176,16 +188,23 @@ meta_renderer_native_get_primary_device_file (MetaRendererNative *renderer_nativ { MetaGpuKms *gpu_kms = renderer_native->primary_gpu_kms; MetaRendererNativeGpuData *renderer_gpu_data; + MetaRenderDevice *render_device; renderer_gpu_data = meta_renderer_native_get_gpu_data (renderer_native, gpu_kms); - return renderer_gpu_data->device_file; + render_device = renderer_gpu_data->render_device; + return meta_render_device_get_device_file (render_device); } static MetaRendererNativeGpuData * meta_create_renderer_native_gpu_data (void) { - return g_new0 (MetaRendererNativeGpuData, 1); + MetaRendererNativeGpuData *renderer_gpu_data; + + renderer_gpu_data = g_new0 (MetaRendererNativeGpuData, 1); + renderer_gpu_data->secondary.egl_context = EGL_NO_CONTEXT; + + return renderer_gpu_data; } MetaEgl * @@ -236,6 +255,7 @@ meta_renderer_native_connect (CoglRenderer *cogl_renderer, MetaRendererNative *renderer_native = cogl_renderer->custom_winsys_user_data; MetaGpuKms *gpu_kms; MetaRendererNativeGpuData *renderer_gpu_data; + MetaRenderDevice *render_device; cogl_renderer->winsys = g_new0 (CoglRendererEGL, 1); cogl_renderer_egl = cogl_renderer->winsys; @@ -243,10 +263,11 @@ meta_renderer_native_connect (CoglRenderer *cogl_renderer, gpu_kms = meta_renderer_native_get_primary_gpu (renderer_native); renderer_gpu_data = meta_renderer_native_get_gpu_data (renderer_native, gpu_kms); + render_device = renderer_gpu_data->render_device; cogl_renderer_egl->platform_vtable = &_cogl_winsys_egl_vtable; cogl_renderer_egl->platform = renderer_gpu_data; - cogl_renderer_egl->edpy = renderer_gpu_data->egl_display; + cogl_renderer_egl->edpy = meta_render_device_get_egl_display (render_device); if (!_cogl_winsys_egl_renderer_connect_common (cogl_renderer, error)) goto fail; @@ -783,56 +804,60 @@ meta_renderer_native_create_dma_buf (CoglRenderer *cogl_renderer, { case META_RENDERER_NATIVE_MODE_GBM: { + MetaRenderDevice *render_device; + MetaDrmBufferFlags flags; + g_autoptr (MetaDrmBuffer) buffer = NULL; + int dmabuf_fd; + uint32_t stride; + uint32_t offset; + uint32_t bpp; + uint32_t modifier; + uint32_t format; CoglFramebuffer *dmabuf_fb; CoglDmaBufHandle *dmabuf_handle; - struct gbm_bo *new_bo; - int stride; - int offset; - int bpp; - int dmabuf_fd = -1; - new_bo = gbm_bo_create (renderer_gpu_data->gbm.device, - width, height, DRM_FORMAT_XRGB8888, - GBM_BO_USE_RENDERING | GBM_BO_USE_LINEAR); - if (!new_bo) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Failed to allocate buffer"); - return NULL; - } - - dmabuf_fd = gbm_bo_get_fd (new_bo); + render_device = renderer_gpu_data->render_device; + flags = META_DRM_BUFFER_FLAG_NONE; + buffer = meta_render_device_allocate_dma_buf (render_device, + width, height, + DRM_FORMAT_XRGB8888, + flags, + error); + if (!buffer) + return NULL; + dmabuf_fd = meta_drm_buffer_export_fd (buffer, error); if (dmabuf_fd == -1) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS, - "Failed to export buffer's DMA fd: %s", - g_strerror (errno)); - return NULL; - } + return NULL; + + stride = meta_drm_buffer_get_stride (buffer); + offset = meta_drm_buffer_get_offset (buffer, 0); + bpp = meta_drm_buffer_get_bpp (buffer); + modifier = meta_drm_buffer_get_modifier (buffer); + format = meta_drm_buffer_get_format (buffer); - stride = gbm_bo_get_stride (new_bo); - offset = gbm_bo_get_offset (new_bo, 0); - bpp = gbm_bo_get_bpp (new_bo) / 8; dmabuf_fb = meta_renderer_native_create_dma_buf_framebuffer (renderer_native, dmabuf_fd, width, height, stride, offset, - DRM_FORMAT_MOD_LINEAR, - DRM_FORMAT_XRGB8888, + modifier, + format, error); if (!dmabuf_fb) - return NULL; + { + close (dmabuf_fd); + return NULL; + } dmabuf_handle = cogl_dma_buf_handle_new (dmabuf_fb, dmabuf_fd, width, height, stride, offset, bpp, - new_bo, - (GDestroyNotify) gbm_bo_destroy); + g_steal_pointer (&buffer), + g_object_unref); g_object_unref (dmabuf_fb); return dmabuf_handle; } @@ -1420,12 +1445,27 @@ init_secondary_gpu_data_gpu (MetaRendererNativeGpuData *renderer_gpu_data, GError **error) { MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native; + MetaRenderDevice *render_device = renderer_gpu_data->render_device; MetaEgl *egl = meta_renderer_native_get_egl (renderer_native); - EGLDisplay egl_display = renderer_gpu_data->egl_display; + EGLDisplay egl_display; EGLConfig egl_config; EGLContext egl_context; const char **missing_gl_extensions; - const char *renderer_str; + + egl_display = meta_render_device_get_egl_display (render_device); + if (egl_display == EGL_NO_DISPLAY) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "No EGL display"); + return FALSE; + } + + if (!meta_render_device_is_hardware_accelerated (render_device)) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Not hardware accelerated"); + return FALSE; + } meta_egl_bind_api (egl, EGL_OPENGL_ES_API, NULL); @@ -1433,7 +1473,8 @@ init_secondary_gpu_data_gpu (MetaRendererNativeGpuData *renderer_gpu_data, &egl_config, error)) goto err; - egl_context = create_secondary_egl_context (egl, egl_display, egl_config, error); + egl_context = create_secondary_egl_context (egl, egl_display, egl_config, + error); if (egl_context == EGL_NO_CONTEXT) goto err; @@ -1450,17 +1491,6 @@ init_secondary_gpu_data_gpu (MetaRendererNativeGpuData *renderer_gpu_data, goto err; } - renderer_str = (const char *) glGetString (GL_RENDERER); - if (g_str_has_prefix (renderer_str, "llvmpipe") || - g_str_has_prefix (renderer_str, "softpipe") || - g_str_has_prefix (renderer_str, "swrast")) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Do not want to use software renderer (%s), falling back to CPU copy path", - renderer_str); - goto err_fail_with_context; - } - if (!meta_gles3_has_extensions (renderer_native->gles3, &missing_gl_extensions, "GL_OES_EGL_image_external", @@ -1476,11 +1506,9 @@ init_secondary_gpu_data_gpu (MetaRendererNativeGpuData *renderer_gpu_data, g_free (missing_gl_extensions_str); g_free (missing_gl_extensions); - goto err_fail_with_context; + goto err_fail_make_current; } - renderer_gpu_data->secondary.is_hardware_rendering = TRUE; - renderer_gpu_data->secondary.egl_context = egl_context; renderer_gpu_data->secondary.egl_config = egl_config; renderer_gpu_data->secondary.copy_mode = META_SHARED_FRAMEBUFFER_COPY_MODE_SECONDARY_GPU; @@ -1493,14 +1521,13 @@ init_secondary_gpu_data_gpu (MetaRendererNativeGpuData *renderer_gpu_data, return TRUE; -err_fail_with_context: +err_fail_make_current: meta_egl_make_current (egl, egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT, NULL); - meta_egl_destroy_context (egl, egl_display, egl_context, NULL); err: maybe_restore_cogl_egl_api (renderer_native); @@ -1511,8 +1538,6 @@ err: static void init_secondary_gpu_data_cpu (MetaRendererNativeGpuData *renderer_gpu_data) { - renderer_gpu_data->secondary.is_hardware_rendering = FALSE; - /* First try ZERO, it automatically falls back to PRIMARY as needed */ renderer_gpu_data->secondary.copy_mode = META_SHARED_FRAMEBUFFER_COPY_MODE_ZERO; @@ -1540,329 +1565,79 @@ gpu_kms_is_hardware_rendering (MetaRendererNative *renderer_native, MetaRendererNativeGpuData *data; data = meta_renderer_native_get_gpu_data (renderer_native, gpu_kms); - return data->secondary.is_hardware_rendering; -} - -static EGLDisplay -init_gbm_egl_display (MetaRendererNative *renderer_native, - struct gbm_device *gbm_device, - GError **error) -{ - MetaEgl *egl = meta_renderer_native_get_egl (renderer_native); - EGLDisplay egl_display; - - if (!meta_egl_has_extensions (egl, EGL_NO_DISPLAY, NULL, - "EGL_MESA_platform_gbm", - NULL) && - !meta_egl_has_extensions (egl, EGL_NO_DISPLAY, NULL, - "EGL_KHR_platform_gbm", - NULL)) - { - g_set_error (error, G_IO_ERROR, - G_IO_ERROR_FAILED, - "Missing extension for GBM renderer: EGL_KHR_platform_gbm"); - return EGL_NO_DISPLAY; - } - - egl_display = meta_egl_get_platform_display (egl, - EGL_PLATFORM_GBM_KHR, - gbm_device, NULL, error); - if (egl_display == EGL_NO_DISPLAY) - return EGL_NO_DISPLAY; - - if (!meta_egl_initialize (egl, egl_display, error)) - return EGL_NO_DISPLAY; - - return egl_display; + return meta_render_device_is_hardware_accelerated (data->render_device); } static MetaRendererNativeGpuData * create_renderer_gpu_data_gbm (MetaRendererNative *renderer_native, MetaDeviceFile *device_file, + MetaGpuKms *gpu_kms, GError **error) { - struct gbm_device *gbm_device; + MetaRenderer *renderer = META_RENDERER (renderer_native); + MetaBackend *backend = meta_renderer_get_backend (renderer); + MetaRenderDeviceGbm *render_device_gbm; MetaRendererNativeGpuData *renderer_gpu_data; - g_autoptr (GError) local_error = NULL; - gbm_device = gbm_create_device (meta_device_file_get_fd (device_file)); - if (!gbm_device) - { - g_set_error (error, G_IO_ERROR, - G_IO_ERROR_FAILED, - "Failed to create gbm device: %s", g_strerror (errno)); - return NULL; - } + render_device_gbm = meta_render_device_gbm_new (backend, device_file, error); + if (!render_device_gbm) + return NULL; renderer_gpu_data = meta_create_renderer_native_gpu_data (); - renderer_gpu_data->device_file = meta_device_file_acquire (device_file); renderer_gpu_data->renderer_native = renderer_native; - renderer_gpu_data->gbm.device = gbm_device; renderer_gpu_data->mode = META_RENDERER_NATIVE_MODE_GBM; - - renderer_gpu_data->egl_display = init_gbm_egl_display (renderer_native, - gbm_device, - &local_error); - if (renderer_gpu_data->egl_display == EGL_NO_DISPLAY) - { - g_debug ("GBM EGL init for %s failed: %s", - meta_device_file_get_path (device_file), - local_error->message); - - init_secondary_gpu_data_cpu (renderer_gpu_data); - return renderer_gpu_data; - } + renderer_gpu_data->render_device = META_RENDER_DEVICE (render_device_gbm); init_secondary_gpu_data (renderer_gpu_data); return renderer_gpu_data; } -static EGLDisplay -init_surfaceless_egl_display (MetaRendererNative *renderer_native, - GError **error) -{ - MetaEgl *egl = meta_renderer_native_get_egl (renderer_native); - EGLDisplay egl_display; - - if (!meta_egl_has_extensions (egl, EGL_NO_DISPLAY, NULL, - "EGL_MESA_platform_surfaceless", - NULL)) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Missing EGL platform required for surfaceless context: " - "EGL_MESA_platform_surfaceless"); - return EGL_NO_DISPLAY; - } - - egl_display = meta_egl_get_platform_display (egl, - EGL_PLATFORM_SURFACELESS_MESA, - EGL_DEFAULT_DISPLAY, - NULL, error); - if (egl_display == EGL_NO_DISPLAY) - return EGL_NO_DISPLAY; - - if (!meta_egl_initialize (egl, egl_display, error)) - return EGL_NO_DISPLAY; - - if (!meta_egl_has_extensions (egl, egl_display, NULL, - "EGL_KHR_no_config_context", - NULL)) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Missing EGL extension required for surfaceless context: " - "EGL_KHR_no_config_context"); - return EGL_NO_DISPLAY; - } - - return egl_display; -} - static MetaRendererNativeGpuData * create_renderer_gpu_data_surfaceless (MetaRendererNative *renderer_native, GError **error) { + MetaRenderer *renderer = META_RENDERER (renderer_native); + MetaBackend *backend = meta_renderer_get_backend (renderer); + MetaRenderDeviceSurfaceless *render_device_surfaceless; MetaRendererNativeGpuData *renderer_gpu_data; - EGLDisplay egl_display; - egl_display = init_surfaceless_egl_display (renderer_native, error); - if (egl_display == EGL_NO_DISPLAY) + render_device_surfaceless = meta_render_device_surfaceless_new (backend, + error); + if (!render_device_surfaceless) return NULL; renderer_gpu_data = meta_create_renderer_native_gpu_data (); renderer_gpu_data->renderer_native = renderer_native; renderer_gpu_data->mode = META_RENDERER_NATIVE_MODE_SURFACELESS; - renderer_gpu_data->egl_display = egl_display; + renderer_gpu_data->render_device = + META_RENDER_DEVICE (render_device_surfaceless); return renderer_gpu_data; } #ifdef HAVE_EGL_DEVICE -static const char * -get_drm_device_file (MetaEgl *egl, - EGLDeviceEXT device, - GError **error) -{ - if (!meta_egl_egl_device_has_extensions (egl, device, - NULL, - "EGL_EXT_device_drm", - NULL)) - { - g_set_error (error, G_IO_ERROR, - G_IO_ERROR_FAILED, - "Missing required EGLDevice extension EGL_EXT_device_drm"); - return NULL; - } - - return meta_egl_query_device_string (egl, device, - EGL_DRM_DEVICE_FILE_EXT, - error); -} - -static EGLDeviceEXT -find_egl_device (MetaRendererNative *renderer_native, - MetaDeviceFile *device_file, - GError **error) -{ - MetaEgl *egl = meta_renderer_native_get_egl (renderer_native); - const char **missing_extensions; - EGLint num_devices; - EGLDeviceEXT *devices; - const char *kms_file_path; - EGLDeviceEXT device; - EGLint i; - - if (!meta_egl_has_extensions (egl, - EGL_NO_DISPLAY, - &missing_extensions, - "EGL_EXT_device_base", - NULL)) - { - char *missing_extensions_str; - - missing_extensions_str = g_strjoinv (", ", (char **) missing_extensions); - g_set_error (error, G_IO_ERROR, - G_IO_ERROR_FAILED, - "Missing EGL extensions required for EGLDevice renderer: %s", - missing_extensions_str); - g_free (missing_extensions_str); - g_free (missing_extensions); - return EGL_NO_DEVICE_EXT; - } - - if (!meta_egl_query_devices (egl, 0, NULL, &num_devices, error)) - return EGL_NO_DEVICE_EXT; - - devices = g_new0 (EGLDeviceEXT, num_devices); - if (!meta_egl_query_devices (egl, num_devices, devices, &num_devices, - error)) - { - g_free (devices); - return EGL_NO_DEVICE_EXT; - } - - kms_file_path = meta_device_file_get_path (device_file); - - device = EGL_NO_DEVICE_EXT; - for (i = 0; i < num_devices; i++) - { - const char *egl_device_drm_path; - - g_clear_error (error); - - egl_device_drm_path = get_drm_device_file (egl, devices[i], error); - if (!egl_device_drm_path) - continue; - - if (g_str_equal (egl_device_drm_path, kms_file_path)) - { - device = devices[i]; - break; - } - } - g_free (devices); - - if (device == EGL_NO_DEVICE_EXT) - { - if (!*error) - g_set_error (error, G_IO_ERROR, - G_IO_ERROR_FAILED, - "Failed to find matching EGLDeviceEXT"); - return EGL_NO_DEVICE_EXT; - } - - return device; -} - -static EGLDisplay -get_egl_device_display (MetaRendererNative *renderer_native, - MetaDeviceFile *device_file, - EGLDeviceEXT egl_device, - GError **error) -{ - MetaEgl *egl = meta_renderer_native_get_egl (renderer_native); - int kms_fd = meta_device_file_get_fd (device_file); - EGLint platform_attribs[] = { - EGL_DRM_MASTER_FD_EXT, kms_fd, - EGL_NONE - }; - - return meta_egl_get_platform_display (egl, EGL_PLATFORM_DEVICE_EXT, - (void *) egl_device, - platform_attribs, - error); -} - -static int -count_drm_devices (MetaRendererNative *renderer_native) -{ - MetaRenderer *renderer = META_RENDERER (renderer_native); - MetaBackend *backend = meta_renderer_get_backend (renderer); - - return g_list_length (meta_backend_get_gpus (backend)); -} - static MetaRendererNativeGpuData * create_renderer_gpu_data_egl_device (MetaRendererNative *renderer_native, MetaDeviceFile *device_file, + MetaGpuKms *gpu_kms, GError **error) { - MetaEgl *egl = meta_renderer_native_get_egl (renderer_native); - const char **missing_extensions; - EGLDeviceEXT egl_device; - EGLDisplay egl_display; + MetaRenderer *renderer = META_RENDERER (renderer_native); + MetaBackend *backend = meta_renderer_get_backend (renderer); + MetaRenderDeviceEglStream *render_device_egl_stream; MetaRendererNativeGpuData *renderer_gpu_data; - if (count_drm_devices (renderer_native) != 1) - { - g_set_error (error, G_IO_ERROR, - G_IO_ERROR_FAILED, - "EGLDevice currently only works with single GPU systems"); - return NULL; - } - - egl_device = find_egl_device (renderer_native, device_file, error); - if (egl_device == EGL_NO_DEVICE_EXT) + render_device_egl_stream = meta_render_device_egl_stream_new (backend, + device_file, + error); + if (!render_device_egl_stream) return NULL; - egl_display = get_egl_device_display (renderer_native, device_file, - egl_device, error); - if (egl_display == EGL_NO_DISPLAY) - return NULL; - - if (!meta_egl_initialize (egl, egl_display, error)) - return NULL; - - if (!meta_egl_has_extensions (egl, - egl_display, - &missing_extensions, - "EGL_NV_output_drm_flip_event", - "EGL_EXT_output_base", - "EGL_EXT_output_drm", - "EGL_KHR_stream", - "EGL_KHR_stream_producer_eglsurface", - "EGL_EXT_stream_consumer_egloutput", - "EGL_EXT_stream_acquire_mode", - NULL)) - { - char *missing_extensions_str; - - missing_extensions_str = g_strjoinv (", ", (char **) missing_extensions); - g_set_error (error, G_IO_ERROR, - G_IO_ERROR_FAILED, - "Missing EGL extensions required for EGLDevice renderer: %s", - missing_extensions_str); - meta_egl_terminate (egl, egl_display, NULL); - g_free (missing_extensions_str); - g_free (missing_extensions); - return NULL; - } - renderer_gpu_data = meta_create_renderer_native_gpu_data (); - renderer_gpu_data->device_file = meta_device_file_acquire (device_file); renderer_gpu_data->renderer_native = renderer_native; - renderer_gpu_data->egl.device = egl_device; renderer_gpu_data->mode = META_RENDERER_NATIVE_MODE_EGL_DEVICE; - renderer_gpu_data->egl_display = egl_display; + renderer_gpu_data->render_device = + META_RENDER_DEVICE (render_device_egl_stream); return renderer_gpu_data; } @@ -1907,6 +1682,7 @@ meta_renderer_native_create_renderer_gpu_data (MetaRendererNative *renderer_nat */ renderer_gpu_data = create_renderer_gpu_data_egl_device (renderer_native, device_file, + gpu_kms, &egl_device_error); if (renderer_gpu_data) return renderer_gpu_data; @@ -1914,6 +1690,7 @@ meta_renderer_native_create_renderer_gpu_data (MetaRendererNative *renderer_nat renderer_gpu_data = create_renderer_gpu_data_gbm (renderer_native, device_file, + gpu_kms, &gbm_error); if (renderer_gpu_data) { @@ -2113,11 +1890,13 @@ choose_primary_gpu (MetaBackend *backend, { MetaGpuKms *gpu_kms; MetaRendererNativeGpuData *renderer_gpu_data; + MetaRenderDevice *render_device; gpu_kms = choose_primary_gpu_unchecked (backend, renderer_native); renderer_gpu_data = meta_renderer_native_get_gpu_data (renderer_native, gpu_kms); - if (renderer_gpu_data->egl_display == EGL_NO_DISPLAY) + render_device = renderer_gpu_data->render_device; + if (meta_render_device_get_egl_display (render_device) == EGL_NO_DISPLAY) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "The GPU %s chosen as primary is not supported by EGL.",