Skip to content

Commit

Permalink
Merge pull request #13165 from hrydgard/sdl-vsync-fix
Browse files Browse the repository at this point in the history
Implement VSync control for SDL/OpenGL
  • Loading branch information
hrydgard authored Jul 19, 2020
2 parents cd6f161 + 6560192 commit 2c237fd
Show file tree
Hide file tree
Showing 14 changed files with 53 additions and 44 deletions.
10 changes: 0 additions & 10 deletions Common/GraphicsContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,3 @@ class GraphicsContext {

virtual Draw::DrawContext *GetDrawContext() = 0;
};

class DummyGraphicsContext : public GraphicsContext {
public:
void Shutdown() override {}
void SwapInterval(int interval) override {}
void SwapBuffers() override {}
void Resize() override {}

Draw::DrawContext *GetDrawContext() override { return nullptr; }
};
12 changes: 6 additions & 6 deletions Common/MsgHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@
#include "base/logging.h"
#include "util/text/utf8.h"

bool MsgHandler(const char *caption, const char *text, bool yes_no, int Style);
bool MsgHandler(const char *caption, const char *text, const char *file, int line, bool yes_no, int Style);

bool MsgAlert(bool yes_no, int Style, const char* format, ...) {
bool MsgAlert(bool yes_no, int Style, const char *file, int line, const char* format, ...) {
// Read message and write it to the log
char buffer[2048];
static const char *captions[] = {
Expand All @@ -42,10 +42,10 @@ bool MsgAlert(bool yes_no, int Style, const char* format, ...) {
CharArrayFromFormatV(buffer, sizeof(buffer)-1, format, args);
va_end(args);
// Normal logging (will also log to Android log)
ERROR_LOG(SYSTEM, "%s: %s", caption, buffer);
ERROR_LOG(SYSTEM, "(%s:%d) %s: %s", file, line, caption, buffer);
// Don't ignore questions, especially AskYesNo, PanicYesNo could be ignored
if (Style == QUESTION || Style == CRITICAL)
return MsgHandler(caption, buffer, yes_no, Style);
return MsgHandler(caption, buffer, file, line, yes_no, Style);
return true;
}

Expand All @@ -54,7 +54,7 @@ bool MsgAlert(bool yes_no, int Style, const char* format, ...) {
#endif

// Default non library dependent panic alert
bool MsgHandler(const char* caption, const char* text, bool yes_no, int Style) {
bool MsgHandler(const char* caption, const char* text, const char *file, int line, bool yes_no, int Style) {
#if defined(USING_WIN_UI)
int msgBoxStyle = MB_ICONINFORMATION;
if (Style == QUESTION) msgBoxStyle = MB_ICONQUESTION;
Expand All @@ -69,7 +69,7 @@ bool MsgHandler(const char* caption, const char* text, bool yes_no, int Style) {
return false;
#else
// Will use android-log if available, printf if not.
ELOG("%s", text);
ELOG("(%s:%d) %s", file, line, text);
return false;
#endif
}
8 changes: 4 additions & 4 deletions Common/MsgHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ enum MSG_TYPE {
CRITICAL
};

bool MsgAlert(bool yes_no, int Style, const char* format, ...)
bool MsgAlert(bool yes_no, int Style, const char *file, int line, const char* format, ...)
#ifdef __GNUC__
__attribute__((format(printf, 3, 4)))
__attribute__((format(printf, 5, 6)))
#endif
;

#define PanicAlert(...) MsgAlert(false, WARNING, __VA_ARGS__)
#define PanicAlert(...) MsgAlert(false, WARNING, __FILE__, __LINE__, __VA_ARGS__)

// Used only for asserts.
#define PanicYesNo(...) MsgAlert(true, CRITICAL, __VA_ARGS__)
#define PanicYesNo(...) MsgAlert(true, CRITICAL, __FILE__, __LINE__, __VA_ARGS__)
2 changes: 1 addition & 1 deletion Core/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ static int DefaultInternalResolution() {
}

static bool DefaultFrameskipUnthrottle() {
#if !PPSSPP_PLATFORM(WINDOWS) || PPSSPP_PLATFORM(UWP)
#if PPSSPP_PLATFORM(ANDROID) || defined(USING_QT_UI) || PPSSPP_PLATFORM(UWP) || PPSSPP_PLATFORM(IOS)
return true;
#else
return false;
Expand Down
2 changes: 1 addition & 1 deletion GPU/GPUCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ void GPUCommon::Reinitialize() {
}

void GPUCommon::UpdateVsyncInterval(bool force) {
#ifdef _WIN32
#if !(PPSSPP_PLATFORM(ANDROID) || USING_QT_UI || PPSSPP_PLATFORM(UWP) || PPSSPP_PLATFORM(IOS))
int desiredVSyncInterval = g_Config.bVSync ? 1 : 0;
if (PSP_CoreParameter().unthrottle) {
desiredVSyncInterval = 0;
Expand Down
2 changes: 0 additions & 2 deletions GPU/GPUCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -364,9 +364,7 @@ class GPUCommon : public GPUInterface, public GPUDebugInterface {
double timeSteppingStarted_;
double timeSpentStepping_;

#ifdef _WIN32
int lastVsync_ = -1;
#endif
};

struct CommonCommandTableEntry {
Expand Down
7 changes: 6 additions & 1 deletion Qt/QtMain.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ class QtGLGraphicsContext : public GraphicsContext {
renderManager_->SetInflightFrames(g_Config.iInflightFrames);
bool success = draw_->CreatePresets();
_assert_msg_(G3D, success, "Failed to compile preset shaders");

// TODO: Need to figure out how to implement SetSwapInterval for Qt.
}

~QtGLGraphicsContext() {
Expand All @@ -65,7 +67,10 @@ class QtGLGraphicsContext : public GraphicsContext {
}

void Shutdown() override {}
void SwapInterval(int interval) override {}
void SwapInterval(int interval) override {
// See TODO in constructor.
// renderManager_->SwapInterval(interval);
}
void SwapBuffers() override {}
void Resize() override {}

Expand Down
9 changes: 9 additions & 0 deletions SDL/SDLGLGraphicsContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -423,10 +423,19 @@ int SDLGLGraphicsContext::Init(SDL_Window *&window, int x, int y, int mode, std:
SDL_GL_SwapWindow(window_);
#endif
});

renderManager_->SetSwapIntervalFunction([&](int interval) {
ILOG("SDL SwapInterval: %d", interval);
SDL_GL_SetSwapInterval(interval);
});
window_ = window;
return 0;
}

void SDLGLGraphicsContext::SwapInterval(int interval) {
renderManager_->SwapInterval(interval);
}

void SDLGLGraphicsContext::Shutdown() {
}

Expand Down
7 changes: 6 additions & 1 deletion SDL/SDLGLGraphicsContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include "gfx/gl_common.h"
#include "Common/GraphicsContext.h"

class SDLGLGraphicsContext : public DummyGraphicsContext {
class SDLGLGraphicsContext : public GraphicsContext {
public:
SDLGLGraphicsContext() {
}
Expand All @@ -20,6 +20,11 @@ class SDLGLGraphicsContext : public DummyGraphicsContext {
// Do nothing, the render thread takes care of this.
}

// Gets forwarded to the render thread.
void SwapInterval(int interval) override;

void Resize() override {}

Draw::DrawContext *GetDrawContext() override {
return draw_;
}
Expand Down
4 changes: 2 additions & 2 deletions UI/GameSettingsScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ void GameSettingsScreen::CreateViews() {
return !g_Config.bSoftwareRendering && g_Config.iRenderingMode != FB_NON_BUFFERED_MODE;
});

#ifdef __ANDROID__
#if PPSSPP_PLATFORM(ANDROID)
if (System_GetPropertyInt(SYSPROP_DEVICE_TYPE) != DEVICE_TYPE_TV) {
static const char *deviceResolutions[] = { "Native device resolution", "Auto (same as Rendering)", "1x PSP", "2x PSP", "3x PSP", "4x PSP", "5x PSP" };
int max_res_temp = std::max(System_GetPropertyInt(SYSPROP_DISPLAY_XRES), System_GetPropertyInt(SYSPROP_DISPLAY_YRES)) / 480 + 2;
Expand All @@ -350,7 +350,7 @@ void GameSettingsScreen::CreateViews() {
}
#endif

#if !PPSSPP_PLATFORM(ANDROID)
#if !(PPSSPP_PLATFORM(ANDROID) || defined(USING_QT_UI) || PPSSPP_PLATFORM(UWP)) || PPSSPP_PLATFORM(IOS)
CheckBox *vSync = graphicsSettings->Add(new CheckBox(&g_Config.bVSync, gr->T("VSync")));
vSync->OnClick.Add([=](EventParams &e) {
NativeResized();
Expand Down
14 changes: 3 additions & 11 deletions ext/native/thin3d/VulkanRenderManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1040,7 +1040,7 @@ void VulkanRenderManager::BeginSubmitFrame(int frame) {
// Hopefully the resize will happen shortly. Ignore - one frame might look bad or something.
WLOG("VK_SUBOPTIMAL_KHR returned - ignoring");
} else if (res == VK_ERROR_OUT_OF_DATE_KHR) {
WLOG("VK_ERROR_OUT_OF_DATE_KHR returned - not presenting");
WLOG("VK_ERROR_OUT_OF_DATE_KHR returned - processing the frame, but not presenting");
frameData.skipSwap = true;
} else {
_assert_msg_(G3D, res == VK_SUCCESS, "vkAcquireNextImageKHR failed! result=%s", VulkanResultToString(res));
Expand Down Expand Up @@ -1084,11 +1084,7 @@ void VulkanRenderManager::Submit(int frame, bool triggerFrameFence) {
submit_info.pCommandBuffers = cmdBufs;
res = vkQueueSubmit(vulkan_->GetGraphicsQueue(), 1, &submit_info, VK_NULL_HANDLE);
if (res == VK_ERROR_DEVICE_LOST) {
#ifdef _WIN32
_assert_msg_(G3D, false, "Lost the Vulkan device! If this happens again, switch Graphics Backend from Vulkan to Direct3D11");
#else
_assert_msg_(G3D, false, "Lost the Vulkan device! If this happens again, switch Graphics Backend from Vulkan to OpenGL");
#endif
_assert_msg_(G3D, false, "Lost the Vulkan device in split submit! If this happens again, switch Graphics Backend away from Vulkan");
} else {
_assert_msg_(G3D, res == VK_SUCCESS, "vkQueueSubmit failed (init)! result=%s", VulkanResultToString(res));
}
Expand All @@ -1112,11 +1108,7 @@ void VulkanRenderManager::Submit(int frame, bool triggerFrameFence) {
}
res = vkQueueSubmit(vulkan_->GetGraphicsQueue(), 1, &submit_info, triggerFrameFence ? frameData.fence : frameData.readbackFence);
if (res == VK_ERROR_DEVICE_LOST) {
#ifdef _WIN32
_assert_msg_(G3D, false, "Lost the Vulkan device! If this happens again, switch Graphics Backend from Vulkan to Direct3D11");
#else
_assert_msg_(G3D, false, "Lost the Vulkan device! If this happens again, switch Graphics Backend from Vulkan to OpenGL");
#endif
_assert_msg_(G3D, false, "Lost the Vulkan device in vkQueueSubmit! If this happens again, switch Graphics Backend away from Vulkan");
} else {
_assert_msg_(G3D, res == VK_SUCCESS, "vkQueueSubmit failed (main, split=%d)! result=%s", (int)splitSubmit_, VulkanResultToString(res));
}
Expand Down
2 changes: 0 additions & 2 deletions ext/native/thin3d/thin3d_gl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,6 @@ class OpenGLPipeline : public Pipeline {
OpenGLPipeline(GLRenderManager *render) : render_(render) {
}
~OpenGLPipeline() {
DLOG("OpenGLPipeline released");
for (auto &iter : shaders) {
iter->Release();
}
Expand Down Expand Up @@ -979,7 +978,6 @@ Pipeline *OpenGLContext::CreateGraphicsPipeline(const PipelineDesc &desc) {
pipeline->dynamicUniforms = *desc.uniformDesc;
pipeline->dynamicUniformLocs_.resize(desc.uniformDesc->uniforms.size());
}
ILOG("Linking shaders.");
if (pipeline->LinkShaders()) {
// Build the rest of the virtual pipeline object.
pipeline->prim = primToGL[(int)desc.prim];
Expand Down
9 changes: 7 additions & 2 deletions headless/SDLHeadlessHost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ SDL_Window *CreateHiddenWindow() {
return SDL_CreateWindow("PPSSPPHeadless", 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, flags);
}

class GLDummyGraphicsContext : public DummyGraphicsContext {
class GLDummyGraphicsContext : public GraphicsContext {
public:
GLDummyGraphicsContext() {
}
Expand Down Expand Up @@ -92,6 +92,11 @@ class GLDummyGraphicsContext : public DummyGraphicsContext {
renderManager_->StopThread();
}

void Shutdown() override {}
void Resize() override {}
void SwapInterval(int interval) override {}
void SwapBuffers() override {}

private:
Draw::DrawContext *draw_;
GLRenderManager *renderManager_ = nullptr;
Expand Down Expand Up @@ -124,7 +129,7 @@ bool GLDummyGraphicsContext::InitFromRenderThread(std::string *errorMessage) {
glContext_ = SDL_GL_CreateContext(screen_);

// Ensure that the swap interval is set after context creation (needed for kmsdrm)
SDL_GL_SetSwapInterval(1);
SDL_GL_SetSwapInterval(0);

#ifndef USING_GLES2
// Some core profile drivers elide certain extensions from GL_EXTENSIONS/etc.
Expand Down
9 changes: 8 additions & 1 deletion ios/ViewController.mm
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
#define IS_IPAD() ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)
#define IS_IPHONE() ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone)

class IOSGraphicsContext : public DummyGraphicsContext {
class IOSGraphicsContext : public GraphicsContext {
public:
IOSGraphicsContext() {
CheckGLExtensions();
Expand All @@ -55,6 +55,12 @@
Draw::DrawContext *GetDrawContext() override {
return draw_;
}

void SwapInterval(int interval) override {}
void SwapBuffers() override {}
void Resize() override {}
void Shutdown() override {}

void ThreadStart() override {
renderManager_->ThreadStart(draw_);
}
Expand All @@ -71,6 +77,7 @@ void StopThread() override {
renderManager_->WaitUntilQueueIdle();
renderManager_->StopThread();
}

private:
Draw::DrawContext *draw_;
GLRenderManager *renderManager_;
Expand Down

0 comments on commit 2c237fd

Please sign in to comment.