| View previous topic :: View next topic |
| Author |
Message |
darkness
Joined: 15 Jun 2008 Posts: 121
|
Posted: Thu Jul 10, 2008 6:12 am Post subject: SDL allocated memory problem! |
|
|
Hi,
I'm try to learn SDL lib,
I've coded a simple JPG image loader,
it works great but if I try to load 10-15 images
I've a error (Error while loading image...)
I've try to look on the disponible RAM and when I load a image a part of RAM is normally allocated, but when I exit the function the RAM is not free correctly!!!
Please, help....
Here is the code:
| Code: |
int Image_viewer(char* target)
{
SDL_Surface *background = NULL; // Image surface
SDL_Surface *screen = NULL; // Screen surface
SDL_Init(SDL_INIT_EVERYTHING);
SDL_ShowCursor(0);
screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE);
SDL_RWops* rwfile = SDL_RWFromFile(target, "rb");
background = IMG_LoadJPG_RW(rwfile);
if( background != NULL )
{
//Create an optimized image
background = SDL_DisplayFormat(background);
}
else
{
Init();
printf("\nError while loading image...");
sleep(2000000);
SDL_FreeSurface(background);
SDL_FreeSurface(screen);
SDL_FreeRW(rwfile);
SDL_Quit();
initGraphics();
return 1;
}
SDL_FreeRW(rwfile);
// Show the image centered on the screen
//Make a temporary rectangle to hold the offsets
SDL_Rect offset;
//Give the offsets to the rectangle
offset.x = ( screen->w - background->w ) / 2;
offset.y = ( screen->h - background->h ) / 2;
//Blit the surface
SDL_BlitSurface( background, NULL, screen, &offset );
SDL_Flip( screen );
SceCtrlLatch pad;
while(1)
{
sceCtrlReadLatch(&pad);
if(pad.uiMake==PSP_CTRL_CIRCLE)
{
break;
}
}
SDL_FreeSurface(background);
SDL_FreeSurface(screen);
SDL_Quit();
initGraphics();
return 0;
}
|
|
|
| Back to top |
|
 |
darkness
Joined: 15 Jun 2008 Posts: 121
|
Posted: Fri Jul 11, 2008 5:22 am Post subject: |
|
|
| Ok, I've resolved! |
|
| Back to top |
|
 |
darkness
Joined: 15 Jun 2008 Posts: 121
|
Posted: Fri Jul 11, 2008 6:10 am Post subject: |
|
|
Excuse me, I've a new error! :(
The allocated memory is not the real problem!
Now I can load a lot of image but at end of the function the occupated memory is the same!
But if I try to load 10-15 different! images the SDL_RWFromFile funct don't load the image and return a null pointer!!!
Where is the problem?
It is a possible SDL bug or I've bad writed the code??
( The name and the estension is always correcly )
Here is the "new" code:
| Code: |
int Image_viewer(char* target, char* estensione)
{
SDL_Surface *background = NULL; // Image surface
SDL_Surface *screen = NULL; // Screen surface
SDL_Init(SDL_INIT_EVERYTHING); // It fail never
SDL_ShowCursor(0);
screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE); // It fail never
SDL_RWops* rwfile = SDL_RWFromFile(target, "rb"); // This is the bad function!
if(rwfile==NULL)
{
Init();
printf("\nRwfile NULL!");
sleep(2000000);
SDL_FreeSurface(background);
SDL_FreeSurface(screen);
SDL_FreeRW(rwfile);
SDL_Quit();
initGraphics();
return 1;
}
//Load the image
if(strcmp(estensione, "BMP")==0) background = SDL_LoadBMP_RW(rwfile, 0);
if((strcmp(estensione, "PNM")==0) || (strcmp(estensione, "PPM")==0) ||
(strcmp(estensione, "PGM")==0) || (strcmp(estensione, "PBM")==0))
background = IMG_LoadPNM_RW(rwfile);
if(strcmp(estensione, "XPM")==0) background = IMG_LoadXPM_RW(rwfile);
if(strcmp(estensione, "XCF")==0) background = IMG_LoadXCF_RW(rwfile);
if(strcmp(estensione, "PCX")==0) background = IMG_LoadPCX_RW(rwfile);
if(strcmp(estensione, "GIF")==0) background = IMG_LoadGIF_RW(rwfile);
if(strcmp(estensione, "JPG")==0) background = IMG_LoadJPG_RW(rwfile);
if((strcmp(estensione, "TIF")==0) || (strcmp(estensione, "TIFF")==0))
background = IMG_LoadTIF_RW(rwfile);
if(strcmp(estensione, "PNG")==0) background = IMG_LoadPNG_RW(rwfile);
if(strcmp(estensione, "LBM")==0) background = IMG_LoadLBM_RW(rwfile);
if(strcmp(estensione, "TGA")==0) background = IMG_LoadTGA_RW(rwfile);
if(background == NULL )
{
Init();
printf("\nErrore durante il caricamento dell'immagine\n o formato non supportato");
sleep(2000000);
SDL_FreeSurface(background);
SDL_FreeSurface(screen);
SDL_FreeRW(rwfile);
SDL_Quit();
initGraphics();
return 1;
}
SDL_FreeRW(rwfile);
//Make a temporary rectangle to hold the offsets
SDL_Rect offset;
//Give the offsets to the rectangle
offset.x = ( screen->w - background->w ) / 2;
offset.y = ( screen->h - background->h ) / 2;
//Blit the surface
SDL_BlitSurface( background, NULL, screen, &offset );
SDL_Flip( screen );
SceCtrlLatch pad;
while(1)
{
sceCtrlReadLatch(&pad);
if(pad.uiMake==PSP_CTRL_CIRCLE)
{
break;
}
}
SDL_FreeSurface(screen);
SDL_FreeSurface(background);
SDL_Quit();
initGraphics();
return 0;
}
|
|
|
| Back to top |
|
 |
J.F.
Joined: 22 Feb 2004 Posts: 2906
|
Posted: Fri Jul 11, 2008 6:44 am Post subject: |
|
|
| You're running out of memory. Remember that SDL loads the images in 32 bit mode, and rounds the size of the image up to the next power of two. So a 480x272 image becomes 512x512, consuming a full megabyte of space. |
|
| Back to top |
|
 |
darkness
Joined: 15 Jun 2008 Posts: 121
|
Posted: Fri Jul 11, 2008 7:17 am Post subject: |
|
|
Why? I ever free the memory! When I load a image I'll call Image_viewer funct and it returns to my programm and then I load another image, but when exit from Image_viewer funct the memory it's free, right?
I've a function to check the disponible Ram and the when return the funct the Ram is the same as when I call the funct!
Excuse for my bad english and thanks! |
|
| Back to top |
|
 |
J.F.
Joined: 22 Feb 2004 Posts: 2906
|
Posted: Fri Jul 11, 2008 7:29 am Post subject: |
|
|
| You only show the routine that loads the image, not the rest of the program, so we can't tell you what's wrong. If you want help, you're going to have to post more code. |
|
| Back to top |
|
 |
jean

Joined: 05 Jan 2008 Posts: 489
|
Posted: Fri Jul 11, 2008 5:35 pm Post subject: |
|
|
| Quote: | | So a 480x272 image becomes 512x512, consuming a full megabyte of space. |
Is this something SDL-wide or PSP-specific?? I used to think that on PSP alignment to nearest 2 power was only to be perfomed on x, not y.... so i did expect something like 480x272 =>512*272 (*4 bytes = 500Kb). If this depends on the fact that older PC cards need both dimensions aligned, this could be fixed on PSP specific implementation (don't know how hardwired this technique is in SDL) greatly improving memory usage. |
|
| Back to top |
|
 |
darkness
Joined: 15 Jun 2008 Posts: 121
|
Posted: Sat Jul 12, 2008 2:53 am Post subject: |
|
|
J.F., I cannot post the entire code! But I think that the code is not the problem because it out of that funct!
However this is a example of the structure of my program!
| Code: |
PSP_MODULE_INFO("...", 0, 1, 0);
int main_thread(SceSize args, void *argp)
{
// Inizializzazione schermo e callbacks
SetupCallbacks();
pspDebugScreenInit();
// Carica la root della MS
char* buf=(char*)malloc(MAXPATHLEN);
char* argm=argp;
if(argm[0]!='P'){
cd("ms0:/");
}
else{
argm[0]='m';
cd(argm);
}
cd("ms0:/");
carica(getcwd_0(buf,MAXPATHLEN));
free(buf);
// INIZIALIZZO GRAFICA
sleep(160000);
initGraphics();
while(running())
{
...
if(pad.Buttons==PSP_CTRL_CROSS)
{
Image_viewer(name, estension);
}
...
}
sceKernelSleepThread();
return 0;
}
int module_start(SceSize args, void *argp)
{
SceUID th = sceKernelCreateThread("main_thread", main_thread, 8, 18*1024, 0, NULL);
if (th >= 0)
{
sceKernelStartThread(th, args, argp);
}
return 0;
}
int module_stop(SceSize args, void *argp)
{
return 0;
}
|
All the code works fine, there's no one other problem!
I've think to start a thread whit clear_stack attrib, maybe it's a solution!
I've tryed but nothing is started, maybe wrong code! |
|
| Back to top |
|
 |
J.F.
Joined: 22 Feb 2004 Posts: 2906
|
Posted: Sat Jul 12, 2008 3:54 am Post subject: |
|
|
Okay, yeah, I see the structure now. It's basically this:
main
loop ----> init SDL, get/show pic, wait for button, cleanup SDL
exit
And that may the problem. SDL for the PSP isn't meant to be started and stopped in that manner. You need to try to restructure the program like this:
main
init SDL
loop ----> get/show pic, wait for button
cleanup SDL
exit |
|
| Back to top |
|
 |
darkness
Joined: 15 Jun 2008 Posts: 121
|
Posted: Sat Jul 12, 2008 5:52 am Post subject: |
|
|
I've build a new exec.
This is the code:
| Code: |
PSP_MODULE_INFO("Image_Viewer", 0, 0, 1);
#define SCREEN_WIDTH 480
#define SCREEN_HEIGHT 272
#define SCREEN_BPP 32
#define Init pspDebugScreenInit
#define sleep sceKernelDelayThread
#define printf pspDebugScreenPrintf
// int main_thread(SceSize args, void *argp)
int main(int argc, char *argv[])
{
SetupCallbacks();
SDL_Init(SDL_INIT_EVERYTHING); // It fail never
SceCtrlLatch pad;
SDL_ShowCursor(0);
SDL_Surface *background = NULL;
SDL_Surface *screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE); // It fail never
int refresh=0;
char* target = NULL;
int a=0;
char* array[20][256];
*array[0]="ms0:/PICTURE/CRISIS_CORE/snap0q18.bmp";
*array[1]="ms0:/PICTURE/CRISIS_CORE/snap0q19.bmp";
*array[2]="ms0:/PICTURE/CRISIS_CORE/snap0q20.bmp";
*array[3]="ms0:/PICTURE/CRISIS_CORE/snap0q21.bmp";
*array[4]="ms0:/PICTURE/CRISIS_CORE/snap0q22.bmp";
*array[5]="ms0:/PICTURE/CRISIS_CORE/snap0q23.bmp";
*array[6]="ms0:/PICTURE/CRISIS_CORE/snap0q25.bmp";
*array[7]="ms0:/PICTURE/CRISIS_CORE/snap0q27.bmp";
*array[8]="ms0:/PICTURE/CRISIS_CORE/snap0q28.bmp";
*array[9]="ms0:/PICTURE/CRISIS_CORE/snap0q29.bmp";
*array[10]="ms0:/PICTURE/CRISIS_CORE/snap0q30.bmp";
*array[11]="ms0:/PICTURE/CRISIS_CORE/snap0q32.bmp";
*array[12]="ms0:/PICTURE/CRISIS_CORE/snap0q34.bmp";
*array[13]="ms0:/PICTURE/CRISIS_CORE/snap0q35.bmp";
*array[14]="ms0:/PICTURE/CRISIS_CORE/snap0q37.bmp";
*array[15]="ms0:/PICTURE/CRISIS_CORE/snap0q41.bmp";
*array[16]="ms0:/PICTURE/CRISIS_CORE/snap0q42.bmp";
*array[17]="ms0:/PICTURE/CRISIS_CORE/snap0q52.bmp";
*array[18]="ms0:/PICTURE/CRISIS_CORE/snap0q53.bmp";
*array[19]="ms0:/PICTURE/CRISIS_CORE/snap0q54.bmp";
int fd=0;
while(1)
{
sceCtrlReadLatch(&pad);
if(refresh==1)
{
background = NULL;
Init();
printf("\n%s", target);
sleep(1000000);
if(!(fd = sceIoOpen(target, PSP_O_RDONLY, 0777)))
{
Init();
printf("\nFile doesn't exist!");
sleep(2000000);
}
sceIoClose(fd);
SDL_RWops* rwfile = SDL_RWFromFile(target, "rb"); // This is the bad function!
if(rwfile==NULL)
{
Init();
printf("\nRwfile NULL!");
sleep(2000000);
SDL_FreeSurface(background);
SDL_FreeSurface(screen);
SDL_FreeRW(rwfile);
SDL_Quit();
initGraphics();
sceKernelExitGame();
}
//Load the image
background = SDL_LoadBMP_RW(rwfile, 0);
if(background == NULL )
{
Init();
printf("\nErrore durante il caricamento dell'immagine\n o formato non supportato");
sleep(2000000);
SDL_FreeSurface(background);
SDL_FreeSurface(screen);
SDL_FreeRW(rwfile);
SDL_Quit();
initGraphics();
sceKernelExitGame();
}
SDL_FreeRW(rwfile);
//Give the offsets to the rectangle
SDL_Rect offset;
offset.x = ( screen->w - background->w ) / 2;
offset.y = ( screen->h - background->h ) / 2;
//Blit the surface
SDL_BlitSurface( background, NULL, screen, &offset );
SDL_Flip( screen );
refresh=0;
}
if(pad.uiMake==PSP_CTRL_CIRCLE)
{
break;
}
if(pad.uiMake==PSP_CTRL_CROSS)
{
refresh=1;
if(a<20)a++;
target=*array[a];
}
}
SDL_FreeSurface(screen);
SDL_FreeSurface(background);
SDL_Quit();
initGraphics();
sceKernelExitGame();
return 0;
}
|
It doesn't work, I've the same problem!
The first 8-15 images it's blitted perfeclty, and after I've a error! (Rwfile NULL!) |
|
| Back to top |
|
 |
J.F.
Joined: 22 Feb 2004 Posts: 2906
|
Posted: Sat Jul 12, 2008 6:18 am Post subject: |
|
|
| Okay, sounds like the file isn't being closed. The number of loops sounds like the max # of files that can be opened. |
|
| Back to top |
|
 |
J.F.
Joined: 22 Feb 2004 Posts: 2906
|
Posted: Sat Jul 12, 2008 6:25 am Post subject: |
|
|
| J.F. wrote: | | Okay, sounds like the file isn't being closed. The number of loops sounds like the max # of files that can be opened. |
And here's why:
| Code: | | background = SDL_LoadBMP_RW(rwfile, 0); |
That 0 should be a 1. That parameter tells the function to free the source when done. Since you don't free the source, the file isn't close, and the PSP quits opening more files after 14 or so. |
|
| Back to top |
|
 |
darkness
Joined: 15 Jun 2008 Posts: 121
|
Posted: Sat Jul 12, 2008 6:53 am Post subject: |
|
|
I haven't understand this post, however the option ( 0 or 1 ) there aren't in the other IMG_Load* function!
And I've free the rwfile ( SDL_FreeRW(rwfile); ) and than I've set it parameter to 0!
However if I set that parameter to 1 the error is resolved, but I want to load another type of image! ( e.g. JPG, PNG, TIF etc.. )! |
|
| Back to top |
|
 |
darkness
Joined: 15 Jun 2008 Posts: 121
|
Posted: Sat Jul 12, 2008 6:55 am Post subject: |
|
|
Ok, I've rebuilted it for load JPG image!
This is the new code:
| Code: |
int main(int argc, char *argv[])
{
SetupCallbacks();
SDL_Init(SDL_INIT_EVERYTHING); // It fail never
SceCtrlLatch pad;
SDL_ShowCursor(0);
SDL_Surface *background = NULL;
SDL_Surface *screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE); // It fail never
int refresh=0;
char* target = NULL;
int a=0;
char* array[20][256];
*array[0]="ms0:/fd/1.jpg";
*array[1]="ms0:/fd/2.jpg";
*array[2]="ms0:/fd/3.jpg";
*array[3]="ms0:/fd/4.jpg";
*array[4]="ms0:/fd/5.jpg";
*array[5]="ms0:/fd/6.jpg";
*array[6]="ms0:/fd/7.jpg";
*array[7]="ms0:/fd/8.jpg";
*array[8]="ms0:/fd/9.jpg";
*array[9]="ms0:/fd/10.jpg";
*array[10]="ms0:/fd/11.jpg";
*array[11]="ms0:/fd/12.jpg";
*array[12]="ms0:/fd/13.jpg";
*array[13]="ms0:/fd/14.jpg";
*array[14]="ms0:/fd/15.jpg";
*array[15]="ms0:/fd/16.jpg";
*array[16]="ms0:/fd/17.jpg";
*array[17]="ms0:/fd/18.jpg";
*array[18]="ms0:/fd/19.jpg";
*array[19]="ms0:/fd/20.jpg";
int fd=0;
while(1)
{
sceCtrlReadLatch(&pad);
if(refresh==1)
{
background = NULL;
Init();
printf("\n%s", target);
sleep(200000);
if(!(fd = sceIoOpen(target, PSP_O_RDONLY, 0777)))
{
Init();
printf("\nFile doesn't exist!");
sleep(2000000);
}
sceIoClose(fd);
SDL_RWops* rwfile = SDL_RWFromFile(target, "rb"); // This is the bad function!
if(rwfile==NULL)
{
Init();
printf("\nRwfile NULL!");
sleep(2000000);
SDL_FreeSurface(background);
SDL_FreeSurface(screen);
SDL_FreeRW(rwfile);
SDL_Quit();
initGraphics();
sceKernelExitGame();
}
//Load the image
background = IMG_LoadJPG_RW(rwfile);
if(background == NULL )
{
Init();
printf("\nErrore durante il caricamento dell'immagine\n o formato non supportato");
sleep(2000000);
SDL_FreeSurface(background);
SDL_FreeSurface(screen);
SDL_FreeRW(rwfile);
SDL_Quit();
initGraphics();
sceKernelExitGame();
}
SDL_FreeRW(rwfile);
//Give the offsets to the rectangle
SDL_Rect offset;
offset.x = ( screen->w - background->w ) / 2;
offset.y = ( screen->h - background->h ) / 2;
//Blit the surface
SDL_BlitSurface( background, NULL, screen, &offset );
SDL_Flip( screen );
refresh=0;
}
if(pad.uiMake==PSP_CTRL_CIRCLE)
{
break;
}
if(pad.uiMake==PSP_CTRL_CROSS)
{
refresh=1;
if(a<19) a++;
else a=0;
target=*array[a];
}
}
SDL_FreeSurface(screen);
SDL_FreeSurface(background);
SDL_Quit();
initGraphics();
sceKernelExitGame();
return 0;
}
|
But I've the same error!
At the 12° image I've error (Rwfile NULL)!
What I've to free? |
|
| Back to top |
|
 |
J.F.
Joined: 22 Feb 2004 Posts: 2906
|
Posted: Sat Jul 12, 2008 6:56 am Post subject: |
|
|
| darkness wrote: | I haven't understand this post, however the option ( 0 or 1 ) there aren't in the other IMG_Load* function!
And I've free the rwfile ( SDL_FreeRW(rwfile); ) and than I've set it parameter to 0!
However if I set that parameter to 1 the error is resolved, but I want to load another type of image! ( e.g. JPG, PNG, TIF etc.. )! |
Do like I did and go look over the SDL code. See what it's doing. For example, SDL_FreeRW(rwfile) simply does free(rwfile) - it only frees the memory. it doesn't close the file. So go look at the SDL code. :) |
|
| Back to top |
|
 |
darkness
Joined: 15 Jun 2008 Posts: 121
|
Posted: Sat Jul 12, 2008 7:24 am Post subject: |
|
|
I'll download tomorrow the lib!
Thanks very much!
Last edited by darkness on Sat Jul 12, 2008 7:38 am; edited 1 time in total |
|
| Back to top |
|
 |
darkness
Joined: 15 Jun 2008 Posts: 121
|
Posted: Sat Jul 12, 2008 7:30 am Post subject: |
|
|
I've used the SDL_GetError funct and it returns:
Couldn't not open ms0:/fd/12.jpg!
But the file is not the problem!
I've try to replace 12.jpg with another image and I've the same error! |
|
| Back to top |
|
 |
J.F.
Joined: 22 Feb 2004 Posts: 2906
|
Posted: Sat Jul 12, 2008 7:42 am Post subject: |
|
|
| darkness wrote: | I've used the SDL_GetError funct and it returns:
Couldn't not open ms0:/fd/12.jpg!
But the file is not the problem!
I've try to replace 12.jpg with another image and I've the same error! |
The PSP can only open so many files. After you reach the limit, no more files will open no matter what is doing the opening or whether or not the files are any good. They simply don't open because there are no more handles available. The limit is like 11 to 15. I forget the exact number. |
|
| Back to top |
|
 |
darkness
Joined: 15 Jun 2008 Posts: 121
|
Posted: Sat Jul 12, 2008 7:32 pm Post subject: |
|
|
And then it's a bug of SDL? The image is opened but it is not closed?
I'll look in the SDL src, but where I can find the code of the PSP port of SDL?
I'm not using Cygwin and then I've no svn!
Where I can find it? |
|
| Back to top |
|
 |
J.F.
Joined: 22 Feb 2004 Posts: 2906
|
Posted: Sat Jul 12, 2008 8:19 pm Post subject: |
|
|
| darkness wrote: | And then it's a bug of SDL? The image is opened but it is not closed?
I'll look in the SDL src, but where I can find the code of the PSP port of SDL?
I'm not using Cygwin and then I've no svn!
Where I can find it? |
It's quite possibly a bug in SDL. Wouldn't be the first. People on *nix or Windows wouldn't get a "can't open anymore files" error except after a truly silly number of files.
If you search the board for SDL, you'll see a thread I made on adding TV support to SDL. In that thread, I post links for downloading the SDL code from a download service. |
|
| Back to top |
|
 |
darkness
Joined: 15 Jun 2008 Posts: 121
|
Posted: Sat Jul 12, 2008 9:13 pm Post subject: |
|
|
8 MB is too big for me! 56K! :(
Can you upload only the I need of SDL? |
|
| Back to top |
|
 |
darkness
Joined: 15 Jun 2008 Posts: 121
|
Posted: Sat Jul 12, 2008 9:22 pm Post subject: |
|
|
All resolved!!!!!!!!!!!!!!!!!!!!!!
Thanks very much J.F! Now I don't need SDL src! |
|
| Back to top |
|
 |
J.F.
Joined: 22 Feb 2004 Posts: 2906
|
Posted: Sun Jul 13, 2008 3:35 am Post subject: |
|
|
| darkness wrote: | All resolved!!!!!!!!!!!!!!!!!!!!!!
Thanks very much J.F! Now I don't need SDL src! |
Could you mention what the solution turned out to be in case someone else runs into this same problem? |
|
| Back to top |
|
 |
darkness
Joined: 15 Jun 2008 Posts: 121
|
Posted: Sun Jul 13, 2008 3:55 am Post subject: |
|
|
| SDL_RWclose(rwfile) and I've used SDL_RWFromFP(fp, 1); funct to load RW file! |
|
| Back to top |
|
 |
|