Removed finalizers, optimized support for LispWorks, bug fix in examples.
Hi, there, Thank you for your great works! I'm interested in using cl-sdl2-ttf in my own code adventures. After trying out code, I have eliminated some bugs and made some improvements, and I would like to share them with you and others.
This PR contains three major improvements/fixes.
- Removed finalizers, i.e. TRIVIAL-GARBAGE. Finalizers can cause problems, as they are not thread-safe and the time it triggers garbage collection can be randomized. It can also be misleading for newcomers who has no idea about how finalizers work, see issues like this. Recently CL-SDL2 has dropped finalizers and is welcomed by the community, so I guess it's time for CL-SDL2-TTF to take the shot. We should let users manage the fonts/surfaces allocated by the program, like writing a with-macro, after all, it's very easy to do so in Lisp.
- Since I've been using LispWorks, I have rewritten the code in src/render.lisp to better support it. I have done two things:
- Dropped libffi dependency for LispWorks. Libffi can be hard to compile in some platforms, and it is used in the code solely to support passing
struct sdl-coloras arguments in FFI call. As LispWorks' own FFI has already supported passing structs as arguments, we can omit this redundency by writing a bare-metal FFI call for LispWorks FFI. - Fixed glyph rendering functions, like
TTF_RenderGlyph_Shaded. In these special kind of functions, the second argument to be passed should be anuint16, wheras the master code mistakenly passed a C-string. I have fixed this bug for my LispWorks implementation.
- Dropped libffi dependency for LispWorks. Libffi can be hard to compile in some platforms, and it is used in the code solely to support passing
- Fixed a bug in examples/gl-example.lisp that can cause the text rendered as garbage on Windows platform. It turns out that the
surface-pixelsin cl-sdl2 can have their own layout of pixels by adding paddings, sosurface-widthdoes not represent how much bytes are in a single scanline of the image. Changed it tosurface-pitch / 4.
Regards, niwtr
I had thought the finalizers in this library were causing an issue in a hobby project of mine. My program was leaking memory when rendering text, and I tried to fix it by manually freeing the surface created by sdl2-ttf:render-text-solid, but that would cause the finalizers to crash the program attempting to double-free the same surface.
But it turned out I misunderstood the memory leak. It was caused because I wasn't calling sdl2:destroy-texture on a texture created after rendering the text using sdl2:create-texture-from-surface, entirely outside the scope of sdl2-ttf.
Also, the double-free crash caused by manually freeing the surface is fixable without any code changes in this library by calling trivial-garbage:cancel-finalization on the surface created by sdl2-ttf:render-text-solid. That said, the finalizers also do the job perfectly well, so as long as you free your sdl2 rects and textures, you can let sdl2-ttf's finalizers clean up its surfaces for you if you want.
Just leaving this comment in case any of my fellow Common Lisp newbies run into the same confusion I did.