egl: Use correct yuv details for importing
Make the dmabuf import api take color space and range hints as ints, and update all callers to pass them. The callers use the new dmabuf egl yuv hints helper api to get this information from the dmabuf + colorstate. Note that the old gl renderer is not handling color states carefully and may not get dmabuf import right wrt to color states.
This commit is contained in:
@@ -209,12 +209,15 @@ gdk_dmabuf_egl_create_image (GdkDisplay *display,
|
||||
int width,
|
||||
int height,
|
||||
const GdkDmabuf *dmabuf,
|
||||
int color_space_hint,
|
||||
int range_hint,
|
||||
int target)
|
||||
{
|
||||
EGLDisplay egl_display = gdk_display_get_egl_display (display);
|
||||
EGLint attribs[64];
|
||||
int i;
|
||||
EGLImage image;
|
||||
gboolean is_yuv;
|
||||
|
||||
g_return_val_if_fail (width > 0, 0);
|
||||
g_return_val_if_fail (height > 0, 0);
|
||||
@@ -228,6 +231,25 @@ gdk_dmabuf_egl_create_image (GdkDisplay *display,
|
||||
return EGL_NO_IMAGE;
|
||||
}
|
||||
|
||||
if (gdk_dmabuf_fourcc_is_yuv (dmabuf->fourcc, &is_yuv) && is_yuv)
|
||||
{
|
||||
if (color_space_hint == 0 || range_hint == 0)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"Can't import yuv dmabuf into GL without color space hints");
|
||||
return EGL_NO_IMAGE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (color_space_hint != 0 || range_hint != 0)
|
||||
{
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"Can't import non-yuv dmabuf into GL with color space hints");
|
||||
return EGL_NO_IMAGE;
|
||||
}
|
||||
}
|
||||
|
||||
GDK_DISPLAY_DEBUG (display, DMABUF,
|
||||
"Importing dmabuf (format: %.4s:%#" G_GINT64_MODIFIER "x, planes: %u) into GL",
|
||||
(char *) &dmabuf->fourcc, dmabuf->modifier, dmabuf->n_planes);
|
||||
@@ -241,10 +263,16 @@ gdk_dmabuf_egl_create_image (GdkDisplay *display,
|
||||
attribs[i++] = height;
|
||||
attribs[i++] = EGL_LINUX_DRM_FOURCC_EXT;
|
||||
attribs[i++] = dmabuf->fourcc;
|
||||
attribs[i++] = EGL_YUV_COLOR_SPACE_HINT_EXT;
|
||||
attribs[i++] = EGL_ITU_REC601_EXT;
|
||||
attribs[i++] = EGL_SAMPLE_RANGE_HINT_EXT;
|
||||
attribs[i++] = EGL_YUV_NARROW_RANGE_EXT;
|
||||
if (color_space_hint != 0)
|
||||
{
|
||||
attribs[i++] = EGL_YUV_COLOR_SPACE_HINT_EXT;
|
||||
attribs[i++] = color_space_hint;
|
||||
}
|
||||
if (range_hint != 0)
|
||||
{
|
||||
attribs[i++] = EGL_SAMPLE_RANGE_HINT_EXT;
|
||||
attribs[i++] = range_hint;
|
||||
}
|
||||
|
||||
#define ADD_PLANE(plane) \
|
||||
{ \
|
||||
|
||||
@@ -13,6 +13,8 @@ EGLImage gdk_dmabuf_egl_create_image (GdkDisplay
|
||||
int width,
|
||||
int height,
|
||||
const GdkDmabuf *dmabuf,
|
||||
int color_state_hint,
|
||||
int range_hint,
|
||||
int target);
|
||||
|
||||
void gdk_dmabuf_get_egl_yuv_hints (const GdkDmabuf *dmabuf,
|
||||
|
||||
@@ -2198,6 +2198,8 @@ gdk_gl_context_import_dmabuf_for_target (GdkGLContext *self,
|
||||
int width,
|
||||
int height,
|
||||
const GdkDmabuf *dmabuf,
|
||||
int color_space_hint,
|
||||
int range_hint,
|
||||
int target)
|
||||
{
|
||||
#if defined(HAVE_EGL) && defined(HAVE_DMABUF)
|
||||
@@ -2209,6 +2211,8 @@ gdk_gl_context_import_dmabuf_for_target (GdkGLContext *self,
|
||||
width,
|
||||
height,
|
||||
dmabuf,
|
||||
color_space_hint,
|
||||
range_hint,
|
||||
target);
|
||||
if (image == EGL_NO_IMAGE)
|
||||
return 0;
|
||||
@@ -2232,6 +2236,8 @@ gdk_gl_context_import_dmabuf (GdkGLContext *self,
|
||||
int width,
|
||||
int height,
|
||||
const GdkDmabuf *dmabuf,
|
||||
int color_space_hint,
|
||||
int range_hint,
|
||||
gboolean *external)
|
||||
{
|
||||
GdkDisplay *display = gdk_gl_context_get_display (self);
|
||||
@@ -2248,6 +2254,8 @@ gdk_gl_context_import_dmabuf (GdkGLContext *self,
|
||||
texture_id = gdk_gl_context_import_dmabuf_for_target (self,
|
||||
width, height,
|
||||
dmabuf,
|
||||
color_space_hint,
|
||||
range_hint,
|
||||
GL_TEXTURE_2D);
|
||||
if (texture_id == 0)
|
||||
{
|
||||
@@ -2277,6 +2285,8 @@ gdk_gl_context_import_dmabuf (GdkGLContext *self,
|
||||
texture_id = gdk_gl_context_import_dmabuf_for_target (self,
|
||||
width, height,
|
||||
dmabuf,
|
||||
color_space_hint,
|
||||
range_hint,
|
||||
GL_TEXTURE_EXTERNAL_OES);
|
||||
if (texture_id == 0)
|
||||
{
|
||||
@@ -2309,6 +2319,8 @@ gdk_gl_context_import_dmabuf (GdkGLContext *self,
|
||||
texture_id = gdk_gl_context_import_dmabuf_for_target (self,
|
||||
width, height,
|
||||
dmabuf,
|
||||
color_space_hint,
|
||||
range_hint,
|
||||
target);
|
||||
|
||||
if (texture_id == 0)
|
||||
|
||||
@@ -185,6 +185,8 @@ guint gdk_gl_context_import_dmabuf (GdkGLContext
|
||||
int width,
|
||||
int height,
|
||||
const GdkDmabuf *dmabuf,
|
||||
int color_space_hint,
|
||||
int range_hint,
|
||||
gboolean *external);
|
||||
|
||||
gboolean gdk_gl_context_export_dmabuf (GdkGLContext *self,
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include <gdk/gdkmemoryformatprivate.h>
|
||||
#include <gdk/gdkprofilerprivate.h>
|
||||
#include <gdk/gdktextureprivate.h>
|
||||
#include <gdk/gdkdmabufeglprivate.h>
|
||||
|
||||
#include <gdk/gdkmemoryformatprivate.h>
|
||||
#include <gdk/gdkdmabuftextureprivate.h>
|
||||
@@ -814,6 +815,8 @@ gsk_gl_driver_import_dmabuf_texture (GskGLDriver *self,
|
||||
gboolean external;
|
||||
GdkMemoryFormat format;
|
||||
gboolean premultiply;
|
||||
GdkColorState *color_state;
|
||||
int color_space, range;
|
||||
|
||||
gdk_gl_context_make_current (context);
|
||||
|
||||
@@ -831,10 +834,16 @@ gsk_gl_driver_import_dmabuf_texture (GskGLDriver *self,
|
||||
dmabuf = gdk_dmabuf_texture_get_dmabuf (texture);
|
||||
format = gdk_texture_get_format (GDK_TEXTURE (texture));
|
||||
premultiply = gdk_memory_format_alpha (format) == GDK_MEMORY_ALPHA_STRAIGHT;
|
||||
color_state = gdk_texture_get_color_state (GDK_TEXTURE (texture));
|
||||
|
||||
gdk_dmabuf_get_egl_yuv_hints (dmabuf, color_state, &color_space, &range);
|
||||
|
||||
|
||||
texture_id = gdk_gl_context_import_dmabuf (context,
|
||||
width, height,
|
||||
dmabuf,
|
||||
color_space,
|
||||
range,
|
||||
&external);
|
||||
if (texture_id == 0)
|
||||
return 0;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "gskglimageprivate.h"
|
||||
|
||||
#include "gdkdmabuftextureprivate.h"
|
||||
#include "gdkdmabufeglprivate.h"
|
||||
#include "gdkglcontextprivate.h"
|
||||
#include "gdkgltextureprivate.h"
|
||||
|
||||
@@ -105,11 +106,20 @@ gsk_gl_frame_upload_texture (GskGpuFrame *frame,
|
||||
{
|
||||
gboolean external;
|
||||
GLuint tex_id;
|
||||
int color_space_hint;
|
||||
int range_hint;
|
||||
|
||||
gdk_dmabuf_get_egl_yuv_hints (gdk_dmabuf_texture_get_dmabuf (GDK_DMABUF_TEXTURE (texture)),
|
||||
gdk_texture_get_color_state (texture),
|
||||
&color_space_hint,
|
||||
&range_hint);
|
||||
|
||||
tex_id = gdk_gl_context_import_dmabuf (GDK_GL_CONTEXT (gsk_gpu_frame_get_context (frame)),
|
||||
gdk_texture_get_width (texture),
|
||||
gdk_texture_get_height (texture),
|
||||
gdk_dmabuf_texture_get_dmabuf (GDK_DMABUF_TEXTURE (texture)),
|
||||
color_space_hint,
|
||||
range_hint,
|
||||
&external);
|
||||
if (tex_id)
|
||||
{
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <gdk/gdkglcontextprivate.h>
|
||||
#include <gdk/gdkdmabuffourccprivate.h>
|
||||
#include <gdk/gdkdmabuftextureprivate.h>
|
||||
#include <gdk/gdkdmabufeglprivate.h>
|
||||
|
||||
static cairo_surface_t *
|
||||
make_surface (int width,
|
||||
@@ -191,6 +192,8 @@ test_dmabuf_import (void)
|
||||
GdkGLTextureBuilder *builder;
|
||||
guchar *data;
|
||||
gboolean external;
|
||||
GdkColorState *color_state;
|
||||
int color_space, range;
|
||||
|
||||
display = gdk_display_get_default ();
|
||||
if (!gdk_display_prepare_gl (display, &error))
|
||||
@@ -229,7 +232,9 @@ test_dmabuf_import (void)
|
||||
g_assert_no_error (error);
|
||||
|
||||
dmabuf2 = gdk_dmabuf_texture_get_dmabuf (GDK_DMABUF_TEXTURE (texture));
|
||||
texture_id2 = gdk_gl_context_import_dmabuf (context2, 64, 64, dmabuf2, &external);
|
||||
color_state = gdk_texture_get_color_state (texture);
|
||||
gdk_dmabuf_get_egl_yuv_hints (dmabuf2, color_state, &color_space, &range);
|
||||
texture_id2 = gdk_gl_context_import_dmabuf (context2, 64, 64, dmabuf2, color_space, range, &external);
|
||||
g_assert_cmpint (texture_id2, !=, 0);
|
||||
g_assert_false (external);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user