mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-08 09:40:10 +00:00
testdmabuf: Test dmabuf viewports
Allow specifying padding via --padding. The argument to --padding is a string of up to 4 comma-separated numbers, for the left, right, top, bottom padding. If less numbers are given, the remaining ones are set to zero. This commit also includes an image that can be used for testing with testdmabuf --padding 20,20,20,20 NV12 padded.png
This commit is contained in:
parent
d91d0f1c0a
commit
70380661fe
157
tests/gtkclipper.c
Normal file
157
tests/gtkclipper.c
Normal file
@ -0,0 +1,157 @@
|
||||
#include "gtk/gtk.h"
|
||||
#include "gtkclipperprivate.h"
|
||||
|
||||
struct _GtkClipper
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
GdkPaintable *paintable;
|
||||
graphene_rect_t clip;
|
||||
};
|
||||
|
||||
struct _GtkClipperClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
static void
|
||||
gtk_clipper_paintable_snapshot (GdkPaintable *paintable,
|
||||
GdkSnapshot *snapshot,
|
||||
double width,
|
||||
double height)
|
||||
{
|
||||
GtkClipper *self = GTK_CLIPPER (paintable);
|
||||
float sx, sy;
|
||||
|
||||
gtk_snapshot_save (snapshot);
|
||||
|
||||
sx = gdk_paintable_get_intrinsic_width (self->paintable) / self->clip.size.width;
|
||||
sy = gdk_paintable_get_intrinsic_height (self->paintable) / self->clip.size.height;
|
||||
|
||||
gtk_snapshot_push_clip (snapshot, &GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
|
||||
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (- self->clip.origin.x * width / self->clip.size.width,
|
||||
- self->clip.origin.y * height / self->clip.size.height));
|
||||
gdk_paintable_snapshot (self->paintable, snapshot, width * sx, height * sy);
|
||||
gtk_snapshot_pop (snapshot);
|
||||
gtk_snapshot_restore (snapshot);
|
||||
}
|
||||
|
||||
static GdkPaintable *
|
||||
gtk_clipper_paintable_get_current_image (GdkPaintable *paintable)
|
||||
{
|
||||
GtkClipper *self = GTK_CLIPPER (paintable);
|
||||
GdkPaintable *current_paintable, *current_self;
|
||||
|
||||
current_paintable = gdk_paintable_get_current_image (self->paintable);
|
||||
current_self = gtk_clipper_new (current_paintable, &self->clip);
|
||||
g_object_unref (current_paintable);
|
||||
|
||||
return current_self;
|
||||
}
|
||||
|
||||
static GdkPaintableFlags
|
||||
gtk_clipper_paintable_get_flags (GdkPaintable *paintable)
|
||||
{
|
||||
GtkClipper *self = GTK_CLIPPER (paintable);
|
||||
|
||||
return gdk_paintable_get_flags (self->paintable);
|
||||
}
|
||||
|
||||
static int
|
||||
gtk_clipper_paintable_get_intrinsic_width (GdkPaintable *paintable)
|
||||
{
|
||||
GtkClipper *self = GTK_CLIPPER (paintable);
|
||||
|
||||
return self->clip.size.width;
|
||||
}
|
||||
|
||||
static int
|
||||
gtk_clipper_paintable_get_intrinsic_height (GdkPaintable *paintable)
|
||||
{
|
||||
GtkClipper *self = GTK_CLIPPER (paintable);
|
||||
|
||||
return self->clip.size.height;
|
||||
}
|
||||
|
||||
static double gtk_clipper_paintable_get_intrinsic_aspect_ratio (GdkPaintable *paintable)
|
||||
{
|
||||
GtkClipper *self = GTK_CLIPPER (paintable);
|
||||
|
||||
return self->clip.size.width / (double) self->clip.size.height;
|
||||
};
|
||||
|
||||
static void
|
||||
gtk_clipper_paintable_init (GdkPaintableInterface *iface)
|
||||
{
|
||||
iface->snapshot = gtk_clipper_paintable_snapshot;
|
||||
iface->get_current_image = gtk_clipper_paintable_get_current_image;
|
||||
iface->get_flags = gtk_clipper_paintable_get_flags;
|
||||
iface->get_intrinsic_width = gtk_clipper_paintable_get_intrinsic_width;
|
||||
iface->get_intrinsic_height = gtk_clipper_paintable_get_intrinsic_height;
|
||||
iface->get_intrinsic_aspect_ratio = gtk_clipper_paintable_get_intrinsic_aspect_ratio;
|
||||
}
|
||||
|
||||
G_DEFINE_TYPE_EXTENDED (GtkClipper, gtk_clipper, G_TYPE_OBJECT, 0,
|
||||
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
|
||||
gtk_clipper_paintable_init))
|
||||
|
||||
static void
|
||||
gtk_clipper_dispose (GObject *object)
|
||||
{
|
||||
GtkClipper *self = GTK_CLIPPER (object);
|
||||
|
||||
if (self->paintable)
|
||||
{
|
||||
const guint flags = gdk_paintable_get_flags (self->paintable);
|
||||
|
||||
if ((flags & GDK_PAINTABLE_STATIC_CONTENTS) == 0)
|
||||
g_signal_handlers_disconnect_by_func (self->paintable, gdk_paintable_invalidate_contents, self);
|
||||
|
||||
if ((flags & GDK_PAINTABLE_STATIC_SIZE) == 0)
|
||||
g_signal_handlers_disconnect_by_func (self->paintable, gdk_paintable_invalidate_size, self);
|
||||
|
||||
g_clear_object (&self->paintable);
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (gtk_clipper_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_clipper_class_init (GtkClipperClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->dispose = gtk_clipper_dispose;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_clipper_init (GtkClipper *self)
|
||||
{
|
||||
}
|
||||
|
||||
GdkPaintable *
|
||||
gtk_clipper_new (GdkPaintable *paintable,
|
||||
const graphene_rect_t *clip)
|
||||
{
|
||||
GtkClipper *self;
|
||||
guint flags;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_PAINTABLE (paintable), NULL);
|
||||
g_return_val_if_fail (clip != NULL, NULL);
|
||||
|
||||
self = g_object_new (GTK_TYPE_CLIPPER, NULL);
|
||||
|
||||
self->paintable = g_object_ref (paintable);
|
||||
flags = gdk_paintable_get_flags (paintable);
|
||||
|
||||
if ((flags & GDK_PAINTABLE_STATIC_CONTENTS) == 0)
|
||||
g_signal_connect_swapped (paintable, "invalidate-contents", G_CALLBACK (gdk_paintable_invalidate_contents), self);
|
||||
|
||||
if ((flags & GDK_PAINTABLE_STATIC_SIZE) == 0)
|
||||
g_signal_connect_swapped (paintable, "invalidate-size", G_CALLBACK (gdk_paintable_invalidate_size), self);
|
||||
|
||||
self->clip = *clip;
|
||||
|
||||
return GDK_PAINTABLE (self);
|
||||
}
|
16
tests/gtkclipperprivate.h
Normal file
16
tests/gtkclipperprivate.h
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <graphene.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_CLIPPER (gtk_clipper_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (GtkClipper, gtk_clipper, GTK, CLIPPER, GObject)
|
||||
|
||||
GdkPaintable * gtk_clipper_new (GdkPaintable *paintable,
|
||||
const graphene_rect_t *clip);
|
||||
|
||||
G_END_DECLS
|
||||
|
@ -133,7 +133,7 @@ endif
|
||||
|
||||
if os_linux
|
||||
gtk_tests += [
|
||||
['testdmabuf'],
|
||||
['testdmabuf', ['testdmabuf.c', 'gtkclipper.c']],
|
||||
]
|
||||
endif
|
||||
|
||||
|
BIN
tests/padded.png
Normal file
BIN
tests/padded.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.1 KiB |
@ -9,6 +9,9 @@
|
||||
#ifdef GDK_RENDERING_VULKAN
|
||||
#include <vulkan/vulkan.h>
|
||||
#endif
|
||||
|
||||
#include "gtkclipperprivate.h"
|
||||
|
||||
/* For this to work, you may need to give /dev/dma_heap/system
|
||||
* lax permissions.
|
||||
*/
|
||||
@ -449,13 +452,12 @@ texture_builder_set_planes (GdkDmabufTextureBuilder *builder,
|
||||
}
|
||||
|
||||
static GdkTexture *
|
||||
make_dmabuf_texture (const char *filename,
|
||||
make_dmabuf_texture (GdkTexture *texture,
|
||||
guint32 format,
|
||||
gboolean disjoint,
|
||||
gboolean premultiplied,
|
||||
gboolean flip)
|
||||
{
|
||||
GdkTexture *texture;
|
||||
GdkTextureDownloader *downloader;
|
||||
int width, height;
|
||||
gsize rgb_stride, rgb_size;
|
||||
@ -471,8 +473,6 @@ make_dmabuf_texture (const char *filename,
|
||||
else
|
||||
g_print ("Using memfd\n");
|
||||
|
||||
texture = gdk_texture_new_from_filename (filename, NULL);
|
||||
|
||||
width = gdk_texture_get_width (texture);
|
||||
height = gdk_texture_get_height (texture);
|
||||
rgb_stride = 4 * width;
|
||||
@ -490,8 +490,6 @@ make_dmabuf_texture (const char *filename,
|
||||
gdk_texture_downloader_download_into (downloader, rgb_data, rgb_stride);
|
||||
gdk_texture_downloader_free (downloader);
|
||||
|
||||
g_object_unref (texture);
|
||||
|
||||
if (flip)
|
||||
{
|
||||
for (int y = 0; y < height; y++)
|
||||
@ -643,7 +641,7 @@ static void
|
||||
usage (void)
|
||||
{
|
||||
char *formats = supported_formats_to_string ();
|
||||
g_print ("Usage: testdmabuf [--undecorated][--disjoint][--download-to FILE] FORMAT FILE\n"
|
||||
g_print ("Usage: testdmabuf [--undecorated][--disjoint][--download-to FILE][--padding PADDING] FORMAT FILE\n"
|
||||
"Supported formats: %s\n", formats);
|
||||
g_free (formats);
|
||||
exit (1);
|
||||
@ -717,6 +715,9 @@ toggle_flip (GtkWidget *widget,
|
||||
{
|
||||
GtkPicture *picture = data;
|
||||
|
||||
if (!texture_flipped)
|
||||
return FALSE;
|
||||
|
||||
if (gtk_picture_get_paintable (picture) == GDK_PAINTABLE (texture))
|
||||
gtk_picture_set_paintable (picture, GDK_PAINTABLE (texture_flipped));
|
||||
else
|
||||
@ -756,6 +757,10 @@ main (int argc, char *argv[])
|
||||
GtkShortcutTrigger *trigger;
|
||||
GtkShortcutAction *action;
|
||||
GtkShortcut *shortcut;
|
||||
GdkPaintable *paintable;
|
||||
GdkTexture *orig;
|
||||
int padding[4] = { 0, }; /* left, right, top, bottom */
|
||||
int padding_set = 0;
|
||||
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
@ -775,6 +780,37 @@ main (int argc, char *argv[])
|
||||
|
||||
save_filename = argv[i];
|
||||
}
|
||||
else if (g_str_equal (argv[i], "--padding"))
|
||||
{
|
||||
if (padding_set < 4)
|
||||
{
|
||||
char **strv;
|
||||
|
||||
i++;
|
||||
if (i == argc)
|
||||
usage ();
|
||||
|
||||
strv = g_strsplit (argv[i], ",", 0);
|
||||
if (g_strv_length (strv) > 4)
|
||||
g_error ("Too much padding");
|
||||
|
||||
for (padding_set = 0; padding_set < 4; padding_set++)
|
||||
{
|
||||
guint64 num;
|
||||
GError *error = NULL;
|
||||
|
||||
if (!strv[padding_set])
|
||||
break;
|
||||
|
||||
if (!g_ascii_string_to_unsigned (strv[padding_set], 10, 0, 100, &num, &error))
|
||||
g_error ("%s", error->message);
|
||||
|
||||
padding[padding_set] = (int) num;
|
||||
}
|
||||
}
|
||||
else
|
||||
g_error ("Too much padding");
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
@ -793,8 +829,21 @@ main (int argc, char *argv[])
|
||||
/* Get the list of supported formats with GDK_DEBUG=opengl */
|
||||
gdk_display_get_dmabuf_formats (gdk_display_get_default ());
|
||||
|
||||
texture = make_dmabuf_texture (filename, format, disjoint, premultiplied, FALSE);
|
||||
texture_flipped = make_dmabuf_texture (filename, format, disjoint, premultiplied, TRUE);
|
||||
orig = gdk_texture_new_from_filename (filename, NULL);
|
||||
texture = make_dmabuf_texture (orig, format, disjoint, premultiplied, FALSE);
|
||||
texture_flipped = make_dmabuf_texture (orig, format, disjoint, premultiplied, TRUE);
|
||||
g_object_unref (orig);
|
||||
|
||||
if (padding_set > 0)
|
||||
{
|
||||
paintable = gtk_clipper_new (GDK_PAINTABLE (texture),
|
||||
&GRAPHENE_RECT_INIT (padding[0],
|
||||
padding[2],
|
||||
gdk_texture_get_width (texture) - padding[0] - padding[1],
|
||||
gdk_texture_get_height (texture) - padding[2] - padding[3]));
|
||||
}
|
||||
else
|
||||
paintable = GDK_PAINTABLE (texture);
|
||||
|
||||
if (save_filename)
|
||||
gdk_texture_save_to_png (texture, save_filename);
|
||||
@ -804,7 +853,7 @@ main (int argc, char *argv[])
|
||||
if (fullscreen)
|
||||
gtk_window_fullscreen (GTK_WINDOW (window));
|
||||
|
||||
picture = gtk_picture_new_for_paintable (GDK_PAINTABLE (texture));
|
||||
picture = gtk_picture_new_for_paintable (paintable);
|
||||
offload = gtk_graphics_offload_new (picture);
|
||||
gtk_widget_set_halign (offload, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (offload, GTK_ALIGN_CENTER);
|
||||
|
Loading…
Reference in New Issue
Block a user