Sign in to follow this  
Drogin

SDL_BlitSurface function

Recommended Posts

Drogin    122
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]

Share this post


Link to post
Share on other sites
rip-off    10979
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.

Share this post


Link to post
Share on other sites
Drogin    122
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.

Share this post


Link to post
Share on other sites
Drogin    122
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.

Share this post


Link to post
Share on other sites
rip-off    10979
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.

Share this post


Link to post
Share on other sites
Drogin    122
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

Share this post


Link to post
Share on other sites
rip-off    10979
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.

Share this post


Link to post
Share on other sites
Drogin    122
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]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this