[SDL] SDL_PollEvent freezes on alt-tab

lemmn dwlemon at gmail.com
Mon Sep 19 09:35:34 PDT 2016


I am using Windows 10 and visual studio 2015, and SDL 2.0.4.

I believe this is a minimal repro case.. I had to cut out a lot of code to get down to this, so I'm sorry if there is extra code here.

This program just draws a square on the screen and then should quit when you press the space bar.

Repro steps:
- run the program
- press alt-tab while the game is running
- notice the game program locking up

The bug happens when I hit alt-tab.  If I do that, then the game becomes locked up at the call to PeekMessage() inside of WIN_PumpEvents(), with this callstack if I break:


Code:

 	[External Code]	
>	SDL2.dll!WIN_PumpEvents(SDL_VideoDevice * _this) Line 977	C
 	SDL2.dll!SDL_PumpEvents_REAL() Line 405	C
 	SDL2.dll!SDL_WaitEventTimeout_REAL(SDL_Event * event, int timeout) Line 437	C
 	SDL2.dll!SDL_PollEvent_REAL(SDL_Event * event) Line 419	C
 	SDL2.dll!SDL_PollEvent(SDL_Event * a) Line 157	C
 	MyMusic.exe!SDL_main(int argc, char * * argv) Line 154	C++
 	MyMusic.exe!main_utf8(int argc, char * * argv) Line 127	C
 	MyMusic.exe!WinMain(HINSTANCE__ * hInst, HINSTANCE__ * hPrev, char * szCmdLine, int sw) Line 191	C
 	[External Code]	




And the render thread is running happily.

This bug only happens in full screen.  If I remove this code:

flags |= SDL_WINDOW_FULLSCREEN;

then the game runs fine, and I do not get any freeze on using alt-tab.


I have a feeling that the render thread might be the problem, but I must be able to render in a separate thread for this game.  I followed this guide and everything seems to be working fine, apart from this freeze
https://github.com/vheuken/SDL-Render-Thread-Example/blob/master/main.cpp



Code:

#include "stdafx.h"

#include <vector>
#include <map>
#include <fstream>
#include <memory>
#include <limits>
#include <iomanip>
#include <thread>

#include <Windows.h>

#include <SDL.h>



// singleton to hold a bunch of global game state stuff
class Game
{
public:
	Game()
	{}

	SDL_Rect m_windowedRect;

	void SetUpScreen();
	void TearDownScreen();

	void StartRenderer();
	void KillRenderer();


	static Game& Get();

	// window and screen
	SDL_Window* m_Window;
	SDL_GLContext m_Context;


	bool m_QuitGame;

	SDL_Renderer* m_Renderer = nullptr;
	std::thread* m_RenderThread = nullptr;
};



static Game g_Game;
Game& Game::Get()
{
	return g_Game;
}

void Game::SetUpScreen()
{
	// make a sane default window position and size
	if ( 0 == SDL_GetDisplayBounds( 0, &m_windowedRect ) )
	{
		m_windowedRect.x = m_windowedRect.w * 0.05f;
		m_windowedRect.y = m_windowedRect.h * 0.05f;
		m_windowedRect.w = m_windowedRect.w * 0.9f;
		m_windowedRect.h = m_windowedRect.h * 0.9f;
	}
	else
	{
		m_windowedRect = { 10, 10, 1024, 768 };
	}

	int32_t flags = SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE;

	flags |= SDL_WINDOW_FULLSCREEN;

	SDL_Rect resolution;
	resolution = m_windowedRect;

	m_Window = SDL_CreateWindow( "hi friend", resolution.x, resolution.y, resolution.w, resolution.h, flags );
}

void Game::TearDownScreen()
{
	SDL_DestroyWindow( m_Window );
	m_Window = NULL;
}

void RenderThread();

void Game::StartRenderer()
{
	m_RenderThread = new std::thread( RenderThread );
}

static bool stopRenderer;

void Game::KillRenderer()
{
	stopRenderer = true;
	m_RenderThread->join();

	delete m_RenderThread;
	m_RenderThread = nullptr;
}

void RenderThread()
{
	SDL_GL_MakeCurrent( g_Game.m_Window, g_Game.m_Context ); // not sure what this does - it was happening in the example

	g_Game.m_Renderer = SDL_CreateRenderer( g_Game.m_Window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC );
	SDL_SetRenderDrawBlendMode( g_Game.m_Renderer, SDL_BLENDMODE_BLEND );

	while( 1 )
	{
		if ( stopRenderer )
		{
			goto quit;
		}

		SDL_Rect rect{ 10, 10, 10, 10 };
		SDL_SetRenderDrawColor( g_Game.m_Renderer, 0xff, 0xff, 0xff, 0xff );
		SDL_RenderFillRect( g_Game.m_Renderer, &rect );
		SDL_RenderPresent( g_Game.m_Renderer );
	}

quit:
	// shut down
	SDL_DestroyRenderer( g_Game.m_Renderer );
	g_Game.m_Renderer = NULL;
}

int main( int argc, char* argv[] )
{

	SDL_Init( SDL_INIT_AUDIO | SDL_INIT_VIDEO );

	SDL_SetHint( SDL_HINT_RENDER_SCALE_QUALITY, "linear" );

	g_Game.SetUpScreen();


	// not entirely sure this is needed but it was happening before creating the render thread in example
	g_Game.m_Context = SDL_GL_GetCurrentContext();
	SDL_GL_MakeCurrent( g_Game.m_Window, nullptr );

	g_Game.StartRenderer();

	// main loopy thing
	while ( 1 )
	{
		if ( g_Game.m_QuitGame )
		{
			break;
		}

		SDL_Event e;
		while ( SDL_PollEvent( &e ) )
		{
			if ( e.type == SDL_KEYDOWN )
			{
				if ( e.key.keysym.sym == SDLK_SPACE )
				{
					g_Game.m_QuitGame = true;
				}
			}
		}

		Sleep( 10 );
	}

	g_Game.KillRenderer();

	g_Game.TearDownScreen();

	SDL_Quit();
	return 0;
}








-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20160919/7f1fb850/attachment-0001.htm>


More information about the SDL mailing list