GLInterface: Destroy GLWin

Everything is now safely tucked inside each individual GLInterface.
This commit is contained in:
Jasper St. Pierre 2014-08-09 09:49:45 -04:00
parent 63f1a16969
commit 2d974b6086
15 changed files with 141 additions and 147 deletions

View File

@ -4,8 +4,10 @@
#include <unordered_map>
#include "Common/FileUtil.h"
#include "Common/IniFile.h"
#include "Common/Thread.h"
#include "DolphinWX/Android/ButtonManager.h"
#include "DolphinWX/GLInterface/GLInterface.h"
namespace ButtonManager
{

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x64">
@ -100,7 +100,6 @@
<ClCompile Include="WxUtils.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="GLInterface\GLInterface.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="AboutDolphin.h" />
<ClInclude Include="ARCodeAddEdit.h" />

View File

@ -282,7 +282,6 @@
<ClInclude Include="WiimoteConfigDiag.h">
<Filter>GUI</Filter>
</ClInclude>
<ClInclude Include="GLInterface\GLInterface.h" />
<ClInclude Include="SoftwareVideoConfigDialog.h">
<Filter>GUI\Video</Filter>
</ClInclude>

View File

@ -4,14 +4,15 @@
#include <wx/panel.h>
#include "DolphinWX/GLInterface/GLInterface.h"
#include "DolphinWX/GLInterface/AGL.h"
#include "VideoCommon/RenderBase.h"
#include "VideoCommon/VertexShaderManager.h"
#include "VideoCommon/VideoConfig.h"
void cInterfaceAGL::Swap()
{
[GLWin.cocoaCtx flushBuffer];
[cocoaCtx flushBuffer];
}
// Create rendering window.
@ -19,13 +20,13 @@ void cInterfaceAGL::Swap()
bool cInterfaceAGL::Create(void *window_handle)
{
// FIXME: Get rid of the explicit use of wxPanel here. This shouldn't be necessary.
GLWin.cocoaWin = reinterpret_cast<NSView*>(((wxPanel*)window_handle)->GetHandle());
NSSize size = [GLWin.cocoaWin frame].size;
cocoaWin = reinterpret_cast<NSView*>(((wxPanel*)window_handle)->GetHandle());
NSSize size = [cocoaWin frame].size;
// Enable high-resolution display support.
[GLWin.cocoaWin setWantsBestResolutionOpenGLSurface:YES];
[cocoaWin setWantsBestResolutionOpenGLSurface:YES];
NSWindow *window = [GLWin.cocoaWin window];
NSWindow *window = [cocoaWin window];
float scale = [window backingScaleFactor];
size.width *= scale;
@ -43,21 +44,21 @@ bool cInterfaceAGL::Create(void *window_handle)
return false;
}
GLWin.cocoaCtx = [[NSOpenGLContext alloc]
cocoaCtx = [[NSOpenGLContext alloc]
initWithFormat: fmt shareContext: nil];
[fmt release];
if (GLWin.cocoaCtx == nil) {
if (cocoaCtx == nil) {
ERROR_LOG(VIDEO, "failed to create context");
return false;
}
if (GLWin.cocoaWin == nil) {
if (cocoaWin == nil) {
ERROR_LOG(VIDEO, "failed to create window");
return false;
}
[window makeFirstResponder:GLWin.cocoaWin];
[GLWin.cocoaCtx setView: GLWin.cocoaWin];
[window makeFirstResponder:cocoaWin];
[cocoaCtx setView: cocoaWin];
[window makeKeyAndOrderFront: nil];
return true;
@ -65,7 +66,7 @@ bool cInterfaceAGL::Create(void *window_handle)
bool cInterfaceAGL::MakeCurrent()
{
[GLWin.cocoaCtx makeCurrentContext];
[cocoaCtx makeCurrentContext];
return true;
}
@ -79,15 +80,15 @@ bool cInterfaceAGL::ClearCurrent()
// Close backend
void cInterfaceAGL::Shutdown()
{
[GLWin.cocoaCtx clearDrawable];
[GLWin.cocoaCtx release];
GLWin.cocoaCtx = nil;
[cocoaCtx clearDrawable];
[cocoaCtx release];
cocoaCtx = nil;
}
void cInterfaceAGL::Update()
{
NSWindow *window = [GLWin.cocoaWin window];
NSSize size = [GLWin.cocoaWin frame].size;
NSWindow *window = [cocoaWin window];
NSSize size = [cocoaWin frame].size;
float scale = [window backingScaleFactor];
size.width *= scale;
@ -100,11 +101,11 @@ void cInterfaceAGL::Update()
s_backbuffer_width = size.width;
s_backbuffer_height = size.height;
[GLWin.cocoaCtx update];
[cocoaCtx update];
}
void cInterfaceAGL::SwapInterval(int interval)
{
[GLWin.cocoaCtx setValues:(GLint *)&interval forParameter:NSOpenGLCPSwapInterval];
[cocoaCtx setValues:(GLint *)&interval forParameter:NSOpenGLCPSwapInterval];
}

View File

@ -12,6 +12,9 @@
class cInterfaceAGL : public cInterfaceBase
{
private:
NSView *cocoaWin;
NSOpenGLContext *cocoaCtx;
public:
void Swap();
bool Create(void *window_handle);

View File

@ -3,17 +3,18 @@
// Refer to the license.txt file included.
#include "Core/Host.h"
#include "DolphinWX/GLInterface/GLInterface.h"
#include "DolphinWX/GLInterface/EGL.h"
#include "VideoBackends/OGL/GLInterfaceBase.h"
#include "VideoCommon/RenderBase.h"
// Show the current FPS
void cInterfaceEGL::Swap()
{
eglSwapBuffers(GLWin.egl_dpy, GLWin.egl_surf);
eglSwapBuffers(egl_dpy, egl_surf);
}
void cInterfaceEGL::SwapInterval(int Interval)
{
eglSwapInterval(GLWin.egl_dpy, Interval);
eglSwapInterval(egl_dpy, Interval);
}
void* cInterfaceEGL::GetFuncAddress(const std::string& name)
@ -39,7 +40,7 @@ void cInterfaceEGL::DetectMode()
EGL_NONE };
// Get how many configs there are
if (!eglChooseConfig( GLWin.egl_dpy, attribs, nullptr, 0, &num_configs))
if (!eglChooseConfig( egl_dpy, attribs, nullptr, 0, &num_configs))
{
INFO_LOG(VIDEO, "Error: couldn't get an EGL visual config\n");
goto err_exit;
@ -48,7 +49,7 @@ void cInterfaceEGL::DetectMode()
config = new EGLConfig[num_configs];
// Get all the configurations
if (!eglChooseConfig(GLWin.egl_dpy, attribs, config, num_configs, &num_configs))
if (!eglChooseConfig(egl_dpy, attribs, config, num_configs, &num_configs))
{
INFO_LOG(VIDEO, "Error: couldn't get an EGL visual config\n");
goto err_exit;
@ -58,7 +59,7 @@ void cInterfaceEGL::DetectMode()
{
EGLint attribVal;
bool ret;
ret = eglGetConfigAttrib(GLWin.egl_dpy, config[i], EGL_RENDERABLE_TYPE, &attribVal);
ret = eglGetConfigAttrib(egl_dpy, config[i], EGL_RENDERABLE_TYPE, &attribVal);
if (ret)
{
if (attribVal & EGL_OPENGL_BIT)
@ -89,15 +90,15 @@ bool cInterfaceEGL::Create(void *window_handle)
const char *s;
EGLint egl_major, egl_minor;
GLWin.egl_dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
egl_dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (!GLWin.egl_dpy)
if (!egl_dpy)
{
INFO_LOG(VIDEO, "Error: eglGetDisplay() failed\n");
return false;
}
if (!eglInitialize(GLWin.egl_dpy, &egl_major, &egl_minor))
if (!eglInitialize(egl_dpy, &egl_major, &egl_minor))
{
INFO_LOG(VIDEO, "Error: eglInitialize() failed\n");
return false;
@ -142,7 +143,7 @@ bool cInterfaceEGL::Create(void *window_handle)
break;
}
if (!eglChooseConfig( GLWin.egl_dpy, attribs, &config, 1, &num_configs))
if (!eglChooseConfig( egl_dpy, attribs, &config, 1, &num_configs))
{
INFO_LOG(VIDEO, "Error: couldn't get an EGL visual config\n");
exit(1);
@ -153,38 +154,36 @@ bool cInterfaceEGL::Create(void *window_handle)
else
eglBindAPI(EGL_OPENGL_ES_API);
EGLNativeWindowType native_window = window_handle;
EGLNativeWindowType native_window = (EGLNativeWindowType) window_handle;
EGLint format;
eglGetConfigAttrib(GLWin.egl_dpy, config, EGL_NATIVE_VISUAL_ID, &format);
eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &format);
ANativeWindow_setBuffersGeometry(native_window, 0, 0, format);
int none, width, height;
Host_GetRenderWindowSize(none, none, width, height);
GLWin.width = width;
GLWin.height = height;
GLInterface->SetBackBufferDimensions(width, height);
s = eglQueryString(GLWin.egl_dpy, EGL_VERSION);
s = eglQueryString(egl_dpy, EGL_VERSION);
INFO_LOG(VIDEO, "EGL_VERSION = %s\n", s);
s = eglQueryString(GLWin.egl_dpy, EGL_VENDOR);
s = eglQueryString(egl_dpy, EGL_VENDOR);
INFO_LOG(VIDEO, "EGL_VENDOR = %s\n", s);
s = eglQueryString(GLWin.egl_dpy, EGL_EXTENSIONS);
s = eglQueryString(egl_dpy, EGL_EXTENSIONS);
INFO_LOG(VIDEO, "EGL_EXTENSIONS = %s\n", s);
s = eglQueryString(GLWin.egl_dpy, EGL_CLIENT_APIS);
s = eglQueryString(egl_dpy, EGL_CLIENT_APIS);
INFO_LOG(VIDEO, "EGL_CLIENT_APIS = %s\n", s);
GLWin.egl_ctx = eglCreateContext(GLWin.egl_dpy, config, EGL_NO_CONTEXT, ctx_attribs );
if (!GLWin.egl_ctx)
egl_ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, ctx_attribs );
if (!egl_ctx)
{
INFO_LOG(VIDEO, "Error: eglCreateContext failed\n");
exit(1);
}
GLWin.egl_surf = eglCreateWindowSurface(GLWin.egl_dpy, config, native_window, nullptr);
if (!GLWin.egl_surf)
egl_surf = eglCreateWindowSurface(egl_dpy, config, native_window, nullptr);
if (!egl_surf)
{
INFO_LOG(VIDEO, "Error: eglCreateWindowSurface failed\n");
exit(1);
@ -195,22 +194,22 @@ bool cInterfaceEGL::Create(void *window_handle)
bool cInterfaceEGL::MakeCurrent()
{
return eglMakeCurrent(GLWin.egl_dpy, GLWin.egl_surf, GLWin.egl_surf, GLWin.egl_ctx);
return eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx);
}
// Close backend
void cInterfaceEGL::Shutdown()
{
if (GLWin.egl_ctx && !eglMakeCurrent(GLWin.egl_dpy, GLWin.egl_surf, GLWin.egl_surf, GLWin.egl_ctx))
if (egl_ctx && !eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx))
NOTICE_LOG(VIDEO, "Could not release drawing context.");
if (GLWin.egl_ctx)
if (egl_ctx)
{
eglMakeCurrent(GLWin.egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (!eglDestroyContext(GLWin.egl_dpy, GLWin.egl_ctx))
eglMakeCurrent(egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (!eglDestroyContext(egl_dpy, egl_ctx))
NOTICE_LOG(VIDEO, "Could not destroy drawing context.");
if (!eglDestroySurface(GLWin.egl_dpy, GLWin.egl_surf))
if (!eglDestroySurface(egl_dpy, egl_surf))
NOTICE_LOG(VIDEO, "Could not destroy window surface.");
if (!eglTerminate(GLWin.egl_dpy))
if (!eglTerminate(egl_dpy))
NOTICE_LOG(VIDEO, "Could not destroy display connection.");
GLWin.egl_ctx = nullptr;
egl_ctx = nullptr;
}
}

View File

@ -14,6 +14,9 @@ class cInterfaceEGL : public cInterfaceBase
{
private:
void DetectMode();
EGLSurface egl_surf;
EGLContext egl_ctx;
EGLDisplay egl_dpy;
public:
void SwapInterval(int Interval);
void Swap();

View File

@ -2,10 +2,19 @@
// Licensed under GPLv2
// Refer to the license.txt file included.
#include "DolphinWX/GLInterface/GLInterface.h"
#include "VideoBackends/OGL/GLInterfaceBase.h"
GLWindow GLWin;
#if USE_EGL
#include "DolphinWX/GLInterface/EGL.h"
#elif defined(__APPLE__)
#include "DolphinWX/GLInterface/AGL.h"
#elif defined(_WIN32)
#include "DolphinWX/GLInterface/WGL.h"
#elif HAVE_X11
#include "DolphinWX/GLInterface/GLX.h"
#else
#error Platform doesnt have a GLInterface
#endif
cInterfaceBase* HostGL_CreateGLInterface()
{

View File

@ -1,42 +0,0 @@
// Copyright 2013 Dolphin Emulator Project
// Licensed under GPLv2
// Refer to the license.txt file included.
#pragma once
#include "Common/Thread.h"
#if USE_EGL
#include "DolphinWX/GLInterface/EGL.h"
#elif defined(__APPLE__)
#include "DolphinWX/GLInterface/AGL.h"
#elif defined(_WIN32)
#include "DolphinWX/GLInterface/WGL.h"
#elif HAVE_X11
#include "DolphinWX/GLInterface/GLX.h"
#include <GL/glx.h>
#else
#error Platform doesnt have a GLInterface
#endif
typedef struct {
#if USE_EGL
EGLSurface egl_surf;
EGLContext egl_ctx;
EGLDisplay egl_dpy;
#elif defined(__APPLE__)
NSView *cocoaWin;
NSOpenGLContext *cocoaCtx;
#elif HAVE_X11
GLXContext ctx;
int screen;
Window win;
Window parent;
Display *dpy;
XVisualInfo *vi;
XSetWindowAttributes attr;
std::thread xEventThread;
#endif
} GLWindow;
extern GLWindow GLWin;

View File

@ -4,7 +4,7 @@
#include <string>
#include "DolphinWX/GLInterface/GLInterface.h"
#include "DolphinWX/GLInterface/GLX.h"
#include "VideoCommon/RenderBase.h"
#include "VideoCommon/VideoConfig.h"
@ -26,7 +26,7 @@ void* cInterfaceGLX::GetFuncAddress(const std::string& name)
void cInterfaceGLX::Swap()
{
glXSwapBuffers(GLWin.dpy, GLWin.win);
glXSwapBuffers(dpy, win);
}
// Create rendering window.
@ -58,26 +58,25 @@ bool cInterfaceGLX::Create(void *window_handle)
GLX_DOUBLEBUFFER,
None };
GLWin.dpy = XOpenDisplay(nullptr);
GLWin.parent = (Window)window_handle;
GLWin.screen = DefaultScreen(GLWin.dpy);
dpy = XOpenDisplay(nullptr);
int screen = DefaultScreen(dpy);
glXQueryVersion(GLWin.dpy, &glxMajorVersion, &glxMinorVersion);
glXQueryVersion(dpy, &glxMajorVersion, &glxMinorVersion);
NOTICE_LOG(VIDEO, "glX-Version %d.%d", glxMajorVersion, glxMinorVersion);
// Get an appropriate visual
GLWin.vi = glXChooseVisual(GLWin.dpy, GLWin.screen, attrListDbl);
if (GLWin.vi == nullptr)
vi = glXChooseVisual(dpy, screen, attrListDbl);
if (vi == nullptr)
{
GLWin.vi = glXChooseVisual(GLWin.dpy, GLWin.screen, attrListSgl);
if (GLWin.vi != nullptr)
vi = glXChooseVisual(dpy, screen, attrListSgl);
if (vi != nullptr)
{
ERROR_LOG(VIDEO, "Only single buffered visual!");
}
else
{
GLWin.vi = glXChooseVisual(GLWin.dpy, GLWin.screen, attrListDefault);
if (GLWin.vi == nullptr)
vi = glXChooseVisual(dpy, screen, attrListDefault);
if (vi == nullptr)
{
ERROR_LOG(VIDEO, "Could not choose visual (glXChooseVisual)");
return false;
@ -88,20 +87,23 @@ bool cInterfaceGLX::Create(void *window_handle)
NOTICE_LOG(VIDEO, "Got double buffered visual!");
// Create a GLX context.
GLWin.ctx = glXCreateContext(GLWin.dpy, GLWin.vi, nullptr, GL_TRUE);
if (!GLWin.ctx)
ctx = glXCreateContext(dpy, vi, nullptr, GL_TRUE);
if (!ctx)
{
PanicAlert("Unable to create GLX context.");
return false;
}
XWindow.CreateXWindow();
XWindow.Initialize(dpy);
Window parent = (Window)window_handle;
win = XWindow.CreateXWindow(parent, vi);
return true;
}
bool cInterfaceGLX::MakeCurrent()
{
bool success = glXMakeCurrent(GLWin.dpy, GLWin.win, GLWin.ctx);
bool success = glXMakeCurrent(dpy, win, ctx);
if (success)
{
// load this function based on the current bound context
@ -112,7 +114,7 @@ bool cInterfaceGLX::MakeCurrent()
bool cInterfaceGLX::ClearCurrent()
{
return glXMakeCurrent(GLWin.dpy, None, nullptr);
return glXMakeCurrent(dpy, None, nullptr);
}
@ -120,11 +122,11 @@ bool cInterfaceGLX::ClearCurrent()
void cInterfaceGLX::Shutdown()
{
XWindow.DestroyXWindow();
if (GLWin.ctx)
if (ctx)
{
glXDestroyContext(GLWin.dpy, GLWin.ctx);
XCloseDisplay(GLWin.dpy);
GLWin.ctx = nullptr;
glXDestroyContext(dpy, ctx);
XCloseDisplay(dpy);
ctx = nullptr;
}
}

View File

@ -5,6 +5,7 @@
#pragma once
#include <string>
#include <GL/glx.h>
#include "DolphinWX/GLInterface/X11_Util.h"
#include "VideoBackends/OGL/GLInterfaceBase.h"
@ -13,6 +14,10 @@ class cInterfaceGLX : public cInterfaceBase
{
private:
cX11Window XWindow;
Display *dpy;
Window win;
GLXContext ctx;
XVisualInfo *vi;
public:
friend class cX11Window;
void SwapInterval(int Interval) override;

View File

@ -6,7 +6,7 @@
#include "Core/Host.h"
#include "DolphinWX/GLInterface/GLInterface.h"
#include "DolphinWX/GLInterface/WGL.h"
#include "VideoCommon/RenderBase.h"
#include "VideoCommon/VertexShaderManager.h"

View File

@ -2,50 +2,61 @@
// Licensed under GPLv2
// Refer to the license.txt file included.
#include "Common/Thread.h"
#include "Core/Host.h"
#include "DolphinWX/GLInterface/GLInterface.h"
#include "DolphinWX/GLInterface/X11_Util.h"
#include "VideoBackends/OGL/GLInterfaceBase.h"
#include "VideoCommon/VideoConfig.h"
void cX11Window::CreateXWindow(void)
void cX11Window::Initialize(Display *_dpy)
{
dpy = _dpy;
}
Window cX11Window::CreateXWindow(Window parent, XVisualInfo *vi)
{
XSetWindowAttributes attr;
colormap = XCreateColormap(dpy, parent, vi->visual, AllocNone);
// Setup window attributes
GLWin.attr.colormap = XCreateColormap(GLWin.dpy,
GLWin.parent, GLWin.vi->visual, AllocNone);
GLWin.attr.background_pixel = BlackPixel(GLWin.dpy, GLWin.screen);
GLWin.attr.border_pixel = 0;
attr.colormap = colormap;
attr.background_pixel = BlackPixel(dpy, 0);
attr.border_pixel = 0;
// Create the window
GLWin.win = XCreateWindow(GLWin.dpy, GLWin.parent,
0, 0, 1, 1, 0,
GLWin.vi->depth, InputOutput, GLWin.vi->visual,
CWBorderPixel | CWBackPixel | CWColormap, &GLWin.attr);
XSelectInput(GLWin.dpy, GLWin.parent, StructureNotifyMask);
XMapWindow(GLWin.dpy, GLWin.win);
XSync(GLWin.dpy, True);
win = XCreateWindow(dpy, parent,
0, 0, 1, 1, 0,
vi->depth, InputOutput, vi->visual,
CWBorderPixel | CWBackPixel | CWColormap, &attr);
XSelectInput(dpy, parent, StructureNotifyMask);
XMapWindow(dpy, win);
XSync(dpy, True);
GLWin.xEventThread = std::thread(&cX11Window::XEventThread, this);
xEventThread = std::thread(&cX11Window::XEventThread, this);
return win;
}
void cX11Window::DestroyXWindow(void)
{
XUnmapWindow(GLWin.dpy, GLWin.win);
GLWin.win = 0;
if (GLWin.xEventThread.joinable())
GLWin.xEventThread.join();
XFreeColormap(GLWin.dpy, GLWin.attr.colormap);
XUnmapWindow(dpy, win);
if (xEventThread.joinable())
xEventThread.join();
XFreeColormap(dpy, colormap);
}
void cX11Window::XEventThread()
{
while (GLWin.win)
while (win)
{
XEvent event;
for (int num_events = XPending(GLWin.dpy); num_events > 0; num_events--)
for (int num_events = XPending(dpy); num_events > 0; num_events--)
{
XNextEvent(GLWin.dpy, &event);
XNextEvent(dpy, &event);
switch (event.type) {
case ConfigureNotify:
XResizeWindow(GLWin.dpy, GLWin.win, event.xconfigure.width, event.xconfigure.height);
XResizeWindow(dpy, win, event.xconfigure.width, event.xconfigure.height);
GLInterface->SetBackBufferDimensions(event.xconfigure.width, event.xconfigure.height);
break;
default:

View File

@ -5,6 +5,7 @@
#pragma once
#include <string>
#include <thread>
#include <X11/keysym.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
@ -13,7 +14,13 @@ class cX11Window
{
private:
void XEventThread();
std::thread xEventThread;
Colormap colormap;
public:
void CreateXWindow(void);
void Initialize(Display *dpy);
Window CreateXWindow(Window parent, XVisualInfo *vi);
void DestroyXWindow(void);
Display *dpy;
Window win;
};

View File

@ -5,10 +5,6 @@
#include "Common/Thread.h"
#include "InputCommon/ControllerInterface/ControllerInterface.h"
#if USE_EGL
#include "DolphinWX/GLInterface/GLInterface.h"
#endif
#ifdef CIFACE_USE_XINPUT
#include "InputCommon/ControllerInterface/XInput/XInput.h"
#endif