From 17740f8664d299483251a19ffda4191fef93ec52 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Thu, 30 Jun 2022 17:14:45 +1000 Subject: [PATCH] Fix window showing garbage when resizing on 64 bit macOS (Thanks popdymc, fixes #957). Also change .vcxproj so that you show no longer need to change SDK version/platform toolset when compiling on a platform that isn't Windows 7 + VS 2015 The issue happened because a) when resizing the window, cocoa runs in the blocking resizing window event loop (i.e. effectively pauses/suspends the launcher's event loop) b) due to recent changes to the launcher content drawing until absolutely necessary, the contents would only get redrawn when LBackend_Tick was called However because of a), this meant that although resize events were delivered to the game which hence reallocated the framebuffer, the framebuffer did not actually get drawn to because LBackend_Tick never got called - hence why garbage appeared on screen --- {misc => ios}/CCIOS.xcodeproj/project.pbxproj | 0 src/ClassiCube.vcxproj | 10 ++++---- src/Event.c | 2 +- src/Event.h | 6 +++-- src/LBackend.c | 25 ++++++++++++------- src/Window_Android.c | 2 +- src/Window_Carbon.c | 2 +- src/Window_SDL.c | 2 +- src/Window_Win.c | 2 +- src/Window_X11.c | 2 +- src/interop_cocoa.m | 2 ++ 11 files changed, 33 insertions(+), 22 deletions(-) rename {misc => ios}/CCIOS.xcodeproj/project.pbxproj (100%) diff --git a/misc/CCIOS.xcodeproj/project.pbxproj b/ios/CCIOS.xcodeproj/project.pbxproj similarity index 100% rename from misc/CCIOS.xcodeproj/project.pbxproj rename to ios/CCIOS.xcodeproj/project.pbxproj diff --git a/src/ClassiCube.vcxproj b/src/ClassiCube.vcxproj index bee89cfff..0e8c20475 100644 --- a/src/ClassiCube.vcxproj +++ b/src/ClassiCube.vcxproj @@ -22,32 +22,32 @@ {8A7D82BD-178A-4785-B41B-70EDE998920A} Win32Proj ClassiCube - 8.1 + $(SDKVersion) Application true Unicode - v140 + $(DefaultPlatformToolset) Application false true Unicode - v140 + $(DefaultPlatformToolset) Application true - v140 + $(DefaultPlatformToolset) Unicode Application false - v140 + $(DefaultPlatformToolset) true Unicode diff --git a/src/Event.c b/src/Event.c index 50785b483..549f2a511 100644 --- a/src/Event.c +++ b/src/Event.c @@ -87,7 +87,7 @@ void Event_UnregisterAll(void) { ChatEvents.ChatSending.Count = 0; ChatEvents.ColCodeChanged.Count = 0; - WindowEvents.Redraw.Count = 0; + WindowEvents.RedrawNeeded.Count = 0; WindowEvents.Resized.Count = 0; WindowEvents.Closing.Count = 0; WindowEvents.FocusChanged.Count = 0; diff --git a/src/Event.h b/src/Event.h index 4d801e7f1..6d2a71162 100644 --- a/src/Event.h +++ b/src/Event.h @@ -108,7 +108,8 @@ void Event_UnregisterAll(void); /* NOTE: Event_UnregisterAll MUST be updated when events lists are changed */ /* Event API version supported by the client */ -/* Version 1 - Added NetEvents.PluginMessageReceived, */ +/* Version 1 - Added NetEvents.PluginMessageReceived */ +/* Version 2 - Added WindowEvents.Redrawing */ /* You MUST CHECK the event API version before attempting to use the events listed above, */ /* as otherwise if the player is using an older client that lacks some of the above events, */ /* you will be calling Event_Register on random data instead of the expected EventsList struct */ @@ -166,13 +167,14 @@ CC_VAR extern struct _ChatEventsList { } ChatEvents; CC_VAR extern struct _WindowEventsList { - struct Event_Void Redraw; /* Window contents invalidated, should be redrawn */ + struct Event_Void RedrawNeeded; /* Window contents invalidated and will need to be redrawn */ struct Event_Void Resized; /* Window is resized */ struct Event_Void Closing; /* Window is about to close (should free resources/save state/etc here) */ struct Event_Void FocusChanged; /* Focus of the window changed */ struct Event_Void StateChanged; /* State of the window changed (e.g. minimised, fullscreen) */ struct Event_Void Created; /* Window has been created, Window_Handle is valid now. */ struct Event_Void InactiveChanged; /* Inactive/background state of the window changed */ + struct Event_Void Redrawing; /* Window contents should be redrawn (as they are about to be displayed) */ } WindowEvents; CC_VAR extern struct _InputEventsList { diff --git a/src/LBackend.c b/src/LBackend.c index e5461ecf9..81ea98966 100644 --- a/src/LBackend.c +++ b/src/LBackend.c @@ -245,13 +245,7 @@ static CC_NOINLINE void RedrawDirty(void) { MarkAllDirty(); } -void LBackend_Redraw(void) { - pendingRedraw = REDRAW_ALL; - MarkAllDirty(); -} -void LBackend_ThemeChanged(void) { LBackend_Redraw(); } - -void LBackend_Tick(void) { +static CC_NOINLINE void DoRedraw(void) { if (pendingRedraw & REDRAW_ALL) { RedrawAll(); pendingRedraw = 0; @@ -259,8 +253,18 @@ void LBackend_Tick(void) { RedrawDirty(); pendingRedraw = 0; } +} +void LBackend_Redraw(void) { + pendingRedraw = REDRAW_ALL; + MarkAllDirty(); +} +void LBackend_ThemeChanged(void) { LBackend_Redraw(); } + +void LBackend_Tick(void) { + DoRedraw(); if (!dirty_rect.Width) return; + Window_DrawFramebuffer(dirty_rect); dirty_rect.X = 0; dirty_rect.Width = 0; dirty_rect.Y = 0; dirty_rect.Height = 0; @@ -270,7 +274,8 @@ void LBackend_Tick(void) { /*########################################################################################################################* *-----------------------------------------------------Event handling------------------------------------------------------* *#########################################################################################################################*/ -static void ReqeustRedraw(void* obj) { LBackend_Redraw(); } +static void ReqeustRedraw(void* obj) { LBackend_Redraw(); } +static void RedrawContents(void* obj) { DoRedraw(); } CC_NOINLINE static struct LWidget* GetWidgetAt(struct LScreen* s, int idx) { struct LWidget* w; @@ -361,13 +366,15 @@ static void OnTextChanged(void* obj, const cc_string* str) { } static void HookEvents(void) { - Event_Register_(&WindowEvents.Redraw, NULL, ReqeustRedraw); Event_Register_(&PointerEvents.Down, NULL, OnPointerDown); Event_Register_(&PointerEvents.Up, NULL, OnPointerUp); Event_Register_(&PointerEvents.Moved, NULL, OnPointerMove); Event_Register_(&InputEvents.Press, NULL, OnKeyPress); Event_Register_(&InputEvents.TextChanged, NULL, OnTextChanged); + + Event_Register_(&WindowEvents.RedrawNeeded, NULL, ReqeustRedraw); + Event_Register_(&WindowEvents.Redrawing, NULL, RedrawContents); } diff --git a/src/Window_Android.c b/src/Window_Android.c index db17cc176..2e96a20e7 100644 --- a/src/Window_Android.c +++ b/src/Window_Android.c @@ -154,7 +154,7 @@ static void JNICALL java_processSurfaceResized(JNIEnv* env, jobject o, jobject s static void JNICALL java_processSurfaceRedrawNeeded(JNIEnv* env, jobject o) { Platform_LogConst("WIN - REDRAW"); - Event_RaiseVoid(&WindowEvents.Redraw); + Event_RaiseVoid(&WindowEvents.RedrawNeeded); } static void JNICALL java_onStart(JNIEnv* env, jobject o) { diff --git a/src/Window_Carbon.c b/src/Window_Carbon.c index 78833534b..60833afc9 100644 --- a/src/Window_Carbon.c +++ b/src/Window_Carbon.c @@ -237,7 +237,7 @@ static OSStatus Window_ProcessWindowEvent(EventRef inEvent) { return eventNotHandledErr; case kEventWindowDrawContent: - Event_RaiseVoid(&WindowEvents.Redraw); + Event_RaiseVoid(&WindowEvents.RedrawNeeded); return eventNotHandledErr; } return eventNotHandledErr; diff --git a/src/Window_SDL.c b/src/Window_SDL.c index 432dabba0..00c184ed8 100644 --- a/src/Window_SDL.c +++ b/src/Window_SDL.c @@ -197,7 +197,7 @@ static void OnTextEvent(const SDL_Event* e) { static void OnWindowEvent(const SDL_Event* e) { switch (e->window.event) { case SDL_WINDOWEVENT_EXPOSED: - Event_RaiseVoid(&WindowEvents.Redraw); + Event_RaiseVoid(&WindowEvents.RedrawNeeded); break; case SDL_WINDOWEVENT_SIZE_CHANGED: RefreshWindowBounds(); diff --git a/src/Window_Win.c b/src/Window_Win.c index 4cfc05270..41e6e3e9d 100644 --- a/src/Window_Win.c +++ b/src/Window_Win.c @@ -119,7 +119,7 @@ static LRESULT CALLBACK Window_Procedure(HWND handle, UINT message, WPARAM wPara case WM_PAINT: ValidateRect(win_handle, NULL); - Event_RaiseVoid(&WindowEvents.Redraw); + Event_RaiseVoid(&WindowEvents.RedrawNeeded); return 0; case WM_WINDOWPOSCHANGED: diff --git a/src/Window_X11.c b/src/Window_X11.c index 50b6963cc..89f2b6115 100644 --- a/src/Window_X11.c +++ b/src/Window_X11.c @@ -541,7 +541,7 @@ void Window_ProcessEvents(void) { break; case Expose: - if (e.xexpose.count == 0) Event_RaiseVoid(&WindowEvents.Redraw); + if (e.xexpose.count == 0) Event_RaiseVoid(&WindowEvents.RedrawNeeded); break; case LeaveNotify: diff --git a/src/interop_cocoa.m b/src/interop_cocoa.m index 7f7fded50..6670c31a9 100644 --- a/src/interop_cocoa.m +++ b/src/interop_cocoa.m @@ -552,6 +552,8 @@ static void DoDrawFramebuffer(CGRect dirty) { NSGraphicsContext* nsContext; CGImageRef image; CGRect rect; + + Event_RaiseVoid(&WindowEvents.Redrawing); // Unfortunately CGImageRef is immutable, so changing the // underlying data doesn't change what shows when drawing.