Randomly appearing black/empty surface after resize

Hi!

Im doing some tests for a qt (Linux) application with embedded SDL surface. Im planning to use the XReparentWindow trick to embed the surface inside my main window.

But for now, I have the SDL surface as extra window. Nevertheless, the SDL window is resized when the QT main window is resized. I’d like to get the resize logic working before I actually embed the surface in my app. This way I can easily check the size of the surface without having it cropped by the main window.

Im mentioning QT just for completeness. The SDL window should be quite independent. Only QT’s resizeEvent is used to resize the SDL surface.

In the result, the SDL window is resized when I resize the QT Window. My problem: Resize actions work most of the time, but do produce a black/empty surface in some cases. The surface can be recovered by further resize actions or repaint actions (i.e. by moving other windows over the surface). I already noticed that qt triggers a lot of resize events when the window size is changed gradually. I imagine that this may be part of my problem, but I wouldn’t count on it.

I already did a lot of tests with function calls like QApplication::syncX() or SDL_UpdateRect() at various placed, but that didn’t help.

relevant parts of my code are:

class members:

SDL_Surface *m_Surface;
SDL_Overlay *m_Overlay;
QMutex m_SdlMutex;
[…]

class member functions:

void SdlVideoWidget::initVideo() // only called once in the init phase. apparently ok
{
QApplication::syncX();
SDL_Init ( SDL_INIT_VIDEO );
m_Surface = SDL_SetVideoMode ( width() , height() , 0, SDL_SWSURFACE|SDL_RESIZABLE );
m_Overlay = SDL_CreateYUVOverlay ( 240, 240, SDL_YUY2_OVERLAY , m_Surface );
m_bWindowInitialized = true;
}

void SdlVideoWidget::resizeEvent ( QResizeEvent * event ) // called after each resize. apparently somethings wrong here
{
if ( m_bWindowInitialized )
{
QApplication::syncX();
m_SdlMutex.lock();
m_Surface = SDL_SetVideoMode ( width() , height() , 0, SDL_SWSURFACE|SDL_RESIZABLE );
m_Surface = SDL_GetVideoSurface();
//m_Overlay = SDL_CreateYUVOverlay ( 240, 240, SDL_YUY2_OVERLAY , m_Surface );
m_SdlMutex.unlock();
}
}

void SdlVideoWidget::newFrame() // called asynchronuosly from another thread. synchronized by mutex
{
m_SdlMutex.lock();
SDL_LockYUVOverlay ( m_Overlay );

    [code changing the overlay memory]

SDL_UnlockYUVOverlay ( m_Overlay );

SDL_DisplayYUVOverlay ( m_Overlay, &m_Surface->clip_rect );
m_SdlMutex.unlock();

}

any idea?

Thanks,
Philipp

I found the problem by myself:
I inserted SDL_FreeYUVOverlay/SDL_CreateYUVOverlay and now it works:

void SdlVideoWidget::resizeEvent ( QResizeEvent * event )
{
if ( m_bWindowInitialized )
{
QApplication::syncX();
m_SdlMutex.lock();
SDL_FreeYUVOverlay( m_Overlay );
m_Surface = SDL_SetVideoMode ( width() , height() , 0, SDL_SWSURFACE|SDL_RESIZABLE );
m_Surface = SDL_GetVideoSurface();
m_Overlay = SDL_CreateYUVOverlay ( 240, 240, SDL_YUY2_OVERLAY , m_Surface );
m_SdlMutex.unlock();
}
}

The fact that the ‘old’ Overlay was still usable somehow after SDL_SetVideoMode made me think that this isn’t needed…________________________________

From: sdl-bounces@lists.libsdl.org [mailto:sdl-bounces at lists.libsdl.org] On Behalf Of Beyer, Philipp
Sent: Monday, August 25, 2008 5:04 PM
To: sdl at lists.libsdl.org
Subject: [SDL] randomly appearing black/empty surface after resize

Hi!

Im doing some tests for a qt (Linux) application with embedded SDL surface. Im planning to use the XReparentWindow trick to embed the surface inside my main window.

But for now, I have the SDL surface as extra window. Nevertheless, the SDL window is resized when the QT main window is resized. I’d like to get the resize logic working before I actually embed the surface in my app. This way I can easily check the size of the surface without having it cropped by the main window.

Im mentioning QT just for completeness. The SDL window should be quite independent. Only QT’s resizeEvent is used to resize the SDL surface.

In the result, the SDL window is resized when I resize the QT Window. My problem: Resize actions work most of the time, but do produce a black/empty surface in some cases. The surface can be recovered by further resize actions or repaint actions (i.e. by moving other windows over the surface). I already noticed that qt triggers a lot of resize events when the window size is changed gradually. I imagine that this may be part of my problem, but I wouldn’t count on it.

I already did a lot of tests with function calls like QApplication::syncX() or SDL_UpdateRect() at various placed, but that didn’t help.

relevant parts of my code are:

class members:

SDL_Surface *m_Surface;
SDL_Overlay *m_Overlay;
QMutex m_SdlMutex;
[…]

class member functions:

void SdlVideoWidget::initVideo() // only called once in the init phase. apparently ok
{
QApplication::syncX();
SDL_Init ( SDL_INIT_VIDEO );
m_Surface = SDL_SetVideoMode ( width() , height() , 0, SDL_SWSURFACE|SDL_RESIZABLE );
m_Overlay = SDL_CreateYUVOverlay ( 240, 240, SDL_YUY2_OVERLAY , m_Surface );
m_bWindowInitialized = true;
}

void SdlVideoWidget::resizeEvent ( QResizeEvent * event ) // called after each resize. apparently somethings wrong here
{
if ( m_bWindowInitialized )
{
QApplication::syncX();
m_SdlMutex.lock();
m_Surface = SDL_SetVideoMode ( width() , height() , 0, SDL_SWSURFACE|SDL_RESIZABLE );
m_Surface = SDL_GetVideoSurface();
//m_Overlay = SDL_CreateYUVOverlay ( 240, 240, SDL_YUY2_OVERLAY , m_Surface );
m_SdlMutex.unlock();
}
}

void SdlVideoWidget::newFrame() // called asynchronuosly from another thread. synchronized by mutex
{
m_SdlMutex.lock();
SDL_LockYUVOverlay ( m_Overlay );

    [code changing the overlay memory]
   
    SDL_UnlockYUVOverlay ( m_Overlay );

    SDL_DisplayYUVOverlay ( m_Overlay, &m_Surface->clip_rect );
    m_SdlMutex.unlock();

}

any idea?

Thanks,
Philipp