[cogl/rstrode/wip/render-node: 5/5] kms-winsys: support drm render nodes
- From: Ray Strode <halfline src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [cogl/rstrode/wip/render-node: 5/5] kms-winsys: support drm render nodes
- Date: Thu, 27 Aug 2015 00:22:16 +0000 (UTC)
commit b7f1c23983df73f8d1b6abf63847454f1ad71bdb
Author: Ray Strode <rstrode redhat com>
Date: Wed Aug 26 17:02:45 2015 -0400
kms-winsys: support drm render nodes
Right now cogl does all rendering and modesetting using
/dev/dri/card0. If rendering were moved to /dev/dri/renderD128
then it will be in a better position to support offloading
rendering operations to a secondary gpu.
Also, some drivers (some versions of the vmware driver) don't
support using card0 when VT switched away. The result is crashes.
This commit leaves card0 for modesetting operations, but defers
rendering operations to the the render node. The output is synchronized
to card0 using dma-buf.
cogl/winsys/cogl-winsys-egl-kms.c | 95 ++++++++++++++++++++++++++++++++-----
1 files changed, 82 insertions(+), 13 deletions(-)
---
diff --git a/cogl/winsys/cogl-winsys-egl-kms.c b/cogl/winsys/cogl-winsys-egl-kms.c
index 29b6bc0..8ecbb22 100644
--- a/cogl/winsys/cogl-winsys-egl-kms.c
+++ b/cogl/winsys/cogl-winsys-egl-kms.c
@@ -46,6 +46,7 @@
#include <xf86drmMode.h>
#include <gbm.h>
#include <glib.h>
+#include <glob.h>
#include <sys/fcntl.h>
#include <unistd.h>
#include <string.h>
@@ -76,6 +77,8 @@ typedef struct _CoglRendererDeviceKMS
typedef struct _CoglRendererKMS
{
CoglRendererDeviceKMS card_device;
+ CoglRendererDeviceKMS rendering_device;
+ struct gbm_device *gbm_for_egl;
CoglClosure *swap_notify_idle;
CoglBool page_flips_not_supported;
} CoglRendererKMS;
@@ -115,6 +118,7 @@ typedef struct _CoglOnscreenKMS
uint32_t next_fb_id;
struct gbm_bo *current_bo;
struct gbm_bo *next_bo;
+ struct gbm_bo *card_bo;
CoglBool pending_swap_notify;
EGLSurface *pending_egl_surface;
@@ -122,6 +126,7 @@ typedef struct _CoglOnscreenKMS
} CoglOnscreenKMS;
static const char card_device_name[] = "/dev/dri/card0";
+static const char rendering_device_glob[] = "/dev/dri/renderD*";
static void
_cogl_winsys_renderer_disconnect (CoglRenderer *renderer)
@@ -135,9 +140,15 @@ _cogl_winsys_renderer_disconnect (CoglRenderer *renderer)
if (kms_renderer->card_device.gbm != NULL)
gbm_device_destroy (kms_renderer->card_device.gbm);
+ if (kms_renderer->rendering_device.gbm != NULL)
+ gbm_device_destroy (kms_renderer->rendering_device.gbm);
+
if (kms_renderer->card_device.is_borrowed && kms_renderer->card_device.fd >= 0)
close (kms_renderer->card_device.fd);
+ if (kms_renderer->rendering_device.is_borrowed && kms_renderer->rendering_device.fd >= 0)
+ close (kms_renderer->rendering_device.fd);
+
g_slice_free (CoglRendererKMS, kms_renderer);
g_slice_free (CoglRendererEGL, egl_renderer);
}
@@ -255,6 +266,9 @@ process_flip (CoglFlipKMS *flip)
kms_onscreen->current_bo = kms_onscreen->next_bo;
kms_onscreen->next_bo = NULL;
+ gbm_bo_destroy (kms_onscreen->card_bo);
+ kms_onscreen->card_bo = NULL;
+
cogl_object_unref (flip->onscreen);
g_slice_free (CoglFlipKMS, flip);
@@ -306,6 +320,8 @@ _cogl_winsys_renderer_connect (CoglRenderer *renderer,
{
CoglRendererEGL *egl_renderer;
CoglRendererKMS *kms_renderer;
+ glob_t glob_buffer = { 0 };
+ int ret;
renderer->winsys = g_slice_new0 (CoglRendererEGL);
egl_renderer = renderer->winsys;
@@ -314,10 +330,34 @@ _cogl_winsys_renderer_connect (CoglRenderer *renderer,
egl_renderer->platform = g_slice_new0 (CoglRendererKMS);
kms_renderer = egl_renderer->platform;
- kms_renderer->card_device.fd = -1;
-
egl_renderer->edpy = EGL_NO_DISPLAY;
+ kms_renderer->rendering_device.fd = -1;
+
+ ret = glob (rendering_device_glob, 0, NULL, &glob_buffer);
+
+ if (ret != GLOB_NOMATCH)
+ {
+ kms_renderer->rendering_device.fd = open (glob_buffer.gl_pathv[0], O_RDWR);
+
+ if (kms_renderer->rendering_device.fd < 0)
+ g_debug ("could not open '%s': %m", glob_buffer.gl_pathv[0]);
+ }
+
+ globfree (&glob_buffer);
+
+ if (kms_renderer->rendering_device.fd >= 0)
+ {
+ kms_renderer->rendering_device.gbm = gbm_create_device (kms_renderer->rendering_device.fd);
+ if (kms_renderer->rendering_device.gbm != NULL)
+ {
+ egl_renderer->edpy = eglGetDisplay ((EGLNativeDisplayType)kms_renderer->rendering_device.gbm);
+ kms_renderer->gbm_for_egl = kms_renderer->rendering_device.gbm;
+ }
+ }
+
+ kms_renderer->card_device.fd = -1;
+
if (renderer->kms_fd >= 0)
{
kms_renderer->card_device.fd = renderer->kms_fd;
@@ -345,13 +385,18 @@ _cogl_winsys_renderer_connect (CoglRenderer *renderer,
goto fail;
}
- egl_renderer->edpy = eglGetDisplay ((EGLNativeDisplayType)kms_renderer->card_device.gbm);
if (egl_renderer->edpy == EGL_NO_DISPLAY)
{
- _cogl_set_error (error, COGL_WINSYS_ERROR,
- COGL_WINSYS_ERROR_INIT,
- "Couldn't get eglDisplay");
- goto fail;
+ egl_renderer->edpy = eglGetDisplay ((EGLNativeDisplayType)kms_renderer->card_device.gbm);
+ if (egl_renderer->edpy == EGL_NO_DISPLAY)
+ {
+ _cogl_set_error (error, COGL_WINSYS_ERROR,
+ COGL_WINSYS_ERROR_INIT,
+ "Couldn't get eglDisplay");
+ goto fail;
+ }
+
+ kms_renderer->gbm_for_egl = kms_renderer->card_device.gbm;
}
if (!_cogl_winsys_egl_renderer_connect_common (renderer, error))
@@ -808,7 +853,7 @@ _cogl_winsys_egl_context_created (CoglDisplay *display,
COGL_EGL_WINSYS_FEATURE_SURFACELESS_CONTEXT) == 0)
{
kms_display->dummy_gbm_surface =
- gbm_surface_create (kms_renderer->card_device.gbm,
+ gbm_surface_create (kms_renderer->gbm_for_egl,
16, 16,
GBM_FORMAT_XRGB8888,
GBM_BO_USE_RENDERING);
@@ -883,7 +928,7 @@ _cogl_winsys_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
CoglRendererKMS *kms_renderer = egl_renderer->platform;
CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
CoglOnscreenKMS *kms_onscreen = egl_onscreen->platform;
- uint32_t handle, stride;
+ uint32_t handle = 0, stride;
CoglFlipKMS *flip;
/* If we already have a pending swap then block until it completes */
@@ -913,8 +958,30 @@ _cogl_winsys_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
}
/* Now we need to set the CRTC to whatever is the front buffer */
kms_onscreen->next_bo = gbm_surface_lock_front_buffer (kms_onscreen->surface);
- stride = gbm_bo_get_stride (kms_onscreen->next_bo);
- handle = gbm_bo_get_handle (kms_onscreen->next_bo).u32;
+
+ if (kms_renderer->rendering_device.gbm != NULL)
+ {
+ struct gbm_import_fd_data dma_buf_data = { 0 };
+
+ dma_buf_data.fd = gbm_bo_get_fd (kms_onscreen->next_bo);
+ dma_buf_data.width = gbm_bo_get_width (kms_onscreen->next_bo);
+ dma_buf_data.height = gbm_bo_get_height (kms_onscreen->next_bo);
+ dma_buf_data.stride = gbm_bo_get_stride (kms_onscreen->next_bo);
+ dma_buf_data.format = gbm_bo_get_format (kms_onscreen->next_bo);
+
+ kms_onscreen->card_bo = gbm_bo_import (kms_renderer->rendering_device.gbm,
+ GBM_BO_IMPORT_FD,
+ &dma_buf_data,
+ GBM_BO_USE_SCANOUT);
+ if (kms_onscreen->card_bo != NULL)
+ handle = gbm_bo_get_handle (kms_onscreen->card_bo).u32;
+ }
+
+ if (handle == 0)
+ {
+ handle = gbm_bo_get_handle (kms_onscreen->next_bo).u32;
+ stride = gbm_bo_get_stride (kms_onscreen->next_bo);
+ }
if (drmModeAddFB (kms_renderer->card_device.fd,
kms_display->width,
@@ -926,6 +993,7 @@ _cogl_winsys_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
&kms_onscreen->next_fb_id))
{
g_warning ("Failed to create new back buffer handle: %m");
+ g_clear_pointer (&kms_onscreen->card_bo, gbm_bo_destroy);
gbm_surface_release_buffer (kms_onscreen->surface,
kms_onscreen->next_bo);
kms_onscreen->next_bo = NULL;
@@ -949,6 +1017,7 @@ _cogl_winsys_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
if (flip->pending == 0)
{
drmModeRmFB (kms_renderer->card_device.fd, kms_onscreen->next_fb_id);
+ g_clear_pointer (&kms_onscreen->card_bo, gbm_bo_destroy);
gbm_surface_release_buffer (kms_onscreen->surface,
kms_onscreen->next_bo);
kms_onscreen->next_bo = NULL;
@@ -1023,7 +1092,7 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
egl_onscreen->platform = kms_onscreen;
kms_onscreen->surface =
- gbm_surface_create (kms_renderer->card_device.gbm,
+ gbm_surface_create (kms_renderer->gbm_for_egl,
kms_display->width,
kms_display->height,
GBM_BO_FORMAT_XRGB8888,
@@ -1224,7 +1293,7 @@ cogl_kms_display_set_layout (CoglDisplay *display,
/* Need to drop the GBM surface and create a new one */
- new_surface = gbm_surface_create (kms_renderer->card_device.gbm,
+ new_surface = gbm_surface_create (kms_renderer->gbm_for_egl,
width, height,
GBM_BO_FORMAT_XRGB8888,
GBM_BO_USE_SCANOUT |
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]