NVG memleak?

Started by mudlee, December 01, 2019, 09:10:23

Previous topic - Next topic


When I draw an image with NV (after it was rasterized from SVG), after a while my app get killed by osx. Any idea?

I have no problem with drawing other images.



The crash looks like a double-free bug. It also looks like there's rendering going on inside an event callback. Could you please post an MCVE?


Well, yes and no. I have very limited time and the rendering code (https://github.com/mudlee/spck) I wrote is at a complexity level where to provide a MCVE takes a little bit more time, but I try to copy here some code parts that might be interesting.

Image rendering:
public void beginFrame(int screenWidth, int screenHeight, int devicePixelRatio) {
        nvgBeginFrame(pointer, screenWidth, screenHeight, devicePixelRatio);
        nvgFontFace(pointer, defaultFont);

    public void endFrame() {

    public void renderImage(UIImage image) {

        int width = image.getWidth();
        int height = image.getHeight();
        float x = image.getScreenCoords().x;
        float y = image.getScreenCoords().y;

            image.handle = nvglCreateImageFromHandle(pointer, image.getTextureId(), width, height, 0);

        //int imageID = nvglCreateImageFromHandle(pointer, image.getTextureId(), width, height, 0);
        NVGPaint paint = NVGPaint.create();
        nvgImagePattern(pointer, x, y, width, height, 0, image.handle, 1f, paint);
        nvgRect(pointer, x, y, width, height);
        nvgFillPaint(pointer, paint);

Texture Creation:
long rast = nsvgCreateRasterizer();

        float scaleX = Engine.window.getPreferences().getDeviceScaleX().orElseThrow();
        float scaleY = Engine.window.getPreferences().getDeviceScaleY().orElseThrow();
        int width = (int) (svg.width() * scaleX);
        int height = (int) (svg.height() * scaleY);

        ByteBuffer image = memAlloc(width * height * 4);
        nsvgRasterize(rast, svg, 0, 0, min(scaleX, scaleY), image, width, height, width * 4);

        // creating texture
        int id = GL.genTextureContext(GL41.GL_TEXTURE_2D, textureId -> {
            GL41.glTexParameteri(GL41.GL_TEXTURE_2D, GL41.GL_TEXTURE_MAG_FILTER, GL41.GL_LINEAR);
            GL41.glTexParameteri(GL41.GL_TEXTURE_2D, GL41.GL_TEXTURE_MIN_FILTER, GL41.GL_LINEAR);
            GL41.glTexParameteri(GL41.GL_TEXTURE_2D, GL41.GL_TEXTURE_WRAP_S, GL41.GL_CLAMP_TO_EDGE);
            GL41.glTexParameteri(GL41.GL_TEXTURE_2D, GL41.GL_TEXTURE_WRAP_T, GL41.GL_CLAMP_TO_EDGE);

            premultiplyAlpha(image, width, height, width * 4);

            GL41.glTexImage2D(GL41.GL_TEXTURE_2D, 0, GL41.GL_RGBA, width, height, 0, GL41.GL_RGBA, GL41.GL_UNSIGNED_BYTE, image);