Compare commits
6 Commits
cogl-1.22
...
halfline/w
Author | SHA1 | Date |
---|---|---|
Ray Strode | 2cc3013c3f | |
Ray Strode | e4b5dbb7a1 | |
Ray Strode | 268e430548 | |
Ray Strode | 07aa682054 | |
Ray Strode | 06bdc4e2c1 | |
Ray Strode | 8e6f30ae60 |
|
@ -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>
|
||||
|
@ -66,11 +67,18 @@ static const CoglWinsysEGLVtable _cogl_winsys_egl_vtable;
|
|||
|
||||
static const CoglWinsysVtable *parent_vtable;
|
||||
|
||||
typedef struct _CoglRendererKMS
|
||||
typedef struct _CoglRendererDeviceKMS
|
||||
{
|
||||
int fd;
|
||||
int opened_fd;
|
||||
struct gbm_device *gbm;
|
||||
CoglBool is_borrowed;
|
||||
} CoglRendererDeviceKMS;
|
||||
|
||||
typedef struct _CoglRendererKMS
|
||||
{
|
||||
struct gbm_device *rendering_gbm;
|
||||
CoglRendererDeviceKMS card_device;
|
||||
CoglRendererDeviceKMS render_offload_device;
|
||||
CoglClosure *swap_notify_idle;
|
||||
CoglBool page_flips_not_supported;
|
||||
} CoglRendererKMS;
|
||||
|
@ -110,13 +118,15 @@ 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;
|
||||
struct gbm_surface *pending_surface;
|
||||
} CoglOnscreenKMS;
|
||||
|
||||
static const char device_name[] = "/dev/dri/card0";
|
||||
static const char card_device_name[] = "/dev/dri/card0";
|
||||
static const char render_offload_device_glob[] = "/dev/dri/renderD*";
|
||||
|
||||
static void
|
||||
_cogl_winsys_renderer_disconnect (CoglRenderer *renderer)
|
||||
|
@ -124,10 +134,20 @@ _cogl_winsys_renderer_disconnect (CoglRenderer *renderer)
|
|||
CoglRendererEGL *egl_renderer = renderer->winsys;
|
||||
CoglRendererKMS *kms_renderer = egl_renderer->platform;
|
||||
|
||||
if (egl_renderer->edpy != EGL_NO_DISPLAY)
|
||||
eglTerminate (egl_renderer->edpy);
|
||||
|
||||
if (kms_renderer->opened_fd >= 0)
|
||||
close (kms_renderer->opened_fd);
|
||||
if (kms_renderer->card_device.gbm != NULL)
|
||||
gbm_device_destroy (kms_renderer->card_device.gbm);
|
||||
|
||||
if (kms_renderer->render_offload_device.gbm != NULL)
|
||||
gbm_device_destroy (kms_renderer->render_offload_device.gbm);
|
||||
|
||||
if (!kms_renderer->card_device.is_borrowed && kms_renderer->card_device.fd >= 0)
|
||||
close (kms_renderer->card_device.fd);
|
||||
|
||||
if (!kms_renderer->render_offload_device.is_borrowed && kms_renderer->render_offload_device.fd >= 0)
|
||||
close (kms_renderer->render_offload_device.fd);
|
||||
|
||||
g_slice_free (CoglRendererKMS, kms_renderer);
|
||||
g_slice_free (CoglRendererEGL, egl_renderer);
|
||||
|
@ -187,7 +207,7 @@ free_current_bo (CoglOnscreen *onscreen)
|
|||
|
||||
if (kms_onscreen->current_fb_id)
|
||||
{
|
||||
drmModeRmFB (kms_renderer->fd,
|
||||
drmModeRmFB (kms_renderer->card_device.fd,
|
||||
kms_onscreen->current_fb_id);
|
||||
kms_onscreen->current_fb_id = 0;
|
||||
}
|
||||
|
@ -246,6 +266,8 @@ process_flip (CoglFlipKMS *flip)
|
|||
kms_onscreen->current_bo = kms_onscreen->next_bo;
|
||||
kms_onscreen->next_bo = NULL;
|
||||
|
||||
g_clear_pointer (&kms_onscreen->card_bo, gbm_bo_destroy);
|
||||
|
||||
cogl_object_unref (flip->onscreen);
|
||||
|
||||
g_slice_free (CoglFlipKMS, flip);
|
||||
|
@ -275,7 +297,7 @@ handle_drm_event (CoglRendererKMS *kms_renderer)
|
|||
memset (&evctx, 0, sizeof evctx);
|
||||
evctx.version = DRM_EVENT_CONTEXT_VERSION;
|
||||
evctx.page_flip_handler = page_flip_handler;
|
||||
drmHandleEvent (kms_renderer->fd, &evctx);
|
||||
drmHandleEvent (kms_renderer->card_device.fd, &evctx);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -297,6 +319,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;
|
||||
|
@ -305,50 +329,89 @@ _cogl_winsys_renderer_connect (CoglRenderer *renderer,
|
|||
egl_renderer->platform = g_slice_new0 (CoglRendererKMS);
|
||||
kms_renderer = egl_renderer->platform;
|
||||
|
||||
kms_renderer->fd = -1;
|
||||
kms_renderer->opened_fd = -1;
|
||||
egl_renderer->edpy = EGL_NO_DISPLAY;
|
||||
|
||||
if (renderer->kms_fd >= 0)
|
||||
kms_renderer->render_offload_device.fd = -1;
|
||||
|
||||
ret = glob (render_offload_device_glob, 0, NULL, &glob_buffer);
|
||||
|
||||
if (ret != GLOB_NOMATCH)
|
||||
{
|
||||
kms_renderer->fd = renderer->kms_fd;
|
||||
kms_renderer->render_offload_device.fd = open (glob_buffer.gl_pathv[0], O_RDWR);
|
||||
|
||||
if (kms_renderer->render_offload_device.fd < 0)
|
||||
g_debug ("could not open '%s': %m", glob_buffer.gl_pathv[0]);
|
||||
}
|
||||
|
||||
globfree (&glob_buffer);
|
||||
|
||||
if (kms_renderer->render_offload_device.fd >= 0)
|
||||
{
|
||||
kms_renderer->render_offload_device.gbm = gbm_create_device (kms_renderer->render_offload_device.fd);
|
||||
if (kms_renderer->render_offload_device.gbm != NULL)
|
||||
{
|
||||
egl_renderer->edpy = eglGetDisplay ((EGLNativeDisplayType)kms_renderer->render_offload_device.gbm);
|
||||
|
||||
if (egl_renderer->edpy != EGL_NO_DISPLAY)
|
||||
{
|
||||
kms_renderer->rendering_gbm = kms_renderer->render_offload_device.gbm;
|
||||
}
|
||||
else
|
||||
{
|
||||
kms_renderer->opened_fd = open (device_name, O_RDWR);
|
||||
kms_renderer->fd = kms_renderer->opened_fd;
|
||||
if (kms_renderer->fd < 0)
|
||||
gbm_device_destroy (kms_renderer->render_offload_device.gbm);
|
||||
kms_renderer->render_offload_device.gbm = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
kms_renderer->card_device.fd = -1;
|
||||
|
||||
if (renderer->kms_fd >= 0)
|
||||
{
|
||||
kms_renderer->card_device.fd = renderer->kms_fd;
|
||||
kms_renderer->card_device.is_borrowed = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
kms_renderer->card_device.fd = open (card_device_name, O_RDWR);
|
||||
if (kms_renderer->card_device.fd < 0)
|
||||
{
|
||||
/* Probably permissions error */
|
||||
_cogl_set_error (error, COGL_WINSYS_ERROR,
|
||||
COGL_WINSYS_ERROR_INIT,
|
||||
"Couldn't open %s", device_name);
|
||||
"Couldn't open %s", card_device_name);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
kms_renderer->gbm = gbm_create_device (kms_renderer->fd);
|
||||
if (kms_renderer->gbm == NULL)
|
||||
kms_renderer->card_device.gbm = gbm_create_device (kms_renderer->card_device.fd);
|
||||
if (kms_renderer->card_device.gbm == NULL)
|
||||
{
|
||||
_cogl_set_error (error, COGL_WINSYS_ERROR,
|
||||
COGL_WINSYS_ERROR_INIT,
|
||||
"Couldn't create gbm device");
|
||||
goto close_fd;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
egl_renderer->edpy = eglGetDisplay ((EGLNativeDisplayType)kms_renderer->gbm);
|
||||
if (egl_renderer->edpy == EGL_NO_DISPLAY)
|
||||
{
|
||||
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 destroy_gbm_device;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
kms_renderer->rendering_gbm = kms_renderer->card_device.gbm;
|
||||
}
|
||||
|
||||
if (!_cogl_winsys_egl_renderer_connect_common (renderer, error))
|
||||
goto egl_terminate;
|
||||
goto fail;
|
||||
|
||||
_cogl_poll_renderer_add_fd (renderer,
|
||||
kms_renderer->fd,
|
||||
kms_renderer->card_device.fd,
|
||||
COGL_POLL_FD_EVENT_IN,
|
||||
NULL, /* no prepare callback */
|
||||
dispatch_kms_events,
|
||||
|
@ -356,14 +419,7 @@ _cogl_winsys_renderer_connect (CoglRenderer *renderer,
|
|||
|
||||
return TRUE;
|
||||
|
||||
egl_terminate:
|
||||
eglTerminate (egl_renderer->edpy);
|
||||
destroy_gbm_device:
|
||||
gbm_device_destroy (kms_renderer->gbm);
|
||||
close_fd:
|
||||
if (kms_renderer->opened_fd >= 0)
|
||||
close (kms_renderer->opened_fd);
|
||||
|
||||
fail:
|
||||
_cogl_winsys_renderer_disconnect (renderer);
|
||||
|
||||
return FALSE;
|
||||
|
@ -567,7 +623,7 @@ setup_crtc_modes (CoglDisplay *display, int fb_id)
|
|||
{
|
||||
CoglKmsCrtc *crtc = l->data;
|
||||
|
||||
int ret = drmModeSetCrtc (kms_renderer->fd,
|
||||
int ret = drmModeSetCrtc (kms_renderer->card_device.fd,
|
||||
crtc->id,
|
||||
fb_id, crtc->x, crtc->y,
|
||||
crtc->connectors, crtc->count,
|
||||
|
@ -599,7 +655,7 @@ flip_all_crtcs (CoglDisplay *display, CoglFlipKMS *flip, int fb_id)
|
|||
|
||||
if (!kms_renderer->page_flips_not_supported)
|
||||
{
|
||||
ret = drmModePageFlip (kms_renderer->fd,
|
||||
ret = drmModePageFlip (kms_renderer->card_device.fd,
|
||||
crtc->id, fb_id,
|
||||
DRM_MODE_PAGE_FLIP_EVENT, flip);
|
||||
if (ret)
|
||||
|
@ -653,7 +709,7 @@ _cogl_winsys_egl_display_setup (CoglDisplay *display,
|
|||
kms_display = g_slice_new0 (CoglDisplayKMS);
|
||||
egl_display->platform = kms_display;
|
||||
|
||||
resources = drmModeGetResources (kms_renderer->fd);
|
||||
resources = drmModeGetResources (kms_renderer->card_device.fd);
|
||||
if (!resources)
|
||||
{
|
||||
_cogl_set_error (error, COGL_WINSYS_ERROR,
|
||||
|
@ -663,7 +719,7 @@ _cogl_winsys_egl_display_setup (CoglDisplay *display,
|
|||
}
|
||||
|
||||
output0 = find_output (0,
|
||||
kms_renderer->fd,
|
||||
kms_renderer->card_device.fd,
|
||||
resources,
|
||||
NULL,
|
||||
0, /* n excluded connectors */
|
||||
|
@ -682,7 +738,7 @@ _cogl_winsys_egl_display_setup (CoglDisplay *display,
|
|||
{
|
||||
int exclude_connector = output0->connector->connector_id;
|
||||
output1 = find_output (1,
|
||||
kms_renderer->fd,
|
||||
kms_renderer->card_device.fd,
|
||||
resources,
|
||||
&exclude_connector,
|
||||
1, /* n excluded connectors */
|
||||
|
@ -782,7 +838,7 @@ _cogl_winsys_egl_display_destroy (CoglDisplay *display)
|
|||
GList *l;
|
||||
|
||||
for (l = kms_display->outputs; l; l = l->next)
|
||||
output_free (kms_renderer->fd, l->data);
|
||||
output_free (kms_renderer->card_device.fd, l->data);
|
||||
g_list_free (kms_display->outputs);
|
||||
kms_display->outputs = NULL;
|
||||
|
||||
|
@ -805,7 +861,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->gbm,
|
||||
gbm_surface_create (kms_renderer->rendering_gbm,
|
||||
16, 16,
|
||||
GBM_FORMAT_XRGB8888,
|
||||
GBM_BO_USE_RENDERING);
|
||||
|
@ -880,7 +936,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 */
|
||||
|
@ -910,16 +966,32 @@ _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);
|
||||
|
||||
#if (COGL_VERSION_ENCODE (COGL_GBM_MAJOR, COGL_GBM_MINOR, COGL_GBM_MICRO) >= \
|
||||
COGL_VERSION_ENCODE (8, 1, 0))
|
||||
stride = gbm_bo_get_stride (kms_onscreen->next_bo);
|
||||
#else
|
||||
stride = gbm_bo_get_pitch (kms_onscreen->next_bo);
|
||||
#endif
|
||||
|
||||
if (kms_renderer->render_offload_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 = stride;
|
||||
dma_buf_data.format = gbm_bo_get_format (kms_onscreen->next_bo);
|
||||
|
||||
kms_onscreen->card_bo = gbm_bo_import (kms_renderer->card_device.gbm,
|
||||
GBM_BO_IMPORT_FD,
|
||||
&dma_buf_data,
|
||||
GBM_BO_USE_SCANOUT);
|
||||
close (dma_buf_data.fd);
|
||||
|
||||
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;
|
||||
|
||||
if (drmModeAddFB (kms_renderer->fd,
|
||||
if (drmModeAddFB (kms_renderer->card_device.fd,
|
||||
kms_display->width,
|
||||
kms_display->height,
|
||||
24, /* depth */
|
||||
|
@ -929,6 +1001,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;
|
||||
|
@ -951,7 +1024,8 @@ _cogl_winsys_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
|||
|
||||
if (flip->pending == 0)
|
||||
{
|
||||
drmModeRmFB (kms_renderer->fd, kms_onscreen->next_fb_id);
|
||||
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;
|
||||
|
@ -1026,10 +1100,10 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
|
|||
egl_onscreen->platform = kms_onscreen;
|
||||
|
||||
kms_onscreen->surface =
|
||||
gbm_surface_create (kms_renderer->gbm,
|
||||
gbm_surface_create (kms_renderer->rendering_gbm,
|
||||
kms_display->width,
|
||||
kms_display->height,
|
||||
GBM_BO_FORMAT_XRGB8888,
|
||||
GBM_FORMAT_XRGB8888,
|
||||
GBM_BO_USE_SCANOUT |
|
||||
GBM_BO_USE_RENDERING);
|
||||
|
||||
|
@ -1168,7 +1242,7 @@ cogl_kms_renderer_get_gbm (CoglRenderer *renderer)
|
|||
{
|
||||
CoglRendererEGL *egl_renderer = renderer->winsys;
|
||||
CoglRendererKMS *kms_renderer = egl_renderer->platform;
|
||||
return kms_renderer->gbm;
|
||||
return kms_renderer->card_device.gbm;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
|
@ -1183,7 +1257,7 @@ cogl_kms_renderer_get_kms_fd (CoglRenderer *renderer)
|
|||
{
|
||||
CoglRendererEGL *egl_renderer = renderer->winsys;
|
||||
CoglRendererKMS *kms_renderer = egl_renderer->platform;
|
||||
return kms_renderer->fd;
|
||||
return kms_renderer->card_device.fd;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
|
@ -1227,9 +1301,9 @@ 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->gbm,
|
||||
new_surface = gbm_surface_create (kms_renderer->rendering_gbm,
|
||||
width, height,
|
||||
GBM_BO_FORMAT_XRGB8888,
|
||||
GBM_FORMAT_XRGB8888,
|
||||
GBM_BO_USE_SCANOUT |
|
||||
GBM_BO_USE_RENDERING);
|
||||
|
||||
|
|
Loading…
Reference in New Issue