How well does SDL3 work with cairo-graphics?
Is cairo-graphics hardware accelerated?
Check this link Cairo and SDL.
In summary; they can work together very well, but be careful to ensure format of the SDL surface match those used in Cairo.
I tried something like that, is this the right approach?
On the SDL side, hardware is definitely used to accelerate it, as I have a renderer.
What about the cairo side?
#include <SDL3/SDL.h>
#include <cairo/cairo.h>
void CairoDraw(SDL_Texture *texture, int w, int h){
void *pixels;
int pitch;
SDL_LockTexture(texture, nullptr, &pixels, &pitch);
cairo_surface_t *surface = cairo_image_surface_create_for_data((char unsigned*)pixels, CAIRO_FORMAT_ARGB32, w, h, pitch);
cairo_t *context = cairo_create(surface);
cairo_set_source_rgba(context, 1.0, 1.0, 1.0, 1.0);
cairo_arc(context, w / 2, h / 2, w / 4, 0, SDL_PI_D * 2);
cairo_stroke(context);
cairo_destroy(context);
cairo_surface_destroy(surface);
SDL_UnlockTexture(texture);
}
int main(int argc, char *argv[])
{
int Width = 320;
int Height = 200;
SDL_Init(SDL_INIT_VIDEO);
SDL_Window *win = SDL_CreateWindow("Test", 320, 200, SDL_WINDOW_RESIZABLE);
SDL_Renderer *renderer = SDL_CreateRenderer(win, nullptr);
SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, Width, Height);
SDL_bool quit = SDL_FALSE;
while (!quit)
{
SDL_Event event;
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_EVENT_QUIT:
quit = SDL_TRUE;
break;
case SDL_EVENT_WINDOW_RESIZED:
SDL_DestroyTexture(texture);
SDL_GetWindowSize(win, &Width, &Height);
texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, Width, Height);
break;
}
}
CairoDraw(texture, Width, Height);
SDL_RenderTexture(renderer, texture, nullptr, nullptr);
SDL_RenderPresent(renderer);
}
SDL_DestroyTexture(texture);
SDL_DestroyWindow(win);
SDL_DestroyRenderer(renderer);
SDL_Quit();
return 0;
}
Do I understand correctly that the pointer from pixels in SDL_LockTexture()
points directly to the VRAM?
And if so, does Cairo recognize this and then use the GPU for drawing?
No. It’s in RAM.
I’m no expert on Cairo but if I understand correctly all these cairo_image_*
functions create things in RAM.
Apparently there was an experimental backend named cairo-gl, with it’s own set of cairo_gl_*
functions, that used OpenGL but it was removed.
Update: found the following:
cairo-image: pure CPU rasterisation
cairo-gl: use OpenGL for GPU compositing and some rasterisation, depends upon driver quality
cairo-xlib: use XRender to send commands to X which uses the GPU for compositing and some rasterisation, depends upon driver quality
cairo-quartz: use Quartz to offload some commands to the GPU
cairo-win32: uses image + GDI blitting, one day should have a d2d backend
When I read through your links, it looks like GPU acceleration is still a work in progress.
You have to bear in mind that the comments, apart from those posted by cairo_gl, are over 12 years old.
A lot could have happened in that time.
If xlib already supports it a little, let’s see what it looks like with Wayland.
Yeah, it’s old. I just thought it was a nice summary that explained that some “backends” use hardware acceleration if available but not cairo-image which you used in your code. I don’t think this has changed. The official docs says it’s for “rendering to memory buffers”.
Then it will probably be quite difficult to integrate this into SDL3, unless you take a detour via XLib_surfaces.
Unless it is integrated into SDL_Texture
/ SDL_Renderer
at some point. As far as I know, these two also use the GPU/VRAM.
I did a test with cairo_libx and a long for loop.
You can clearly see that it is written directly to the VRAM.
Without any swap buffers.