xcb surface oddity?
Uli Schlachter
psychon at znc.in
Thu Dec 5 04:54:17 UTC 2024
Hi,
Am 05.12.24 um 00:11 schrieb Steven J Abner:
> Using cairo_surface_destroy() for clean up of a destroyed window causes
> an error in xcb. This error seems to depend on placement of the
> cairo_surface_destroy(). I was under the assumption that I, as the
> caller, per API description, am responsible for a
> cairo_xcb_surface_create().
> Conditions to cause the error of "BadPicture" are when freeing of
> resources, that I own, occurs after a xcb_destroy_window() call. If I
> call cairo_surface_destroy() before
> the window destruction, no error occurs. However, one would assume that
> it still exists due to the later call of cairo_surface_destroy() on
> subsurfaces created by cairo_surface_create_for_rectangle() after
> xcb_destroy_window().
I do not completely get your description here, but I think I understand
that there are cases where you call xcb_destroy_window() before you
cairo_surface_destroy() the cairo xcb surface. I feel like that case is
pretty much covered by the documentation of cairo_surface_finish() [0]:
> [...]
> For example, for the Xlib backend it means that cairo will no longer
> access the drawable, which can be freed.
> [...]
This talks about the Xlib backend, but I think one can easily see that
the same condition should apply to the xcb backend. So, you should
cairo_surface_finish() *before* the drawable is destroyed.
What does cairo_surface_finish() have to do with your question about
XCB? The next paragraph of the docs for cairo_surface_finish() explain:
> When the last call to cairo_surface_destroy() decreases the reference
> count to zero, cairo will call cairo_surface_finish() if it hasn't
> been called already
[0]:
https://cairographics.org/manual/cairo-cairo-surface-t.html#cairo-surface-finish
I am not quite sure what happens technically here, but a random guess
would be:
When you destroy the window, this also implicitly destroy the RENDER
picture that cairo created for the window. When cairo then ends up in
cairo_surface_finish() for the XCB surface, it calls
xcb_render_free_picture() for the Picture. This should then cause a
BadPicture error, because cairo is trying to free a picture which was
already freed and thus no longer exists.
> To clarify, the only cairo_xcb_surface_create() is used as a
> 'vid_buffer' with one 'simular' surface getting drawn to by multiple
> cairo_surface_create_for_rectangle() surface drawings. 'simular' gets
> 'paint()'ed to the 'vid_buffer' then flushed() for an exposed event.
> Now if the destroy() of 'vid_buffer' must be before xcb_destroy_window()
> instead of after like it's 'simular', does this mean xcb owns the
> surface and I own the subsurfaces? I thought I understood what I was
> doing, the double buffer concept, but this threw a monkey wrench at me.
I am not quite sure I understand this, but: The similar surfaces use
xcb_create_pixmap() and draw to that. Thus, if they are finish()ed, this
pixmap also gets destroyed. These cairo surfaces own their target.
Your main surface however does not own its target and it depends on your
program to make sure that its target stays around and is not destroyed
before cairo stops using it.
Cheers,
Uli
--
Sent from my Game Boy.
More information about the cairo
mailing list