From 92485ed222d7841bc8994ceddedb85a68420ab96 Mon Sep 17 00:00:00 2001 From: Gleb Mazovetskiy Date: Sun, 18 Apr 2021 23:55:42 +0100 Subject: [PATCH] DiabloUI: Support non-doublebuf HW surfaces If using a hardware surface without double-buffering, perform rendering in a single blit to avoid flickering and tearing. --- Source/DiabloUI/diabloui.cpp | 4 ++++ Source/DiabloUI/diabloui.h | 13 ++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/Source/DiabloUI/diabloui.cpp b/Source/DiabloUI/diabloui.cpp index 6c52e2740..10f479471 100644 --- a/Source/DiabloUI/diabloui.cpp +++ b/Source/DiabloUI/diabloui.cpp @@ -623,6 +623,8 @@ void LoadBackgroundArt(const char *pszFile, int frames) fadeValue = 0; BlackPalette(); SDL_FillRect(DiabloUiSurface(), NULL, 0x000000); + if (DiabloUiSurface() == pal_surface) + BltFast(nullptr, nullptr); RenderPresent(); } @@ -655,6 +657,8 @@ void UiFadeIn() } SetFadeLevel(fadeValue); } + if (DiabloUiSurface() == pal_surface) + BltFast(nullptr, nullptr); RenderPresent(); } diff --git a/Source/DiabloUI/diabloui.h b/Source/DiabloUI/diabloui.h index 2698f907d..f874def68 100644 --- a/Source/DiabloUI/diabloui.h +++ b/Source/DiabloUI/diabloui.h @@ -80,7 +80,18 @@ extern bool (*gfnHeroInfo)(bool (*fninfofunc)(_uiheroinfo *)); inline SDL_Surface *DiabloUiSurface() { - return GetOutputSurface(); + auto *output_surface = GetOutputSurface(); + +#ifdef USE_SDL1 + // When using a non double-buffered hardware surface, render the UI + // to an off-screen surface first to avoid flickering / tearing. + if ((output_surface->flags & SDL_HWSURFACE) != 0 + && (output_surface->flags & SDL_DOUBLEBUF) == 0) { + return pal_surface; + } +#endif + + return output_surface; } void UiDestroy();