Compare commits
1 Commits
main
...
dmabuf-y-i
Author | SHA1 | Date | |
---|---|---|---|
|
e63b69a589 |
@@ -45,9 +45,40 @@ struct _GdkDrmFormatInfo
|
||||
gsize height,
|
||||
const GdkDmabuf *dmabuf,
|
||||
const guchar *src_datas[GDK_DMABUF_MAX_PLANES],
|
||||
gsize sizes[GDK_DMABUF_MAX_PLANES]);
|
||||
gsize sizes[GDK_DMABUF_MAX_PLANES],
|
||||
gboolean y_invert);
|
||||
};
|
||||
|
||||
static inline void
|
||||
flip_upside_down (guchar *dst_data,
|
||||
gsize dst_stride,
|
||||
GdkMemoryFormat dst_format,
|
||||
gsize width,
|
||||
gsize height)
|
||||
{
|
||||
guchar *tmp;
|
||||
guint bpp;
|
||||
|
||||
bpp = gdk_memory_format_bytes_per_pixel (dst_format);
|
||||
tmp = g_malloc (dst_stride);
|
||||
|
||||
g_assert (dst_stride >= bpp * width);
|
||||
|
||||
for (gsize i = 0 ; i < height / 2; i++)
|
||||
{
|
||||
guchar *row1, *row2;
|
||||
|
||||
row1 = dst_data + i * dst_stride;
|
||||
row2 = dst_data + (height - 1 - i) * dst_stride;
|
||||
|
||||
memcpy (tmp, row1, bpp * width);
|
||||
memcpy (row1, row2, bpp * width);
|
||||
memcpy (row2, tmp, bpp * width);
|
||||
}
|
||||
|
||||
g_free (tmp);
|
||||
}
|
||||
|
||||
static void
|
||||
download_memcpy (guchar *dst_data,
|
||||
gsize dst_stride,
|
||||
@@ -56,7 +87,8 @@ download_memcpy (guchar *dst_data,
|
||||
gsize height,
|
||||
const GdkDmabuf *dmabuf,
|
||||
const guchar *src_datas[GDK_DMABUF_MAX_PLANES],
|
||||
gsize sizes[GDK_DMABUF_MAX_PLANES])
|
||||
gsize sizes[GDK_DMABUF_MAX_PLANES],
|
||||
gboolean y_invert)
|
||||
{
|
||||
const guchar *src_data;
|
||||
gsize src_stride;
|
||||
@@ -67,14 +99,15 @@ download_memcpy (guchar *dst_data,
|
||||
src_data = src_datas[0] + dmabuf->planes[0].offset;
|
||||
g_return_if_fail (sizes[0] >= dmabuf->planes[0].offset + (height - 1) * dst_stride + width * bpp);
|
||||
|
||||
if (dst_stride == src_stride)
|
||||
if (dst_stride == src_stride && !y_invert)
|
||||
memcpy (dst_data, src_data, (height - 1) * dst_stride + width * bpp);
|
||||
else
|
||||
{
|
||||
gsize i;
|
||||
|
||||
for (i = 0; i < height; i++)
|
||||
memcpy (dst_data + i * dst_stride, src_data + i * src_stride, width * bpp);
|
||||
for (gsize i = 0; i < height; i++)
|
||||
{
|
||||
gsize src_row = y_invert ? height - 1 - i : i;
|
||||
memcpy (dst_data + i * dst_stride, src_data + src_row * src_stride, width * bpp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +119,8 @@ download_memcpy_3_1 (guchar *dst_data,
|
||||
gsize height,
|
||||
const GdkDmabuf *dmabuf,
|
||||
const guchar *src_datas[GDK_DMABUF_MAX_PLANES],
|
||||
gsize sizes[GDK_DMABUF_MAX_PLANES])
|
||||
gsize sizes[GDK_DMABUF_MAX_PLANES],
|
||||
gboolean y_invert)
|
||||
{
|
||||
guint a;
|
||||
guchar *dst_row;
|
||||
@@ -95,7 +129,7 @@ download_memcpy_3_1 (guchar *dst_data,
|
||||
|
||||
g_assert (dmabuf->n_planes == 2);
|
||||
|
||||
download_memcpy (dst_data, dst_stride, dst_format, width, height, dmabuf, src_datas, sizes);
|
||||
download_memcpy (dst_data, dst_stride, dst_format, width, height, dmabuf, src_datas, sizes, y_invert);
|
||||
|
||||
switch ((int)dst_format)
|
||||
{
|
||||
@@ -178,11 +212,13 @@ download_nv12 (guchar *dst_data,
|
||||
gsize height,
|
||||
const GdkDmabuf *dmabuf,
|
||||
const guchar *src_data[GDK_DMABUF_MAX_PLANES],
|
||||
gsize sizes[GDK_DMABUF_MAX_PLANES])
|
||||
gsize sizes[GDK_DMABUF_MAX_PLANES],
|
||||
gboolean y_invert)
|
||||
{
|
||||
const guchar *y_data, *uv_data;
|
||||
gsize x, y, y_stride, uv_stride;
|
||||
gsize U, V, X_SUB, Y_SUB;
|
||||
guchar *orig_dst_data = dst_data;
|
||||
|
||||
switch (dmabuf->fourcc)
|
||||
{
|
||||
@@ -233,6 +269,9 @@ download_nv12 (guchar *dst_data,
|
||||
y_data += Y_SUB * y_stride;
|
||||
uv_data += uv_stride;
|
||||
}
|
||||
|
||||
if (y_invert)
|
||||
flip_upside_down (orig_dst_data, dst_stride, dst_format, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -243,11 +282,13 @@ download_yuv_3 (guchar *dst_data,
|
||||
gsize height,
|
||||
const GdkDmabuf *dmabuf,
|
||||
const guchar *src_data[GDK_DMABUF_MAX_PLANES],
|
||||
gsize sizes[GDK_DMABUF_MAX_PLANES])
|
||||
gsize sizes[GDK_DMABUF_MAX_PLANES],
|
||||
gboolean y_invert)
|
||||
{
|
||||
const guchar *y_data, *u_data, *v_data;
|
||||
gsize x, y, y_stride, u_stride, v_stride;
|
||||
gsize U, V, X_SUB, Y_SUB;
|
||||
guchar *orig_dst_data = dst_data;
|
||||
|
||||
switch (dmabuf->fourcc)
|
||||
{
|
||||
@@ -314,6 +355,9 @@ download_yuv_3 (guchar *dst_data,
|
||||
u_data += u_stride;
|
||||
v_data += v_stride;
|
||||
}
|
||||
|
||||
if (y_invert)
|
||||
flip_upside_down (orig_dst_data, dst_stride, dst_format, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -324,11 +368,13 @@ download_yuyv (guchar *dst_data,
|
||||
gsize height,
|
||||
const GdkDmabuf *dmabuf,
|
||||
const guchar *src_datas[GDK_DMABUF_MAX_PLANES],
|
||||
gsize sizes[GDK_DMABUF_MAX_PLANES])
|
||||
gsize sizes[GDK_DMABUF_MAX_PLANES],
|
||||
gboolean y_invert)
|
||||
{
|
||||
const guchar *src_data;
|
||||
gsize x, y, src_stride;
|
||||
gsize Y1, Y2, U, V;
|
||||
guchar *orig_dst_data = dst_data;
|
||||
|
||||
switch (dmabuf->fourcc)
|
||||
{
|
||||
@@ -367,6 +413,9 @@ download_yuyv (guchar *dst_data,
|
||||
dst_data += dst_stride;
|
||||
src_data += src_stride;
|
||||
}
|
||||
|
||||
if (y_invert)
|
||||
flip_upside_down (orig_dst_data, dst_stride, dst_format, width, height);
|
||||
}
|
||||
|
||||
static const GdkDrmFormatInfo supported_formats[] = {
|
||||
@@ -703,12 +752,15 @@ gdk_dmabuf_direct_downloader_do_download (const GdkDmabufDownloader *downloader,
|
||||
{
|
||||
const GdkDrmFormatInfo *info;
|
||||
const GdkDmabuf *dmabuf;
|
||||
gboolean y_invert;
|
||||
const guchar *src_data[GDK_DMABUF_MAX_PLANES];
|
||||
gsize sizes[GDK_DMABUF_MAX_PLANES];
|
||||
gsize needs_unmap[GDK_DMABUF_MAX_PLANES] = { FALSE, };
|
||||
gsize i, j;
|
||||
|
||||
dmabuf = gdk_dmabuf_texture_get_dmabuf (GDK_DMABUF_TEXTURE (texture));
|
||||
y_invert = gdk_dmabuf_texture_get_y_invert (GDK_DMABUF_TEXTURE (texture));
|
||||
|
||||
info = get_drm_format_info (dmabuf->fourcc);
|
||||
|
||||
g_return_if_fail (info && info->download);
|
||||
@@ -759,7 +811,8 @@ gdk_dmabuf_direct_downloader_do_download (const GdkDmabufDownloader *downloader,
|
||||
gdk_texture_get_height (texture),
|
||||
dmabuf,
|
||||
src_data,
|
||||
sizes);
|
||||
sizes,
|
||||
y_invert);
|
||||
|
||||
out:
|
||||
for (i = 0; i < dmabuf->n_planes; i++)
|
||||
|
@@ -51,6 +51,8 @@ struct _GdkDmabufTexture
|
||||
|
||||
GDestroyNotify destroy;
|
||||
gpointer data;
|
||||
|
||||
gboolean y_invert;
|
||||
};
|
||||
|
||||
struct _GdkDmabufTextureClass
|
||||
@@ -116,6 +118,12 @@ gdk_dmabuf_texture_get_dmabuf (GdkDmabufTexture *self)
|
||||
return &self->dmabuf;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_dmabuf_texture_get_y_invert (GdkDmabufTexture *self)
|
||||
{
|
||||
return self->y_invert;
|
||||
}
|
||||
|
||||
GdkTexture *
|
||||
gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder,
|
||||
GDestroyNotify destroy,
|
||||
@@ -184,6 +192,7 @@ gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder,
|
||||
self->dmabuf = dmabuf;
|
||||
self->destroy = destroy;
|
||||
self->data = data;
|
||||
self->y_invert = gdk_dmabuf_texture_builder_get_y_invert (builder);
|
||||
|
||||
update_texture = gdk_dmabuf_texture_builder_get_update_texture (builder);
|
||||
if (update_texture)
|
||||
|
@@ -37,6 +37,7 @@ struct _GdkDmabufTextureBuilder
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
gboolean premultiplied;
|
||||
gboolean y_invert;
|
||||
|
||||
GdkDmabuf dmabuf;
|
||||
|
||||
@@ -123,6 +124,7 @@ enum
|
||||
PROP_MODIFIER,
|
||||
PROP_PREMULTIPLIED,
|
||||
PROP_N_PLANES,
|
||||
PROP_Y_INVERT,
|
||||
PROP_UPDATE_REGION,
|
||||
PROP_UPDATE_TEXTURE,
|
||||
|
||||
@@ -182,6 +184,10 @@ gdk_dmabuf_texture_builder_get_property (GObject *object,
|
||||
g_value_set_uint (value, self->dmabuf.n_planes);
|
||||
break;
|
||||
|
||||
case PROP_Y_INVERT:
|
||||
g_value_set_boolean (value, self->y_invert);
|
||||
break;
|
||||
|
||||
case PROP_UPDATE_REGION:
|
||||
g_value_set_boxed (value, self->update_region);
|
||||
break;
|
||||
@@ -234,6 +240,10 @@ gdk_dmabuf_texture_builder_set_property (GObject *object,
|
||||
gdk_dmabuf_texture_builder_set_n_planes (self, g_value_get_uint (value));
|
||||
break;
|
||||
|
||||
case PROP_Y_INVERT:
|
||||
gdk_dmabuf_texture_builder_set_y_invert (self, g_value_get_boolean (value));
|
||||
break;
|
||||
|
||||
case PROP_UPDATE_REGION:
|
||||
gdk_dmabuf_texture_builder_set_update_region (self, g_value_get_boxed (value));
|
||||
break;
|
||||
@@ -346,6 +356,18 @@ gdk_dmabuf_texture_builder_class_init (GdkDmabufTextureBuilderClass *klass)
|
||||
1, GDK_DMABUF_MAX_PLANES, 1,
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GdkDmabufTextureBuilder:y-invert: (attributes org.gtk.Property.get=gdk_dmabuf_texture_builder_get_y_invert org.gtk.Property.set=gdk_dmabuf_texture_builder_set_y_invert)
|
||||
*
|
||||
* Whether the texture is upside-down.
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
properties[PROP_Y_INVERT] =
|
||||
g_param_spec_boolean ("y-invert", NULL, NULL,
|
||||
FALSE,
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GdkDmabufTextureBuilder:update-region: (attributes org.gtk.Property.get=gdk_dmabuf_texture_builder_get_update_region org.gtk.Property.set=gdk_dmabuf_texture_builder_set_update_region)
|
||||
*
|
||||
@@ -842,6 +864,47 @@ gdk_dmabuf_texture_builder_set_offset (GdkDmabufTextureBuilder *self,
|
||||
self->dmabuf.planes[plane].offset = offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_dmabuf_texture_builder_get_y_invert:
|
||||
* @self: a `GdkDmabufTextureBuilder`
|
||||
*
|
||||
* Gets whether the texture is upside-down.
|
||||
*
|
||||
* Returns: whether the texture is upside-down.
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
gboolean
|
||||
gdk_dmabuf_texture_builder_get_y_invert (GdkDmabufTextureBuilder *self)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self), FALSE);
|
||||
|
||||
return self->y_invert;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_dmabuf_texture_builder_set_y_invert:
|
||||
* @self: a `GdkDmabufTextureBuilder`
|
||||
* @y_invert: whether the texture is upside-down
|
||||
*
|
||||
* Sets whether the texture is upside-down.
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
void
|
||||
gdk_dmabuf_texture_builder_set_y_invert (GdkDmabufTextureBuilder *self,
|
||||
gboolean y_invert)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DMABUF_TEXTURE_BUILDER (self));
|
||||
|
||||
if (self->y_invert == y_invert)
|
||||
return;
|
||||
|
||||
self->y_invert = y_invert;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_Y_INVERT]);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_dmabuf_texture_builder_get_update_texture: (attributes org.gtk.Method.get_property=update-texture)
|
||||
* @self: a `GdkDmabufTextureBuilder`
|
||||
|
@@ -100,6 +100,12 @@ void gdk_dmabuf_texture_builder_set_offset (GdkDmabufT
|
||||
unsigned int plane,
|
||||
unsigned int offset);
|
||||
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
gboolean gdk_dmabuf_texture_builder_get_y_invert (GdkDmabufTextureBuilder *self) G_GNUC_PURE;
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
void gdk_dmabuf_texture_builder_set_y_invert (GdkDmabufTextureBuilder *self,
|
||||
gboolean y_invert);
|
||||
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
GdkTexture * gdk_dmabuf_texture_builder_get_update_texture (GdkDmabufTextureBuilder *self) G_GNUC_PURE;
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
|
@@ -16,6 +16,7 @@ GdkTexture * gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBui
|
||||
|
||||
GdkDisplay * gdk_dmabuf_texture_get_display (GdkDmabufTexture *self);
|
||||
const GdkDmabuf * gdk_dmabuf_texture_get_dmabuf (GdkDmabufTexture *self);
|
||||
gboolean gdk_dmabuf_texture_get_y_invert (GdkDmabufTexture *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@@ -106,8 +106,11 @@ get_wl_buffer (GdkWaylandSubsurface *self,
|
||||
struct wl_buffer *buffer;
|
||||
CreateBufferData cd = { NULL, FALSE };
|
||||
struct wl_event_queue *event_queue;
|
||||
uint32_t flags = 0;
|
||||
|
||||
dmabuf = gdk_dmabuf_texture_get_dmabuf (GDK_DMABUF_TEXTURE (texture));
|
||||
if (gdk_dmabuf_texture_get_y_invert (GDK_DMABUF_TEXTURE (texture)))
|
||||
flags = ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_Y_INVERT;
|
||||
|
||||
params = zwp_linux_dmabuf_v1_create_params (display->linux_dmabuf);
|
||||
|
||||
@@ -130,7 +133,7 @@ get_wl_buffer (GdkWaylandSubsurface *self,
|
||||
gdk_texture_get_width (texture),
|
||||
gdk_texture_get_height (texture),
|
||||
dmabuf->fourcc,
|
||||
0);
|
||||
flags);
|
||||
|
||||
while (!cd.done)
|
||||
gdk_wayland_display_dispatch_queue (GDK_DISPLAY (display), event_queue);
|
||||
|
@@ -772,7 +772,8 @@ draw_rect (GskGLCommandQueue *command_queue,
|
||||
float min_x,
|
||||
float min_y,
|
||||
float max_x,
|
||||
float max_y)
|
||||
float max_y,
|
||||
gboolean y_invert)
|
||||
{
|
||||
GskGLDrawVertex *vertices = gsk_gl_command_queue_add_vertices (command_queue);
|
||||
float min_u = 0;
|
||||
@@ -781,6 +782,12 @@ draw_rect (GskGLCommandQueue *command_queue,
|
||||
float max_v = 0;
|
||||
guint16 c = FP16_ZERO;
|
||||
|
||||
if (y_invert)
|
||||
{
|
||||
min_v = 0;
|
||||
max_v = 1;
|
||||
}
|
||||
|
||||
vertices[0] = (GskGLDrawVertex) { .position = { min_x, min_y }, .uv = { min_u, min_v }, .color = { c, c, c, c } };
|
||||
vertices[1] = (GskGLDrawVertex) { .position = { min_x, max_y }, .uv = { min_u, max_v }, .color = { c, c, c, c } };
|
||||
vertices[2] = (GskGLDrawVertex) { .position = { max_x, min_y }, .uv = { max_u, min_v }, .color = { c, c, c, c } };
|
||||
@@ -807,6 +814,7 @@ gsk_gl_driver_import_dmabuf_texture (GskGLDriver *self,
|
||||
GskGLRenderTarget *render_target;
|
||||
guint prev_fbo;
|
||||
gboolean external;
|
||||
gboolean y_invert;
|
||||
|
||||
gdk_gl_context_make_current (context);
|
||||
|
||||
@@ -822,6 +830,7 @@ gsk_gl_driver_import_dmabuf_texture (GskGLDriver *self,
|
||||
}
|
||||
|
||||
dmabuf = gdk_dmabuf_texture_get_dmabuf (texture);
|
||||
y_invert = gdk_dmabuf_texture_get_y_invert (texture);
|
||||
|
||||
texture_id = gdk_gl_context_import_dmabuf (context,
|
||||
width, height,
|
||||
@@ -830,7 +839,7 @@ gsk_gl_driver_import_dmabuf_texture (GskGLDriver *self,
|
||||
if (texture_id == 0)
|
||||
return 0;
|
||||
|
||||
if (!external)
|
||||
if (!external && !y_invert)
|
||||
return texture_id;
|
||||
|
||||
gsk_gl_driver_autorelease_texture (self, texture_id);
|
||||
@@ -853,7 +862,7 @@ gsk_gl_driver_import_dmabuf_texture (GskGLDriver *self,
|
||||
UNIFORM_EXTERNAL_SOURCE, 0,
|
||||
GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE0, texture_id);
|
||||
|
||||
draw_rect (self->command_queue, 0, 0, width, height);
|
||||
draw_rect (self->command_queue, 0, 0, width, height, y_invert);
|
||||
|
||||
gsk_gl_command_queue_end_draw (self->command_queue);
|
||||
}
|
||||
|
Reference in New Issue
Block a user