Hello,

I use "current cvs" from 2003-12-17 (dri - Mesa-newtree) on an Ati
Mobility M7 LW. When dri is enabled (OpenGL renderer string: Mesa DRI
Radeon 20030328 AGP 4xTCL) I get a memory leak when I load and unload
a texture.

Attached an example program. Put it in Mesa-newtree progs/tests and
add an entry in the good make file. Then, run it and look at the
memory usage. Each time you type 'r' in the window, the texture is
reloaded 100 times and here this program use 6M more memory (each time).

This problem does not happen if  LIBGL_ALWAYS_INDIRECT=1. This problem
does not happen with XFree-4.4.0-rc1.

Regards, Olivier
 
/*
 * Test glDeleteTexture mem usage, Olivier Chapuis
 */

#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define GL_GLEXT_PROTOTYPES
#include <GL/glut.h>

#include "readtex.c"   /* I know, this is a hack. */

/* a pot image */
#define TEXTURE_FILE "../images/reflect.rgb"

static GLfloat Xrot = 0, Yrot = 0, Zrot = 0;
static GLint ImgWidth, ImgHeight;
static GLenum ImgFormat;
GLubyte *ImgRGB;
GLuint texNum = 0;

static void DrawObject(void)
{
        glBegin(GL_QUADS);

        glTexCoord2f(0, 0);
        glVertex2f(-1.0, -1.0);

        glTexCoord2f(1.0, 0);
        glVertex2f(1.0, -1.0);
        
        glTexCoord2f(1.0, 1.0);
        glVertex2f(1.0, 1.0);

        glTexCoord2f(0, 1.0);
        glVertex2f(-1.0, 1.0);

        glEnd();
}


static void Display( void )
{
   glClear( GL_COLOR_BUFFER_BIT );

   glPushMatrix();
      glRotatef(Xrot, 1.0, 0.0, 0.0);
      glRotatef(Yrot, 0.0, 1.0, 0.0);
      glRotatef(Zrot, 0.0, 0.0, 1.0);
      DrawObject();
   glPopMatrix();

   glutSwapBuffers();
}


static void Reshape( int width, int height )
{
   glViewport( 0, 0, width, height );
   glMatrixMode( GL_PROJECTION );
   glLoadIdentity();
   glFrustum( -1.0, 1.0, -1.0, 1.0, 10.0, 100.0 );
   glMatrixMode( GL_MODELVIEW );
   glLoadIdentity();
   glTranslatef( 0.0, 0.0, -15.0 );
}


static void ReloadTexture( void)
{
        if (texNum)
        {
                glDeleteTextures(1, &texNum);

        }

        glGenTextures(1, &texNum) ;
        
        glBindTexture(GL_TEXTURE_2D, texNum) ;
        glTexImage2D(
                GL_TEXTURE_2D, 0, ImgFormat, ImgWidth, ImgHeight, 0,
                ImgFormat, GL_UNSIGNED_BYTE, ImgRGB) ;
         glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
         glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}

static void Key( unsigned char key, int x, int y )
{
   int i;

   switch (key)
   {
   case 'R':
   case 'r':
           fprintf(stderr,"ReloadTexture 100 times\n");
           for (i = 0; i < 100; i++)
                   ReloadTexture();
           break;
   case 27:
         exit(0);
         break;
   }
   glutPostRedisplay();
}


static void SpecialKey( int key, int x, int y )
{
   float step = 3.0;
   (void) x;
   (void) y;

   switch (key) {
      case GLUT_KEY_UP:
         Xrot += step;
         break;
      case GLUT_KEY_DOWN:
         Xrot -= step;
         break;
      case GLUT_KEY_LEFT:
         Yrot += step;
         break;
      case GLUT_KEY_RIGHT:
         Yrot -= step;
         break;
   }
   glutPostRedisplay();
}





static void Init( int argc, char *argv[] )
{
   ImgRGB = LoadRGBImage(TEXTURE_FILE, &ImgWidth, &ImgHeight, &ImgFormat);
   if (!ImgRGB) {
      printf("Couldn't read %s\n", TEXTURE_FILE);
      exit(0);
   }

   printf("Image: %dx%d\n", ImgWidth, ImgHeight);
   
   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);

   ReloadTexture();

   glEnable(GL_TEXTURE_2D) ;

   glShadeModel(GL_FLAT);
   glClearColor(0.3, 0.3, 0.4, 1.0);

   printf("Type 'r' to reload 100 the texture. Take a look at the mem usage\n");
}


int main( int argc, char *argv[] )
{
   glutInit( &argc, argv );
   glutInitWindowSize( 300, 300 );
   //glutInitWindowPosition( 0, 0 );
   glutInitDisplayMode( GLUT_RGB | GLUT_RGBA | GLUT_DOUBLE );
   glutCreateWindow(argv[0] );

   Init( argc, argv );

   glutReshapeFunc( Reshape );
   glutKeyboardFunc( Key );
   glutSpecialFunc( SpecialKey );
   glutDisplayFunc( Display );

   glutMainLoop();
   return 0;
}

Reply via email to