GraphicsContext: Abstract away things like swapbuffers etc before adding even more backends.

Needed to prevent clutter all over the codebase.

Does not go all the way yet, goal would be a common render loop between platforms but not there yet.
This commit is contained in:
Henrik Rydgard 2015-12-31 16:59:40 +01:00
parent 16053c08a0
commit 15de6e6b98
38 changed files with 230 additions and 145 deletions

View File

@ -222,6 +222,7 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClInclude>
<ClInclude Include="GraphicsContext.h" />
<ClInclude Include="KeyMap.h" />
<ClInclude Include="Log.h" />
<ClInclude Include="LogManager.h" />

View File

@ -57,6 +57,7 @@
<ClInclude Include="GL\GLInterfaceBase.h">
<Filter>GL</Filter>
</ClInclude>
<ClInclude Include="GraphicsContext.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp" />

35
Common/GraphicsContext.h Normal file
View File

@ -0,0 +1,35 @@
#pragma once
#include <string>
#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; }
};

View File

@ -54,6 +54,7 @@ static std::set<Core_ShutdownFunc> 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.

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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.";

View File

@ -47,6 +47,7 @@ enum PSPDirectories {
DIRECTORY_CACHE,
};
class GraphicsContext;
void UpdateUIState(GlobalUIState newState);
GlobalUIState GetUIState();

View File

@ -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;
}

View File

@ -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_;
};

View File

@ -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());

View File

@ -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();

View File

@ -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;

View File

@ -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
}
}

View File

@ -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:

View File

@ -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();

View File

@ -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();

View File

@ -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;
}

View File

@ -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();
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;
};

View File

@ -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;
};

View File

@ -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();
}
}

View File

@ -368,6 +368,7 @@
<ClInclude Include="GEDebugger\TabDisplayLists.h" />
<ClInclude Include="GEDebugger\TabState.h" />
<ClInclude Include="GEDebugger\TabVertices.h" />
<ClInclude Include="GPU\WindowsGraphicsContext.h" />
<ClInclude Include="InputDevice.h" />
<ClInclude Include="KeyboardDevice.h" />
<ClInclude Include="MainWindowMenu.h" />

View File

@ -275,6 +275,9 @@
<ClInclude Include="GPU\WindowsGLContext.h">
<Filter>Windows\System</Filter>
</ClInclude>
<ClInclude Include="GPU\WindowsGraphicsContext.h">
<Filter>Windows\System</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="icon1.ico">

View File

@ -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);
}

View File

@ -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<KeyboardDevice> keyboard;
GraphicsContext *GetGraphicsContext() { return gfx_; }
private:
void SetConsolePosition();
void UpdateConsolePosition();
HINSTANCE hInstance_;
HWND displayWindow_;
HWND mainWindow_;
GraphicsContext *gfx_;
std::list<std::shared_ptr<InputDevice>> input;
};

View File

@ -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();

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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 {}

View File

@ -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();
}

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -247,7 +247,7 @@ ViewController* sharedViewController;
EndInputState(&input_state);
}
NativeRender();
NativeRender(NULL);
time_update();
}

2
lang

@ -1 +1 @@
Subproject commit 9900b0978a3e51dfe8d58cd86c6a58d3a0135580
Subproject commit 84fd93497b9718a89ac04edfe9636b0f90943505

View File

@ -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) {}