diff --git a/plugins/GSdx/GS.cpp b/plugins/GSdx/GS.cpp index f78b8da455..b72e97336b 100644 --- a/plugins/GSdx/GS.cpp +++ b/plugins/GSdx/GS.cpp @@ -220,10 +220,35 @@ static int _GSopen(void** dsp, const char* title, GSRendererType renderer, int t threads = theApp.GetConfigI("extrathreads"); } - std::shared_ptr wnd[2]; + std::vector> wnds; try { + // Only a dummy shell is built. Therefore you can create all objects now. + switch (renderer) + { + case GSRendererType::OGL_HW: + case GSRendererType::OGL_SW: + case GSRendererType::OGL_OpenCL: +#if defined(EGL_SUPPORTED) && defined(__unix__) + // Note: EGL code use GLX otherwise maybe it could be also compatible with Windows + // Yes OpenGL code isn't complicated enough ! + wnds.push_back(std::make_shared()); +#endif +#if defined(__unix__) + wnds.push_back(std::make_shared()); +#else + wnds.push_back(std::make_shared()); +#endif + break; + default: +#ifdef _WIN32 + wnds.push_back(std::make_shared()); +#endif + break; + } + + if (s_renderer != renderer) { // Emulator has made a render change request, which requires a completely @@ -343,30 +368,6 @@ static int _GSopen(void** dsp, const char* title, GSRendererType renderer, int t s_renderer = renderer; } - - if (s_gs->m_wnd == NULL) - { -#ifdef _WIN32 - switch (renderer) - { - case GSRendererType::OGL_HW: - case GSRendererType::OGL_SW: - case GSRendererType::OGL_OpenCL: - s_gs->m_wnd = std::make_shared(); - break; - default: - s_gs->m_wnd = std::make_shared(); - break; - } -#else -#ifdef EGL_SUPPORTED - wnd[0] = std::make_shared(); - wnd[1] = std::make_shared(); -#else - wnd[0] = std::make_shared(); -#endif -#endif - } } catch (std::exception& ex) { @@ -391,89 +392,63 @@ static int _GSopen(void** dsp, const char* title, GSRendererType renderer, int t int w = theApp.GetConfigI("ModeWidth"); int h = theApp.GetConfigI("ModeHeight"); -#if defined(__unix__) - for(uint32 i = 0; i < 2; i++) { + for(auto& wnd : wnds) + { try { - if (wnd[i] == NULL) continue; + wnd->Create(title, w, h); + // Create didn't throw so wnd is fine + s_gs->m_wnd = wnd; - wnd[i]->Create(title, w, h); - s_gs->m_wnd = wnd[i]; + s_gs->m_wnd->Show(); + + *dsp = s_gs->m_wnd->GetDisplay(); break; } catch (GSDXRecoverableError) { - wnd[i]->Detach(); + wnd->Detach(); } } - if (s_gs->m_wnd == NULL) - { - GSclose(); - return -1; - } -#endif -#ifdef _WIN32 - if(!s_gs->CreateWnd(title, w, h)) - { - GSclose(); - return -1; - } -#endif - - s_gs->m_wnd->Show(); - - *dsp = s_gs->m_wnd->GetDisplay(); } else { s_gs->SetMultithreaded(true); #if defined(__unix__) + void *win_handle = (void*)((uptr*)(dsp)+1); +#else + void *win_handle = *dsp; +#endif + if (s_gs->m_wnd) { // A window was already attached to s_gs so we also // need to restore the window state (Attach) - s_gs->m_wnd->Attach((void*)((uptr*)(dsp)+1), false); + s_gs->m_wnd->Attach(win_handle, false); } else { - // No window found, try to attach a GLX win and retry - // with EGL win if failed. - for(uint32 i = 0; i < 2; i++) { + // No window found, try to attach a window + for(auto& wnd : wnds) + { try { - if (wnd[i] == NULL) continue; - - wnd[i]->Attach((void*)((uptr*)(dsp)+1), false); - s_gs->m_wnd = wnd[i]; + wnd->Attach(win_handle, false); + // Attach didn't throw so wnd is fine + s_gs->m_wnd = wnd; break; } catch (GSDXRecoverableError) { - wnd[i]->Detach(); + wnd->Detach(); } } } -#endif -#ifdef _WIN32 - try - { - s_gs->m_wnd->Attach(*dsp, false); - } - catch (GSDXRecoverableError) - { - s_gs->m_wnd->Detach(); - s_gs->m_wnd.reset(); - } -#endif - if (s_gs->m_wnd == NULL) - { - return -1; - } } - if(!s_gs->CreateDevice(dev)) + if(!s_gs->m_wnd || !s_gs->CreateDevice(dev)) { // This probably means the user has DX11 configured with a video card that is only DX9 // compliant. Cound mean drivr issues of some sort also, but to be sure, that's the most diff --git a/plugins/GSdx/GSRenderer.cpp b/plugins/GSdx/GSRenderer.cpp index db4f89364c..cac0fef5a2 100644 --- a/plugins/GSdx/GSRenderer.cpp +++ b/plugins/GSdx/GSRenderer.cpp @@ -63,11 +63,6 @@ GSRenderer::~GSRenderer() delete m_dev; } -bool GSRenderer::CreateWnd(const string& title, int w, int h) -{ - return m_wnd->Create(title, w, h); -} - bool GSRenderer::CreateDevice(GSDevice* dev) { ASSERT(dev); diff --git a/plugins/GSdx/GSRenderer.h b/plugins/GSdx/GSRenderer.h index f66d1268a1..273f7c526b 100644 --- a/plugins/GSdx/GSRenderer.h +++ b/plugins/GSdx/GSRenderer.h @@ -62,7 +62,6 @@ public: GSRenderer(); virtual ~GSRenderer(); - virtual bool CreateWnd(const string& title, int w, int h); virtual bool CreateDevice(GSDevice* dev); virtual void ResetDevice(); virtual void VSync(int field); diff --git a/plugins/GSdx/GSWndDX.cpp b/plugins/GSdx/GSWndDX.cpp index 52750aa350..7b5a2d1343 100644 --- a/plugins/GSdx/GSWndDX.cpp +++ b/plugins/GSdx/GSWndDX.cpp @@ -81,7 +81,8 @@ LRESULT GSWndDX::OnMessage(UINT message, WPARAM wParam, LPARAM lParam) bool GSWndDX::Create(const string& title, int w, int h) { - if(m_hWnd) return false; + if(m_hWnd) + throw GSDXRecoverableError(); m_managed = true; @@ -101,7 +102,7 @@ bool GSWndDX::Create(const string& title, int w, int h) { if(!RegisterClass(&wc)) { - return false; + throw GSDXRecoverableError(); } } @@ -134,7 +135,10 @@ bool GSWndDX::Create(const string& title, int w, int h) m_hWnd = CreateWindow(wc.lpszClassName, title.c_str(), style, r.left, r.top, r.width(), r.height(), NULL, NULL, wc.hInstance, (LPVOID)this); - return m_hWnd != NULL; + if (!m_hWnd) + throw GSDXRecoverableError(); + + return true; } bool GSWndDX::Attach(void* handle, bool managed)