GLFW and Cairo Use

Hi,

GLFW and Cairo
There is little information on this, if someone has something to say at this point, please tell me, pros and cons combinations of these two libraries.

Kind regards,
Rafał

Hi @Rafal, welcome to the GLFW forum,

GLFW is an Open Source, multi-platform library for OpenGL, OpenGL ES and Vulkan development on the desktop. It provides a simple API for creating windows, contexts and surfaces, receiving input and events.

Cairo is a 2D canvas drawing API, primarily focussed on the CPU doing the rendering. You can combine Cairo and OpenGL (or Vulkan), as per their documentation:

I would personally not use Cairo in combination with OpenGL/Vulkan, butwould instead use an API designed for use with GPU rendering APIs directly, such as NanoVG or Dear ImGui.

Cheers,

Doug.

Thank you.

I have already invested some time in Cairo. In my question, I meant the pros and cons of this combination.

Anyone have a working example of such a connection?

Example provided by: tobyp

//gcc $(pkg-config --cflags --libs glfw3 cairo) glfw-cairo-xlib.c

#include <math.h>
#include <stdio.h>

#include <cairo/cairo.h>
#include <cairo/cairo-xlib.h>

#include <GLFW/glfw3.h>
#define GLFW_EXPOSE_NATIVE_X11
#include <GLFW/glfw3native.h>


int main(int argc, char * argv[]) {
	/* Initialize the library */
	if (!glfwInit())
		return -1;

	glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
	GLFWwindow * window = glfwCreateWindow(800, 600, "Test", NULL, NULL);
	if (!window) {
		glfwTerminate();
		return -1;
	}

	glfwSwapInterval(1);

	int fb_w, fb_h;
	glfwGetFramebufferSize(window, &fb_w, &fb_h);
	Display * x11_display = glfwGetX11Display();
	Window x11_window = glfwGetX11Window(window);
	Visual * vis = DefaultVisual(x11_display, DefaultScreen(x11_display));
	cairo_surface_t * surface = cairo_xlib_surface_create(x11_display, x11_window, vis, fb_w, fb_h);
	cairo_t * ctx = cairo_create(surface);

	while (!glfwWindowShouldClose(window)) {
		// on framebuffer size change, resize the surface
		glfwGetFramebufferSize(window, &fb_w, &fb_h);
		cairo_xlib_surface_set_size(surface, fb_w, fb_h);

		// have to group, else the x server does weird queueing
		cairo_push_group(ctx);

		//clear
		cairo_set_source_rgb(ctx, 1.0, 0.0, 0.0);
		cairo_set_operator(ctx, CAIRO_OPERATOR_SOURCE);
		cairo_paint(ctx);

		// RENDER HERE

		// ungroup and actually display
		cairo_pop_group_to_source(ctx);
		cairo_paint(ctx);
		cairo_surface_flush(surface);
		glfwSwapBuffers(window);

		glfwPollEvents();

		glfwSetWindowShouldClose(window, 1);
	}

	cairo_destroy(ctx);
	cairo_surface_finish(surface);
	cairo_surface_destroy(surface);
	glfwDestroyWindow(window);
	glfwTerminate();

	return 0;
}

In search of back-end GLFW and Caior the web browser directed me here.
Hmm… I think I’m old already.
I couldn’t believe my eyes that this was my post, so I decided to refresh it.

Invite you to the project.

Best regards
– Rafał

Alternative to xlib backed cairo surface would be to do regular image surface with cairo_image_surface_create and then uploading it with glTexImage2D (or similar GL functions) and rendering with OpenGL primitives. That would integrate better with OpenGL applications and allow better performance as image upload happens in background OpenGL driver thread. It would also allow better portability (which is glfw goal) - as xlib works only on Linux, but image surface would work on any OS, Windows, macOS, Linux.

It’s a great idea, I invite you to the project.

If I use GL functions, it is pointless to use Cairo on this connection.
Please feel free to discuss.

Only reason is performance reason, so you have more control of how/when the cairo result is uploaded to OpenGL texture and used. With xlib you don’t have control over that. If you plan to use OpenGL then sooner or later you will want control over that, otherwise there’s no reason to use OpenGL.

For building simple applications, this connection is positive, you can build applications, for example for touch devices, etc. I decided to include this screenshot, maybe it will be useful to someone who is interested in 2D graphics.

gl_11.c