SDL_BlitSurface function

Started by
6 comments, last by Drogin 15 years, 3 months ago
At the SDL documentation, it says that SDL_BlitSurface() can return: 0(All good) -1(error) -2(video memory lost) At the documentation, we find this: If either of the surfaces were in video memory, and the blit returns -2, the video memory was lost, so it should be reloaded with artwork and re-blitted: while ( SDL_BlitSurface(image, imgrect, screen, dstrect) == -2 ) { while ( SDL_LockSurface(image)) < 0 ) Sleep(10); -- Write image pixels to image->pixels -- SDL_UnlockSurface(image); } So, the first while-loop continues untill the video memory arent lost anymore. The second while-loop continues untill we've managed to lock the surface. But what about the "-- Write image pixels to image->pixels --" ? What exactly are they suggesting we should do here? [Edited by - Drogin on December 20, 2008 7:11:16 AM]
Advertisement
This may sound crazy, but I think they might be suggesting that you write the picture data to image -> pixels [smile]

Sorry [grin]. The way it works is that SDL_Surfaces have a pointer to the raw data that make up the image. So, to reload the artwork (assuming no caching for the moment):
while ( SDL_BlitSurface(image, imgrect, screen, dstrect) == -2 ){    while ( SDL_LockSurface(image)) < 0 )    {        Sleep(10);    }    SDL_Surface disk = SDL_LoadBMP(filename);    if(!disk)    {        // handle the error        SDL_UnlockSurface(image);        // return error code, throw exception, etc    }    SDL_PixelFormat *format = image->format;    SDL_Surface *formatted = SDL_CreateRGBSurface(SDL_SWSURFACE,image->w,image->h,format->BitsPerPixel,format->Rmask,format->Gmask,format->Bmask,format->Amask);    if(formatted)    {         // copy the data to a surface with the correct format         SDL_BlitSurface(disk,NULL,image,NULL);         // use memcpy or std::copy in C++ to copy the raw formatted data         // double check the last argument here. I *think* its right         memcpy(image->pixels,formatted->pixels,image->pitch * image->h);    }    else    {        // handle the error        SDL_UnlockSurface(image);        // return error code, throw exception, etc            }    SDL_UnlockSurface(image);}


However, we could do this in a simpler fashion:
if( SDL_BlitSurface(image, imgrect, screen, dstrect) == -2 ){    SDL_Surface *disk = SDL_LoadBMP(filename);    if(disk)    {         SDL_FreeSurface(image);         image = disk;         // could use SDL_DisplayFormat etc etc.    }    else    {         // error handling    }}

I am not 100% sure on whether it is ok to do this. It depends on whether freeing a surface whose video memory has been lost is well defined. I would hope so, but it does sounds like a corner case that might not be handled well.

AFAIK, SDL_BlitSurface will only return -2 if you are using Hardware surfaces. Most SDL backends no longer support hardware surfaces. In any case, alpha blending is typically slow on such surfaces. Most people get away with using software surfaces just fine. Those who want high performance graphics tend to use something like OpenGL directly.
Quote:Original post by rip-off
This may sound crazy, but I think they might be suggesting that you write the picture data to image -> pixels [smile]


Wow, you're a geniuous xD


Got a better picture of what to do after seeing your code =)
Thanks man.
Hmm..after some spiritual meditation, I found some points of interest in your code.

I don't understand the point of the "SDL_Surface* formatted". Because from what I see, you just reload the image we wanted to show with SDL_LoadBMP(filename), then blit the newly loaded image onto the surface that had it's data lost.

Are you sure you didnt mean:
SDL_BlitSurface(disk,NULL,formatted,NULL);


instead of:
SDL_BlitSurface(disk,NULL,image,NULL);





Btw, I think the last argument are correct.
 // use memcpy or std::copy in C++ to copy the raw formatted data // double check the last argument here. I *think* its right memcpy(image->pixels,formatted->pixels,image->pitch * image->h);

memcpy takes number of bytes to be copied. And pitch contains number of bytes pr scanline..and image->h holds number of scanlines, if I've got it right.

Quote:Original post by Drogin
Are you sure you didnt mean:
*** Source Snippet Removed ***

instead of:
*** Source Snippet Removed ***


I certainly did. Good eye! [smile]

I didn't compile or test the code. I just typed it up and submitted it.
Quote:
I certainly did. Good eye!

I didn't compile or test the code. I just typed it up and submitted it.

Thanks [smile]
Frankly, I havent tried to compile it yet either.
But I will soon. This seems like a fairly uncommon problem(The -2 return value)
...but I don't like having "uncomplete" code =D
It is uncommon. I've used SDL for a few years on various projects and haven't ever come across this problem. As I have already said though, I never look for hardware surfaces.
According to the SDL-documentation, it can happen under DirectX 5.0 when the system switches away from your fullscreen application.

Not that I'm using DirectX 5.0..but I just like covering all return values just in case [smile]

This topic is closed to new replies.

Advertisement