kms: Add first version of "baremetal" backend for EGL on KMS
To start with this backend only supports creating a single CoglOnscreen framebuffer and will automatically set is up to display fullscreen on the first suitable crtc it can find. To compile this backend - get some dribbly black candles, sacrifice a goat and configure with: --enable-kms-egl-platform Note: There is currently a problem with using GLES2 with this winsys so you need to run with EGL_DRIVER=gl Note: If you have problems with mesa crashing in XCB during eglInitialize then you may need to explicitly run with EGL_PLATFORM=gbm Reviewed-by: Robert Bragg <robert@linux.intel.com>
This commit is contained in:
parent
d44e548715
commit
1b54c8023e
@ -370,6 +370,11 @@ if SUPPORT_EGL_PLATFORM_WAYLAND
|
|||||||
cogl_public_h += \
|
cogl_public_h += \
|
||||||
$(srcdir)/cogl-wayland-renderer.h
|
$(srcdir)/cogl-wayland-renderer.h
|
||||||
endif
|
endif
|
||||||
|
if SUPPORT_EGL_PLATFORM_KMS
|
||||||
|
cogl_sources_c += \
|
||||||
|
$(srcdir)/winsys/cogl-winsys-kms.c \
|
||||||
|
$(srcdir)/winsys/cogl-winsys-kms.h
|
||||||
|
endif
|
||||||
if SUPPORT_EGL
|
if SUPPORT_EGL
|
||||||
cogl_sources_c += \
|
cogl_sources_c += \
|
||||||
$(srcdir)/winsys/cogl-winsys-egl.c \
|
$(srcdir)/winsys/cogl-winsys-egl.c \
|
||||||
|
@ -62,7 +62,12 @@
|
|||||||
#include <android/native_window.h>
|
#include <android/native_window.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef COGL_HAS_EGL_PLATFORM_KMS_SUPPORT
|
||||||
|
#include "cogl-winsys-kms.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@ -106,6 +111,9 @@ typedef struct _CoglRendererEGL
|
|||||||
#ifdef COGL_HAS_EGL_PLATFORM_GDL_SUPPORT
|
#ifdef COGL_HAS_EGL_PLATFORM_GDL_SUPPORT
|
||||||
gboolean gdl_initialized;
|
gboolean gdl_initialized;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef COGL_HAS_EGL_PLATFORM_KMS_SUPPORT
|
||||||
|
CoglRendererKMS kms_renderer;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Function pointers for GLX specific extensions */
|
/* Function pointers for GLX specific extensions */
|
||||||
#define COGL_WINSYS_FEATURE_BEGIN(a, b, c, d)
|
#define COGL_WINSYS_FEATURE_BEGIN(a, b, c, d)
|
||||||
@ -137,8 +145,13 @@ typedef struct _CoglDisplayEGL
|
|||||||
EGLSurface dummy_surface;
|
EGLSurface dummy_surface;
|
||||||
#elif defined (COGL_HAS_EGL_PLATFORM_POWERVR_NULL_SUPPORT) || \
|
#elif defined (COGL_HAS_EGL_PLATFORM_POWERVR_NULL_SUPPORT) || \
|
||||||
defined (COGL_HAS_EGL_PLATFORM_GDL_SUPPORT) || \
|
defined (COGL_HAS_EGL_PLATFORM_GDL_SUPPORT) || \
|
||||||
defined (COGL_HAS_EGL_PLATFORM_ANDROID_SUPPORT)
|
defined (COGL_HAS_EGL_PLATFORM_ANDROID_SUPPORT) || \
|
||||||
|
defined (COGL_HAS_EGL_PLATFORM_KMS_SUPPORT)
|
||||||
|
#ifndef COGL_HAS_EGL_PLATFORM_KMS_SUPPORT
|
||||||
EGLSurface egl_surface;
|
EGLSurface egl_surface;
|
||||||
|
#else
|
||||||
|
CoglDisplayKMS kms_display;
|
||||||
|
#endif
|
||||||
int egl_surface_width;
|
int egl_surface_width;
|
||||||
int egl_surface_height;
|
int egl_surface_height;
|
||||||
gboolean have_onscreen;
|
gboolean have_onscreen;
|
||||||
@ -175,7 +188,11 @@ typedef struct _CoglOnscreenEGL
|
|||||||
struct wl_surface *wayland_surface;
|
struct wl_surface *wayland_surface;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef COGL_HAS_EGL_PLATFORM_KMS_SUPPORT
|
||||||
|
CoglOnscreenKMS kms_onscreen;
|
||||||
|
#else
|
||||||
EGLSurface egl_surface;
|
EGLSurface egl_surface;
|
||||||
|
#endif
|
||||||
} CoglOnscreenEGL;
|
} CoglOnscreenEGL;
|
||||||
|
|
||||||
#ifdef EGL_KHR_image_pixmap
|
#ifdef EGL_KHR_image_pixmap
|
||||||
@ -434,6 +451,11 @@ _cogl_winsys_renderer_connect (CoglRenderer *renderer,
|
|||||||
&egl_renderer->egl_version_major,
|
&egl_renderer->egl_version_major,
|
||||||
&egl_renderer->egl_version_minor);
|
&egl_renderer->egl_version_minor);
|
||||||
|
|
||||||
|
#elif defined (COGL_HAS_EGL_PLATFORM_KMS_SUPPORT)
|
||||||
|
if (!_cogl_winsys_kms_connect (&egl_renderer->kms_renderer, error))
|
||||||
|
goto error;
|
||||||
|
egl_renderer->edpy = egl_renderer->kms_renderer.dpy;
|
||||||
|
status = EGL_TRUE;
|
||||||
#else
|
#else
|
||||||
egl_renderer->edpy = eglGetDisplay (EGL_DEFAULT_DISPLAY);
|
egl_renderer->edpy = eglGetDisplay (EGL_DEFAULT_DISPLAY);
|
||||||
|
|
||||||
@ -641,12 +663,14 @@ try_create_context (CoglDisplay *display,
|
|||||||
CoglXlibRenderer *xlib_renderer = display->renderer->winsys;
|
CoglXlibRenderer *xlib_renderer = display->renderer->winsys;
|
||||||
#endif
|
#endif
|
||||||
CoglRendererEGL *egl_renderer = display->renderer->winsys;
|
CoglRendererEGL *egl_renderer = display->renderer->winsys;
|
||||||
|
#ifndef COGL_HAS_EGL_PLATFORM_KMS_SUPPORT
|
||||||
EGLDisplay edpy;
|
EGLDisplay edpy;
|
||||||
EGLConfig config;
|
EGLConfig config;
|
||||||
EGLint config_count = 0;
|
EGLint config_count = 0;
|
||||||
EGLBoolean status;
|
EGLBoolean status;
|
||||||
EGLint cfg_attribs[MAX_EGL_CONFIG_ATTRIBS];
|
|
||||||
EGLint attribs[3];
|
EGLint attribs[3];
|
||||||
|
#endif
|
||||||
|
EGLint cfg_attribs[MAX_EGL_CONFIG_ATTRIBS];
|
||||||
#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
|
#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
|
||||||
XVisualInfo *xvisinfo;
|
XVisualInfo *xvisinfo;
|
||||||
XSetWindowAttributes attrs;
|
XSetWindowAttributes attrs;
|
||||||
@ -660,11 +684,12 @@ try_create_context (CoglDisplay *display,
|
|||||||
|
|
||||||
_COGL_RETURN_VAL_IF_FAIL (egl_display->egl_context == NULL, TRUE);
|
_COGL_RETURN_VAL_IF_FAIL (egl_display->egl_context == NULL, TRUE);
|
||||||
|
|
||||||
edpy = egl_renderer->edpy;
|
|
||||||
|
|
||||||
if (display->renderer->driver == COGL_DRIVER_GL)
|
if (display->renderer->driver == COGL_DRIVER_GL)
|
||||||
eglBindAPI (EGL_OPENGL_API);
|
eglBindAPI (EGL_OPENGL_API);
|
||||||
|
|
||||||
|
#ifndef COGL_HAS_EGL_PLATFORM_KMS_SUPPORT
|
||||||
|
edpy = egl_renderer->edpy;
|
||||||
|
|
||||||
status = eglChooseConfig (edpy,
|
status = eglChooseConfig (edpy,
|
||||||
cfg_attribs,
|
cfg_attribs,
|
||||||
&config, 1,
|
&config, 1,
|
||||||
@ -695,7 +720,7 @@ try_create_context (CoglDisplay *display,
|
|||||||
error_message = "Unable to create a suitable EGL context";
|
error_message = "Unable to create a suitable EGL context";
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
|
#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
|
||||||
|
|
||||||
xvisinfo = get_visual_info (display, config);
|
xvisinfo = get_visual_info (display, config);
|
||||||
@ -907,14 +932,24 @@ try_create_context (CoglDisplay *display,
|
|||||||
EGL_HEIGHT,
|
EGL_HEIGHT,
|
||||||
&egl_display->egl_surface_height);
|
&egl_display->egl_surface_height);
|
||||||
|
|
||||||
|
#elif defined (COGL_HAS_EGL_PLATFORM_KMS_SUPPORT)
|
||||||
|
if (!_cogl_winsys_kms_create_context (&egl_renderer->kms_renderer,
|
||||||
|
&egl_display->kms_display,
|
||||||
|
error))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
egl_display->egl_surface_width = egl_display->kms_display.width;
|
||||||
|
egl_display->egl_surface_height = egl_display->kms_display.height;
|
||||||
|
egl_display->egl_context = egl_display->kms_display.egl_context;
|
||||||
#else
|
#else
|
||||||
#error "Unknown EGL platform"
|
#error "Unknown EGL platform"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
#ifndef COGL_HAS_EGL_PLATFORM_KMS_SUPPORT
|
||||||
fail:
|
fail:
|
||||||
|
#endif
|
||||||
g_set_error (error, COGL_WINSYS_ERROR,
|
g_set_error (error, COGL_WINSYS_ERROR,
|
||||||
COGL_WINSYS_ERROR_CREATE_CONTEXT,
|
COGL_WINSYS_ERROR_CREATE_CONTEXT,
|
||||||
"%s", error_message);
|
"%s", error_message);
|
||||||
@ -930,6 +965,17 @@ cleanup_context (CoglDisplay *display)
|
|||||||
CoglXlibDisplay *xlib_display = display->winsys;
|
CoglXlibDisplay *xlib_display = display->winsys;
|
||||||
CoglXlibRenderer *xlib_renderer = display->renderer->winsys;
|
CoglXlibRenderer *xlib_renderer = display->renderer->winsys;
|
||||||
#endif
|
#endif
|
||||||
|
#if defined (COGL_HAS_EGL_PLATFORM_KMS_SUPPORT)
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
if (!_cogl_winsys_kms_destroy_context (&egl_renderer->kms_renderer,
|
||||||
|
&egl_display->kms_display,
|
||||||
|
&error))
|
||||||
|
{
|
||||||
|
g_critical (G_STRLOC ": Error cleaning up KMS rendering state: %s", error->message);
|
||||||
|
g_clear_error (&error);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (egl_display->egl_context != EGL_NO_CONTEXT)
|
if (egl_display->egl_context != EGL_NO_CONTEXT)
|
||||||
{
|
{
|
||||||
@ -1108,7 +1154,8 @@ _cogl_winsys_display_setup (CoglDisplay *display,
|
|||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
CoglDisplayEGL *egl_display;
|
CoglDisplayEGL *egl_display;
|
||||||
#ifdef COGL_HAS_WAYLAND_EGL_SERVER_SUPPORT
|
#if defined (COGL_HAS_WAYLAND_EGL_SERVER_SUPPORT) || \
|
||||||
|
defined (COGL_HAS_EGL_PLATFORM_KMS_SUPPORT)
|
||||||
CoglRendererEGL *egl_renderer = display->renderer->winsys;
|
CoglRendererEGL *egl_renderer = display->renderer->winsys;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1131,6 +1178,13 @@ _cogl_winsys_display_setup (CoglDisplay *display,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef COGL_HAS_EGL_PLATFORM_KMS_SUPPORT
|
||||||
|
if (!_cogl_winsys_kms_display_setup (&egl_renderer->kms_renderer,
|
||||||
|
&egl_display->kms_display,
|
||||||
|
error))
|
||||||
|
goto error;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!create_context (display, error))
|
if (!create_context (display, error))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
@ -1181,19 +1235,24 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
|
|||||||
CoglOnscreenXlib *xlib_onscreen;
|
CoglOnscreenXlib *xlib_onscreen;
|
||||||
Window xwin;
|
Window xwin;
|
||||||
#endif
|
#endif
|
||||||
#ifdef COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT
|
#if defined (COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT) || \
|
||||||
|
defined (COGL_HAS_EGL_PLATFORM_KMS_SUPPORT)
|
||||||
CoglRendererEGL *egl_renderer = display->renderer->winsys;
|
CoglRendererEGL *egl_renderer = display->renderer->winsys;
|
||||||
#endif
|
#endif
|
||||||
CoglOnscreenEGL *egl_onscreen;
|
CoglOnscreenEGL *egl_onscreen;
|
||||||
|
#ifndef COGL_HAS_EGL_PLATFORM_KMS_SUPPORT
|
||||||
EGLint attributes[MAX_EGL_CONFIG_ATTRIBS];
|
EGLint attributes[MAX_EGL_CONFIG_ATTRIBS];
|
||||||
EGLConfig egl_config;
|
EGLConfig egl_config;
|
||||||
EGLint config_count = 0;
|
EGLint config_count = 0;
|
||||||
EGLBoolean status;
|
EGLBoolean status;
|
||||||
gboolean need_stencil =
|
gboolean need_stencil =
|
||||||
egl_display->stencil_disabled ? FALSE : framebuffer->config.need_stencil;
|
egl_display->stencil_disabled ? FALSE : framebuffer->config.need_stencil;
|
||||||
|
#endif
|
||||||
|
|
||||||
_COGL_RETURN_VAL_IF_FAIL (egl_display->egl_context, FALSE);
|
_COGL_RETURN_VAL_IF_FAIL (egl_display->egl_context, FALSE);
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef COGL_HAS_EGL_PLATFORM_KMS_SUPPORT
|
||||||
egl_attributes_from_framebuffer_config (display,
|
egl_attributes_from_framebuffer_config (display,
|
||||||
&framebuffer->config,
|
&framebuffer->config,
|
||||||
need_stencil,
|
need_stencil,
|
||||||
@ -1222,7 +1281,7 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
|
|||||||
g_return_val_if_fail (status == EGL_TRUE, TRUE);
|
g_return_val_if_fail (status == EGL_TRUE, TRUE);
|
||||||
framebuffer->samples_per_pixel = samples;
|
framebuffer->samples_per_pixel = samples;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
|
#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
|
||||||
|
|
||||||
/* FIXME: We need to explicitly Select for ConfigureNotify events.
|
/* FIXME: We need to explicitly Select for ConfigureNotify events.
|
||||||
@ -1384,7 +1443,8 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
|
|||||||
|
|
||||||
#elif defined (COGL_HAS_EGL_PLATFORM_POWERVR_NULL_SUPPORT) || \
|
#elif defined (COGL_HAS_EGL_PLATFORM_POWERVR_NULL_SUPPORT) || \
|
||||||
defined (COGL_HAS_EGL_PLATFORM_ANDROID_SUPPORT) || \
|
defined (COGL_HAS_EGL_PLATFORM_ANDROID_SUPPORT) || \
|
||||||
defined (COGL_HAS_EGL_PLATFORM_GDL_SUPPORT)
|
defined (COGL_HAS_EGL_PLATFORM_GDL_SUPPORT) || \
|
||||||
|
defined (COGL_HAS_EGL_PLATFORM_KMS_SUPPORT)
|
||||||
if (egl_display->have_onscreen)
|
if (egl_display->have_onscreen)
|
||||||
{
|
{
|
||||||
g_set_error (error, COGL_WINSYS_ERROR,
|
g_set_error (error, COGL_WINSYS_ERROR,
|
||||||
@ -1393,7 +1453,16 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef COGL_HAS_EGL_PLATFORM_KMS_SUPPORT
|
||||||
|
if (!_cogl_winsys_kms_onscreen_init (cogl_framebuffer_get_context (framebuffer),
|
||||||
|
&egl_renderer->kms_renderer,
|
||||||
|
&egl_display->kms_display,
|
||||||
|
&egl_onscreen->kms_onscreen,
|
||||||
|
error))
|
||||||
|
return FALSE;
|
||||||
|
#else
|
||||||
egl_onscreen->egl_surface = egl_display->egl_surface;
|
egl_onscreen->egl_surface = egl_display->egl_surface;
|
||||||
|
#endif
|
||||||
|
|
||||||
_cogl_framebuffer_winsys_update_size (framebuffer,
|
_cogl_framebuffer_winsys_update_size (framebuffer,
|
||||||
egl_display->egl_surface_width,
|
egl_display->egl_surface_width,
|
||||||
@ -1411,6 +1480,7 @@ _cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen)
|
|||||||
{
|
{
|
||||||
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
||||||
CoglContext *context = framebuffer->context;
|
CoglContext *context = framebuffer->context;
|
||||||
|
CoglRendererEGL *egl_renderer = context->display->renderer->winsys;
|
||||||
#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
|
#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
|
||||||
CoglXlibRenderer *xlib_renderer = context->display->renderer->winsys;
|
CoglXlibRenderer *xlib_renderer = context->display->renderer->winsys;
|
||||||
CoglXlibTrapState old_state;
|
CoglXlibTrapState old_state;
|
||||||
@ -1418,13 +1488,12 @@ _cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen)
|
|||||||
#elif defined (COGL_HAS_EGL_PLATFORM_POWERVR_NULL_SUPPORT)
|
#elif defined (COGL_HAS_EGL_PLATFORM_POWERVR_NULL_SUPPORT)
|
||||||
CoglDisplayEGL *egl_display = context->display->winsys;
|
CoglDisplayEGL *egl_display = context->display->winsys;
|
||||||
#endif
|
#endif
|
||||||
CoglRendererEGL *egl_renderer = context->display->renderer->winsys;
|
|
||||||
CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
|
CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
|
||||||
|
|
||||||
/* If we never successfully allocated then there's nothing to do */
|
/* If we never successfully allocated then there's nothing to do */
|
||||||
if (egl_onscreen == NULL)
|
if (egl_onscreen == NULL)
|
||||||
return;
|
return;
|
||||||
|
#ifndef COGL_HAS_EGL_PLATFORM_KMS_SUPPORT
|
||||||
if (egl_onscreen->egl_surface != EGL_NO_SURFACE)
|
if (egl_onscreen->egl_surface != EGL_NO_SURFACE)
|
||||||
{
|
{
|
||||||
if (eglDestroySurface (egl_renderer->edpy, egl_onscreen->egl_surface)
|
if (eglDestroySurface (egl_renderer->edpy, egl_onscreen->egl_surface)
|
||||||
@ -1432,7 +1501,7 @@ _cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen)
|
|||||||
g_warning ("Failed to destroy EGL surface");
|
g_warning ("Failed to destroy EGL surface");
|
||||||
egl_onscreen->egl_surface = EGL_NO_SURFACE;
|
egl_onscreen->egl_surface = EGL_NO_SURFACE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_NULL_SUPPORT
|
#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_NULL_SUPPORT
|
||||||
egl_display->have_onscreen = FALSE;
|
egl_display->have_onscreen = FALSE;
|
||||||
#endif
|
#endif
|
||||||
@ -1469,6 +1538,11 @@ _cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef COGL_HAS_EGL_PLATFORM_KMS_SUPPORT
|
||||||
|
_cogl_winsys_kms_onscreen_deinit (&egl_renderer->kms_renderer,
|
||||||
|
&egl_onscreen->kms_onscreen);
|
||||||
|
#endif
|
||||||
|
|
||||||
g_slice_free (CoglOnscreenEGL, onscreen->winsys);
|
g_slice_free (CoglOnscreenEGL, onscreen->winsys);
|
||||||
onscreen->winsys = NULL;
|
onscreen->winsys = NULL;
|
||||||
}
|
}
|
||||||
@ -1477,10 +1551,19 @@ static void
|
|||||||
_cogl_winsys_onscreen_bind (CoglOnscreen *onscreen)
|
_cogl_winsys_onscreen_bind (CoglOnscreen *onscreen)
|
||||||
{
|
{
|
||||||
CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
|
CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
|
||||||
CoglContextEGL *egl_context = context->winsys;
|
|
||||||
CoglDisplayEGL *egl_display = context->display->winsys;
|
CoglDisplayEGL *egl_display = context->display->winsys;
|
||||||
CoglRendererEGL *egl_renderer = context->display->renderer->winsys;
|
CoglRendererEGL *egl_renderer = context->display->renderer->winsys;
|
||||||
|
#ifndef COGL_HAS_EGL_PLATFORM_KMS_SUPPORT
|
||||||
CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
|
CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
|
||||||
|
CoglContextEGL *egl_context = context->winsys;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef COGL_HAS_EGL_PLATFORM_KMS_SUPPORT
|
||||||
|
_cogl_winsys_kms_bind (&egl_renderer->kms_renderer,
|
||||||
|
&egl_display->kms_display);
|
||||||
|
return;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
if (egl_context->current_surface == egl_onscreen->egl_surface)
|
if (egl_context->current_surface == egl_onscreen->egl_surface)
|
||||||
return;
|
return;
|
||||||
@ -1497,6 +1580,7 @@ _cogl_winsys_onscreen_bind (CoglOnscreen *onscreen)
|
|||||||
#elif defined (COGL_HAS_EGL_PLATFORM_POWERVR_NULL_SUPPORT) || \
|
#elif defined (COGL_HAS_EGL_PLATFORM_POWERVR_NULL_SUPPORT) || \
|
||||||
defined (COGL_HAS_EGL_PLATFORM_ANDROID_SUPPORT) || \
|
defined (COGL_HAS_EGL_PLATFORM_ANDROID_SUPPORT) || \
|
||||||
defined (COGL_HAS_EGL_PLATFORM_GDL_SUPPORT)
|
defined (COGL_HAS_EGL_PLATFORM_GDL_SUPPORT)
|
||||||
|
|
||||||
return;
|
return;
|
||||||
#else
|
#else
|
||||||
#error "Unknown EGL platform"
|
#error "Unknown EGL platform"
|
||||||
@ -1515,6 +1599,8 @@ _cogl_winsys_onscreen_bind (CoglOnscreen *onscreen)
|
|||||||
eglSwapInterval (egl_renderer->edpy, 1);
|
eglSwapInterval (egl_renderer->edpy, 1);
|
||||||
else
|
else
|
||||||
eglSwapInterval (egl_renderer->edpy, 0);
|
eglSwapInterval (egl_renderer->edpy, 0);
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1522,6 +1608,7 @@ _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
|
|||||||
const int *user_rectangles,
|
const int *user_rectangles,
|
||||||
int n_rectangles)
|
int n_rectangles)
|
||||||
{
|
{
|
||||||
|
#ifndef COGL_HAS_EGL_PLATFORM_KMS_SUPPORT
|
||||||
CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
|
CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
|
||||||
CoglRendererEGL *egl_renderer = context->display->renderer->winsys;
|
CoglRendererEGL *egl_renderer = context->display->renderer->winsys;
|
||||||
CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
|
CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
|
||||||
@ -1545,6 +1632,7 @@ _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
|
|||||||
n_rectangles,
|
n_rectangles,
|
||||||
rectangles) == EGL_FALSE)
|
rectangles) == EGL_FALSE)
|
||||||
g_warning ("Error reported by eglSwapBuffersRegion");
|
g_warning ("Error reported by eglSwapBuffersRegion");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
|
#ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
|
||||||
@ -1569,8 +1657,18 @@ _cogl_winsys_onscreen_swap_buffers (CoglOnscreen *onscreen)
|
|||||||
CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
|
CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
|
||||||
CoglRendererEGL *egl_renderer = context->display->renderer->winsys;
|
CoglRendererEGL *egl_renderer = context->display->renderer->winsys;
|
||||||
CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
|
CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
|
||||||
|
#ifdef COGL_HAS_EGL_PLATFORM_KMS_SUPPORT
|
||||||
|
CoglDisplayEGL *egl_display = context->display->winsys;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef COGL_HAS_EGL_PLATFORM_KMS_SUPPORT
|
||||||
|
_cogl_winsys_kms_swap_buffers (&egl_renderer->kms_renderer,
|
||||||
|
&egl_display->kms_display,
|
||||||
|
&egl_onscreen->kms_onscreen);
|
||||||
|
return;
|
||||||
|
#else
|
||||||
eglSwapBuffers (egl_renderer->edpy, egl_onscreen->egl_surface);
|
eglSwapBuffers (egl_renderer->edpy, egl_onscreen->egl_surface);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT
|
#ifdef COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT
|
||||||
/*
|
/*
|
||||||
@ -1595,6 +1693,7 @@ _cogl_winsys_onscreen_x11_get_window_xid (CoglOnscreen *onscreen)
|
|||||||
static void
|
static void
|
||||||
_cogl_winsys_onscreen_update_swap_throttled (CoglOnscreen *onscreen)
|
_cogl_winsys_onscreen_update_swap_throttled (CoglOnscreen *onscreen)
|
||||||
{
|
{
|
||||||
|
#ifndef COGL_HAS_EGL_PLATFORM_KMS_SUPPORT
|
||||||
CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
|
CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
|
||||||
CoglContextEGL *egl_context = context->winsys;
|
CoglContextEGL *egl_context = context->winsys;
|
||||||
CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
|
CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
|
||||||
@ -1603,6 +1702,7 @@ _cogl_winsys_onscreen_update_swap_throttled (CoglOnscreen *onscreen)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
egl_context->current_surface = EGL_NO_SURFACE;
|
egl_context->current_surface = EGL_NO_SURFACE;
|
||||||
|
#endif
|
||||||
_cogl_winsys_onscreen_bind (onscreen);
|
_cogl_winsys_onscreen_bind (onscreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
390
cogl/winsys/cogl-winsys-kms.c
Normal file
390
cogl/winsys/cogl-winsys-kms.c
Normal file
@ -0,0 +1,390 @@
|
|||||||
|
/*
|
||||||
|
* Cogl
|
||||||
|
*
|
||||||
|
* An object oriented GL/GLES Abstraction/Utility Layer
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011 Intel Corporation.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* Some code inspired by mesa demos eglkms.c.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Rob Bradford <rob@linux.intel.com>
|
||||||
|
* Kristian Høgsberg (from eglkms.c)
|
||||||
|
* Benjamin Franzke (from eglkms.c)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <GL/gl.h>
|
||||||
|
#include <GL/glext.h>
|
||||||
|
#include <EGL/egl.h>
|
||||||
|
#include <EGL/eglext.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "cogl.h"
|
||||||
|
|
||||||
|
#include "cogl-util.h"
|
||||||
|
#include "cogl-winsys-egl-private.h"
|
||||||
|
#include "cogl-winsys-private.h"
|
||||||
|
#include "cogl-feature-private.h"
|
||||||
|
#include "cogl-context-private.h"
|
||||||
|
#include "cogl-framebuffer.h"
|
||||||
|
#include "cogl-onscreen-private.h"
|
||||||
|
#include "cogl-swap-chain-private.h"
|
||||||
|
#include "cogl-renderer-private.h"
|
||||||
|
#include "cogl-private.h"
|
||||||
|
|
||||||
|
#include "cogl-winsys-kms.h"
|
||||||
|
|
||||||
|
static const char device_name[] = "/dev/dri/card0";
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
setup_kms (CoglRendererKMS *kms_renderer,
|
||||||
|
CoglDisplayKMS *kms_display,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
drmModeRes *resources;
|
||||||
|
drmModeConnector *connector;
|
||||||
|
drmModeEncoder *encoder;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
resources = drmModeGetResources (kms_renderer->fd);
|
||||||
|
if (!resources)
|
||||||
|
{
|
||||||
|
g_set_error (error, COGL_WINSYS_ERROR,
|
||||||
|
COGL_WINSYS_ERROR_INIT,
|
||||||
|
"drmModeGetResources failed");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < resources->count_connectors; i++)
|
||||||
|
{
|
||||||
|
connector = drmModeGetConnector (kms_renderer->fd, resources->connectors[i]);
|
||||||
|
if (connector == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (connector->connection == DRM_MODE_CONNECTED &&
|
||||||
|
connector->count_modes > 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
drmModeFreeConnector(connector);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == resources->count_connectors)
|
||||||
|
{
|
||||||
|
g_set_error (error, COGL_WINSYS_ERROR,
|
||||||
|
COGL_WINSYS_ERROR_INIT,
|
||||||
|
"No currently active connector found");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < resources->count_encoders; i++)
|
||||||
|
{
|
||||||
|
encoder = drmModeGetEncoder (kms_renderer->fd, resources->encoders[i]);
|
||||||
|
|
||||||
|
if (encoder == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (encoder->encoder_id == connector->encoder_id)
|
||||||
|
break;
|
||||||
|
|
||||||
|
drmModeFreeEncoder (encoder);
|
||||||
|
}
|
||||||
|
|
||||||
|
kms_display->saved_crtc = drmModeGetCrtc (kms_renderer->fd,
|
||||||
|
kms_display->encoder->crtc_id);
|
||||||
|
|
||||||
|
kms_display->connector = connector;
|
||||||
|
kms_display->encoder = encoder;
|
||||||
|
kms_display->mode = connector->modes[0];
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_cogl_winsys_kms_connect (CoglRendererKMS *kms_renderer,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
EGLint major, minor;
|
||||||
|
|
||||||
|
kms_renderer->fd = open (device_name, O_RDWR);
|
||||||
|
if (kms_renderer->fd < 0)
|
||||||
|
{
|
||||||
|
/* Probably permissions error */
|
||||||
|
g_set_error (error, COGL_WINSYS_ERROR,
|
||||||
|
COGL_WINSYS_ERROR_INIT,
|
||||||
|
"Couldn't open %s", device_name);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
kms_renderer->gbm = gbm_create_device (kms_renderer->fd);
|
||||||
|
if (kms_renderer->gbm == NULL)
|
||||||
|
{
|
||||||
|
g_set_error (error, COGL_WINSYS_ERROR,
|
||||||
|
COGL_WINSYS_ERROR_INIT,
|
||||||
|
"Couldn't create gbm device");
|
||||||
|
goto close_fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
kms_renderer->dpy = eglGetDisplay ((EGLNativeDisplayType)kms_renderer->gbm);
|
||||||
|
if (kms_renderer->dpy == EGL_NO_DISPLAY)
|
||||||
|
{
|
||||||
|
g_set_error (error, COGL_WINSYS_ERROR,
|
||||||
|
COGL_WINSYS_ERROR_INIT,
|
||||||
|
"Couldn't get eglDisplay");
|
||||||
|
goto destroy_gbm_device;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!eglInitialize (kms_renderer->dpy, &major, &minor))
|
||||||
|
{
|
||||||
|
g_set_error (error, COGL_WINSYS_ERROR,
|
||||||
|
COGL_WINSYS_ERROR_INIT,
|
||||||
|
"Couldn't initialize EGL");
|
||||||
|
goto egl_terminate;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
egl_terminate:
|
||||||
|
eglTerminate (kms_renderer->dpy);
|
||||||
|
destroy_gbm_device:
|
||||||
|
gbm_device_destroy (kms_renderer->gbm);
|
||||||
|
close_fd:
|
||||||
|
close (kms_renderer->fd);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_cogl_winsys_kms_display_setup (CoglRendererKMS *kms_renderer,
|
||||||
|
CoglDisplayKMS *kms_display,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
if (!setup_kms (kms_renderer, kms_display, error))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
kms_display->width = kms_display->mode.hdisplay;
|
||||||
|
kms_display->height = kms_display->mode.vdisplay;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_cogl_winsys_kms_create_context (CoglRendererKMS *kms_renderer,
|
||||||
|
CoglDisplayKMS *kms_display,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
kms_display->egl_context = eglCreateContext (kms_renderer->dpy, NULL, EGL_NO_CONTEXT, NULL);
|
||||||
|
|
||||||
|
if (kms_display->egl_context == NULL)
|
||||||
|
{
|
||||||
|
g_set_error (error, COGL_WINSYS_ERROR,
|
||||||
|
COGL_WINSYS_ERROR_CREATE_CONTEXT,
|
||||||
|
"Couldn't create EGL context");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!eglMakeCurrent (kms_renderer->dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, kms_display->egl_context))
|
||||||
|
{
|
||||||
|
g_set_error (error, COGL_WINSYS_ERROR,
|
||||||
|
COGL_WINSYS_ERROR_CREATE_CONTEXT,
|
||||||
|
"Failed to make context current");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_cogl_winsys_kms_onscreen_init (CoglContext *context,
|
||||||
|
CoglRendererKMS *kms_renderer,
|
||||||
|
CoglDisplayKMS *kms_display,
|
||||||
|
CoglOnscreenKMS *kms_onscreen,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
kms_onscreen->cogl_context = context;
|
||||||
|
|
||||||
|
context->glGenRenderbuffers (2, kms_onscreen->color_rb);
|
||||||
|
|
||||||
|
for (i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
uint32_t handle, stride;
|
||||||
|
|
||||||
|
kms_onscreen->bo[i] =
|
||||||
|
gbm_bo_create (kms_renderer->gbm,
|
||||||
|
kms_display->mode.hdisplay, kms_display->mode.vdisplay,
|
||||||
|
GBM_BO_FORMAT_XRGB8888,
|
||||||
|
GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
|
||||||
|
if (!kms_onscreen->bo[i])
|
||||||
|
{
|
||||||
|
g_set_error (error, COGL_WINSYS_ERROR,
|
||||||
|
COGL_WINSYS_ERROR_CREATE_CONTEXT,
|
||||||
|
"Failed to allocate buffer");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
kms_onscreen->image[i] = _cogl_egl_create_image (context,
|
||||||
|
EGL_NATIVE_PIXMAP_KHR,
|
||||||
|
kms_onscreen->bo[i],
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (kms_onscreen->image[i] == EGL_NO_IMAGE_KHR)
|
||||||
|
{
|
||||||
|
g_set_error (error, COGL_WINSYS_ERROR,
|
||||||
|
COGL_WINSYS_ERROR_CREATE_CONTEXT,
|
||||||
|
"Failed to create EGL image");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
context->glBindRenderbuffer (GL_RENDERBUFFER_EXT, kms_onscreen->color_rb[i]);
|
||||||
|
context->glEGLImageTargetRenderbufferStorage (GL_RENDERBUFFER, kms_onscreen->image[i]);
|
||||||
|
context->glBindRenderbuffer (GL_RENDERBUFFER_EXT, 0);
|
||||||
|
|
||||||
|
handle = gbm_bo_get_handle (kms_onscreen->bo[i]).u32;
|
||||||
|
stride = gbm_bo_get_pitch (kms_onscreen->bo[i]);
|
||||||
|
|
||||||
|
if (drmModeAddFB (kms_renderer->fd,
|
||||||
|
kms_display->mode.hdisplay, kms_display->mode.vdisplay,
|
||||||
|
24, 32,
|
||||||
|
stride,
|
||||||
|
handle,
|
||||||
|
&kms_onscreen->fb_id[i]) != 0)
|
||||||
|
{
|
||||||
|
g_set_error (error, COGL_WINSYS_ERROR,
|
||||||
|
COGL_WINSYS_ERROR_CREATE_CONTEXT,
|
||||||
|
"Failed to create framebuffer from buffer");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
context->glGenFramebuffers (1, &kms_onscreen->fb);
|
||||||
|
context->glBindFramebuffer (GL_FRAMEBUFFER_EXT, kms_onscreen->fb);
|
||||||
|
|
||||||
|
context->glGenRenderbuffers(1, &kms_onscreen->depth_rb);
|
||||||
|
context->glBindRenderbuffer(GL_RENDERBUFFER_EXT, kms_onscreen->depth_rb);
|
||||||
|
context->glRenderbufferStorage(GL_RENDERBUFFER_EXT,
|
||||||
|
GL_DEPTH_COMPONENT,
|
||||||
|
kms_display->mode.hdisplay, kms_display->mode.vdisplay);
|
||||||
|
context->glBindRenderbuffer (GL_RENDERBUFFER_EXT, 0);
|
||||||
|
|
||||||
|
context->glFramebufferRenderbuffer (GL_FRAMEBUFFER_EXT,
|
||||||
|
GL_DEPTH_ATTACHMENT_EXT,
|
||||||
|
GL_RENDERBUFFER_EXT,
|
||||||
|
kms_onscreen->depth_rb);
|
||||||
|
|
||||||
|
kms_onscreen->current_frame = 0;
|
||||||
|
_cogl_winsys_kms_swap_buffers (kms_renderer, kms_display, kms_onscreen);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_winsys_kms_onscreen_deinit (CoglRendererKMS *kms_renderer,
|
||||||
|
CoglOnscreenKMS *kms_onscreen)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
CoglContext *context = kms_onscreen->cogl_context;
|
||||||
|
|
||||||
|
context->glBindFramebuffer (GL_FRAMEBUFFER_EXT, kms_onscreen->fb);
|
||||||
|
context->glFramebufferRenderbuffer (GL_FRAMEBUFFER_EXT,
|
||||||
|
GL_COLOR_ATTACHMENT0_EXT,
|
||||||
|
GL_RENDERBUFFER_EXT,
|
||||||
|
0);
|
||||||
|
context->glDeleteRenderbuffers(2, kms_onscreen->color_rb);
|
||||||
|
context->glFramebufferRenderbuffer (GL_FRAMEBUFFER_EXT,
|
||||||
|
GL_DEPTH_ATTACHMENT_EXT,
|
||||||
|
GL_RENDERBUFFER_EXT,
|
||||||
|
0);
|
||||||
|
context->glDeleteRenderbuffers(1, &kms_onscreen->depth_rb);
|
||||||
|
|
||||||
|
for (i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
drmModeRmFB (kms_renderer->fd, kms_onscreen->fb_id[i]);
|
||||||
|
_cogl_egl_destroy_image (context, kms_onscreen->image[i]);
|
||||||
|
gbm_bo_destroy (kms_onscreen->bo[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_cogl_winsys_kms_destroy_context (CoglRendererKMS *kms_renderer,
|
||||||
|
CoglDisplayKMS *kms_display,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Restore the saved CRTC - this failing should not propagate an error */
|
||||||
|
ret = drmModeSetCrtc (kms_renderer->fd,
|
||||||
|
kms_display->saved_crtc->crtc_id,
|
||||||
|
kms_display->saved_crtc->buffer_id,
|
||||||
|
kms_display->saved_crtc->x, kms_display->saved_crtc->y,
|
||||||
|
&kms_display->connector->connector_id, 1,
|
||||||
|
&kms_display->saved_crtc->mode);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
g_critical (G_STRLOC ": Error restoring saved CRTC");
|
||||||
|
}
|
||||||
|
|
||||||
|
drmModeFreeCrtc (kms_display->saved_crtc);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_winsys_kms_swap_buffers (CoglRendererKMS *kms_renderer,
|
||||||
|
CoglDisplayKMS *kms_display,
|
||||||
|
CoglOnscreenKMS *kms_onscreen)
|
||||||
|
{
|
||||||
|
CoglContext *context = kms_onscreen->cogl_context;
|
||||||
|
|
||||||
|
if (drmModeSetCrtc (kms_renderer->fd,
|
||||||
|
kms_display->encoder->crtc_id,
|
||||||
|
kms_onscreen->fb_id[kms_onscreen->current_frame],
|
||||||
|
0, 0,
|
||||||
|
&kms_display->connector->connector_id,
|
||||||
|
1,
|
||||||
|
&kms_display->mode) != 0)
|
||||||
|
{
|
||||||
|
g_error (G_STRLOC ": Setting CRTC failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update frame that we're drawing to be the new one */
|
||||||
|
kms_onscreen->current_frame ^= 1;
|
||||||
|
|
||||||
|
context->glBindFramebuffer (GL_FRAMEBUFFER_EXT, kms_onscreen->fb);
|
||||||
|
context->glFramebufferRenderbuffer (GL_FRAMEBUFFER_EXT,
|
||||||
|
GL_COLOR_ATTACHMENT0_EXT,
|
||||||
|
GL_RENDERBUFFER_EXT,
|
||||||
|
kms_onscreen->color_rb[kms_onscreen->current_frame]);
|
||||||
|
|
||||||
|
if (context->glCheckFramebufferStatus (GL_FRAMEBUFFER_EXT) !=
|
||||||
|
GL_FRAMEBUFFER_COMPLETE)
|
||||||
|
{
|
||||||
|
g_error (G_STRLOC ": FBO not complete");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_winsys_kms_bind (CoglRendererKMS *kms_renderer,
|
||||||
|
CoglDisplayKMS *kms_display)
|
||||||
|
{
|
||||||
|
eglMakeCurrent (kms_renderer->dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, kms_display->egl_context);
|
||||||
|
}
|
104
cogl/winsys/cogl-winsys-kms.h
Normal file
104
cogl/winsys/cogl-winsys-kms.h
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* Cogl
|
||||||
|
*
|
||||||
|
* An object oriented GL/GLES Abstraction/Utility Layer
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011 Intel Corporation.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Rob Bradford <rob@linux.intel.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _COGL_WINSYS_KMS_PRIVATE_H_
|
||||||
|
#define _COGL_WINSYS_KMS_PRIVATE_H_
|
||||||
|
|
||||||
|
#include <EGL/egl.h>
|
||||||
|
#include <EGL/eglext.h>
|
||||||
|
#include <drm.h>
|
||||||
|
#include <xf86drmMode.h>
|
||||||
|
#include <gbm.h>
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
#include "cogl-winsys-private.h"
|
||||||
|
|
||||||
|
typedef struct _CoglRendererKMS
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
struct gbm_device *gbm;
|
||||||
|
EGLDisplay *dpy;
|
||||||
|
} CoglRendererKMS;
|
||||||
|
|
||||||
|
typedef struct _CoglDisplayKMS
|
||||||
|
{
|
||||||
|
EGLContext egl_context;
|
||||||
|
drmModeConnector *connector;
|
||||||
|
drmModeEncoder *encoder;
|
||||||
|
drmModeModeInfo mode;
|
||||||
|
drmModeCrtcPtr saved_crtc;
|
||||||
|
gint width, height;
|
||||||
|
} CoglDisplayKMS;
|
||||||
|
|
||||||
|
typedef struct _CoglOnscreenKMS
|
||||||
|
{
|
||||||
|
CoglContext *cogl_context;
|
||||||
|
|
||||||
|
uint32_t fb_id[2];
|
||||||
|
struct gbm_bo *bo[2];
|
||||||
|
GLuint fb, color_rb[2], depth_rb;
|
||||||
|
EGLImageKHR image[2];
|
||||||
|
gint current_frame;
|
||||||
|
} CoglOnscreenKMS;
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_cogl_winsys_kms_connect (CoglRendererKMS *kms_renderer,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_cogl_winsys_kms_onscreen_init (CoglContext *context,
|
||||||
|
CoglRendererKMS *kms_renderer,
|
||||||
|
CoglDisplayKMS *kms_display,
|
||||||
|
CoglOnscreenKMS *kms_onscreen,
|
||||||
|
GError **error);
|
||||||
|
void
|
||||||
|
_cogl_winsys_kms_onscreen_deinit (CoglRendererKMS *kms_renderer,
|
||||||
|
CoglOnscreenKMS *kms_onscreen);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_cogl_winsys_kms_display_setup (CoglRendererKMS *kms_renderer,
|
||||||
|
CoglDisplayKMS *kms_display,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_winsys_kms_swap_buffers (CoglRendererKMS *kms_renderer,
|
||||||
|
CoglDisplayKMS *kms_display,
|
||||||
|
CoglOnscreenKMS *kms_onscreen);
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_winsys_kms_bind (CoglRendererKMS *kms_renderer,
|
||||||
|
CoglDisplayKMS *kms_display);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_cogl_winsys_kms_create_context (CoglRendererKMS *kms_renderer,
|
||||||
|
CoglDisplayKMS *kms_display,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_cogl_winsys_kms_destroy_context (CoglRendererKMS *kms_renderer,
|
||||||
|
CoglDisplayKMS *kms_display,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
|
#endif /* _COGL_WINSYS_KMS_PRIVATE_H_ */
|
26
configure.ac
26
configure.ac
@ -755,6 +755,32 @@ AS_IF([test "x$enable_wayland_egl_platform" == "xyes"],
|
|||||||
AM_CONDITIONAL(SUPPORT_EGL_PLATFORM_WAYLAND,
|
AM_CONDITIONAL(SUPPORT_EGL_PLATFORM_WAYLAND,
|
||||||
[test "x$enable_wayland_egl_platform" = "xyes"])
|
[test "x$enable_wayland_egl_platform" = "xyes"])
|
||||||
|
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(
|
||||||
|
[kms-egl-platform],
|
||||||
|
[AC_HELP_STRING([--enable-kms-egl-platform=@<:@no/yes@:>@], [Enable support for the Wayland egl platform @<:@default=no@:>@])],
|
||||||
|
[],
|
||||||
|
enable_kms_egl_platform=no
|
||||||
|
)
|
||||||
|
AS_IF([test "x$enable_kms_egl_platform" == "xyes"],
|
||||||
|
[
|
||||||
|
EGL_PLATFORM_COUNT=$((EGL_PLATFORM_COUNT+1))
|
||||||
|
NEED_EGL=yes
|
||||||
|
EGL_PLATFORMS="$EGL_PLATFORMS kms"
|
||||||
|
|
||||||
|
PKG_CHECK_EXISTS([gbm],
|
||||||
|
[
|
||||||
|
COGL_PKG_REQUIRES="$COGL_PKG_REQUIRES gbm"
|
||||||
|
COGL_PKG_REQUIRES="$COGL_PKG_REQUIRES libdrm"
|
||||||
|
COGL_PKG_REQUIRES="$COGL_PKG_REQUIRES gl"
|
||||||
|
],
|
||||||
|
[AC_MSG_ERROR([Unable to locate required kms libraries])])
|
||||||
|
|
||||||
|
COGL_DEFINES_SYMBOLS="$COGL_DEFINES_SYMBOLS COGL_HAS_EGL_PLATFORM_KMS_SUPPORT"
|
||||||
|
])
|
||||||
|
AM_CONDITIONAL(SUPPORT_EGL_PLATFORM_KMS,
|
||||||
|
[test "x$enable_kms_egl_platform" = "xyes"])
|
||||||
|
|
||||||
AC_ARG_ENABLE(
|
AC_ARG_ENABLE(
|
||||||
[wayland-egl-server],
|
[wayland-egl-server],
|
||||||
[AC_HELP_STRING([--enable-wayland-egl-server=@<:@no/yes@:>@], [Enable server side wayland support @<:@default=no@:>@])],
|
[AC_HELP_STRING([--enable-wayland-egl-server=@<:@no/yes@:>@], [Enable server side wayland support @<:@default=no@:>@])],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user