diff --git a/Source/Core/Core/Src/Core.cpp b/Source/Core/Core/Src/Core.cpp index f1c83b313a..57398aee64 100644 --- a/Source/Core/Core/Src/Core.cpp +++ b/Source/Core/Core/Src/Core.cpp @@ -203,8 +203,6 @@ bool Init() Host_SetWaitCursor(true); Host_UpdateMainFrame(); // Disable any menus or buttons at boot - emuThreadGoing.Init(); - g_aspect_wide = _CoreParameter.bWii; if (g_aspect_wide) { @@ -221,14 +219,19 @@ bool Init() g_pWindowHandle = Host_GetRenderHandle(); if (!g_video_backend->Initialize(g_pWindowHandle)) { - emuThreadGoing.Shutdown(); Host_SetWaitCursor(false); return false; } HW::Init(); - DSP::GetDSPEmulator()->Initialize(g_pWindowHandle, - _CoreParameter.bWii, _CoreParameter.bDSPThread); + if (!DSP::GetDSPEmulator()->Initialize(g_pWindowHandle, + _CoreParameter.bWii, _CoreParameter.bDSPThread)) + { + HW::Shutdown(); + g_video_backend->Shutdown(); + Host_SetWaitCursor(false); + return false; + } Pad::Initialize(g_pWindowHandle); // Load and Init Wiimotes - only if we are booting in wii mode if (g_CoreStartupParameter.bWii) @@ -245,6 +248,8 @@ bool Init() // The hardware is initialized. g_bHwInit = true; + emuThreadGoing.Init(); + // Start the emu thread g_EmuThread = std::thread(EmuThread); diff --git a/Source/Core/Core/Src/DSP/DSPCore.cpp b/Source/Core/Core/Src/DSP/DSPCore.cpp index 0d4ff5b962..07290c54cb 100644 --- a/Source/Core/Core/Src/DSP/DSPCore.cpp +++ b/Source/Core/Core/Src/DSP/DSPCore.cpp @@ -61,7 +61,7 @@ static bool LoadRom(const char *fname, int size_in_words, u16 *rom) return true; } - PanicAlertT("Failed to load DSP ROM: %s", fname); + PanicAlertT("Failed to load DSP ROM:\n%s\nThis file is required to use DSP LLE", fname); return false; } @@ -87,6 +87,14 @@ static bool VerifyRoms(const char *irom_filename, const char *coef_filename) return true; } +static void DSPCore_FreeMemoryPages() +{ + FreeMemoryPages(g_dsp.irom, DSP_IROM_BYTE_SIZE); + FreeMemoryPages(g_dsp.iram, DSP_IRAM_BYTE_SIZE); + FreeMemoryPages(g_dsp.dram, DSP_DRAM_BYTE_SIZE); + FreeMemoryPages(g_dsp.coef, DSP_COEF_BYTE_SIZE); +} + bool DSPCore_Init(const char *irom_filename, const char *coef_filename, bool bUsingJIT) { @@ -104,10 +112,13 @@ bool DSPCore_Init(const char *irom_filename, const char *coef_filename, memset(g_dsp.coef, 0, DSP_COEF_BYTE_SIZE); // Try to load real ROM contents. - LoadRom(irom_filename, DSP_IROM_SIZE, g_dsp.irom); - LoadRom(coef_filename, DSP_COEF_SIZE, g_dsp.coef); - if (!VerifyRoms(irom_filename, coef_filename)) + if (!LoadRom(irom_filename, DSP_IROM_SIZE, g_dsp.irom) || + !LoadRom(coef_filename, DSP_COEF_SIZE, g_dsp.coef) || + !VerifyRoms(irom_filename, coef_filename)) + { + DSPCore_FreeMemoryPages(); return false; + } memset(&g_dsp.r,0,sizeof(g_dsp.r)); @@ -163,6 +174,9 @@ bool DSPCore_Init(const char *irom_filename, const char *coef_filename, void DSPCore_Shutdown() { + if (core_state == DSPCORE_STOP) + return; + core_state = DSPCORE_STOP; if(dspjit) { @@ -170,10 +184,7 @@ void DSPCore_Shutdown() dspjit = NULL; } step_event.Shutdown(); - FreeMemoryPages(g_dsp.irom, DSP_IROM_BYTE_SIZE); - FreeMemoryPages(g_dsp.iram, DSP_IRAM_BYTE_SIZE); - FreeMemoryPages(g_dsp.dram, DSP_DRAM_BYTE_SIZE); - FreeMemoryPages(g_dsp.coef, DSP_COEF_BYTE_SIZE); + DSPCore_FreeMemoryPages(); } void DSPCore_Reset() diff --git a/Source/Core/Core/Src/DSPEmulator.h b/Source/Core/Core/Src/DSPEmulator.h index 07d83da177..34ebe83252 100644 --- a/Source/Core/Core/Src/DSPEmulator.h +++ b/Source/Core/Core/Src/DSPEmulator.h @@ -28,7 +28,7 @@ public: virtual bool IsLLE() = 0; - virtual void Initialize(void *hWnd, bool bWii, bool bDSPThread) = 0; + virtual bool Initialize(void *hWnd, bool bWii, bool bDSPThread) = 0; virtual void Shutdown() = 0; virtual void DoState(PointerWrap &p) = 0; diff --git a/Source/Core/Core/Src/HW/DSPHLE/DSPHLE.cpp b/Source/Core/Core/Src/HW/DSPHLE/DSPHLE.cpp index fab709d8b9..07e6cb1b4d 100644 --- a/Source/Core/Core/Src/HW/DSPHLE/DSPHLE.cpp +++ b/Source/Core/Core/Src/HW/DSPHLE/DSPHLE.cpp @@ -50,7 +50,7 @@ struct DSPState } }; -void DSPHLE::Initialize(void *hWnd, bool bWii, bool bDSPThread) +bool DSPHLE::Initialize(void *hWnd, bool bWii, bool bDSPThread) { m_hWnd = hWnd; m_bWii = bWii; @@ -65,6 +65,8 @@ void DSPHLE::Initialize(void *hWnd, bool bWii, bool bDSPThread) m_InitMixer = false; m_dspState.Reset(); + + return true; } void DSPHLE::DSP_StopSoundStream() diff --git a/Source/Core/Core/Src/HW/DSPHLE/DSPHLE.h b/Source/Core/Core/Src/HW/DSPHLE/DSPHLE.h index f54cfec783..8abd6c0358 100644 --- a/Source/Core/Core/Src/HW/DSPHLE/DSPHLE.h +++ b/Source/Core/Core/Src/HW/DSPHLE/DSPHLE.h @@ -29,7 +29,7 @@ class DSPHLE : public DSPEmulator { public: DSPHLE(); - virtual void Initialize(void *hWnd, bool bWii, bool bDSPThread); + virtual bool Initialize(void *hWnd, bool bWii, bool bDSPThread); virtual void Shutdown(); virtual bool IsLLE() { return false; } diff --git a/Source/Core/Core/Src/HW/DSPLLE/DSPLLE.cpp b/Source/Core/Core/Src/HW/DSPLLE/DSPLLE.cpp index 67d088b7b7..e7c9e0aac2 100644 --- a/Source/Core/Core/Src/HW/DSPLLE/DSPLLE.cpp +++ b/Source/Core/Core/Src/HW/DSPLLE/DSPLLE.cpp @@ -99,33 +99,26 @@ void DSPLLE::dsp_thread(DSPLLE *lpParameter) } } -void DSPLLE::Initialize(void *hWnd, bool bWii, bool bDSPThread) +bool DSPLLE::Initialize(void *hWnd, bool bWii, bool bDSPThread) { m_hWnd = hWnd; m_bWii = bWii; m_bDSPThread = bDSPThread; m_InitMixer = false; - bool bCanWork = true; + std::string irom_file = File::GetSysDirectory() + GC_SYS_DIR DIR_SEP DSP_IROM; std::string coef_file = File::GetSysDirectory() + GC_SYS_DIR DIR_SEP DSP_COEF; if (!File::Exists(irom_file)) - irom_file = File::GetUserPath(D_GCUSER_IDX) + DIR_SEP DSP_IROM; + irom_file = File::GetUserPath(D_GCUSER_IDX) + DSP_IROM; if (!File::Exists(coef_file)) - coef_file = File::GetUserPath(D_GCUSER_IDX) + DIR_SEP DSP_COEF; - bCanWork = DSPCore_Init(irom_file.c_str(), coef_file.c_str(), AudioCommon::UseJIT()); + coef_file = File::GetUserPath(D_GCUSER_IDX) + DSP_COEF; + if (!DSPCore_Init(irom_file.c_str(), coef_file.c_str(), AudioCommon::UseJIT())) + return false; g_dsp.cpu_ram = Memory::GetPointer(0); DSPCore_Reset(); - if (!bCanWork) - { - DSPCore_Shutdown(); - // No way to shutdown Core from here? Hardcore shutdown! - exit(EXIT_FAILURE); - return; - } - m_bIsRunning = true; InitInstructionTable(); @@ -134,6 +127,8 @@ void DSPLLE::Initialize(void *hWnd, bool bWii, bool bDSPThread) m_hDSPThread = std::thread(dsp_thread, this); Host_RefreshDSPDebuggerWindow(); + + return true; } void DSPLLE::DSP_StopSoundStream() diff --git a/Source/Core/Core/Src/HW/DSPLLE/DSPLLE.h b/Source/Core/Core/Src/HW/DSPLLE/DSPLLE.h index 0d80993020..7df273503e 100644 --- a/Source/Core/Core/Src/HW/DSPLLE/DSPLLE.h +++ b/Source/Core/Core/Src/HW/DSPLLE/DSPLLE.h @@ -27,7 +27,7 @@ class DSPLLE : public DSPEmulator { public: DSPLLE(); - virtual void Initialize(void *hWnd, bool bWii, bool bDSPThread); + virtual bool Initialize(void *hWnd, bool bWii, bool bDSPThread); virtual void Shutdown(); virtual bool IsLLE() { return true; } diff --git a/Source/Plugins/Plugin_VideoDX11/Src/main.cpp b/Source/Plugins/Plugin_VideoDX11/Src/main.cpp index 62a7128c3d..42782451fe 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/main.cpp @@ -174,11 +174,6 @@ bool VideoBackend::Initialize(void *&window_handle) OSD::AddMessage("Dolphin Direct3D11 Video Backend.", 5000); s_BackendInitialized = true; - return true; -} - -void VideoBackend::Video_Prepare() -{ // Better be safe... s_efbAccessRequested = FALSE; s_FifoShuttingDown = FALSE; @@ -203,6 +198,11 @@ void VideoBackend::Video_Prepare() PixelEngine::Init(); DLCache::Init(); + return true; +} + +void VideoBackend::Video_Prepare() +{ // Tell the host that the window is ready Core::Callback_CoreMessage(WM_USER_CREATE); } diff --git a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp index 98d2dd0cda..6a98f37a02 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp @@ -159,11 +159,6 @@ bool VideoBackend::Initialize(void *&window_handle) OSD::AddMessage("Dolphin Direct3D9 Video Backend.", 5000); s_BackendInitialized = true; - return true; -} - -void VideoBackend::Video_Prepare() -{ // Better be safe... s_efbAccessRequested = FALSE; s_FifoShuttingDown = FALSE; @@ -184,6 +179,11 @@ void VideoBackend::Video_Prepare() PixelEngine::Init(); DLCache::Init(); + return true; +} + +void VideoBackend::Video_Prepare() +{ // Notify the core that the video backend is ready Core::Callback_CoreMessage(WM_USER_CREATE); } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp b/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp index 46140b4e7b..ce4198f699 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp @@ -117,16 +117,10 @@ void VideoBackend::UpdateFPSDisplay(const char *text) #if defined(HAVE_X11) && HAVE_X11 void XEventThread(); -void CreateXWindow (void) +void CreateXWindow(void) { Atom wmProtocols[1]; - // use evdpy to create the window, so that connection gets the events - // the colormap needs to be created on the same display, because it - // is a client side structure, as well as wmProtocols(or so it seems) - // GLWin.win is a xserver global window handle, so it can be used by both - // display connections - // Setup window attributes GLWin.attr.colormap = XCreateColormap(GLWin.evdpy, GLWin.parent, GLWin.vi->visual, AllocNone); @@ -136,7 +130,8 @@ void CreateXWindow (void) // Create the window GLWin.win = XCreateWindow(GLWin.evdpy, GLWin.parent, - GLWin.x, GLWin.y, GLWin.width, GLWin.height, 0, GLWin.vi->depth, InputOutput, GLWin.vi->visual, + GLWin.x, GLWin.y, GLWin.width, GLWin.height, 0, + GLWin.vi->depth, InputOutput, GLWin.vi->visual, CWBorderPixel | CWBackPixel | CWColormap | CWEventMask, &GLWin.attr); wmProtocols[0] = XInternAtom(GLWin.evdpy, "WM_DELETE_WINDOW", True); XSetWMProtocols(GLWin.evdpy, GLWin.win, wmProtocols, 1); @@ -151,7 +146,8 @@ void DestroyXWindow(void) { XUnmapWindow(GLWin.dpy, GLWin.win); GLWin.win = 0; - GLWin.xEventThread.join(); + if (GLWin.xEventThread.joinable()) + GLWin.xEventThread.join(); XFreeColormap(GLWin.evdpy, GLWin.attr.colormap); } @@ -298,11 +294,14 @@ void XEventThread() s_backbuffer_height = GLWin.height; break; case ClientMessage: - if ((unsigned long) event.xclient.data.l[0] == XInternAtom(GLWin.evdpy, "WM_DELETE_WINDOW", False)) + if ((unsigned long) event.xclient.data.l[0] == + XInternAtom(GLWin.evdpy, "WM_DELETE_WINDOW", False)) Core::Callback_CoreMessage(WM_USER_STOP); - if ((unsigned long) event.xclient.data.l[0] == XInternAtom(GLWin.evdpy, "RESIZE", False)) - XMoveResizeWindow(GLWin.evdpy, GLWin.win, event.xclient.data.l[1], - event.xclient.data.l[2], event.xclient.data.l[3], event.xclient.data.l[4]); + if ((unsigned long) event.xclient.data.l[0] == + XInternAtom(GLWin.evdpy, "RESIZE", False)) + XMoveResizeWindow(GLWin.evdpy, GLWin.win, + event.xclient.data.l[1], event.xclient.data.l[2], + event.xclient.data.l[3], event.xclient.data.l[4]); break; default: break; @@ -385,26 +384,26 @@ bool OpenGL_Create(void *&window_handle) // Show the window EmuWindow::Show(); - PIXELFORMATDESCRIPTOR pfd = // pfd Tells Windows How We Want Things To Be + PIXELFORMATDESCRIPTOR pfd = // pfd Tells Windows How We Want Things To Be { - sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor - 1, // Version Number - PFD_DRAW_TO_WINDOW | // Format Must Support Window - PFD_SUPPORT_OPENGL | // Format Must Support OpenGL - PFD_DOUBLEBUFFER, // Must Support Double Buffering - PFD_TYPE_RGBA, // Request An RGBA Format - 32, // Select Our Color Depth - 0, 0, 0, 0, 0, 0, // Color Bits Ignored - 0, // 8bit Alpha Buffer - 0, // Shift Bit Ignored - 0, // No Accumulation Buffer - 0, 0, 0, 0, // Accumulation Bits Ignored - 24, // 24Bit Z-Buffer (Depth Buffer) - 8, // 8bit Stencil Buffer - 0, // No Auxiliary Buffer - PFD_MAIN_PLANE, // Main Drawing Layer - 0, // Reserved - 0, 0, 0 // Layer Masks Ignored + sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor + 1, // Version Number + PFD_DRAW_TO_WINDOW | // Format Must Support Window + PFD_SUPPORT_OPENGL | // Format Must Support OpenGL + PFD_DOUBLEBUFFER, // Must Support Double Buffering + PFD_TYPE_RGBA, // Request An RGBA Format + 32, // Select Our Color Depth + 0, 0, 0, 0, 0, 0, // Color Bits Ignored + 0, // 8bit Alpha Buffer + 0, // Shift Bit Ignored + 0, // No Accumulation Buffer + 0, 0, 0, 0, // Accumulation Bits Ignored + 24, // 24Bit Z-Buffer (Depth Buffer) + 8, // 8bit Stencil Buffer + 0, // No Auxiliary Buffer + PFD_MAIN_PLANE, // Main Drawing Layer + 0, // Reserved + 0, 0, 0 // Layer Masks Ignored }; GLuint PixelFormat; // Holds The Results After Searching For A Match @@ -413,7 +412,7 @@ bool OpenGL_Create(void *&window_handle) PanicAlert("(1) Can't create an OpenGL Device context. Fail."); return false; } - if (!(PixelFormat = ChoosePixelFormat(hDC,&pfd))) { + if (!(PixelFormat = ChoosePixelFormat(hDC, &pfd))) { PanicAlert("(2) Can't find a suitable PixelFormat."); return false; } @@ -475,7 +474,7 @@ bool OpenGL_Create(void *&window_handle) GLWin.vi = glXChooseVisual(GLWin.dpy, GLWin.screen, attrListSgl); if (GLWin.vi != NULL) { - ERROR_LOG(VIDEO, "Only Singlebuffered Visual!"); + ERROR_LOG(VIDEO, "Only single buffered visual!"); } else { @@ -488,13 +487,13 @@ bool OpenGL_Create(void *&window_handle) } } else - NOTICE_LOG(VIDEO, "Got Doublebuffered Visual!"); + NOTICE_LOG(VIDEO, "Got double buffered visual!"); // Create a GLX context. GLWin.ctx = glXCreateContext(GLWin.dpy, GLWin.vi, 0, GL_TRUE); if (!GLWin.ctx) { - PanicAlert("Couldn't Create GLX context.Quit"); + PanicAlert("Unable to create GLX context."); return false; } @@ -517,17 +516,28 @@ bool OpenGL_MakeCurrent() #elif defined(__APPLE__) [GLWin.cocoaCtx makeCurrentContext]; #elif defined(_WIN32) - return wglMakeCurrent(hDC,hRC) ? true : false; + return wglMakeCurrent(hDC, hRC) ? true : false; #elif defined(HAVE_X11) && HAVE_X11 #if defined(HAVE_WX) && (HAVE_WX) - Core::Callback_VideoGetWindowSize(GLWin.x, GLWin.y, (int&)GLWin.width, (int&)GLWin.height); - XMoveResizeWindow(GLWin.dpy, GLWin.win, GLWin.x, GLWin.y, GLWin.width, GLWin.height); + Core::Callback_VideoGetWindowSize(GLWin.x, GLWin.y, + (int&)GLWin.width, (int&)GLWin.height); + XMoveResizeWindow(GLWin.dpy, GLWin.win, GLWin.x, GLWin.y, + GLWin.width, GLWin.height); #endif return glXMakeCurrent(GLWin.dpy, GLWin.win, GLWin.ctx); #endif return true; } +bool OpenGL_ReleaseContext() +{ +#ifdef _WIN32 + return wglMakeCurrent(NULL, NULL); +#elif defined(HAVE_X11) && HAVE_X11 + return glXMakeCurrent(GLWin.dpy, None, NULL); +#endif +} + // Update window width, size and etc. Called from Render.cpp void OpenGL_Update() { @@ -577,7 +587,9 @@ void OpenGL_Update() int height = rcWindow.bottom - rcWindow.top; // If we are rendering to a child window - if (EmuWindow::GetParentWnd() != 0 && (s_backbuffer_width != width || s_backbuffer_height != height) && width >= 4 && height >= 4) + if (EmuWindow::GetParentWnd() != 0 && + (s_backbuffer_width != width || s_backbuffer_height != height) && + width >= 4 && height >= 4) { ::MoveWindow(EmuWindow::GetWnd(), 0, 0, width, height, FALSE); s_backbuffer_width = width; @@ -586,7 +598,6 @@ void OpenGL_Update() #endif } - // Close backend void OpenGL_Shutdown() { @@ -599,27 +610,21 @@ void OpenGL_Shutdown() [GLWin.cocoaCtx clearDrawable]; [GLWin.cocoaCtx release]; #elif defined(_WIN32) - if (hRC) // Do We Have A Rendering Context? + if (hRC) { - if (!wglMakeCurrent(NULL,NULL)) // Are We Able To Release The DC And RC Contexts? - { - // [F|RES]: if this fails i dont see the message box and - // cant get out of the modal state so i disable it. - // This function fails only if i render to main window - // MessageBox(NULL,"Release Of DC And RC Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); - } + if (!wglMakeCurrent(NULL, NULL)) + NOTICE_LOG(VIDEO, "Could not release drawing context."); - if (!wglDeleteContext(hRC)) // Are We Able To Delete The RC? - { + if (!wglDeleteContext(hRC)) ERROR_LOG(VIDEO, "Release Rendering Context Failed."); - } - hRC = NULL; // Set RC To NULL + + hRC = NULL; } - if (hDC && !ReleaseDC(EmuWindow::GetWnd(), hDC)) // Are We Able To Release The DC + if (hDC && !ReleaseDC(EmuWindow::GetWnd(), hDC)) { ERROR_LOG(VIDEO, "Release Device Context Failed."); - hDC = NULL; // Set DC To NULL + hDC = NULL; } EmuWindow::Close(); #elif defined(HAVE_X11) && HAVE_X11 @@ -641,7 +646,8 @@ GLuint OpenGL_ReportGLError(const char *function, const char *file, int line) GLint err = glGetError(); if (err != GL_NO_ERROR) { - ERROR_LOG(VIDEO, "%s:%d: (%s) OpenGL error 0x%x - %s\n", file, line, function, err, gluErrorString(err)); + ERROR_LOG(VIDEO, "%s:%d: (%s) OpenGL error 0x%x - %s\n", + file, line, function, err, gluErrorString(err)); } return err; } @@ -667,15 +673,30 @@ bool OpenGL_ReportFBOError(const char *function, const char *file, int line) const char *error = "-"; switch (fbo_status) { - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: error = "INCOMPLETE_ATTACHMENT_EXT"; break; - case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: error = "INCOMPLETE_MISSING_ATTACHMENT_EXT"; break; - case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: error = "INCOMPLETE_DIMENSIONS_EXT"; break; - case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: error = "INCOMPLETE_FORMATS_EXT"; break; - case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: error = "INCOMPLETE_DRAW_BUFFER_EXT"; break; - case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: error = "INCOMPLETE_READ_BUFFER_EXT"; break; - case GL_FRAMEBUFFER_UNSUPPORTED_EXT: error = "UNSUPPORTED_EXT"; break; + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: + error = "INCOMPLETE_ATTACHMENT_EXT"; + break; + case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: + error = "INCOMPLETE_MISSING_ATTACHMENT_EXT"; + break; + case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: + error = "INCOMPLETE_DIMENSIONS_EXT"; + break; + case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: + error = "INCOMPLETE_FORMATS_EXT"; + break; + case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: + error = "INCOMPLETE_DRAW_BUFFER_EXT"; + break; + case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: + error = "INCOMPLETE_READ_BUFFER_EXT"; + break; + case GL_FRAMEBUFFER_UNSUPPORTED_EXT: + error = "UNSUPPORTED_EXT"; + break; } - ERROR_LOG(VIDEO, "%s:%d: (%s) OpenGL FBO error - %s\n", file, line, function, error); + ERROR_LOG(VIDEO, "%s:%d: (%s) OpenGL FBO error - %s\n", + file, line, function, error); return false; } return true; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.h b/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.h index c82edc0eb8..7fc635460f 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.h @@ -64,9 +64,8 @@ typedef struct { int screen; Window win; Window parent; - // dpy (mainly) used for glx stuff, evdpy for window events etc. - // used to keep the two threads from eating each others events - // evdpy is to be used by XEventThread only (when it is running) + // dpy used for glx stuff, evdpy for window events etc. + // evdpy is to be used by XEventThread only Display *dpy, *evdpy; XVisualInfo *vi; GLXContext ctx; @@ -88,6 +87,7 @@ bool OpenGL_Create(void *&); void OpenGL_Shutdown(); void OpenGL_Update(); bool OpenGL_MakeCurrent(); +bool OpenGL_ReleaseContext(); void OpenGL_SwapBuffers(); // Get status diff --git a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp index 6d0280db21..53c81ec032 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp @@ -176,14 +176,12 @@ bool VideoBackend::Initialize(void *&window_handle) OSD::AddMessage("Dolphin OpenGL Video Backend.", 5000); s_BackendInitialized = true; - return true; -} - -// This is called after Initialize() from the Core -// Run from the graphics thread -void VideoBackend::Video_Prepare() -{ - OpenGL_MakeCurrent(); + if (!OpenGL_MakeCurrent()) + { + ERROR_LOG(VIDEO, "Unable to connect to OpenGL context."); + OpenGL_Shutdown(); + return false; + } g_renderer = new Renderer; @@ -210,6 +208,22 @@ void VideoBackend::Video_Prepare() TextureConverter::Init(); DLCache::Init(); + if (!OpenGL_ReleaseContext()) + { + ERROR_LOG(VIDEO, "Unable to release OpenGL context."); + Shutdown(); + return false; + } + + return true; +} + +// This is called after Initialize() from the Core +// Run from the graphics thread +void VideoBackend::Video_Prepare() +{ + OpenGL_MakeCurrent(); + // Notify the core that the video backend is ready Core::Callback_CoreMessage(WM_USER_CREATE); }