Merge pull request #8347 from hrydgard/graphics-context

Graphics context
This commit is contained in:
Henrik Rydgård 2016-01-03 18:54:58 +01:00
commit 5bd72ea268
44 changed files with 414 additions and 231 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" />

36
Common/GraphicsContext.h Normal file
View file

@ -0,0 +1,36 @@
#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,12 +54,13 @@ 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;
#else
extern InputState input_state;
#endif
void Core_SetGraphicsContext(GraphicsContext *ctx) {
graphicsContext = ctx;
}
void Core_NotifyWindowHidden(bool hidden) {
windowHidden = hidden;
@ -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.
@ -331,10 +318,8 @@ reswitch:
return;
}
}
}
void Core_EnableStepping(bool step) {
if (step) {
sleep_ms(1);

View file

@ -20,11 +20,15 @@
#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();
// For platforms that don't call Core_Run
void Core_SetGraphicsContext(GraphicsContext *ctx);
// called from gui
void Core_EnableStepping(bool step);
void Core_DoSingleStep();

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;
@ -93,7 +93,7 @@ public:
mainWindow->GetDialogDisasm()->SetDebugMode(mode);
}
virtual bool InitGraphics(std::string *error_message) override { return true; }
virtual bool InitGraphics(std::string *error_message, GraphicsContext **ctx) override { return true; }
virtual void ShutdownGraphics() override {}
virtual void InitSound() override;

View file

@ -37,7 +37,6 @@
#if defined(_WIN32)
#include "Windows/DSoundStream.h"
#include "Windows/MainWindow.h"
#include "Windows/GPU/D3D9Context.h"
#endif
#include "base/display.h"
@ -68,6 +67,7 @@
#include "Common/FileUtil.h"
#include "Common/LogManager.h"
#include "Common/MemArena.h"
#include "Common/GraphicsContext.h"
#include "Core/Config.h"
#include "Core/Core.h"
#include "Core/FileLoaders/DiskCachingFileLoader.h"
@ -506,20 +506,9 @@ 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) {
Core_SetGraphicsContext(graphicsContext);
thin3d = graphicsContext->CreateThin3DContext();
ui_draw2d.SetAtlas(&ui_atlas);
ui_draw2d_front.SetAtlas(&ui_atlas);
@ -692,7 +681,7 @@ void DrawDownloadsOverlay(UIContext &dc) {
dc.Flush();
}
void NativeRender() {
void NativeRender(GraphicsContext *graphicsContext) {
g_GameManager.Update();
float xres = dp_xres;
@ -725,17 +714,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

@ -4,7 +4,9 @@
#include "base/NativeApp.h"
#include "base/mutex.h"
#include "i18n/i18n.h"
#include "input/input_state.h"
#include "util/text/utf8.h"
#include "Common/Log.h"
#include "Common/StringUtils.h"
#include "../Globals.h"
@ -29,6 +31,8 @@ static recursive_mutex emuThreadLock;
static HANDLE emuThread;
static volatile long emuThreadReady;
InputState input_state;
extern std::vector<std::wstring> GetWideCmdLine();
enum EmuThreadStatus : long
@ -117,8 +121,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 +160,9 @@ unsigned int WINAPI TheThread(void *)
ExitProcess(1);
}
NativeInitGraphics();
PSP_CoreParameter().graphicsContext = graphicsContext;
NativeInitGraphics(graphicsContext);
NativeResized();
INFO_LOG(BOOT, "Done.");
@ -179,7 +187,7 @@ unsigned int WINAPI TheThread(void *)
if (!Core_IsActive())
UpdateUIState(UISTATE_MENU);
Core_Run();
Core_Run(graphicsContext);
}
shutdown:

View file

@ -1,6 +1,5 @@
#include "Common/CommonWindows.h"
#include <d3d9.h>
#include <DxErr.h>
#include "GPU/Directx9/helper/global.h"
#include "GPU/Directx9/helper/dx_fbo.h"
@ -16,19 +15,7 @@
#include "thin3d/thin3d.h"
#include "thin3d/d3dx9_loader.h"
static bool has9Ex = false;
static LPDIRECT3D9 d3d;
static LPDIRECT3D9EX d3dEx;
static int adapterId;
static LPDIRECT3DDEVICE9 device;
static LPDIRECT3DDEVICE9EX deviceEx;
static HDC hDC; // Private GDI Device Context
static HGLRC hRC; // Permanent Rendering Context
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 +27,7 @@ void D3D9_SwapBuffers() {
}
}
Thin3DContext *D3D9_CreateThin3DContext() {
Thin3DContext *D3D9Context::CreateThin3DContext() {
return T3DCreateDX9Context(d3d, d3dEx, adapterId, device, deviceEx);
}
@ -54,14 +41,19 @@ bool IsWin7OrLater() {
return (major > 6) || ((major == 6) && (minor >= 1));
}
static void GetRes(int &xres, int &yres) {
static void GetRes(HWND hWnd, int &xres, int &yres) {
RECT rc;
GetClientRect(hWnd, &rc);
xres = rc.right - rc.left;
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;
@ -136,7 +128,7 @@ bool D3D9_Init(HWND wnd, bool windowed, std::string *error_message) {
dwBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
int xres, yres;
GetRes(xres, yres);
GetRes(hWnd, xres, yres);
memset(&pp, 0, sizeof(pp));
pp.BackBufferWidth = xres;
@ -195,11 +187,11 @@ 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;
GetRes(xres, yres);
GetRes(hWnd, xres, yres);
bool w_changed = pp.BackBufferWidth != xres;
bool h_changed = pp.BackBufferHeight != yres;
@ -218,7 +210,7 @@ void D3D9_Resize(HWND window) {
}
}
void D3D9_Shutdown() {
void D3D9Context::Shutdown() {
DX9::DestroyShaders();
DX9::fbo_shutdown();
device->EndScene();

View file

@ -3,12 +3,37 @@
#pragma once
#include "Common/CommonWindows.h"
#include "Windows/GPU/WindowsGraphicsContext.h"
#include <d3d9.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:
D3D9Context() : has9Ex(false), d3d(nullptr), d3dEx(nullptr), adapterId(-1), device(nullptr), deviceEx(nullptr), hDC(nullptr), hRC(nullptr), hWnd(nullptr), hD3D9(nullptr) {
memset(&pp, 0, sizeof(pp));
}
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;
private:
bool has9Ex;
LPDIRECT3D9 d3d;
LPDIRECT3D9EX d3dEx;
int adapterId;
LPDIRECT3DDEVICE9 device;
LPDIRECT3DDEVICE9EX deviceEx;
HDC hDC; // Private GDI Device Context
HGLRC hRC; // Permanent Rendering Context
HWND hWnd; // Holds Our Window Handle
HMODULE hD3D9;
D3DPRESENT_PARAMETERS pp;
};
Thin3DContext *D3D9_CreateThin3DContext();

View file

@ -31,18 +31,8 @@
#include "Windows/W32Util/Misc.h"
#include "Windows/GPU/WindowsGLContext.h"
static HDC hDC; // Private GDI Device Context
static HGLRC hRC; // Permanent Rendering Context
static HWND hWnd; // Holds Our Window Handle
static volatile bool pauseRequested;
static volatile bool resumeRequested;
static HANDLE pauseEvent;
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 +50,7 @@ void GL_SwapBuffers() {
// glFinish();
}
void GL_Pause() {
void WindowsGLContext::Pause() {
if (!hRC) {
return;
}
@ -73,7 +63,7 @@ void GL_Pause() {
// OK, we now know the rendering thread is paused.
}
void GL_Resume() {
void WindowsGLContext::Resume() {
if (!hRC) {
return;
}
@ -153,7 +143,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 +310,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 +351,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 +382,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,34 @@
#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;
private:
HDC hDC; // Private GDI Device Context
HGLRC hRC; // Permanent Rendering Context
HWND hWnd; // Holds Our Window Handle
volatile bool pauseRequested;
volatile bool resumeRequested;
HANDLE pauseEvent;
HANDLE resumeEvent;
int xres, yres;
};

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

@ -28,6 +28,7 @@
#include "android/jni/native_audio.h"
#include "gfx/gl_common.h"
#include "Common/GraphicsContext.h"
#include "Common/GL/GLInterfaceBase.h"
#include "app-android.h"
@ -42,6 +43,64 @@ struct FrameCommand {
std::string params;
};
class AndroidEGLGraphicsContext : public GraphicsContext {
public:
AndroidEGLGraphicsContext() : wnd_(nullptr), gl(nullptr) {}
bool Init(ANativeWindow *wnd, int desiredBackbufferSizeX, int desiredBackbufferSizeY, int backbufferFormat);
void Shutdown() override;
void SwapBuffers() override;
void SwapInterval(int interval) override {}
void Resize() {}
Thin3DContext *CreateThin3DContext() {
return T3DCreateGLContext();
}
private:
ANativeWindow *wnd_;
cInterfaceBase *gl;
};
bool AndroidEGLGraphicsContext::Init(ANativeWindow *wnd, int backbufferWidth, int backbufferHeight, int backbufferFormat) {
wnd_ = wnd;
gl = HostGL_CreateGLInterface();
if (!gl) {
ELOG("ERROR: Failed to create GL interface");
return false;
}
ILOG("EGL interface created. Desired backbuffer size: %dx%d", backbufferWidth, backbufferHeight);
// Apparently we still have to set this through Java through setFixedSize on the bufferHolder for it to take effect...
gl->SetBackBufferDimensions(backbufferWidth, backbufferHeight);
gl->SetMode(MODE_DETECT_ES);
bool use565 = false;
switch (backbufferFormat) {
case 4: // PixelFormat.RGB_565
use565 = true;
break;
}
if (!gl->Create(wnd, false, use565)) {
ELOG("EGL creation failed");
// TODO: What do we do now?
delete gl;
return false;
}
gl->MakeCurrent();
return true;
}
void AndroidEGLGraphicsContext::Shutdown() {
gl->ClearCurrent();
delete gl;
ANativeWindow_release(wnd_);
}
void AndroidEGLGraphicsContext::SwapBuffers() {
gl->Swap();
}
static recursive_mutex frameCommandLock;
static std::queue<FrameCommand> frameCommands;
@ -76,10 +135,10 @@ static int desiredBackbufferSizeY;
static jmethodID postCommand;
static jobject nativeActivity;
static volatile bool exitRenderLoop;
bool renderLoopRunning;
static bool renderLoopRunning;
float dp_xscale = 1.0f;
float dp_yscale = 1.0f;
static float dp_xscale = 1.0f;
static float dp_yscale = 1.0f;
InputState input_state;
@ -88,6 +147,8 @@ static bool first_lost = true;
static std::string library_path;
static std::map<SystemPermission, PermissionStatus> permissions;
AndroidEGLGraphicsContext *graphicsContext;
void PushCommand(std::string cmd, std::string param) {
lock_guard guard(frameCommandLock);
frameCommands.push(FrameCommand(cmd, param));
@ -607,33 +668,15 @@ extern "C" bool JNICALL Java_org_ppsspp_ppsspp_NativeActivity_runEGLRenderLoop(J
return false;
}
cInterfaceBase *gl = HostGL_CreateGLInterface();
if (!gl) {
ELOG("ERROR: Failed to create GL interface");
AndroidEGLGraphicsContext *graphicsContext = new AndroidEGLGraphicsContext();
if (!graphicsContext->Init(wnd, desiredBackbufferSizeX, desiredBackbufferSizeY, backbuffer_format)) {
ELOG("Failed to initialize graphics context.");
delete graphicsContext;
return false;
}
ILOG("EGL interface created. Desired backbuffer size: %dx%d", desiredBackbufferSizeX, desiredBackbufferSizeY);
// Apparently we still have to set this through Java through setFixedSize on the bufferHolder for it to take effect...
gl->SetBackBufferDimensions(desiredBackbufferSizeX, desiredBackbufferSizeY);
gl->SetMode(MODE_DETECT_ES);
bool use565 = false;
switch (backbuffer_format) {
case 4: // PixelFormat.RGB_565
use565 = true;
break;
}
if (!gl->Create(wnd, false, use565)) {
ELOG("EGL creation failed");
// TODO: What do we do now?
return false;
}
gl->MakeCurrent();
if (!renderer_inited) {
NativeInitGraphics();
NativeInitGraphics(graphicsContext);
renderer_inited = true;
}
@ -665,10 +708,10 @@ extern "C" bool JNICALL Java_org_ppsspp_ppsspp_NativeActivity_runEGLRenderLoop(J
EndInputState(&input_state);
}
NativeRender();
NativeRender(graphicsContext);
time_update();
gl->Swap();
graphicsContext->SwapBuffers();
lock_guard guard(frameCommandLock);
while (!frameCommands.empty()) {
@ -693,10 +736,8 @@ extern "C" bool JNICALL Java_org_ppsspp_ppsspp_NativeActivity_runEGLRenderLoop(J
NativeShutdownGraphics();
renderer_inited = false;
gl->ClearCurrent();
delete gl;
graphicsContext->Shutdown();
ANativeWindow_release(wnd);
renderLoopRunning = false;
WLOG("Render loop exited;");
return true;

1
b.sh
View file

@ -28,6 +28,7 @@ do
--ios) CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=ios/ios.toolchain.cmake -GXcode ${CMAKE_ARGS}"
TARGET_OS=iOS
PACKAGE=1
echo !!!!!!!!!!!!!!! The error below is expected. Go into build-ios and open the XCodeProj.
;;
--android) CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=android/android.toolchain.cmake ${CMAKE_ARGS}"
TARGET_OS=Android

View file

@ -13,12 +13,22 @@
#include <bps/navigator_invoke.h> // Receive invocation messages
#include "BlackberryMain.h"
#include "base/NKCodeFromBlackberry.h"
#include "thin3d/thin3d.h"
// Bad: PPSSPP includes from native
#include "Core/System.h"
#include "Core/Config.h"
#include "Core/Core.h"
#include "UI/MiscScreens.h"
#include "Common/GraphicsContext.h"
static GraphicsContext *graphicsContext;
class GLDummyGraphicsContext : public DummyGraphicsContext {
public:
Thin3DContext *CreateThin3DContext() override {
return T3DCreateGLContext();
}
};
static bool g_quitRequested = false;
@ -255,7 +265,8 @@ void BlackberryMain::startMain(int argc, char *argv[]) {
dialog_request_events(0);
vibration_request_events(0);
NativeInit(argc, (const char **)argv, "/accounts/1000/shared/misc/", "app/native/assets/", "BADCOFFEE");
NativeInitGraphics();
graphicsContext = new GLDummyGraphicsContext();
NativeInitGraphics(graphicsContext);
audio = new BlackberryAudio();
runMain();
}
@ -349,6 +360,8 @@ void BlackberryMain::endMain() {
bps_shutdown();
NativeShutdownGraphics();
delete audio;
graphicsContext->Shutdown();
delete graphicsContext;
NativeShutdown();
killDisplays();
net::Shutdown();

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,20 @@ 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"
class GLDummyGraphicsContext : public DummyGraphicsContext {
public:
Thin3DContext *CreateThin3DContext() override {
return T3DCreateGLContext();
}
};
GlobalUIState lastUIState = UISTATE_MENU;
GlobalUIState GetUIState();
#endif
static SDL_Window* g_Screen = NULL;
static bool g_ToggleFullScreenNextFrame = false;
@ -621,7 +626,9 @@ int main(int argc, char *argv[]) {
printf("Pixels: %i x %i\n", pixel_xres, pixel_yres);
printf("Virtual pixels: %i x %i\n", dp_xres, dp_yres);
NativeInitGraphics();
GraphicsContext *graphicsContext = new GLDummyGraphicsContext();
NativeInitGraphics(graphicsContext);
NativeResized();
SDL_AudioSpec fmt, ret_fmt;
@ -851,12 +858,7 @@ int main(int argc, char *argv[]) {
SimulateGamepad(keys, &input_state);
input_state.pad_buttons = pad_buttons;
UpdateInputState(&input_state, true);
#ifdef PPSSPP
UpdateRunLoop();
#else
NativeUpdate(input_state);
NativeRender();
#endif
if (g_QuitRequested)
break;
#if defined(PPSSPP) && !defined(MOBILE_DEVICE)
@ -876,8 +878,7 @@ int main(int argc, char *argv[]) {
#ifdef USING_EGL
eglSwapBuffers(g_eglDisplay, g_eglSurface);
#else
if (!keys[SDLK_TAB] || t - lastT >= 1.0/60.0)
{
if (!keys[SDLK_TAB] || t - lastT >= 1.0/60.0) {
SDL_GL_SwapWindow(g_Screen);
lastT = t;
}
@ -892,6 +893,8 @@ int main(int argc, char *argv[]) {
delete joystick;
#endif
NativeShutdownGraphics();
graphicsContext->Shutdown();
delete graphicsContext;
NativeShutdown();
// Faster exit, thanks to the OS. Remove this if you want to debug shutdown
// The speed difference is only really noticable on Linux. On Windows you do notice it though

View file

@ -25,11 +25,12 @@ QTM_USE_NAMESPACE
#include "gfx/gl_common.h"
#include "input/input_state.h"
#include "input/keycodes.h"
#include "thin3d/thin3d.h"
#include "base/NativeApp.h"
#include "net/resolve.h"
#include "base/NKCodeFromQt.h"
// Bad: PPSSPP includes from native
#include "Common/GraphicsContext.h"
#include "Core/System.h"
#include "Core/Core.h"
#include "Core/Config.h"
@ -37,6 +38,13 @@ QTM_USE_NAMESPACE
// Input
void SimulateGamepad(InputState *input);
class QtDummyGraphicsContext : public DummyGraphicsContext {
public:
Thin3DContext *CreateThin3DContext() override {
return T3DCreateGLContext();
}
};
//GUI
class MainUI : public QGLWidget
{
@ -62,6 +70,9 @@ public:
delete acc;
#endif
NativeShutdownGraphics();
graphicsContext->Shutdown();
delete graphicsContext;
graphicsContext = nullptr;
}
public slots:
@ -183,7 +194,8 @@ protected:
#ifndef USING_GLES2
glewInit();
#endif
NativeInitGraphics();
graphicsContext = new QtDummyGraphicsContext();
NativeInitGraphics(graphicsContext);
}
void paintGL()
@ -224,6 +236,7 @@ protected:
private:
InputState input_state;
QtDummyGraphicsContext *graphicsContext;
#if defined(MOBILE_DEVICE) && !defined(MAEMO)
QAccelerometer* acc;
#endif

View file

@ -134,7 +134,7 @@ namespace UI {
class SliderPopupScreen : public PopupScreen {
public:
SliderPopupScreen(int *value, int minValue, int maxValue, const std::string &title, int step = 1, const std::string &units = "")
: PopupScreen(title, "OK", "Cancel"), value_(value), minValue_(minValue), maxValue_(maxValue), step_(step), units_(units) {}
: PopupScreen(title, "OK", "Cancel"), units_(units), value_(value), minValue_(minValue), maxValue_(maxValue), step_(step), changing_(false) {}
virtual void CreatePopupContents(ViewGroup *parent) override;
Event OnChange;
@ -159,7 +159,7 @@ private:
class SliderFloatPopupScreen : public PopupScreen {
public:
SliderFloatPopupScreen(float *value, float minValue, float maxValue, const std::string &title, float step = 1.0f, const std::string &units = "")
: PopupScreen(title, "OK", "Cancel"), value_(value), minValue_(minValue), maxValue_(maxValue), step_(step), units_(units) {}
: PopupScreen(title, "OK", "Cancel"), units_(units), value_(value), minValue_(minValue), maxValue_(maxValue), step_(step), changing_(false) {}
void CreatePopupContents(UI::ViewGroup *parent) override;
Event OnChange;

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) {}
@ -83,9 +83,7 @@ bool System_InputBoxGetWString(const wchar_t *title, const std::wstring &default
void System_AskForPermission(SystemPermission permission) {}
PermissionStatus System_GetPermissionStatus(SystemPermission permission) { return PERMISSION_STATUS_GRANTED; }
#ifndef _WIN32
InputState input_state;
#endif
int printUsage(const char *progname, const char *reason)
{
@ -299,15 +297,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

@ -15,9 +15,11 @@
#include "input/input_state.h"
#include "net/resolve.h"
#include "ui/screen.h"
#include "thin3d/thin3d.h"
#include "input/keycodes.h"
#include "Core/Config.h"
#include "Common/GraphicsContext.h"
#include "GPU/GLES/FBO.h"
#include <sys/types.h>
@ -31,6 +33,13 @@
#define kCFCoreFoundationVersionNumber_IOS_9_0 1240.10
#endif
class IOSDummyGraphicsContext : public DummyGraphicsContext {
public:
Thin3DContext *CreateThin3DContext() override {
return T3DCreateGLContext();
}
};
float dp_xscale = 1.0f;
float dp_yscale = 1.0f;
@ -46,6 +55,7 @@ extern bool iosCanUseJit;
extern bool targetIsJailbroken;
ViewController* sharedViewController;
static GraphicsContext *graphicsContext;
@interface ViewController ()
{
@ -102,7 +112,7 @@ ViewController* sharedViewController;
targetIsJailbroken = true;
// if we're running on iOS arm64, only iOS <9 is supported with JIT.
// if we're running on anything that isn't arm64, then JIT is supported on all iOS versions.
if (![self isArm64] || [self isArm64] && kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber_IOS_9_0) {
if (![self isArm64] || ([self isArm64] && kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber_IOS_9_0)) {
iosCanUseJit = true;
}
}
@ -177,7 +187,9 @@ ViewController* sharedViewController;
pixel_in_dps = (float)pixel_xres / (float)dp_xres;
NativeInitGraphics();
graphicsContext = new IOSDummyGraphicsContext();
NativeInitGraphics(graphicsContext);
dp_xscale = (float)dp_xres / (float)pixel_xres;
dp_yscale = (float)dp_yres / (float)pixel_yres;
@ -222,7 +234,10 @@ ViewController* sharedViewController;
self.gameController = nil;
}
#endif
NativeShutdownGraphics();
graphicsContext->Shutdown();
delete graphicsContext;
graphicsContext = NULL;
NativeShutdown();
}
@ -247,7 +262,7 @@ ViewController* sharedViewController;
EndInputState(&input_state);
}
NativeRender();
NativeRender(graphicsContext);
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) {}

View file

@ -33,11 +33,13 @@
#include "base/NativeApp.h"
#include "base/logging.h"
#include "Common/CPUDetect.h"
#include "Common/ArmEmitter.h"
#include "input/input_state.h"
#include "ext/disarm.h"
#include "math/math_util.h"
#include "util/text/parsers.h"
#include "Common/CPUDetect.h"
#include "Common/ArmEmitter.h"
#include "Core/Config.h"
#include "Core/MIPS/MIPSVFPUUtils.h"
#include "Core/FileSystems/ISOFileSystem.h"
@ -46,6 +48,8 @@
#include "unittest/TestVertexJit.h"
#include "unittest/UnitTest.h"
InputState input_state;
std::string System_GetProperty(SystemProperty prop) { return ""; }
int System_GetPropertyInt(SystemProperty prop) { return -1; }
void NativeMessageReceived(const char *message, const char *value) {}