Compare commits
5 Commits
wip/sessio
...
import-dma
Author | SHA1 | Date | |
---|---|---|---|
|
1868d71163 | ||
|
ff35efeb41 | ||
|
354bf71940 | ||
|
da72c4e451 | ||
|
ad91d213c3 |
@@ -1258,3 +1258,21 @@ gdk_gl_context_use_es_bgra (GdkGLContext *context)
|
|||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GdkTexture *
|
||||||
|
gdk_gl_context_import_dmabuf (GdkGLContext *context,
|
||||||
|
int fd,
|
||||||
|
int fourcc,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
int offset,
|
||||||
|
int stride)
|
||||||
|
{
|
||||||
|
if (GDK_GL_CONTEXT_GET_CLASS (context)->import_dmabuf)
|
||||||
|
return GDK_GL_CONTEXT_GET_CLASS (context)->import_dmabuf (context,
|
||||||
|
fd, fourcc,
|
||||||
|
width, height,
|
||||||
|
offset, stride);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
@@ -90,6 +90,15 @@ GdkGLContext * gdk_gl_context_get_current (void);
|
|||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
void gdk_gl_context_clear_current (void);
|
void gdk_gl_context_clear_current (void);
|
||||||
|
|
||||||
|
GDK_AVAILABLE_IN_4_4
|
||||||
|
GdkTexture * gdk_gl_context_import_dmabuf (GdkGLContext *context,
|
||||||
|
int fd,
|
||||||
|
int fourcc,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
int offset,
|
||||||
|
int stride);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GDK_GL_CONTEXT_H__ */
|
#endif /* __GDK_GL_CONTEXT_H__ */
|
||||||
|
@@ -45,10 +45,18 @@ struct _GdkGLContextClass
|
|||||||
{
|
{
|
||||||
GdkDrawContextClass parent_class;
|
GdkDrawContextClass parent_class;
|
||||||
|
|
||||||
gboolean (* realize) (GdkGLContext *context,
|
gboolean (* realize) (GdkGLContext *context,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
cairo_region_t * (* get_damage) (GdkGLContext *context);
|
cairo_region_t * (* get_damage) (GdkGLContext *context);
|
||||||
|
|
||||||
|
GdkTexture * (* import_dmabuf) (GdkGLContext *context,
|
||||||
|
int fd,
|
||||||
|
int fourcc,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
int offset,
|
||||||
|
int stride);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@@ -313,6 +313,181 @@ gdk_wayland_gl_context_end_frame (GdkDrawContext *draw_context,
|
|||||||
gdk_wayland_surface_notify_committed (surface);
|
gdk_wayland_surface_notify_committed (surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
gdk_wayland_gl_context_import_dmabuf (GdkGLContext *context,
|
||||||
|
uint32_t format,
|
||||||
|
unsigned int width,
|
||||||
|
unsigned int height,
|
||||||
|
uint32_t n_planes,
|
||||||
|
const int *fds,
|
||||||
|
const uint32_t *strides,
|
||||||
|
const uint32_t *offsets,
|
||||||
|
const uint64_t *modifiers)
|
||||||
|
{
|
||||||
|
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||||
|
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||||
|
guint texture;
|
||||||
|
EGLint attribs[2 * (3 + 4 * 5) + 1];
|
||||||
|
int i;
|
||||||
|
EGLImage image;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GDK_IS_WAYLAND_GL_CONTEXT (context), 0);
|
||||||
|
g_return_val_if_fail (0 < n_planes && n_planes <= 4, 0);
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
attribs[i++] = EGL_WIDTH;
|
||||||
|
attribs[i++] = width;
|
||||||
|
attribs[i++] = EGL_HEIGHT;
|
||||||
|
attribs[i++] = height;
|
||||||
|
attribs[i++] = EGL_LINUX_DRM_FOURCC_EXT;
|
||||||
|
attribs[i++] = format;
|
||||||
|
|
||||||
|
if (n_planes > 0)
|
||||||
|
{
|
||||||
|
attribs[i++] = EGL_DMA_BUF_PLANE0_FD_EXT;
|
||||||
|
attribs[i++] = fds[0];
|
||||||
|
attribs[i++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT;
|
||||||
|
attribs[i++] = offsets[0];
|
||||||
|
attribs[i++] = EGL_DMA_BUF_PLANE0_PITCH_EXT;
|
||||||
|
attribs[i++] = strides[0];
|
||||||
|
if (modifiers)
|
||||||
|
{
|
||||||
|
attribs[i++] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT;
|
||||||
|
attribs[i++] = modifiers[0] & 0xFFFFFFFF;
|
||||||
|
attribs[i++] = EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT;
|
||||||
|
attribs[i++] = modifiers[0] >> 32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n_planes > 1)
|
||||||
|
{
|
||||||
|
attribs[i++] = EGL_DMA_BUF_PLANE1_FD_EXT;
|
||||||
|
attribs[i++] = fds[1];
|
||||||
|
attribs[i++] = EGL_DMA_BUF_PLANE1_OFFSET_EXT;
|
||||||
|
attribs[i++] = offsets[1];
|
||||||
|
attribs[i++] = EGL_DMA_BUF_PLANE1_PITCH_EXT;
|
||||||
|
attribs[i++] = strides[1];
|
||||||
|
if (modifiers)
|
||||||
|
{
|
||||||
|
attribs[i++] = EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT;
|
||||||
|
attribs[i++] = modifiers[1] & 0xFFFFFFFF;
|
||||||
|
attribs[i++] = EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT;
|
||||||
|
attribs[i++] = modifiers[1] >> 32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n_planes > 2)
|
||||||
|
{
|
||||||
|
attribs[i++] = EGL_DMA_BUF_PLANE2_FD_EXT;
|
||||||
|
attribs[i++] = fds[2];
|
||||||
|
attribs[i++] = EGL_DMA_BUF_PLANE2_OFFSET_EXT;
|
||||||
|
attribs[i++] = offsets[2];
|
||||||
|
attribs[i++] = EGL_DMA_BUF_PLANE2_PITCH_EXT;
|
||||||
|
attribs[i++] = strides[2];
|
||||||
|
if (modifiers)
|
||||||
|
{
|
||||||
|
attribs[i++] = EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT;
|
||||||
|
attribs[i++] = modifiers[2] & 0xFFFFFFFF;
|
||||||
|
attribs[i++] = EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT;
|
||||||
|
attribs[i++] = modifiers[2] >> 32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n_planes > 3)
|
||||||
|
{
|
||||||
|
attribs[i++] = EGL_DMA_BUF_PLANE3_FD_EXT;
|
||||||
|
attribs[i++] = fds[3];
|
||||||
|
attribs[i++] = EGL_DMA_BUF_PLANE3_OFFSET_EXT;
|
||||||
|
attribs[i++] = offsets[3];
|
||||||
|
attribs[i++] = EGL_DMA_BUF_PLANE3_PITCH_EXT;
|
||||||
|
attribs[i++] = strides[3];
|
||||||
|
if (modifiers)
|
||||||
|
{
|
||||||
|
attribs[i++] = EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT;
|
||||||
|
attribs[i++] = modifiers[3] & 0xFFFFFFFF;
|
||||||
|
attribs[i++] = EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT;
|
||||||
|
attribs[i++] = modifiers[3] >> 32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
attribs[i++] = EGL_NONE;
|
||||||
|
|
||||||
|
image = eglCreateImageKHR (display_wayland->egl_display,
|
||||||
|
EGL_NO_CONTEXT,
|
||||||
|
EGL_LINUX_DMA_BUF_EXT,
|
||||||
|
(EGLClientBuffer)NULL,
|
||||||
|
attribs);
|
||||||
|
if (image == EGL_NO_IMAGE)
|
||||||
|
{
|
||||||
|
switch (eglGetError ())
|
||||||
|
{
|
||||||
|
#define EGL_ERROR(name) \
|
||||||
|
case name: \
|
||||||
|
g_print (#name); \
|
||||||
|
break;
|
||||||
|
|
||||||
|
EGL_ERROR(EGL_NOT_INITIALIZED)
|
||||||
|
EGL_ERROR(EGL_BAD_ACCESS)
|
||||||
|
EGL_ERROR(EGL_BAD_ALLOC)
|
||||||
|
EGL_ERROR(EGL_BAD_ATTRIBUTE)
|
||||||
|
EGL_ERROR(EGL_BAD_CONTEXT)
|
||||||
|
EGL_ERROR(EGL_BAD_CONFIG)
|
||||||
|
EGL_ERROR(EGL_BAD_CURRENT_SURFACE)
|
||||||
|
EGL_ERROR(EGL_BAD_DISPLAY)
|
||||||
|
EGL_ERROR(EGL_BAD_SURFACE)
|
||||||
|
EGL_ERROR(EGL_BAD_MATCH)
|
||||||
|
EGL_ERROR(EGL_BAD_PARAMETER)
|
||||||
|
EGL_ERROR(EGL_BAD_NATIVE_PIXMAP)
|
||||||
|
EGL_ERROR(EGL_BAD_NATIVE_WINDOW)
|
||||||
|
EGL_ERROR(EGL_CONTEXT_LOST)
|
||||||
|
default:
|
||||||
|
g_print ("error: %d\n", eglGetError ());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
gdk_gl_context_make_current (context);
|
||||||
|
|
||||||
|
glGenTextures (1, &texture);
|
||||||
|
glBindTexture (GL_TEXTURE_2D, texture);
|
||||||
|
glEGLImageTargetTexture2DOES (GL_TEXTURE_2D, image);
|
||||||
|
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
|
||||||
|
eglDestroyImage (display_wayland->egl_display, image);
|
||||||
|
|
||||||
|
return texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GdkTexture *
|
||||||
|
import_dmabuf (GdkGLContext *context,
|
||||||
|
int fd,
|
||||||
|
int fourcc,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
int offset,
|
||||||
|
int stride)
|
||||||
|
{
|
||||||
|
int texture;
|
||||||
|
|
||||||
|
texture = gdk_wayland_gl_context_import_dmabuf (context,
|
||||||
|
fourcc,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
1,
|
||||||
|
(const int *)&fd,
|
||||||
|
(const uint32_t *)&stride,
|
||||||
|
(const uint32_t *)&offset,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
return gdk_gl_texture_new (context,
|
||||||
|
texture,
|
||||||
|
width, height,
|
||||||
|
NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gdk_wayland_gl_context_class_init (GdkWaylandGLContextClass *klass)
|
gdk_wayland_gl_context_class_init (GdkWaylandGLContextClass *klass)
|
||||||
{
|
{
|
||||||
@@ -326,6 +501,8 @@ gdk_wayland_gl_context_class_init (GdkWaylandGLContextClass *klass)
|
|||||||
|
|
||||||
context_class->realize = gdk_wayland_gl_context_realize;
|
context_class->realize = gdk_wayland_gl_context_realize;
|
||||||
context_class->get_damage = gdk_wayland_gl_context_get_damage;
|
context_class->get_damage = gdk_wayland_gl_context_get_damage;
|
||||||
|
|
||||||
|
context_class->import_dmabuf = import_dmabuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -576,3 +753,4 @@ gdk_wayland_display_make_gl_context_current (GdkDisplay *display,
|
|||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -32,7 +32,7 @@ G_BEGIN_DECLS
|
|||||||
|
|
||||||
#define GDK_TYPE_WAYLAND_GL_CONTEXT (gdk_wayland_gl_context_get_type ())
|
#define GDK_TYPE_WAYLAND_GL_CONTEXT (gdk_wayland_gl_context_get_type ())
|
||||||
#define GDK_WAYLAND_GL_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_WAYLAND_GL_CONTEXT, GdkWaylandGLContext))
|
#define GDK_WAYLAND_GL_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_WAYLAND_GL_CONTEXT, GdkWaylandGLContext))
|
||||||
#define GDK_WAYLAND_IS_GL_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_WAYLAND_GL_CONTEXT))
|
#define GDK_IS_WAYLAND_GL_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_WAYLAND_GL_CONTEXT))
|
||||||
|
|
||||||
typedef struct _GdkWaylandGLContext GdkWaylandGLContext;
|
typedef struct _GdkWaylandGLContext GdkWaylandGLContext;
|
||||||
typedef struct _GdkWaylandGLContextClass GdkWaylandGLContextClass;
|
typedef struct _GdkWaylandGLContextClass GdkWaylandGLContextClass;
|
||||||
@@ -40,6 +40,17 @@ typedef struct _GdkWaylandGLContextClass GdkWaylandGLContextClass;
|
|||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
GType gdk_wayland_gl_context_get_type (void) G_GNUC_CONST;
|
GType gdk_wayland_gl_context_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
GDK_AVAILABLE_IN_4_4
|
||||||
|
int gdk_wayland_gl_context_import_dmabuf (GdkGLContext *context,
|
||||||
|
uint32_t fourcc,
|
||||||
|
unsigned int width,
|
||||||
|
unsigned int height,
|
||||||
|
uint32_t n_planes,
|
||||||
|
const int *fd,
|
||||||
|
const uint32_t *stride,
|
||||||
|
const uint32_t *offset,
|
||||||
|
const uint64_t *modifiers);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GDK_WAYLAND_GL_CONTEXT_H__ */
|
#endif /* __GDK_WAYLAND_GL_CONTEXT_H__ */
|
||||||
|
@@ -40,6 +40,8 @@
|
|||||||
#include <cairo-xlib.h>
|
#include <cairo-xlib.h>
|
||||||
|
|
||||||
#include <epoxy/glx.h>
|
#include <epoxy/glx.h>
|
||||||
|
#include <epoxy/egl.h>
|
||||||
|
|
||||||
|
|
||||||
G_DEFINE_TYPE (GdkX11GLContext, gdk_x11_gl_context, GDK_TYPE_GL_CONTEXT)
|
G_DEFINE_TYPE (GdkX11GLContext, gdk_x11_gl_context, GDK_TYPE_GL_CONTEXT)
|
||||||
|
|
||||||
@@ -710,6 +712,94 @@ gdk_x11_gl_context_dispose (GObject *gobject)
|
|||||||
G_OBJECT_CLASS (gdk_x11_gl_context_parent_class)->dispose (gobject);
|
G_OBJECT_CLASS (gdk_x11_gl_context_parent_class)->dispose (gobject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
EGLDisplay display;
|
||||||
|
EGLImage image;
|
||||||
|
} ImageData;
|
||||||
|
|
||||||
|
static void
|
||||||
|
free_image (gpointer data)
|
||||||
|
{
|
||||||
|
ImageData *idata = data;
|
||||||
|
eglDestroyImage (idata->display, idata->image);
|
||||||
|
g_free (data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GdkTexture *
|
||||||
|
gdk_x11_gl_context_import_dmabuf (GdkGLContext *context,
|
||||||
|
int fd,
|
||||||
|
int fourcc,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
int offset,
|
||||||
|
int stride)
|
||||||
|
{
|
||||||
|
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||||
|
GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
|
||||||
|
guint texture;
|
||||||
|
const EGLAttrib attribute_list[] = {
|
||||||
|
EGL_WIDTH, width,
|
||||||
|
EGL_HEIGHT, height,
|
||||||
|
EGL_LINUX_DRM_FOURCC_EXT, fourcc,
|
||||||
|
EGL_DMA_BUF_PLANE0_FD_EXT, fd,
|
||||||
|
EGL_DMA_BUF_PLANE0_OFFSET_EXT, offset,
|
||||||
|
EGL_DMA_BUF_PLANE0_PITCH_EXT, stride,
|
||||||
|
EGL_NONE
|
||||||
|
};
|
||||||
|
EGLDisplay egl_display;
|
||||||
|
EGLImage image;
|
||||||
|
ImageData *idata;
|
||||||
|
int major, minor;
|
||||||
|
|
||||||
|
gdk_gl_context_make_current (context);
|
||||||
|
|
||||||
|
egl_display = eglGetDisplay ((EGLNativeDisplayType) display_x11->xdisplay);
|
||||||
|
|
||||||
|
if (!eglInitialize (egl_display, &major, &minor))
|
||||||
|
{
|
||||||
|
g_warning ("Failed to initialize EGL: %x", eglGetError());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (!eglBindAPI(EGL_OPENGL_API))
|
||||||
|
{
|
||||||
|
g_warning ("Failed to bind EGL API: %x", eglGetError());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_message ("EGL API version %d.%d found\n"
|
||||||
|
" - Vendor: %s\n"
|
||||||
|
" - Version: %s\n"
|
||||||
|
" - Client APIs: %s\n"
|
||||||
|
" - Extensions:\n"
|
||||||
|
"\t%s",
|
||||||
|
major, minor,
|
||||||
|
eglQueryString (egl_display, EGL_VENDOR),
|
||||||
|
eglQueryString (egl_display, EGL_VERSION),
|
||||||
|
eglQueryString (egl_display, EGL_CLIENT_APIS),
|
||||||
|
eglQueryString (egl_display, EGL_EXTENSIONS));
|
||||||
|
|
||||||
|
image = eglCreateImage (egl_display,
|
||||||
|
EGL_NO_CONTEXT,
|
||||||
|
EGL_LINUX_DMA_BUF_EXT,
|
||||||
|
(EGLClientBuffer)NULL,
|
||||||
|
attribute_list);
|
||||||
|
if (image == EGL_NO_IMAGE)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
glGenTextures (1, &texture);
|
||||||
|
glBindTexture (GL_TEXTURE_2D, texture);
|
||||||
|
glEGLImageTargetTexture2DOES (GL_TEXTURE_2D, image);
|
||||||
|
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
|
||||||
|
idata = g_new (ImageData, 1);
|
||||||
|
|
||||||
|
idata->display = egl_display;
|
||||||
|
idata->image = image;
|
||||||
|
|
||||||
|
return gdk_gl_texture_new (context, texture, width, height, free_image, idata);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gdk_x11_gl_context_class_init (GdkX11GLContextClass *klass)
|
gdk_x11_gl_context_class_init (GdkX11GLContextClass *klass)
|
||||||
{
|
{
|
||||||
@@ -719,6 +809,7 @@ gdk_x11_gl_context_class_init (GdkX11GLContextClass *klass)
|
|||||||
|
|
||||||
context_class->realize = gdk_x11_gl_context_realize;
|
context_class->realize = gdk_x11_gl_context_realize;
|
||||||
context_class->get_damage = gdk_x11_gl_context_get_damage;
|
context_class->get_damage = gdk_x11_gl_context_get_damage;
|
||||||
|
context_class->import_dmabuf = gdk_x11_gl_context_import_dmabuf;
|
||||||
|
|
||||||
draw_context_class->end_frame = gdk_x11_gl_context_end_frame;
|
draw_context_class->end_frame = gdk_x11_gl_context_end_frame;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user