纹理和可绘制对象

在 GTK4 中,我们一直在尝试为图像数据寻找更好的解决方案。在 GTK3 中,我们用于此目的的对象是 pixbufsCairo surfaces。但它们不再适用,所以现在我们有了 GdkTextureGdkPaintable

GdkTexture

GdkTextureGdkPixbuf 的替代品。它为什么更好?
首先,它要简单得多。API 如下所示

int gdk_texture_get_width (GdkTexture *texture);
int gdk_texture_get_height (GdkTexture *texture);

void gdk_texture_download (GdkTexture *texture,
                           guchar     *data,
                           gsize       stride);

因此,它是一个 2D 像素数组,如果您愿意,可以下载像素。它也保证是不可变的,因此像素永远不会改变。存在许多构造函数,可以从文件、资源、数据或 pixbufs 创建纹理。

但是纹理和 pixbufs 之间最大的区别在于,它们不公开用于存储像素的内存。事实上,在调用 gdk_texture_download() 之前,这些数据甚至不需要存在。
这在 GL 纹理中使用。例如,GtkGLArea 部件 使用此方法来传递数据。预计 GStreamer 也将以 GL 纹理的形式传递视频。

GdkPaintable

但有时,您会遇到比不可变的一堆像素更复杂的东西。例如,您可能有一个动画 GIF 或一个可缩放的 SVG。这就是 GdkPaintable 的用武之地。
从抽象的角度来看,GdkPaintable 是一个接口,用于知道如何在任何大小下渲染自身的对象。受 CSS 图像 的启发,它们可以选择提供 GTK 部件可以用来放置它们的固有尺寸信息。
因此,GdkPaintable 接口的核心是使可绘制对象自行渲染的函数以及提供尺寸信息的 3 个函数

void gdk_paintable_snapshot (GdkPaintable *paintable,
                             GdkSnapshot  *snapshot,
                             double        width,
                             double        height);

int gdk_paintable_get_intrinsic_width (GdkPaintable *paintable);
int gdk_paintable_get_intrinsic_height (GdkPaintable *paintable);
double gdk_paintable_get_intrinsic_aspect_ratio (GdkPaintable *paintable);

最重要的是,当可绘制对象的内容或大小发生变化时,它可以发出 “invalidate-contents” 和 “invalidate-size” 信号。

为了使这一点更具体,让我们以一个可缩放的 SVG 为例:可绘制对象的实现将不返回固有大小(那些尺寸函数的返回值 0 可以实现这一点),并且无论何时绘制它,它都将在给定大小下以像素精确地绘制自身。
或者以动画 GIF 为例:它会将其像素大小作为其固有大小,并绘制缩放到给定大小的动画当前帧。并且每当应显示动画的下一帧时,它都会发出 “invalidate-size” 信号。
最后但并非最不重要的一点是,GdkTexture 实现了此接口。

我们目前正在更改 GTK3 中接受 GdkPixbuf 的所有代码,使其现在接受 GdkPaintable。当然,GtkImage 部件已经更改,拖放图标或 GtkAboutDialog 也是如此。存在实验性补丁,允许应用程序向 GTK CSS 引擎提供可绘制对象。

如果您现在将所有这些关于 GStreamer 可能提供由 GL 图像支持的纹理以及创建可以上传到 CSS 的动画的可绘制对象的信息放在一起,您也许可以 看到它的发展方向

作者:Benjamin Otte

在会议简介中,我这样描述自己:自从 2002 年进入自由软件世界以来,Benjamin Otte 一直在不断尝试让计算机变得更有趣。他的成功故事包括 Swfdec Flash 播放器,共同维护 GStreamer,在 GVfs 上工作以及在 Ohloh 上获得高排名。白天,他会将时间花在 Red Hat 的所有多媒体工作上。

关于“纹理和可绘制对象”的 5 个想法

评论已关闭。