Memory leak when using a pixel buffer to generate thumbnails

69 views
Skip to first unread message

Brian Hutchison

unread,
Jun 23, 2020, 12:58:17 PM6/23/20
to OpenSceneGraph Users
Hi Robert,

I am using code extracted from the osgscreencapture example to generate small thumbnails of loaded shapes.
It all work is very nicely except that it is leaking memory on each usage.  I have commented out our code and based on that and a few other tests I am fairly convinced that the leak is the pixel buffer (GraphicsContext) itself.


osg::ref_ptr<osg::GraphicsContext>
createPixelBuffer(int aSize, int aNumSamples)
{
    osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
    traits->x                                         = 0;
    traits->y                                         = 0;
    traits->width                                     = aSize;
    traits->height                                    = aSize;
    traits->red                                       = 8;
    traits->green                                     = 8;
    traits->blue                                      = 8;
    traits->alpha                                     = 8;
    traits->windowDecoration                          = false;
    traits->pbuffer                                   = true;
    traits->doubleBuffer                              = true;
    traits->sharedContext                             = 0;
    traits->readDISPLAY();
    traits->setUndefinedScreenDetailsToDefaultScreen();

    if (aNumSamples != 0)
    {
        traits->sampleBuffers = 1;
        traits->samples       = aNumSamples;
    }

    return osg::GraphicsContext::createGraphicsContext(traits.get());
}

bool
generateThumbnail(const std::string & aFilePath,
                  const std::string & aThumbnailPath,
                  const std::string & aResourcesPath,
                  int                 aSize,
                  bool                aTopDownView)
{
    auto pixelBuffer = createPixelBuffer(aSize, 8);
    if (!pixelBuffer)
    {
        pixelBuffer = createPixelBuffer(aSize, 0);
    }

//    const auto shape = loadShapeOrError(aFilePath);

    osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
    auto              camera = viewer->getCamera();

    camera->setGraphicsContext(pixelBuffer.get());
    camera->setViewport(new osg::Viewport(0, 0, aSize, aSize));
    camera->setDrawBuffer(GL_BACK);
    camera->setReadBuffer(GL_BACK);

//    setupShapeViewer(viewer, shape.get(), aResourcesPath, aTopDownView);

//    osg::ref_ptr<ImageGrabber> grabber = new ImageGrabber(aThumbnailPath);
//    viewer.getCamera()->setPostDrawCallback(grabber.get());

    viewer->realize();
    viewer->frame();

    return true;
};


If I call the above code repeatedly then it leaks and I cannot understand why since everything is in osg:ref_ptr<>. 
The Viewer was a concrete instance originally but that makes no difference.
I have also tried using a slave camera as in the original example.
I have a nasty workaround of extracting a shared pixel buffer and re-using it - but ideally this code would be called using std::async, to have multiple thumbnails generated in parallel, so that is going to be tricky.

Kinda hoping you can point to my stupid mistake in how I am using osg ;)

Thanks,

Brian


Robert Osfield

unread,
Jun 23, 2020, 1:10:21 PM6/23/20
to OpenSceneGraph Users
I can;t say what the leak will be from the code supply but I can say that creating a dedicated viewer, rendering a frame, then destroying really isn't an efficient way to go about generating a thumbnail image.  Rather than than debug a dubious approach I'd suggest you leave it and try another lighter weight approach.

The best approach is something I can't say at this point as I don't know enough about your application and your needs for generating a thumbnail.  Is it a one off activity, something you do offline, something that is done occasionally?  How to go about things depends upon your usage case.

As a general comment, creating an destroying objects on OpenGL and consequently the OSG is expensive.  It's far better to create once and reuse, even if you don't reuse often.

Also creating separate graphics context is very expensive, if you already have a graphics context then the best thing to do for offscreen rendering is to your a frame buffer object and render to texture.  This way you can minimize the amount of new GL objects being created for the task,  W.r.t running in a background thread, OpenGL isn't a multi-threaded API, you can only multi-thread with multiple graphics context with t a thread per context.  It's only really suitable for mulitple GPU tasks.  It's typically far better to just add the work to the standard frame and run it as part of your normal viewer.

With the OSG you can toggle on/off render to texture by setting the NodeMask of an osg::Camera.


Brian Hutchison

unread,
Jun 24, 2020, 3:14:42 AM6/24/20
to OpenSceneGraph Users
Thanks Robert, excellent answer.

I think I have enough for a way forward now.
One small remaining question,

Does readRefNodeFile access GL at all for any of these file formats:".3ds",".dae",".shp",".dxf"?
Or, to put it another way, can readRefNodeFile be called safely from a std:async thread to return something containing a usable osg::Node within the main application?

Thanks,

Brian

Walid Slimani

unread,
Jun 24, 2020, 7:38:42 AM6/24/20
to osg-...@googlegroups.com
Can you help me i'm confusing;ican't install osg;i have a vsiual studio 2015,PLEASE HELP ME

--
You received this message because you are subscribed to the Google Groups "OpenSceneGraph Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to osg-users+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/osg-users/a8394d4f-92a9-4736-b51f-34b5cf5bee9fn%40googlegroups.com.

OpenSceneGraph Users

unread,
Jun 24, 2020, 7:47:55 AM6/24/20
to OpenSceneGraph Users
On Wed, 24 Jun 2020 at 11:52, OpenSceneGraph Users <osg-...@lists.openscenegraph.org> wrote:
I think I have enough for a way forward now.
One small remaining question,

Does readRefNodeFile access GL at all for any of these file formats:".3ds",".dae",".shp",".dxf"?
Or, to put it another way, can readRefNodeFile be called safely from a std:async thread to return something containing a usable osg::Node within the main application?

None of the OSG plugins doing any OpenGL calls, they simply create scene graph data and then return this to the application which then decides what it wants to do with it.
 
 

Brian Hutchison

unread,
Jun 24, 2020, 11:19:13 AM6/24/20
to OpenSceneGraph Users
Cheers Robert, it is working a treat now.

Brian

OpenSceneGraph Users

unread,
Jun 24, 2020, 11:24:13 AM6/24/20
to OpenSceneGraph Users
On Wed, 24 Jun 2020 at 13:17, OpenSceneGraph Users <osg-...@lists.openscenegraph.org> wrote:
Can you help me i'm confusing;ican't install osg;i have a vsiual studio 2015,PLEASE HELP ME

Please don't hijack other threads to ask a question about a totally unrelated matter.  Please start a dedicated thread, and supply information about the steps you have taken and the problems you have as the information you have provided is of ZERO use to others trying to figure out what problem you are having, what you are confused by, and what advice to provide.
 

 
Reply all
Reply to author
Forward
0 new messages