diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj
index d93b8d8667..e281462434 100644
--- a/Common/Common.vcxproj
+++ b/Common/Common.vcxproj
@@ -222,6 +222,7 @@
true
true
+
diff --git a/Common/Common.vcxproj.filters b/Common/Common.vcxproj.filters
index 5b2bb42345..ffdd697516 100644
--- a/Common/Common.vcxproj.filters
+++ b/Common/Common.vcxproj.filters
@@ -57,6 +57,7 @@
GL
+
diff --git a/Common/GraphicsContext.h b/Common/GraphicsContext.h
new file mode 100644
index 0000000000..ded4d4ccd3
--- /dev/null
+++ b/Common/GraphicsContext.h
@@ -0,0 +1,35 @@
+#pragma once
+
+#include
+
+#include "thin3d/thin3d.h"
+
+// Init is done differently on each platform, and done close to the creation, so it's
+// expected to be implemented by subclasses.
+class GraphicsContext {
+public:
+ virtual ~GraphicsContext() {}
+
+ virtual void Shutdown() = 0;
+ virtual void SwapInterval(int interval) = 0;
+ virtual void SwapBuffers() = 0;
+
+ // Used during window resize. Must be called from the window thread,
+ // not the rendering thread or CPU thread.
+ virtual void Pause() {}
+ virtual void Resume() {}
+
+ virtual void Resize() = 0;
+
+ virtual Thin3DContext *CreateThin3DContext() = 0;
+};
+
+class DummyGraphicsContext : public GraphicsContext {
+public:
+ void Shutdown() override {}
+ void SwapInterval(int interval) override {}
+ void SwapBuffers() override {}
+ void Resize() override {}
+
+ Thin3DContext *CreateThin3DContext() override { return nullptr; }
+};
\ No newline at end of file
diff --git a/Core/Core.cpp b/Core/Core.cpp
index f27c7dfdf7..2287406e07 100644
--- a/Core/Core.cpp
+++ b/Core/Core.cpp
@@ -54,6 +54,7 @@ static std::set shutdownFuncs;
static bool windowHidden = false;
static double lastActivity = 0.0;
static double lastKeepAwake = 0.0;
+static GraphicsContext *graphicsContext;
#ifdef _WIN32
InputState input_state;
@@ -163,26 +164,12 @@ void UpdateRunLoop() {
}
if (GetUIState() != UISTATE_EXIT) {
- NativeRender();
+ NativeRender(graphicsContext);
}
}
-#if defined(USING_WIN_UI)
-
-void GPU_SwapBuffers() {
- switch (g_Config.iGPUBackend) {
- case GPU_BACKEND_OPENGL:
- GL_SwapBuffers();
- break;
- case GPU_BACKEND_DIRECT3D9:
- D3D9_SwapBuffers();
- break;
- }
-}
-
-#endif
-
-void Core_RunLoop() {
+void Core_RunLoop(GraphicsContext *ctx) {
+ graphicsContext = ctx;
while ((GetUIState() != UISTATE_INGAME || !PSP_IsInited()) && GetUIState() != UISTATE_EXIT) {
time_update();
#if defined(USING_WIN_UI)
@@ -196,7 +183,7 @@ void Core_RunLoop() {
if (sleepTime > 0)
Sleep(sleepTime);
if (!windowHidden) {
- GPU_SwapBuffers();
+ ctx->SwapBuffers();
}
#else
UpdateRunLoop();
@@ -208,7 +195,7 @@ void Core_RunLoop() {
UpdateRunLoop();
#if defined(USING_WIN_UI)
if (!windowHidden && !Core_IsStepping()) {
- GPU_SwapBuffers();
+ ctx->SwapBuffers();
// Keep the system awake for longer than normal for cutscenes and the like.
const double now = time_now_d();
@@ -246,7 +233,7 @@ static inline void CoreStateProcessed() {
}
// Some platforms, like Android, do not call this function but handle things on their own.
-void Core_Run()
+void Core_Run(GraphicsContext *ctx)
{
#if defined(_DEBUG)
host->UpdateDisassembly();
@@ -261,7 +248,7 @@ reswitch:
if (GetUIState() == UISTATE_EXIT) {
return;
}
- Core_RunLoop();
+ Core_RunLoop(ctx);
#if defined(USING_QT_UI) && !defined(MOBILE_DEVICE)
return;
#else
@@ -273,7 +260,7 @@ reswitch:
{
case CORE_RUNNING:
// enter a fast runloop
- Core_RunLoop();
+ Core_RunLoop(ctx);
break;
// We should never get here on Android.
diff --git a/Core/Core.h b/Core/Core.h
index 839a63dacf..afda12b26a 100644
--- a/Core/Core.h
+++ b/Core/Core.h
@@ -20,9 +20,11 @@
#include "Core/System.h"
#include "Core/CoreParameter.h"
+class GraphicsContext;
+
// called from emu thread
void UpdateRunLoop();
-void Core_Run();
+void Core_Run(GraphicsContext *ctx);
void Core_Stop();
void Core_ErrorPause();
// called from gui
diff --git a/Core/CoreParameter.h b/Core/CoreParameter.h
index d99d0ea94a..0b60f84189 100644
--- a/Core/CoreParameter.h
+++ b/Core/CoreParameter.h
@@ -35,11 +35,15 @@ enum GPUCore {
class FileLoader;
+class GraphicsContext;
+
// PSP_CoreParameter()
struct CoreParameter {
CoreParameter() : collectEmuLog(0), unthrottle(false), fpsLimit(0), updateRecent(true), freezeNext(false), frozen(false), mountIsoLoader(nullptr) {}
+
CPUCore cpuCore;
GPUCore gpuCore;
+ GraphicsContext *graphicsContext; // TODO: Find a better place.
bool enableSound; // there aren't multiple sound cores.
std::string fileToStart;
diff --git a/Core/Host.h b/Core/Host.h
index bd0993da68..6395769ff1 100644
--- a/Core/Host.h
+++ b/Core/Host.h
@@ -21,6 +21,7 @@
#include "Common/CommonTypes.h"
struct InputState;
+class GraphicsContext;
// TODO: Whittle this down. Collecting a bunch of random stuff like this isn't good design :P
class Host {
@@ -33,7 +34,7 @@ public:
virtual void SetDebugMode(bool mode) { }
- virtual bool InitGraphics(std::string *error_string) = 0;
+ virtual bool InitGraphics(std::string *error_string, GraphicsContext **ctx) = 0;
virtual void ShutdownGraphics() = 0;
virtual void InitSound() = 0;
diff --git a/Core/System.cpp b/Core/System.cpp
index e548e8e75a..a228b9308e 100644
--- a/Core/System.cpp
+++ b/Core/System.cpp
@@ -360,6 +360,7 @@ void System_Wake() {
static bool pspIsInited = false;
static bool pspIsIniting = false;
static bool pspIsQuiting = false;
+// Ugly!
bool PSP_InitStart(const CoreParameter &coreParam, std::string *error_string) {
if (pspIsIniting || pspIsQuiting) {
@@ -407,7 +408,7 @@ bool PSP_InitUpdate(std::string *error_string) {
bool success = coreParameter.fileToStart != "";
*error_string = coreParameter.errorString;
if (success) {
- success = GPU_Init();
+ success = GPU_Init(coreParameter.graphicsContext);
if (!success) {
PSP_Shutdown();
*error_string = "Unable to initialize rendering engine.";
diff --git a/Core/System.h b/Core/System.h
index 806b85bf95..b32a14b26a 100644
--- a/Core/System.h
+++ b/Core/System.h
@@ -47,6 +47,7 @@ enum PSPDirectories {
DIRECTORY_CACHE,
};
+class GraphicsContext;
void UpdateUIState(GlobalUIState newState);
GlobalUIState GetUIState();
diff --git a/GPU/GLES/GLES_GPU.cpp b/GPU/GLES/GLES_GPU.cpp
index 9c434c7f21..152d14a6be 100644
--- a/GPU/GLES/GLES_GPU.cpp
+++ b/GPU/GLES/GLES_GPU.cpp
@@ -19,6 +19,7 @@
#include "profiler/profiler.h"
#include "Common/ChunkFile.h"
+#include "Common/GraphicsContext.h"
#include "Core/Config.h"
#include "Core/Debugger/Breakpoints.h"
@@ -394,8 +395,8 @@ static const CommandTableEntry commandTable[] = {
GLES_GPU::CommandInfo GLES_GPU::cmdInfo_[256];
-GLES_GPU::GLES_GPU()
-: resized_(false) {
+GLES_GPU::GLES_GPU(GraphicsContext *ctx)
+: resized_(false), gfxCtx_(ctx) {
UpdateVsyncInterval(true);
CheckGPUFeatures();
@@ -466,7 +467,7 @@ GLES_GPU::~GLES_GPU() {
shaderManager_ = nullptr;
#ifdef _WIN32
- GL_SwapInterval(0);
+ gfxCtx_->SwapInterval(0);
#endif
}
@@ -674,7 +675,7 @@ inline void GLES_GPU::UpdateVsyncInterval(bool force) {
// // See http://developer.download.nvidia.com/opengl/specs/WGL_EXT_swap_control_tear.txt
// glstate.SetVSyncInterval(-desiredVSyncInterval);
//} else {
- GL_SwapInterval(desiredVSyncInterval);
+ gfxCtx_->SwapInterval(desiredVSyncInterval);
//}
lastVsync_ = desiredVSyncInterval;
}
diff --git a/GPU/GLES/GLES_GPU.h b/GPU/GLES/GLES_GPU.h
index 2df770bad6..5c858a9523 100644
--- a/GPU/GLES/GLES_GPU.h
+++ b/GPU/GLES/GLES_GPU.h
@@ -30,10 +30,11 @@
class ShaderManager;
class LinkedShader;
+class GraphicsContext;
class GLES_GPU : public GPUCommon {
public:
- GLES_GPU();
+ GLES_GPU(GraphicsContext *gfxCtx);
~GLES_GPU();
// This gets called on startup and when we get back from settings.
@@ -192,4 +193,6 @@ private:
std::string reportingPrimaryInfo_;
std::string reportingFullInfo_;
+
+ GraphicsContext *gfxCtx_;
};
diff --git a/GPU/GPU.cpp b/GPU/GPU.cpp
index f4f4a54f6e..f9a3d0ea6f 100644
--- a/GPU/GPU.cpp
+++ b/GPU/GPU.cpp
@@ -38,13 +38,13 @@ static void SetGPU(T *obj) {
gpuDebug = obj;
}
-bool GPU_Init() {
+bool GPU_Init(GraphicsContext *ctx) {
switch (PSP_CoreParameter().gpuCore) {
case GPU_NULL:
SetGPU(new NullGPU());
break;
case GPU_GLES:
- SetGPU(new GLES_GPU());
+ SetGPU(new GLES_GPU(ctx));
break;
case GPU_SOFTWARE:
SetGPU(new SoftGPU());
diff --git a/GPU/GPU.h b/GPU/GPU.h
index b98c30e67b..0849ab8cbc 100644
--- a/GPU/GPU.h
+++ b/GPU/GPU.h
@@ -22,6 +22,7 @@
class GPUInterface;
class GPUDebugInterface;
+class GraphicsContext;
enum SkipDrawReasonFlags {
SKIPDRAW_SKIPFRAME = 1,
@@ -103,6 +104,6 @@ extern GPUStatistics gpuStats;
extern GPUInterface *gpu;
extern GPUDebugInterface *gpuDebug;
-bool GPU_Init();
+bool GPU_Init(GraphicsContext *ctx);
void GPU_Shutdown();
void GPU_Reinitialize();
diff --git a/UI/HostTypes.h b/UI/HostTypes.h
index f27a95aeec..e679f594a5 100644
--- a/UI/HostTypes.h
+++ b/UI/HostTypes.h
@@ -37,7 +37,7 @@ public:
void SetDebugMode(bool mode) override { }
- bool InitGraphics(std::string *error_message) override { return true; }
+ bool InitGraphics(std::string *error_message, GraphicsContext **ctx) override { return true; }
void ShutdownGraphics() override {}
void InitSound() override;
diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp
index ae073621e0..5c9d9fb4e7 100644
--- a/UI/NativeApp.cpp
+++ b/UI/NativeApp.cpp
@@ -506,20 +506,8 @@ void NativeInit(int argc, const char *argv[],
}
}
-void NativeInitGraphics() {
-#ifndef _WIN32
- // Force backend to GL
- g_Config.iGPUBackend = GPU_BACKEND_OPENGL;
-#endif
-
- if (g_Config.iGPUBackend == GPU_BACKEND_OPENGL) {
- thin3d = T3DCreateGLContext();
- CheckGLExtensions();
- } else {
-#ifdef _WIN32
- thin3d = D3D9_CreateThin3DContext();
-#endif
- }
+void NativeInitGraphics(GraphicsContext *graphicsContext) {
+ thin3d = graphicsContext->CreateThin3DContext();
ui_draw2d.SetAtlas(&ui_atlas);
ui_draw2d_front.SetAtlas(&ui_atlas);
@@ -692,7 +680,7 @@ void DrawDownloadsOverlay(UIContext &dc) {
dc.Flush();
}
-void NativeRender() {
+void NativeRender(GraphicsContext *graphicsContext) {
g_GameManager.Update();
float xres = dp_xres;
@@ -725,17 +713,16 @@ void NativeRender() {
if (resized) {
resized = false;
- if (g_Config.iGPUBackend == GPU_BACKEND_DIRECT3D9) {
-#ifdef _WIN32
- D3D9_Resize(0);
-#endif
- } else if (g_Config.iGPUBackend == GPU_BACKEND_OPENGL) {
+
+ graphicsContext->Resize();
+ // TODO: Move this to new GraphicsContext objects for each backend.
#ifndef _WIN32
+ if (g_Config.iGPUBackend == GPU_BACKEND_OPENGL) {
PSP_CoreParameter().pixelWidth = pixel_xres;
PSP_CoreParameter().pixelHeight = pixel_yres;
NativeMessageReceived("gpu resized", "");
-#endif
}
+#endif
}
}
diff --git a/Windows/EmuThread.cpp b/Windows/EmuThread.cpp
index 2ad173e793..40f32028b2 100644
--- a/Windows/EmuThread.cpp
+++ b/Windows/EmuThread.cpp
@@ -117,8 +117,10 @@ unsigned int WINAPI TheThread(void *)
host->UpdateUI();
+ GraphicsContext *graphicsContext;
+
std::string error_string;
- if (!host->InitGraphics(&error_string)) {
+ if (!host->InitGraphics(&error_string, &graphicsContext)) {
I18NCategory *err = GetI18NCategory("Error");
Reporting::ReportMessage("Graphics init error: %s", error_string.c_str());
@@ -154,7 +156,9 @@ unsigned int WINAPI TheThread(void *)
ExitProcess(1);
}
- NativeInitGraphics();
+ PSP_CoreParameter().graphicsContext = graphicsContext;
+
+ NativeInitGraphics(graphicsContext);
NativeResized();
INFO_LOG(BOOT, "Done.");
@@ -179,7 +183,7 @@ unsigned int WINAPI TheThread(void *)
if (!Core_IsActive())
UpdateUIState(UISTATE_MENU);
- Core_Run();
+ Core_Run(graphicsContext);
}
shutdown:
diff --git a/Windows/GPU/D3D9Context.cpp b/Windows/GPU/D3D9Context.cpp
index 957a6b479f..78c8ac7bad 100644
--- a/Windows/GPU/D3D9Context.cpp
+++ b/Windows/GPU/D3D9Context.cpp
@@ -16,6 +16,7 @@
#include "thin3d/thin3d.h"
#include "thin3d/d3dx9_loader.h"
+// TODO: Move these into the context class.
static bool has9Ex = false;
static LPDIRECT3D9 d3d;
static LPDIRECT3D9EX d3dEx;
@@ -28,7 +29,8 @@ static HWND hWnd; // Holds Our Window Handle
static D3DPRESENT_PARAMETERS pp;
static HMODULE hD3D9;
-void D3D9_SwapBuffers() {
+
+void D3D9Context::SwapBuffers() {
if (has9Ex) {
deviceEx->EndScene();
deviceEx->PresentEx(NULL, NULL, NULL, NULL, 0);
@@ -40,7 +42,7 @@ void D3D9_SwapBuffers() {
}
}
-Thin3DContext *D3D9_CreateThin3DContext() {
+Thin3DContext *D3D9Context::CreateThin3DContext() {
return T3DCreateDX9Context(d3d, d3dEx, adapterId, device, deviceEx);
}
@@ -61,7 +63,12 @@ static void GetRes(int &xres, int &yres) {
yres = rc.bottom - rc.top;
}
-bool D3D9_Init(HWND wnd, bool windowed, std::string *error_message) {
+void D3D9Context::SwapInterval(int interval) {
+ // Dummy
+}
+
+bool D3D9Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) {
+ bool windowed = true;
hWnd = wnd;
DIRECT3DCREATE9EX g_pfnCreate9ex;
@@ -195,7 +202,7 @@ bool D3D9_Init(HWND wnd, bool windowed, std::string *error_message) {
return true;
}
-void D3D9_Resize(HWND window) {
+void D3D9Context::Resize() {
// This should only be called from the emu thread.
int xres, yres;
@@ -218,7 +225,7 @@ void D3D9_Resize(HWND window) {
}
}
-void D3D9_Shutdown() {
+void D3D9Context::Shutdown() {
DX9::DestroyShaders();
DX9::fbo_shutdown();
device->EndScene();
diff --git a/Windows/GPU/D3D9Context.h b/Windows/GPU/D3D9Context.h
index 470aac96a4..876fb5850e 100644
--- a/Windows/GPU/D3D9Context.h
+++ b/Windows/GPU/D3D9Context.h
@@ -3,12 +3,19 @@
#pragma once
#include "Common/CommonWindows.h"
+#include "Windows/GPU/WindowsGraphicsContext.h"
class Thin3DContext;
-bool D3D9_Init(HWND window, bool windowed, std::string *error_message);
-void D3D9_Shutdown();
-void D3D9_Resize(HWND window);
-void D3D9_SwapBuffers();
+class D3D9Context : public WindowsGraphicsContext {
+public:
+ bool Init(HINSTANCE hInst, HWND window, std::string *error_message) override;
+ void Shutdown() override;
+ void SwapInterval(int interval) override;
+ void SwapBuffers() override;
+
+ void Resize() override;
+
+ Thin3DContext *CreateThin3DContext() override;
+};
-Thin3DContext *D3D9_CreateThin3DContext();
\ No newline at end of file
diff --git a/Windows/GPU/WindowsGLContext.cpp b/Windows/GPU/WindowsGLContext.cpp
index 21b6a19a17..953173d6d7 100644
--- a/Windows/GPU/WindowsGLContext.cpp
+++ b/Windows/GPU/WindowsGLContext.cpp
@@ -41,8 +41,8 @@ static HANDLE resumeEvent;
static int xres, yres;
-void GL_SwapBuffers() {
- SwapBuffers(hDC);
+void WindowsGLContext::SwapBuffers() {
+ ::SwapBuffers(hDC);
// Used during fullscreen switching to prevent rendering.
if (pauseRequested) {
@@ -60,7 +60,7 @@ void GL_SwapBuffers() {
// glFinish();
}
-void GL_Pause() {
+void WindowsGLContext::Pause() {
if (!hRC) {
return;
}
@@ -73,7 +73,7 @@ void GL_Pause() {
// OK, we now know the rendering thread is paused.
}
-void GL_Resume() {
+void WindowsGLContext::Resume() {
if (!hRC) {
return;
}
@@ -153,7 +153,7 @@ void DebugCallbackARB(GLenum source, GLenum type, GLuint id, GLenum severity,
}
}
-bool GL_Init(HWND window, std::string *error_message) {
+bool WindowsGLContext::Init(HINSTANCE hInst, HWND window, std::string *error_message) {
*error_message = "ok";
hWnd = window;
GLuint PixelFormat;
@@ -320,7 +320,7 @@ bool GL_Init(HWND window, std::string *error_message) {
hRC = m_hrc;
- GL_SwapInterval(0);
+ SwapInterval(0);
if (g_Config.bGfxDebugOutput) {
if (wglewIsSupported("GL_KHR_debug") == 1) {
@@ -361,13 +361,13 @@ bool GL_Init(HWND window, std::string *error_message) {
return true; // Success
}
-void GL_SwapInterval(int interval) {
+void WindowsGLContext::SwapInterval(int interval) {
// glew loads wglSwapIntervalEXT if available
if (wglSwapIntervalEXT)
wglSwapIntervalEXT(interval);
}
-void GL_Shutdown() {
+void WindowsGLContext::Shutdown() {
CloseHandle(pauseEvent);
CloseHandle(resumeEvent);
if (hRC) {
@@ -392,3 +392,14 @@ void GL_Shutdown() {
}
hWnd = NULL;
}
+
+void WindowsGLContext::Resize() {
+}
+
+Thin3DContext *WindowsGLContext::CreateThin3DContext() {
+ Thin3DContext *ctx = T3DCreateGLContext();
+ if (ctx) {
+ CheckGLExtensions();
+ }
+ return ctx;
+}
diff --git a/Windows/GPU/WindowsGLContext.h b/Windows/GPU/WindowsGLContext.h
index 583186aa93..0581b87cfa 100644
--- a/Windows/GPU/WindowsGLContext.h
+++ b/Windows/GPU/WindowsGLContext.h
@@ -1,13 +1,23 @@
#pragma once
#include "Common/CommonWindows.h"
+#include "Windows/GPU/WindowsGraphicsContext.h"
-bool GL_Init(HWND window, std::string *error_message);
-void GL_Shutdown();
-void GL_SwapInterval(int interval);
-void GL_SwapBuffers();
+class Thin3DContext;
-// Used during window resize. Must be called from the window thread,
-// not the rendering thread or CPU thread.
-void GL_Pause();
-void GL_Resume();
\ No newline at end of file
+class WindowsGLContext : public WindowsGraphicsContext {
+public:
+ bool Init(HINSTANCE hInst, HWND window, std::string *error_message) override;
+ void Shutdown() override;
+ void SwapInterval(int interval) override;
+ void SwapBuffers() override;
+
+ // Used during window resize. Must be called from the window thread,
+ // not the rendering thread or CPU thread.
+ void Pause() override;
+ void Resume() override;
+
+ void Resize() override;
+
+ Thin3DContext *CreateThin3DContext() override;
+};
diff --git a/Windows/GPU/WindowsGraphicsContext.h b/Windows/GPU/WindowsGraphicsContext.h
new file mode 100644
index 0000000000..db022e9b5d
--- /dev/null
+++ b/Windows/GPU/WindowsGraphicsContext.h
@@ -0,0 +1,10 @@
+#pragma once
+
+#include "Common/GraphicsContext.h"
+#include "Common/CommonWindows.h"
+
+class WindowsGraphicsContext : public GraphicsContext {
+public:
+ virtual bool Init(HINSTANCE hInst, HWND window, std::string *error_message) = 0;
+};
+
diff --git a/Windows/MainWindow.cpp b/Windows/MainWindow.cpp
index 1c5e12b5f0..d6b54d78b2 100644
--- a/Windows/MainWindow.cpp
+++ b/Windows/MainWindow.cpp
@@ -288,12 +288,10 @@ namespace MainWindow
}
void ToggleFullscreen(HWND hWnd, bool goingFullscreen) {
+ GraphicsContext *graphicsContext = PSP_CoreParameter().graphicsContext;
// Make sure no rendering is happening during the switch.
-
- bool isOpenGL = g_Config.iGPUBackend == GPU_BACKEND_OPENGL;
-
- if (isOpenGL) {
- GL_Pause();
+ if (graphicsContext) {
+ graphicsContext->Pause();
}
int oldWindowState = g_WindowState;
@@ -355,8 +353,8 @@ namespace MainWindow
WindowsRawInput::NotifyMenu();
- if (isOpenGL) {
- GL_Resume();
+ if (graphicsContext) {
+ graphicsContext->Resume();
}
}
diff --git a/Windows/PPSSPP.vcxproj b/Windows/PPSSPP.vcxproj
index 4f1ff2e4a7..05cade844d 100644
--- a/Windows/PPSSPP.vcxproj
+++ b/Windows/PPSSPP.vcxproj
@@ -368,6 +368,7 @@
+
diff --git a/Windows/PPSSPP.vcxproj.filters b/Windows/PPSSPP.vcxproj.filters
index 9bdd231c22..4bf680c53f 100644
--- a/Windows/PPSSPP.vcxproj.filters
+++ b/Windows/PPSSPP.vcxproj.filters
@@ -275,6 +275,9 @@
Windows\System
+
+ Windows\System
+
diff --git a/Windows/WindowsHost.cpp b/Windows/WindowsHost.cpp
index c0b2770c33..ad9107db8d 100644
--- a/Windows/WindowsHost.cpp
+++ b/Windows/WindowsHost.cpp
@@ -63,15 +63,13 @@ static const int numCPUs = 1;
float mouseDeltaX = 0;
float mouseDeltaY = 0;
-static BOOL PostDialogMessage(Dialog *dialog, UINT message, WPARAM wParam = 0, LPARAM lParam = 0)
-{
+static BOOL PostDialogMessage(Dialog *dialog, UINT message, WPARAM wParam = 0, LPARAM lParam = 0) {
return PostMessage(dialog->GetDlgHandle(), message, wParam, lParam);
}
-WindowsHost::WindowsHost(HWND mainWindow, HWND displayWindow)
+WindowsHost::WindowsHost(HINSTANCE hInstance, HWND mainWindow, HWND displayWindow)
+ : gfx_(nullptr), hInstance_(hInstance), mainWindow_(mainWindow), displayWindow_(displayWindow)
{
- mainWindow_ = mainWindow;
- displayWindow_ = displayWindow;
mouseDeltaX = 0;
mouseDeltaY = 0;
@@ -97,33 +95,41 @@ void WindowsHost::SetConsolePosition() {
void WindowsHost::UpdateConsolePosition() {
RECT rc;
HWND console = GetConsoleWindow();
- if (console != NULL && GetWindowRect(console, &rc) && !IsIconic(console))
- {
+ if (console != NULL && GetWindowRect(console, &rc) && !IsIconic(console)) {
g_Config.iConsoleWindowX = rc.left;
g_Config.iConsoleWindowY = rc.top;
}
}
-bool WindowsHost::InitGraphics(std::string *error_message) {
+bool WindowsHost::InitGraphics(std::string *error_message, GraphicsContext **ctx) {
+ WindowsGraphicsContext *graphicsContext = nullptr;
switch (g_Config.iGPUBackend) {
case GPU_BACKEND_OPENGL:
- return GL_Init(displayWindow_, error_message);
+ graphicsContext = new WindowsGLContext();
+ break;
case GPU_BACKEND_DIRECT3D9:
- return D3D9_Init(displayWindow_, true, error_message);
+ graphicsContext = new D3D9Context();
+ break;
default:
return false;
}
+
+ if (graphicsContext->Init(hInstance_, displayWindow_, error_message)) {
+ *ctx = graphicsContext;
+ gfx_ = graphicsContext;
+ return true;
+ } else {
+ delete graphicsContext;
+ *ctx = nullptr;
+ gfx_ = nullptr;
+ return false;
+ }
}
void WindowsHost::ShutdownGraphics() {
- switch (g_Config.iGPUBackend) {
- case GPU_BACKEND_OPENGL:
- GL_Shutdown();
- break;
- case GPU_BACKEND_DIRECT3D9:
- D3D9_Shutdown();
- break;
- }
+ gfx_->Shutdown();
+ delete gfx_;
+ gfx_ = nullptr;
PostMessage(mainWindow_, WM_CLOSE, 0, 0);
}
diff --git a/Windows/WindowsHost.h b/Windows/WindowsHost.h
index fa861aa68a..ed00d060f0 100644
--- a/Windows/WindowsHost.h
+++ b/Windows/WindowsHost.h
@@ -24,9 +24,11 @@
extern float mouseDeltaX;
extern float mouseDeltaY;
+class GraphicsContext;
+
class WindowsHost : public Host {
public:
- WindowsHost(HWND mainWindow, HWND displayWindow);
+ WindowsHost(HINSTANCE hInstance, HWND mainWindow, HWND displayWindow);
~WindowsHost() {
UpdateConsolePosition();
@@ -37,7 +39,8 @@ public:
void UpdateUI() override;
void SetDebugMode(bool mode) override;
- bool InitGraphics(std::string *error_message) override;
+ // If returns false, will return a null context
+ bool InitGraphics(std::string *error_message, GraphicsContext **ctx) override;
void PollControllers(InputState &input_state) override;
void ShutdownGraphics() override;
@@ -65,12 +68,16 @@ public:
std::shared_ptr keyboard;
+ GraphicsContext *GetGraphicsContext() { return gfx_; }
+
private:
void SetConsolePosition();
void UpdateConsolePosition();
+ HINSTANCE hInstance_;
HWND displayWindow_;
HWND mainWindow_;
+ GraphicsContext *gfx_;
std::list> input;
};
diff --git a/Windows/main.cpp b/Windows/main.cpp
index 52c37476e6..6cbe20f783 100644
--- a/Windows/main.cpp
+++ b/Windows/main.cpp
@@ -529,7 +529,7 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin
DialogManager::AddDlg(vfpudlg = new CVFPUDlg(_hInstance, hwndMain, currentDebugMIPS));
- host = new WindowsHost(hwndMain, hwndDisplay);
+ host = new WindowsHost(_hInstance, hwndMain, hwndDisplay);
host->SetWindowTitle(0);
MainWindow::CreateDebugWindows();
diff --git a/ext/native/base/NativeApp.h b/ext/native/base/NativeApp.h
index c927ba5659..daa5a8cbba 100644
--- a/ext/native/base/NativeApp.h
+++ b/ext/native/base/NativeApp.h
@@ -14,6 +14,8 @@ struct TouchInput;
struct KeyInput;
struct AxisInput;
+class GraphicsContext;
+
enum SystemPermission {
SYSTEM_PERMISSION_STORAGE,
};
@@ -48,7 +50,7 @@ void NativeInit(int argc, const char *argv[], const char *savegame_directory, co
// Runs after NativeInit() at some point. May (and probably should) call OpenGL.
// Should not initialize anything screen-size-dependent - do that in NativeResized.
-void NativeInitGraphics();
+void NativeInitGraphics(GraphicsContext *graphicsContext);
// Signals that you need to destroy and recreate all buffered OpenGL resources,
// like textures, vbo etc.
@@ -73,7 +75,7 @@ bool NativeAxis(const AxisInput &axis);
// Called when it's time to render. If the device can keep up, this
// will also be called sixty times per second. Main thread.
-void NativeRender();
+void NativeRender(GraphicsContext *graphicsContext);
// This should render num_samples 44khz stereo samples.
// Try not to make too many assumptions on the granularity
diff --git a/ext/native/base/PCMain.cpp b/ext/native/base/PCMain.cpp
index e3f79b92f2..f64b0a0c71 100644
--- a/ext/native/base/PCMain.cpp
+++ b/ext/native/base/PCMain.cpp
@@ -41,15 +41,13 @@ SDLJoystick *joystick = NULL;
#include "util/text/utf8.h"
#include "math/math_util.h"
-#ifdef PPSSPP
-// Bad: PPSSPP includes from native
#include "Core/System.h"
#include "Core/Core.h"
#include "Core/Config.h"
+#include "Common/GraphicsContext.h"
GlobalUIState lastUIState = UISTATE_MENU;
GlobalUIState GetUIState();
-#endif
static SDL_Window* g_Screen = NULL;
static bool g_ToggleFullScreenNextFrame = false;
@@ -622,6 +620,8 @@ int main(int argc, char *argv[]) {
printf("Virtual pixels: %i x %i\n", dp_xres, dp_yres);
NativeInitGraphics();
+ GraphicsContext *gfx = new DummyGraphicsContext();
+
NativeResized();
SDL_AudioSpec fmt, ret_fmt;
diff --git a/headless/Headless.cpp b/headless/Headless.cpp
index b3c0114ce9..8406f5109c 100644
--- a/headless/Headless.cpp
+++ b/headless/Headless.cpp
@@ -72,7 +72,7 @@ void D3D9_SwapBuffers() { }
void GL_SwapBuffers() { }
void GL_SwapInterval(int) { }
void NativeUpdate(InputState &input_state) { }
-void NativeRender() { }
+void NativeRender(GraphicsContext *graphicsContext) { }
void NativeResized() { }
void NativeMessageReceived(const char *message, const char *value) {}
@@ -299,15 +299,16 @@ int main(int argc, const char* argv[])
host = headlessHost;
std::string error_string;
- bool glWorking = host->InitGraphics(&error_string);
+
+ GraphicsContext *graphicsContext;
+ bool glWorking = host->InitGraphics(&error_string, &graphicsContext);
LogManager::Init();
LogManager *logman = LogManager::GetInstance();
PrintfLogger *printfLogger = new PrintfLogger();
- for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; i++)
- {
+ for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; i++) {
LogTypes::LOG_TYPE type = (LogTypes::LOG_TYPE)i;
logman->SetEnable(type, fullLog);
logman->SetLogLevel(type, LogTypes::LDEBUG);
diff --git a/headless/StubHost.h b/headless/StubHost.h
index 3e19dd83ab..d12ca57099 100644
--- a/headless/StubHost.h
+++ b/headless/StubHost.h
@@ -21,8 +21,7 @@
#include "Core/Debugger/SymbolMap.h"
// TODO: Get rid of this junk
-class HeadlessHost : public Host
-{
+class HeadlessHost : public Host {
public:
void UpdateUI() override {}
@@ -31,7 +30,7 @@ public:
void SetDebugMode(bool mode) { }
- bool InitGraphics(std::string *error_message) override {return false;}
+ bool InitGraphics(std::string *error_message, GraphicsContext **ctx) override {return false;}
void ShutdownGraphics() override {}
void InitSound() override {}
diff --git a/headless/WindowsHeadlessHost.cpp b/headless/WindowsHeadlessHost.cpp
index 7185ae1a0e..7b07b0201a 100644
--- a/headless/WindowsHeadlessHost.cpp
+++ b/headless/WindowsHeadlessHost.cpp
@@ -140,7 +140,7 @@ void WindowsHeadlessHost::SetComparisonScreenshot(const std::string &filename)
comparisonScreenshot = filename;
}
-bool WindowsHeadlessHost::InitGraphics(std::string *error_message)
+bool WindowsHeadlessHost::InitGraphics(std::string *error_message, GraphicsContext **graphicsContext)
{
hWnd = CreateHiddenWindow();
@@ -169,13 +169,14 @@ bool WindowsHeadlessHost::InitGraphics(std::string *error_message)
ENFORCE(hRC = wglCreateContext(hDC), "Unable to create GL context.");
ENFORCE(wglMakeCurrent(hDC, hRC), "Unable to activate GL context.");
- GL_SwapInterval(0);
+ // GL_SwapInterval(0);
glewInit();
CheckGLExtensions();
LoadNativeAssets();
+ *graphicsContext = new DummyGraphicsContext();
return ResizeGL();
}
diff --git a/headless/WindowsHeadlessHost.h b/headless/WindowsHeadlessHost.h
index e5c70f2690..7e968fb9fb 100644
--- a/headless/WindowsHeadlessHost.h
+++ b/headless/WindowsHeadlessHost.h
@@ -28,7 +28,7 @@
class WindowsHeadlessHost : public HeadlessHost
{
public:
- virtual bool InitGraphics(std::string *error_message) override;
+ virtual bool InitGraphics(std::string *error_message, GraphicsContext **ctx) override;
virtual void ShutdownGraphics() override;
virtual void SwapBuffers() override;
diff --git a/headless/WindowsHeadlessHostDx9.cpp b/headless/WindowsHeadlessHostDx9.cpp
index 4fbb57021f..b110d69a7a 100644
--- a/headless/WindowsHeadlessHostDx9.cpp
+++ b/headless/WindowsHeadlessHostDx9.cpp
@@ -33,8 +33,7 @@ const bool WINDOW_VISIBLE = false;
const int WINDOW_WIDTH = 480;
const int WINDOW_HEIGHT = 272;
-HWND DxCreateWindow()
-{
+HWND DxCreateWindow() {
static WNDCLASSEX wndClass = {
sizeof(WNDCLASSEX),
CS_HREDRAW | CS_VREDRAW | CS_OWNDC,
@@ -58,13 +57,12 @@ HWND DxCreateWindow()
return CreateWindowEx(0, _T("PPSSPPHeadless"), _T("PPSSPPHeadless"), style, CW_USEDEFAULT, CW_USEDEFAULT, wr.right - wr.left, wr.bottom - wr.top, NULL, NULL, NULL, NULL);
}
-bool WindowsHeadlessHostDx9::InitGraphics(std::string *error_message)
-{
+bool WindowsHeadlessHostDx9::InitGraphics(std::string *error_message, GraphicsContext **graphicsContext) {
+ *graphicsContext = nullptr;
LoadD3DX9Dynamic();
hWnd = DxCreateWindow();
- if (WINDOW_VISIBLE)
- {
+ if (WINDOW_VISIBLE) {
ShowWindow(hWnd, TRUE);
SetFocus(hWnd);
}
@@ -72,15 +70,13 @@ bool WindowsHeadlessHostDx9::InitGraphics(std::string *error_message)
DX9::DirectxInit(hWnd);
LoadNativeAssets();
-
DX9::pD3Ddevice->BeginScene();
return true;
}
-void WindowsHeadlessHostDx9::ShutdownGraphics()
-{
+void WindowsHeadlessHostDx9::ShutdownGraphics() {
DX9::DestroyShaders();
DX9::fbo_shutdown();
DX9::pD3Ddevice->EndScene();
@@ -89,14 +85,11 @@ void WindowsHeadlessHostDx9::ShutdownGraphics()
hWnd = NULL;
}
-bool WindowsHeadlessHostDx9::ResizeGL()
-{
-
+bool WindowsHeadlessHostDx9::ResizeGL() {
return true;
}
-void WindowsHeadlessHostDx9::SwapBuffers()
-{
+void WindowsHeadlessHostDx9::SwapBuffers() {
MSG msg;
PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
TranslateMessage(&msg);
diff --git a/headless/WindowsHeadlessHostDx9.h b/headless/WindowsHeadlessHostDx9.h
index ea41e64db6..29966ec756 100644
--- a/headless/WindowsHeadlessHostDx9.h
+++ b/headless/WindowsHeadlessHostDx9.h
@@ -29,7 +29,7 @@
class WindowsHeadlessHostDx9 : public WindowsHeadlessHost
{
public:
- bool InitGraphics(std::string *error_message) override;
+ bool InitGraphics(std::string *error_message, GraphicsContext **graphicsContext) override;
void ShutdownGraphics() override;
void SwapBuffers() override;
diff --git a/ios/ViewController.mm b/ios/ViewController.mm
index ac2131394f..4f76d92af4 100644
--- a/ios/ViewController.mm
+++ b/ios/ViewController.mm
@@ -247,7 +247,7 @@ ViewController* sharedViewController;
EndInputState(&input_state);
}
- NativeRender();
+ NativeRender(NULL);
time_update();
}
diff --git a/lang b/lang
index 9900b0978a..84fd93497b 160000
--- a/lang
+++ b/lang
@@ -1 +1 @@
-Subproject commit 9900b0978a3e51dfe8d58cd86c6a58d3a0135580
+Subproject commit 84fd93497b9718a89ac04edfe9636b0f90943505
diff --git a/unittest/JitHarness.cpp b/unittest/JitHarness.cpp
index 1a1e1f9804..e8c2da2e15 100644
--- a/unittest/JitHarness.cpp
+++ b/unittest/JitHarness.cpp
@@ -36,7 +36,7 @@ struct InputState;
void D3D9_SwapBuffers() { }
void GL_SwapBuffers() { }
void NativeUpdate(InputState &input_state) { }
-void NativeRender() { }
+void NativeRender(GraphicsContext *graphicsContext) { }
void NativeResized() { }
void System_SendMessage(const char *command, const char *parameter) {}