NVG memleak?

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

Previous topic - Next topic

mudlee

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.

https://gist.github.com/mudlee/ad4d36dfde5ca04d2adf7f2bf76dc2e7

spasi

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?

mudlee

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() {
        nvgEndFrame(pointer);
        restoreGLState();
    }

    public void renderImage(UIImage image) {
        checkIfInitialised();

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

        if(image.handle==null){
            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);
        nvgBeginPath(pointer);
        nvgRect(pointer, x, y, width, height);
        nvgFillPaint(pointer, paint);
        nvgFill(pointer);
    }


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);
        nsvgDeleteRasterizer(rast);

        // 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);
        });