Hello Marco,

Marco Spoerl wrote:
Hello Carsten,

Thanks for your modified test app. First up, I think I have to mention
that we're using the 1.8 release here, not something fresh from the
repository. So I had to tweak it back a little bit to work with our
version of the library.

The following numbers are simply taken from the task manager.

29.000K when running idle
57.000K before exiting the leak function
31.000K after exiting the leak function

Increasing the number of iterations to 1000, I get the following
numbers.

29.000K when running idle
299.000K before exiting the leak function
61.000K after exiting the leak function

hm, that is indeed a lot of memory.
I've modified the program (attached) so that it now uses only one texture and image [1] for grabbing and writes the result to disk (I enabled readBuffer on the FBOViewport). Of course that means that the grabbed images do not remain available for rendering (at least not without loading them from disk again), neither in texture nor main memory. With that change I don't see a massive increase in memory consumption. So my guess would be that what you see above is (at least a good portion of it) memory allocated by the graphics driver for the textures.

So, from my point of view, I'm still seeing the problem. Maybe I have
to use a newer version of the library? In that case, I'd be grateful for
any tips how to get a reliable revision.

Or do I have to change the way
I grab my textures? In our application, that preprocessing step easily
involves tens of thousands of texture grabs.

The best way for grabbing the textures depends on how you intend to use them and the resources available. If you need all of them at once for rendering there is probably not much that can be done, but to keep them in texture memory, i.e. having a TextureChunk and Image for each of them. If you only need a subset for rendering you could use a small number of chunks and place the images you want to use in them (would still require lots of main memory for all the images, but less texture memory). The last alternative is pretty much what the program does: use one chunk and image and store the data on disk. You could later load in the relevant images and place them in textures for rendering.

        Hope it helps,
                Carsten

[1] that is controlled with the SINGLE_IMAGE define near the top of the program
#include <OSGConfig.h>
#include <OSGRefPtr.h>
#include <OSGGLUTWindow.h>
#include <OSGRenderAction.h>
#include <OSGPerspectiveCamera.h>
#include <OSGViewport.h>
#include <OSGPassiveBackground.h>
#include <OSGTransform.h>
#include <OSGGroup.h>
#include <OSGOrthographicCamera.h>
#include <OSGFBOViewport.h>
#include <OSGSolidBackground.h>
#include <OSGImage.h>
#include <OSGTextureChunk.h>
#include <OSGSimpleGeometry.h>

#include <OSGGLUT.h>


#include <sstream>

#define SINGLE_IMAGE 1

//-----------------------------------------------------------------------------

static const OSG::UInt32 TEX_SIZE       = 256;
static const OSG::UInt32 NUM_ITERATIONS = 1000;

//-----------------------------------------------------------------------------

OSG::GLUTWindowRefPtr  g_pWindow(OSG::NullFC);
OSG::RenderAction*     g_pAction = 0;
OSG::FBOViewportRefPtr g_pFboViewport(OSG::NullFC);

OSG::TransformPtr      g_pGeoTrans;
OSG::NodeRefPtr        g_pGeoTransNode;

OSG::TextureChunkRefPtr g_pTexChunk;
OSG::ImageRefPtr        g_pImage;


void reshape(int w, int h);
void display(void        );
void key    (unsigned char key, int, int);


void onCreateMain(int *argc, char *argv[])
{
    // OSG init
    OSG::osgInit(*argc, argv);

    // GLUT init
    glutInit(argc, argv);
    glutInitDisplayMode( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
    int winid = glutCreateWindow("OpenSG");
    glutReshapeFunc(reshape);
    glutDisplayFunc(display);
    glutKeyboardFunc(key);
    
    
    g_pWindow = OSG::GLUTWindow  ::create();
    g_pAction = OSG::RenderAction::create();

    // create viewport

    OSG::NodePtr      pCameraBeacon = OSG::makeCoredNode<OSG::Transform>();
    OSG::TransformPtr pBeaconTrans  = OSG::TransformPtr::dcast(pCameraBeacon->getCore());
    OSG::beginEditCP(pBeaconTrans);
        pBeaconTrans->editMatrix().setTranslate(OSG::Vec3f(0.0, 0.0, 2.0));
    OSG::endEditCP  (pBeaconTrans);

    OSG::PerspectiveCameraPtr pPerspectiveCam = OSG::PerspectiveCamera::create();
    OSG::beginEditCP(pPerspectiveCam);
        pPerspectiveCam->setBeacon(pCameraBeacon);
        pPerspectiveCam->setFov(OSG::deg2rad(90));
        pPerspectiveCam->setNear(1);
        pPerspectiveCam->setFar(1000);
    OSG::endEditCP(pPerspectiveCam);

    // create background
    OSG::SolidBackgroundPtr pBackground = OSG::SolidBackground::create();
    OSG::beginEditCP(pBackground);
        pBackground->setColor(OSG::Color3f(0.0, 0.5, 0.0));
    OSG::endEditCP(pBackground);

    OSG::NodePtr     pDummyRoot = OSG::makeCone(1.0, 0.5, 16, true, true);
    OSG::GeometryPtr pDummyGeo  = OSG::GeometryPtr::dcast(pDummyRoot->getCore());
    OSG::beginEditCP(pDummyGeo);
        pDummyGeo->setMaterial(OSG::getDefaultUnlitMaterial());
    OSG::endEditCP  (pDummyGeo);

    OSG::ViewportPtr pViewport = OSG::Viewport::create();
    OSG::beginEditCP(pViewport);
        pViewport->setCamera(pPerspectiveCam);
        pViewport->setBackground(pBackground);
        pViewport->setRoot(pDummyRoot);
        pViewport->setSize(0, 0, 1, 1);
    OSG::endEditCP(pViewport);

    // init OpenSG window

    OSG::beginEditCP(g_pWindow);
        g_pWindow->addPort(pViewport);
        g_pWindow->setId(winid);
        g_pWindow->init();
        g_pWindow->deactivate();
    OSG::endEditCP(g_pWindow);
}


void onCreateFbo()
{
    // create nodes
    OSG::NodePtr      pCameraBeacon = OSG::makeCoredNode<OSG::Transform>();
//     OSG::TransformPtr pBeaconTrans  = OSG::TransformPtr::dcast(pCameraBeacon->getCore());
//     OSG::beginEditCP(pBeaconTrans);
//         pBeaconTrans->editMatrix().setTranslate(OSG::Vec3f(0.0, 0.0, -2.0));
//     OSG::endEditCP  (pBeaconTrans);
    
    OSG::NodePtr     pGeometryNode = OSG::makeBox(100.0, 10.0, 50.0, 1, 1, 1);
    OSG::GeometryPtr pGeometry     = OSG::GeometryPtr::dcast(pGeometryNode->getCore());
    OSG::beginEditCP(pGeometry);
        pGeometry->setMaterial(OSG::getDefaultUnlitMaterial());
    OSG::endEditCP  (pGeometry);

    g_pGeoTransNode = OSG::makeCoredNode<OSG::Transform>(&g_pGeoTrans);
    OSG::beginEditCP(g_pGeoTransNode);
        g_pGeoTransNode->addChild(pGeometryNode);
    OSG::endEditCP  (g_pGeoTransNode);
    
    // create root node
    OSG::NodePtr pRootNode = OSG::makeCoredNode<OSG::Group>();
    OSG::beginEditCP(pRootNode);
        pRootNode->addChild(pCameraBeacon);
        pRootNode->addChild(g_pGeoTransNode);
    OSG::endEditCP(pRootNode);

    // create camera
    OSG::OrthographicCameraPtr pCamera = OSG::OrthographicCamera::create();
    OSG::beginEditCP(pCamera);
        pCamera->setBeacon(pCameraBeacon);
        pCamera->setNear(0.1);
        pCamera->setFar(100);
        pCamera->setAspect(1);
        pCamera->setVerticalSize(TEX_SIZE);
    OSG::endEditCP(pCamera);

    // create background
    OSG::SolidBackgroundPtr pBackground = OSG::SolidBackground::create();
    OSG::beginEditCP(pBackground);
        pBackground->setColor(OSG::Color3f(0.6, 0.0, 0.0));
    OSG::endEditCP(pBackground);

    // create viewport
    g_pFboViewport = OSG::FBOViewport::create();
    OSG::beginEditCP(g_pFboViewport);
        g_pFboViewport->setParent(g_pWindow);
        g_pFboViewport->setRoot(pRootNode);
        g_pFboViewport->setBackground(pBackground);
        g_pFboViewport->setCamera(pCamera);
        g_pFboViewport->setSize(0, 0, TEX_SIZE - 1, TEX_SIZE - 1);
        g_pFboViewport->setStorageWidth(TEX_SIZE);
        g_pFboViewport->setStorageHeight(TEX_SIZE);
        g_pFboViewport->setGenCubemaps(false);
        g_pFboViewport->setGenDepthmaps(false);
        g_pFboViewport->setReadBuffer(true);
        g_pFboViewport->setFboOn(true);
        g_pFboViewport->setDirty(true);
    OSG::endEditCP(g_pFboViewport);
}


// Standard GLUT callback functions
void display( void )
{
    if (g_pWindow != OSG::NullFC)
    {
        g_pWindow->render(g_pAction);
    }
}

void reshape( int w, int h )
{
    if (g_pWindow != OSG::NullFC)
    {
        g_pWindow->resize(w, h);
    }
    glutPostRedisplay();
}


//-----------------------------------------------------------------------------

void grab(OSG::TextureChunkPtr pTexture, OSG::UInt32 i)
{
    if (g_pFboViewport != OSG::NullFC)
    {
        OSG::beginEditCP(g_pGeoTrans);
            g_pGeoTrans->editMatrix().setRotate(OSG::Quaternion(OSG::Vec3f(0.0, 0.0, 1.0), (6.28 / NUM_ITERATIONS) * i));
        OSG::endEditCP  (g_pGeoTrans);
        
#ifndef SINGLE_IMAGE
        OSG::ImagePtr pImage = OSG::Image::create();
        OSG::beginEditCP(pImage);
            pImage->set(OSG::Image::OSG_RGBA_PF, TEX_SIZE, TEX_SIZE);
        OSG::endEditCP(pImage);

        OSG::beginEditCP(pTexture, OSG::TextureChunk::ImageFieldMask);
            pTexture->setImage(pImage);
        OSG::endEditCP(pTexture, OSG::TextureChunk::ImageFieldMask);
#endif

        g_pAction->setAutoFrustum(false);
        g_pAction->setCorrectTwoSidedLighting(false);
        g_pAction->setFrustumCulling(false);
        g_pAction->setOcclusionCulling(false);
        g_pAction->setSmallFeatureCulling(false);
        g_pAction->setSortTrans(false);
        g_pAction->setStateSorting(false);
        g_pAction->setStatistics(false);
        g_pAction->setVolumeDrawing(false);
        g_pAction->setZWriteTrans(false);

        OSG::beginEditCP(g_pFboViewport);
            g_pFboViewport->editMFTextures()->push_back(pTexture);
        OSG::endEditCP(g_pFboViewport);

        g_pFboViewport->render(g_pAction);

        OSG::beginEditCP(g_pFboViewport);
            g_pFboViewport->editMFTextures()->clear();
        OSG::endEditCP(g_pFboViewport);
        
        
        std::ostringstream fileName;
        fileName << "texture_" << i << ".png";
#ifndef SINGLE_IMAGE
        pImage->write(fileName.str().c_str());
#else
        g_pImage->write(fileName.str().c_str());
#endif
    }
}

//-----------------------------------------------------------------------------

OSG::TextureChunkPtr createTexture()
{
#ifndef SINGLE_IMAGE
    OSG::Real32 maximumAnistropy;
    glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maximumAnistropy);
    maximumAnistropy = OSG::osgMin(maximumAnistropy, OSG::Real32(8.0));

    OSG::TextureChunkPtr pTexture = OSG::TextureChunk::create();
    OSG::beginEditCP(pTexture);
        pTexture->setAnisotropy(maximumAnistropy);
        pTexture->setMinFilter(GL_LINEAR);
        pTexture->setMagFilter(GL_LINEAR);
        pTexture->setWrapS(GL_CLAMP_TO_EDGE);
        pTexture->setWrapT(GL_CLAMP_TO_EDGE);
        pTexture->setTarget(GL_TEXTURE_2D);
        pTexture->setInternalFormat(GL_RGBA8);
    OSG::endEditCP(pTexture);

    return pTexture;
#else
    if(g_pTexChunk == OSG::NullFC)
    {
        OSG::Real32 maximumAnistropy;
        glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maximumAnistropy);
        maximumAnistropy = OSG::osgMin(maximumAnistropy, OSG::Real32(8.0));

        g_pTexChunk = OSG::TextureChunk::create();
        OSG::beginEditCP(g_pTexChunk);
            g_pTexChunk->setAnisotropy(maximumAnistropy);
            g_pTexChunk->setMinFilter(GL_LINEAR);
            g_pTexChunk->setMagFilter(GL_LINEAR);
            g_pTexChunk->setWrapS(GL_CLAMP_TO_EDGE);
            g_pTexChunk->setWrapT(GL_CLAMP_TO_EDGE);
            g_pTexChunk->setTarget(GL_TEXTURE_2D);
            g_pTexChunk->setInternalFormat(GL_RGBA8);
        OSG::endEditCP(g_pTexChunk);
    }
    
    if(g_pImage == OSG::NullFC)
    {
        g_pImage = OSG::Image::create();
        
        OSG::beginEditCP(g_pImage);
            g_pImage->set(OSG::Image::OSG_RGBA_PF, TEX_SIZE, TEX_SIZE);
        OSG::endEditCP(g_pImage);

        OSG::beginEditCP(g_pTexChunk, OSG::TextureChunk::ImageFieldMask);
            g_pTexChunk->setImage(g_pImage);
        OSG::endEditCP(g_pTexChunk, OSG::TextureChunk::ImageFieldMask);
    }
    
    return g_pTexChunk;
#endif
}

//-----------------------------------------------------------------------------

void leak()
{
    std::cout << "calling 'leak'" << std::endl;
    
    OSG::RefPtr<OSG::TextureChunkPtr> pTexture(OSG::NullFC);

    for(OSG::UInt32 i = 0; i < NUM_ITERATIONS; ++i)
    {
        pTexture = createTexture();
        grab(pTexture, i);
    }
    
    std::cout << "exiting 'leak'" << std::endl;
}


void
key(unsigned char key, int , int )
{
    switch(key)
    {
    case 27:    g_pWindow      = OSG::NullFC;
                g_pFboViewport = OSG::NullFC;
                delete g_pAction;
                g_pAction = NULL;
                exit(1);
    
    case 'l':   leak();
                break;
    }
    glutPostRedisplay();
}

// Initialize GLUT & OpenSG and set up the scene
int main (int argc, char **argv)
{
    onCreateMain(&argc, argv);
    onCreateFbo();
    

    // GLUT main loop
    glutMainLoop();

    return 0;
}
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Opensg-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensg-users

Reply via email to