Hi,
I am working on an UI app using GTK4
I am creating a window (top level) and some widgets.
I want to add a child widget which will have its unique native surface.
So far I always get the surface of the top level window
Then you’ll have to draw on an off screen buffer and create a GdkTexture with the contents. If you can create a GL texture, you can use GdkGLTextureBuilder; if you can get a dmabuf object, you can use GdkDmabufTextureBuilder; and if it all fails, you can use GdkMemoryTexture (or GdkMemoryTextureBuilder with GTK 4.16 once it’s released). You can check how GtkGLArea is implemented, if you want to create the Vulkan equivalent.
What you cannot do is create a native surface and render on it on your own; that’s not how GTK works.
Wouldn’t it be more efficient to transfer Vulkan output to an OpenGL texture and then use GtkGLArea to render it? Is that possible? If it is, is there any example that demonstrates Vulkan usage in GTK4? That would be a great resource.
I have a feeling that approach with GL texture created by Vulkan was initially suggested.
not really, my vulkan Framebuffer object is setup to draw to a texture of my choosing. (not the texture owned by the swapchain object). and moving data from Vulkan texture object to opengl texture object will require use of some extension (which may not always be available).
GTK already defers the rendering: that’s why you cannot use a native surface to draw whatever you want. You can only draw on an offscreen surface, backend by some memory, and then tell GTK to use that memory to draw when it submits the render commands to the GPU. The memory can be represented by a GL texture object, or by a dmabuf file descriptor, to avoid additional copies. Vulkan already has an extension for using dmabuf, and so does OpenGL.
As I said above, your code should use three approaches:
check if you can use the dmabuf extension, and create a GdkDmabufTextureBuilder
check if you can use the GL extension, and create a GdkGLTextureBuilder
fall back to a texture upload, using GdkMemoryTexture to copy the pixels
Once you have a GdkTexture, you can use the following code in your snapshot() virtual function implementation:
float w = gtk_widget_get_width (widget);
float h = gtk_widget_get_height (widget);
gtk_snapshot_append_texture (snapshot,
texture,
&GRAPHENE_RECT_INIT (0, 0, w h));