If the DSP LLE can not find the needed ROM files exit the emulator without crashing the application. Also reimplement soren's revision 7195 in a way that works on linux and windows. (This makes it easier to clean up the video backend if the DSP emulator fails to initialize.)

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@7271 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Glenn Rice 2011-03-02 05:16:49 +00:00
parent 6073600084
commit 3af93e8cf3
12 changed files with 163 additions and 115 deletions

View File

@ -203,8 +203,6 @@ bool Init()
Host_SetWaitCursor(true); Host_SetWaitCursor(true);
Host_UpdateMainFrame(); // Disable any menus or buttons at boot Host_UpdateMainFrame(); // Disable any menus or buttons at boot
emuThreadGoing.Init();
g_aspect_wide = _CoreParameter.bWii; g_aspect_wide = _CoreParameter.bWii;
if (g_aspect_wide) if (g_aspect_wide)
{ {
@ -221,14 +219,19 @@ bool Init()
g_pWindowHandle = Host_GetRenderHandle(); g_pWindowHandle = Host_GetRenderHandle();
if (!g_video_backend->Initialize(g_pWindowHandle)) if (!g_video_backend->Initialize(g_pWindowHandle))
{ {
emuThreadGoing.Shutdown();
Host_SetWaitCursor(false); Host_SetWaitCursor(false);
return false; return false;
} }
HW::Init(); HW::Init();
DSP::GetDSPEmulator()->Initialize(g_pWindowHandle, if (!DSP::GetDSPEmulator()->Initialize(g_pWindowHandle,
_CoreParameter.bWii, _CoreParameter.bDSPThread); _CoreParameter.bWii, _CoreParameter.bDSPThread))
{
HW::Shutdown();
g_video_backend->Shutdown();
Host_SetWaitCursor(false);
return false;
}
Pad::Initialize(g_pWindowHandle); Pad::Initialize(g_pWindowHandle);
// Load and Init Wiimotes - only if we are booting in wii mode // Load and Init Wiimotes - only if we are booting in wii mode
if (g_CoreStartupParameter.bWii) if (g_CoreStartupParameter.bWii)
@ -245,6 +248,8 @@ bool Init()
// The hardware is initialized. // The hardware is initialized.
g_bHwInit = true; g_bHwInit = true;
emuThreadGoing.Init();
// Start the emu thread // Start the emu thread
g_EmuThread = std::thread(EmuThread); g_EmuThread = std::thread(EmuThread);

View File

@ -61,7 +61,7 @@ static bool LoadRom(const char *fname, int size_in_words, u16 *rom)
return true; 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; return false;
} }
@ -87,6 +87,14 @@ static bool VerifyRoms(const char *irom_filename, const char *coef_filename)
return true; 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 DSPCore_Init(const char *irom_filename, const char *coef_filename,
bool bUsingJIT) 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); memset(g_dsp.coef, 0, DSP_COEF_BYTE_SIZE);
// Try to load real ROM contents. // Try to load real ROM contents.
LoadRom(irom_filename, DSP_IROM_SIZE, g_dsp.irom); if (!LoadRom(irom_filename, DSP_IROM_SIZE, g_dsp.irom) ||
LoadRom(coef_filename, DSP_COEF_SIZE, g_dsp.coef); !LoadRom(coef_filename, DSP_COEF_SIZE, g_dsp.coef) ||
if (!VerifyRoms(irom_filename, coef_filename)) !VerifyRoms(irom_filename, coef_filename))
{
DSPCore_FreeMemoryPages();
return false; return false;
}
memset(&g_dsp.r,0,sizeof(g_dsp.r)); 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() void DSPCore_Shutdown()
{ {
if (core_state == DSPCORE_STOP)
return;
core_state = DSPCORE_STOP; core_state = DSPCORE_STOP;
if(dspjit) { if(dspjit) {
@ -170,10 +184,7 @@ void DSPCore_Shutdown()
dspjit = NULL; dspjit = NULL;
} }
step_event.Shutdown(); step_event.Shutdown();
FreeMemoryPages(g_dsp.irom, DSP_IROM_BYTE_SIZE); DSPCore_FreeMemoryPages();
FreeMemoryPages(g_dsp.iram, DSP_IRAM_BYTE_SIZE);
FreeMemoryPages(g_dsp.dram, DSP_DRAM_BYTE_SIZE);
FreeMemoryPages(g_dsp.coef, DSP_COEF_BYTE_SIZE);
} }
void DSPCore_Reset() void DSPCore_Reset()

View File

@ -28,7 +28,7 @@ public:
virtual bool IsLLE() = 0; 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 Shutdown() = 0;
virtual void DoState(PointerWrap &p) = 0; virtual void DoState(PointerWrap &p) = 0;

View File

@ -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_hWnd = hWnd;
m_bWii = bWii; m_bWii = bWii;
@ -65,6 +65,8 @@ void DSPHLE::Initialize(void *hWnd, bool bWii, bool bDSPThread)
m_InitMixer = false; m_InitMixer = false;
m_dspState.Reset(); m_dspState.Reset();
return true;
} }
void DSPHLE::DSP_StopSoundStream() void DSPHLE::DSP_StopSoundStream()

View File

@ -29,7 +29,7 @@ class DSPHLE : public DSPEmulator {
public: public:
DSPHLE(); DSPHLE();
virtual void Initialize(void *hWnd, bool bWii, bool bDSPThread); virtual bool Initialize(void *hWnd, bool bWii, bool bDSPThread);
virtual void Shutdown(); virtual void Shutdown();
virtual bool IsLLE() { return false; } virtual bool IsLLE() { return false; }

View File

@ -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_hWnd = hWnd;
m_bWii = bWii; m_bWii = bWii;
m_bDSPThread = bDSPThread; m_bDSPThread = bDSPThread;
m_InitMixer = false; m_InitMixer = false;
bool bCanWork = true;
std::string irom_file = File::GetSysDirectory() + GC_SYS_DIR DIR_SEP DSP_IROM; 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; std::string coef_file = File::GetSysDirectory() + GC_SYS_DIR DIR_SEP DSP_COEF;
if (!File::Exists(irom_file)) 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)) if (!File::Exists(coef_file))
coef_file = File::GetUserPath(D_GCUSER_IDX) + DIR_SEP DSP_COEF; coef_file = File::GetUserPath(D_GCUSER_IDX) + DSP_COEF;
bCanWork = DSPCore_Init(irom_file.c_str(), coef_file.c_str(), AudioCommon::UseJIT()); if (!DSPCore_Init(irom_file.c_str(), coef_file.c_str(), AudioCommon::UseJIT()))
return false;
g_dsp.cpu_ram = Memory::GetPointer(0); g_dsp.cpu_ram = Memory::GetPointer(0);
DSPCore_Reset(); DSPCore_Reset();
if (!bCanWork)
{
DSPCore_Shutdown();
// No way to shutdown Core from here? Hardcore shutdown!
exit(EXIT_FAILURE);
return;
}
m_bIsRunning = true; m_bIsRunning = true;
InitInstructionTable(); InitInstructionTable();
@ -134,6 +127,8 @@ void DSPLLE::Initialize(void *hWnd, bool bWii, bool bDSPThread)
m_hDSPThread = std::thread(dsp_thread, this); m_hDSPThread = std::thread(dsp_thread, this);
Host_RefreshDSPDebuggerWindow(); Host_RefreshDSPDebuggerWindow();
return true;
} }
void DSPLLE::DSP_StopSoundStream() void DSPLLE::DSP_StopSoundStream()

View File

@ -27,7 +27,7 @@ class DSPLLE : public DSPEmulator {
public: public:
DSPLLE(); DSPLLE();
virtual void Initialize(void *hWnd, bool bWii, bool bDSPThread); virtual bool Initialize(void *hWnd, bool bWii, bool bDSPThread);
virtual void Shutdown(); virtual void Shutdown();
virtual bool IsLLE() { return true; } virtual bool IsLLE() { return true; }

View File

@ -174,11 +174,6 @@ bool VideoBackend::Initialize(void *&window_handle)
OSD::AddMessage("Dolphin Direct3D11 Video Backend.", 5000); OSD::AddMessage("Dolphin Direct3D11 Video Backend.", 5000);
s_BackendInitialized = true; s_BackendInitialized = true;
return true;
}
void VideoBackend::Video_Prepare()
{
// Better be safe... // Better be safe...
s_efbAccessRequested = FALSE; s_efbAccessRequested = FALSE;
s_FifoShuttingDown = FALSE; s_FifoShuttingDown = FALSE;
@ -203,6 +198,11 @@ void VideoBackend::Video_Prepare()
PixelEngine::Init(); PixelEngine::Init();
DLCache::Init(); DLCache::Init();
return true;
}
void VideoBackend::Video_Prepare()
{
// Tell the host that the window is ready // Tell the host that the window is ready
Core::Callback_CoreMessage(WM_USER_CREATE); Core::Callback_CoreMessage(WM_USER_CREATE);
} }

View File

@ -159,11 +159,6 @@ bool VideoBackend::Initialize(void *&window_handle)
OSD::AddMessage("Dolphin Direct3D9 Video Backend.", 5000); OSD::AddMessage("Dolphin Direct3D9 Video Backend.", 5000);
s_BackendInitialized = true; s_BackendInitialized = true;
return true;
}
void VideoBackend::Video_Prepare()
{
// Better be safe... // Better be safe...
s_efbAccessRequested = FALSE; s_efbAccessRequested = FALSE;
s_FifoShuttingDown = FALSE; s_FifoShuttingDown = FALSE;
@ -184,6 +179,11 @@ void VideoBackend::Video_Prepare()
PixelEngine::Init(); PixelEngine::Init();
DLCache::Init(); DLCache::Init();
return true;
}
void VideoBackend::Video_Prepare()
{
// Notify the core that the video backend is ready // Notify the core that the video backend is ready
Core::Callback_CoreMessage(WM_USER_CREATE); Core::Callback_CoreMessage(WM_USER_CREATE);
} }

View File

@ -117,16 +117,10 @@ void VideoBackend::UpdateFPSDisplay(const char *text)
#if defined(HAVE_X11) && HAVE_X11 #if defined(HAVE_X11) && HAVE_X11
void XEventThread(); void XEventThread();
void CreateXWindow (void) void CreateXWindow(void)
{ {
Atom wmProtocols[1]; 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 // Setup window attributes
GLWin.attr.colormap = XCreateColormap(GLWin.evdpy, GLWin.attr.colormap = XCreateColormap(GLWin.evdpy,
GLWin.parent, GLWin.vi->visual, AllocNone); GLWin.parent, GLWin.vi->visual, AllocNone);
@ -136,7 +130,8 @@ void CreateXWindow (void)
// Create the window // Create the window
GLWin.win = XCreateWindow(GLWin.evdpy, GLWin.parent, 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); CWBorderPixel | CWBackPixel | CWColormap | CWEventMask, &GLWin.attr);
wmProtocols[0] = XInternAtom(GLWin.evdpy, "WM_DELETE_WINDOW", True); wmProtocols[0] = XInternAtom(GLWin.evdpy, "WM_DELETE_WINDOW", True);
XSetWMProtocols(GLWin.evdpy, GLWin.win, wmProtocols, 1); XSetWMProtocols(GLWin.evdpy, GLWin.win, wmProtocols, 1);
@ -151,7 +146,8 @@ void DestroyXWindow(void)
{ {
XUnmapWindow(GLWin.dpy, GLWin.win); XUnmapWindow(GLWin.dpy, GLWin.win);
GLWin.win = 0; GLWin.win = 0;
GLWin.xEventThread.join(); if (GLWin.xEventThread.joinable())
GLWin.xEventThread.join();
XFreeColormap(GLWin.evdpy, GLWin.attr.colormap); XFreeColormap(GLWin.evdpy, GLWin.attr.colormap);
} }
@ -298,11 +294,14 @@ void XEventThread()
s_backbuffer_height = GLWin.height; s_backbuffer_height = GLWin.height;
break; break;
case ClientMessage: 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); Core::Callback_CoreMessage(WM_USER_STOP);
if ((unsigned long) event.xclient.data.l[0] == XInternAtom(GLWin.evdpy, "RESIZE", False)) if ((unsigned long) event.xclient.data.l[0] ==
XMoveResizeWindow(GLWin.evdpy, GLWin.win, event.xclient.data.l[1], XInternAtom(GLWin.evdpy, "RESIZE", False))
event.xclient.data.l[2], event.xclient.data.l[3], event.xclient.data.l[4]); 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; break;
default: default:
break; break;
@ -385,26 +384,26 @@ bool OpenGL_Create(void *&window_handle)
// Show the window // Show the window
EmuWindow::Show(); 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 sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
1, // Version Number 1, // Version Number
PFD_DRAW_TO_WINDOW | // Format Must Support Window PFD_DRAW_TO_WINDOW | // Format Must Support Window
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
PFD_DOUBLEBUFFER, // Must Support Double Buffering PFD_DOUBLEBUFFER, // Must Support Double Buffering
PFD_TYPE_RGBA, // Request An RGBA Format PFD_TYPE_RGBA, // Request An RGBA Format
32, // Select Our Color Depth 32, // Select Our Color Depth
0, 0, 0, 0, 0, 0, // Color Bits Ignored 0, 0, 0, 0, 0, 0, // Color Bits Ignored
0, // 8bit Alpha Buffer 0, // 8bit Alpha Buffer
0, // Shift Bit Ignored 0, // Shift Bit Ignored
0, // No Accumulation Buffer 0, // No Accumulation Buffer
0, 0, 0, 0, // Accumulation Bits Ignored 0, 0, 0, 0, // Accumulation Bits Ignored
24, // 24Bit Z-Buffer (Depth Buffer) 24, // 24Bit Z-Buffer (Depth Buffer)
8, // 8bit Stencil Buffer 8, // 8bit Stencil Buffer
0, // No Auxiliary Buffer 0, // No Auxiliary Buffer
PFD_MAIN_PLANE, // Main Drawing Layer PFD_MAIN_PLANE, // Main Drawing Layer
0, // Reserved 0, // Reserved
0, 0, 0 // Layer Masks Ignored 0, 0, 0 // Layer Masks Ignored
}; };
GLuint PixelFormat; // Holds The Results After Searching For A Match 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."); PanicAlert("(1) Can't create an OpenGL Device context. Fail.");
return false; return false;
} }
if (!(PixelFormat = ChoosePixelFormat(hDC,&pfd))) { if (!(PixelFormat = ChoosePixelFormat(hDC, &pfd))) {
PanicAlert("(2) Can't find a suitable PixelFormat."); PanicAlert("(2) Can't find a suitable PixelFormat.");
return false; return false;
} }
@ -475,7 +474,7 @@ bool OpenGL_Create(void *&window_handle)
GLWin.vi = glXChooseVisual(GLWin.dpy, GLWin.screen, attrListSgl); GLWin.vi = glXChooseVisual(GLWin.dpy, GLWin.screen, attrListSgl);
if (GLWin.vi != NULL) if (GLWin.vi != NULL)
{ {
ERROR_LOG(VIDEO, "Only Singlebuffered Visual!"); ERROR_LOG(VIDEO, "Only single buffered visual!");
} }
else else
{ {
@ -488,13 +487,13 @@ bool OpenGL_Create(void *&window_handle)
} }
} }
else else
NOTICE_LOG(VIDEO, "Got Doublebuffered Visual!"); NOTICE_LOG(VIDEO, "Got double buffered visual!");
// Create a GLX context. // Create a GLX context.
GLWin.ctx = glXCreateContext(GLWin.dpy, GLWin.vi, 0, GL_TRUE); GLWin.ctx = glXCreateContext(GLWin.dpy, GLWin.vi, 0, GL_TRUE);
if (!GLWin.ctx) if (!GLWin.ctx)
{ {
PanicAlert("Couldn't Create GLX context.Quit"); PanicAlert("Unable to create GLX context.");
return false; return false;
} }
@ -517,17 +516,28 @@ bool OpenGL_MakeCurrent()
#elif defined(__APPLE__) #elif defined(__APPLE__)
[GLWin.cocoaCtx makeCurrentContext]; [GLWin.cocoaCtx makeCurrentContext];
#elif defined(_WIN32) #elif defined(_WIN32)
return wglMakeCurrent(hDC,hRC) ? true : false; return wglMakeCurrent(hDC, hRC) ? true : false;
#elif defined(HAVE_X11) && HAVE_X11 #elif defined(HAVE_X11) && HAVE_X11
#if defined(HAVE_WX) && (HAVE_WX) #if defined(HAVE_WX) && (HAVE_WX)
Core::Callback_VideoGetWindowSize(GLWin.x, GLWin.y, (int&)GLWin.width, (int&)GLWin.height); Core::Callback_VideoGetWindowSize(GLWin.x, GLWin.y,
XMoveResizeWindow(GLWin.dpy, GLWin.win, GLWin.x, GLWin.y, GLWin.width, GLWin.height); (int&)GLWin.width, (int&)GLWin.height);
XMoveResizeWindow(GLWin.dpy, GLWin.win, GLWin.x, GLWin.y,
GLWin.width, GLWin.height);
#endif #endif
return glXMakeCurrent(GLWin.dpy, GLWin.win, GLWin.ctx); return glXMakeCurrent(GLWin.dpy, GLWin.win, GLWin.ctx);
#endif #endif
return true; 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 // Update window width, size and etc. Called from Render.cpp
void OpenGL_Update() void OpenGL_Update()
{ {
@ -577,7 +587,9 @@ void OpenGL_Update()
int height = rcWindow.bottom - rcWindow.top; int height = rcWindow.bottom - rcWindow.top;
// If we are rendering to a child window // 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); ::MoveWindow(EmuWindow::GetWnd(), 0, 0, width, height, FALSE);
s_backbuffer_width = width; s_backbuffer_width = width;
@ -586,7 +598,6 @@ void OpenGL_Update()
#endif #endif
} }
// Close backend // Close backend
void OpenGL_Shutdown() void OpenGL_Shutdown()
{ {
@ -599,27 +610,21 @@ void OpenGL_Shutdown()
[GLWin.cocoaCtx clearDrawable]; [GLWin.cocoaCtx clearDrawable];
[GLWin.cocoaCtx release]; [GLWin.cocoaCtx release];
#elif defined(_WIN32) #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? if (!wglMakeCurrent(NULL, NULL))
{ NOTICE_LOG(VIDEO, "Could not release drawing context.");
// [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 (!wglDeleteContext(hRC)) // Are We Able To Delete The RC? if (!wglDeleteContext(hRC))
{
ERROR_LOG(VIDEO, "Release Rendering Context Failed."); 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."); ERROR_LOG(VIDEO, "Release Device Context Failed.");
hDC = NULL; // Set DC To NULL hDC = NULL;
} }
EmuWindow::Close(); EmuWindow::Close();
#elif defined(HAVE_X11) && HAVE_X11 #elif defined(HAVE_X11) && HAVE_X11
@ -641,7 +646,8 @@ GLuint OpenGL_ReportGLError(const char *function, const char *file, int line)
GLint err = glGetError(); GLint err = glGetError();
if (err != GL_NO_ERROR) 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; return err;
} }
@ -667,15 +673,30 @@ bool OpenGL_ReportFBOError(const char *function, const char *file, int line)
const char *error = "-"; const char *error = "-";
switch (fbo_status) switch (fbo_status)
{ {
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: error = "INCOMPLETE_ATTACHMENT_EXT"; break; case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: error = "INCOMPLETE_MISSING_ATTACHMENT_EXT"; break; error = "INCOMPLETE_ATTACHMENT_EXT";
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: error = "INCOMPLETE_DIMENSIONS_EXT"; break; break;
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: error = "INCOMPLETE_FORMATS_EXT"; break; case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: error = "INCOMPLETE_DRAW_BUFFER_EXT"; break; error = "INCOMPLETE_MISSING_ATTACHMENT_EXT";
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: error = "INCOMPLETE_READ_BUFFER_EXT"; break; break;
case GL_FRAMEBUFFER_UNSUPPORTED_EXT: error = "UNSUPPORTED_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 false;
} }
return true; return true;

View File

@ -64,9 +64,8 @@ typedef struct {
int screen; int screen;
Window win; Window win;
Window parent; Window parent;
// dpy (mainly) used for glx stuff, evdpy for window events etc. // dpy 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
// evdpy is to be used by XEventThread only (when it is running)
Display *dpy, *evdpy; Display *dpy, *evdpy;
XVisualInfo *vi; XVisualInfo *vi;
GLXContext ctx; GLXContext ctx;
@ -88,6 +87,7 @@ bool OpenGL_Create(void *&);
void OpenGL_Shutdown(); void OpenGL_Shutdown();
void OpenGL_Update(); void OpenGL_Update();
bool OpenGL_MakeCurrent(); bool OpenGL_MakeCurrent();
bool OpenGL_ReleaseContext();
void OpenGL_SwapBuffers(); void OpenGL_SwapBuffers();
// Get status // Get status

View File

@ -176,14 +176,12 @@ bool VideoBackend::Initialize(void *&window_handle)
OSD::AddMessage("Dolphin OpenGL Video Backend.", 5000); OSD::AddMessage("Dolphin OpenGL Video Backend.", 5000);
s_BackendInitialized = true; s_BackendInitialized = true;
return true; if (!OpenGL_MakeCurrent())
} {
ERROR_LOG(VIDEO, "Unable to connect to OpenGL context.");
// This is called after Initialize() from the Core OpenGL_Shutdown();
// Run from the graphics thread return false;
void VideoBackend::Video_Prepare() }
{
OpenGL_MakeCurrent();
g_renderer = new Renderer; g_renderer = new Renderer;
@ -210,6 +208,22 @@ void VideoBackend::Video_Prepare()
TextureConverter::Init(); TextureConverter::Init();
DLCache::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 // Notify the core that the video backend is ready
Core::Callback_CoreMessage(WM_USER_CREATE); Core::Callback_CoreMessage(WM_USER_CREATE);
} }