Compare commits
5 Commits
wip-vulkan
...
import-dma
Author | SHA1 | Date | |
---|---|---|---|
|
1868d71163 | ||
|
ff35efeb41 | ||
|
354bf71940 | ||
|
da72c4e451 | ||
|
ad91d213c3 |
@@ -1258,3 +1258,21 @@ gdk_gl_context_use_es_bgra (GdkGLContext *context)
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
#endif /* __GDK_GL_CONTEXT_H__ */
|
||||
|
@@ -45,10 +45,18 @@ struct _GdkGLContextClass
|
||||
{
|
||||
GdkDrawContextClass parent_class;
|
||||
|
||||
gboolean (* realize) (GdkGLContext *context,
|
||||
GError **error);
|
||||
gboolean (* realize) (GdkGLContext *context,
|
||||
GError **error);
|
||||
|
||||
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 {
|
||||
|
@@ -313,6 +313,181 @@ gdk_wayland_gl_context_end_frame (GdkDrawContext *draw_context,
|
||||
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
|
||||
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->get_damage = gdk_wayland_gl_context_get_damage;
|
||||
|
||||
context_class->import_dmabuf = import_dmabuf;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -576,3 +753,4 @@ gdk_wayland_display_make_gl_context_current (GdkDisplay *display,
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@@ -32,7 +32,7 @@ G_BEGIN_DECLS
|
||||
|
||||
#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_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 _GdkWaylandGLContextClass GdkWaylandGLContextClass;
|
||||
@@ -40,6 +40,17 @@ typedef struct _GdkWaylandGLContextClass GdkWaylandGLContextClass;
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
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
|
||||
|
||||
#endif /* __GDK_WAYLAND_GL_CONTEXT_H__ */
|
||||
|
@@ -40,6 +40,8 @@
|
||||
#include <cairo-xlib.h>
|
||||
|
||||
#include <epoxy/glx.h>
|
||||
#include <epoxy/egl.h>
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
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->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;
|
||||
|
||||
|
Reference in New Issue
Block a user