From 3e8db412fd12c097de390704d4b4b3889a93103e Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Sun, 24 Apr 2022 10:03:42 +1000 Subject: [PATCH] ios: Free framebuffer after it has been blitted to the UIWindow's background, instead of wastefully keeping it around --- src/LBackend.c | 21 ++++++------- src/LScreens.c | 2 +- src/LWidgets.c | 3 +- src/LWidgets.h | 1 - src/Launcher.c | 23 +++++++------- src/Launcher.h | 3 ++ src/interop_ios.m | 77 +++++++++++++++++++++++------------------------ 7 files changed, 63 insertions(+), 67 deletions(-) diff --git a/src/LBackend.c b/src/LBackend.c index 6e30a016a..eedd2b930 100644 --- a/src/LBackend.c +++ b/src/LBackend.c @@ -26,7 +26,6 @@ #include "Event.h" struct FontDesc titleFont, textFont, hintFont; -static struct LScreen* activeScreen; /* Contains the pixels that are drawn to the window */ static struct Bitmap framebuffer; /* The area/region of the window that needs to be redrawn and presented to the screen. */ @@ -87,8 +86,8 @@ void LBackend_Free(void) { Font_Free(&hintFont); } -void LBackend_SetScreen(struct LScreen* s) { activeScreen = s; } -void LBackend_CloseScreen(struct LScreen* s) { activeScreen = NULL; } +void LBackend_SetScreen(struct LScreen* s) { } +void LBackend_CloseScreen(struct LScreen* s) { } void LBackend_WidgetRepositioned(struct LWidget* w) { } @@ -165,7 +164,7 @@ static CC_NOINLINE void DrawWidget(struct LWidget* w) { } static CC_NOINLINE void RedrawAll(void) { - struct LScreen* s = activeScreen; + struct LScreen* s = Launcher_Active; int i; s->DrawBackground(s, &framebuffer); @@ -176,7 +175,7 @@ static CC_NOINLINE void RedrawAll(void) { } static CC_NOINLINE void RedrawDirty(void) { - struct LScreen* s = activeScreen; + struct LScreen* s = Launcher_Active; struct LWidget* w; int i; @@ -201,8 +200,6 @@ void LBackend_Redraw(void) { } void LBackend_Tick(void) { - activeScreen->Tick(activeScreen); - if (pendingRedraw & REDRAW_ALL) { RedrawAll(); pendingRedraw = 0; @@ -224,16 +221,16 @@ void LBackend_Tick(void) { static void ReqeustRedraw(void* obj) { LBackend_Redraw(); } static void OnPointerDown(void* obj, int idx) { - activeScreen->MouseDown(activeScreen, idx); + Launcher_Active->MouseDown(Launcher_Active, idx); } static void OnPointerUp(void* obj, int idx) { - activeScreen->MouseUp(activeScreen, idx); + Launcher_Active->MouseUp(Launcher_Active, idx); } static void OnPointerMove(void* obj, int idx) { - if (!activeScreen) return; - activeScreen->MouseMove(activeScreen, idx); + if (!Launcher_Active) return; + Launcher_Active->MouseMove(Launcher_Active, idx); } static void HookEvents(void) { @@ -391,7 +388,7 @@ void LBackend_InputInit(struct LInput* w, int width) { } static void LInput_DrawOuterBorder(struct LInput* w) { - struct LScreen* s = activeScreen; + struct LScreen* s = Launcher_Active; struct Bitmap* bmp = &framebuffer; BitmapCol color = BitmapCol_Make(97, 81, 110, 255); diff --git a/src/LScreens.c b/src/LScreens.c index e9b2f80af..ab86b5c96 100644 --- a/src/LScreens.c +++ b/src/LScreens.c @@ -1469,7 +1469,7 @@ static struct LWidget* settings_classic[] = { static void SettingsScreen_LockOrientation(struct LCheckbox* w) { Options_SetBool(OPT_LANDSCAPE_MODE, w->value); Window_LockLandscapeOrientation(w->value); - Launcher_Redraw(); + LBackend_Redraw(); } #else static void SettingsScreen_AutoClose(struct LCheckbox* w) { diff --git a/src/LWidgets.c b/src/LWidgets.c index bb58dfb6a..ea815ea65 100644 --- a/src/LWidgets.c +++ b/src/LWidgets.c @@ -161,8 +161,7 @@ void LCheckbox_Init(struct LCheckbox* w, const char* text) { w->VTABLE = &lcheckbox_VTABLE; w->tabSelectable = true; - String_InitArray(w->text, w->_textBuffer); - String_AppendConst(&w->text, text); + w->text = String_FromReadonly(text); LBackend_CheckboxInit(w); } diff --git a/src/LWidgets.h b/src/LWidgets.h index 6ac1fb31c..af8263ad6 100644 --- a/src/LWidgets.h +++ b/src/LWidgets.h @@ -68,7 +68,6 @@ struct LCheckbox { LWidget_Layout cc_bool value; cc_string text; - char _textBuffer[STRING_SIZE]; void (*ValueChanged)(struct LCheckbox* w); }; CC_NOINLINE void LCheckbox_Init(struct LCheckbox* w, const char* text); diff --git a/src/Launcher.c b/src/Launcher.c index 3df41f29e..66250c69c 100644 --- a/src/Launcher.c +++ b/src/Launcher.c @@ -21,7 +21,7 @@ #include "LBackend.h" #include "PackedCol.h" -static struct LScreen* activeScreen; +struct LScreen* Launcher_Active; struct FontDesc Launcher_LogoFont; cc_bool Launcher_ShouldExit, Launcher_ShouldUpdate; @@ -36,16 +36,17 @@ static struct Bitmap dirtBmp, stoneBmp; static void CloseActiveScreen(void) { Window_CloseKeyboard(); - if (!activeScreen) return; + if (!Launcher_Active) return; - activeScreen->Free(activeScreen); - LBackend_CloseScreen(activeScreen); + Launcher_Active->Free(Launcher_Active); + LBackend_CloseScreen(Launcher_Active); + Launcher_Active = NULL; } void Launcher_SetScreen(struct LScreen* screen) { int i; CloseActiveScreen(); - activeScreen = screen; + Launcher_Active = screen; if (!screen->numWidgets) screen->Init(screen); screen->Show(screen); @@ -168,7 +169,7 @@ static void OnResize(void* obj) { LBackend_FreeFramebuffer(); LBackend_InitFramebuffer(); - if (activeScreen) activeScreen->Layout(activeScreen); + if (Launcher_Active) Launcher_Active->Layout(Launcher_Active); LBackend_Redraw(); } @@ -185,19 +186,19 @@ static cc_bool IsShutdown(int key) { static void OnInputDown(void* obj, int key, cc_bool was) { if (IsShutdown(key)) Launcher_ShouldExit = true; - activeScreen->KeyDown(activeScreen, key, was); + Launcher_Active->KeyDown(Launcher_Active, key, was); } static void OnKeyPress(void* obj, int c) { - activeScreen->KeyPress(activeScreen, c); + Launcher_Active->KeyPress(Launcher_Active, c); } static void OnTextChanged(void* obj, const cc_string* str) { - activeScreen->TextChanged(activeScreen, str); + Launcher_Active->TextChanged(Launcher_Active, str); } static void OnMouseWheel(void* obj, float delta) { - activeScreen->MouseWheel(activeScreen, delta); + Launcher_Active->MouseWheel(Launcher_Active, delta); } @@ -225,7 +226,6 @@ static void Launcher_Free(void) { hasBitmappedFont = false; CloseActiveScreen(); - activeScreen = NULL; LBackend_FreeFramebuffer(); } @@ -275,6 +275,7 @@ void Launcher_Run(void) { Window_ProcessEvents(); if (!WindowInfo.Exists || Launcher_ShouldExit) break; + Launcher_Active->Tick(Launcher_Active); LBackend_Tick(); Thread_Sleep(10); } diff --git a/src/Launcher.h b/src/Launcher.h index 477c29493..d7689220b 100644 --- a/src/Launcher.h +++ b/src/Launcher.h @@ -7,8 +7,11 @@ struct LScreen; struct FontDesc; +/* The screen/menu currently being shown */ +extern struct LScreen* Launcher_Active; /* Default font for screen/menu titles */ extern struct FontDesc Launcher_LogoFont; + /* Whether at the next tick, the launcher window should proceed to stop displaying frames and subsequently exit */ extern cc_bool Launcher_ShouldExit; /* Whether game should be updated on exit */ diff --git a/src/interop_ios.m b/src/interop_ios.m index 21a64b8e4..936cfcf24 100644 --- a/src/interop_ios.m +++ b/src/interop_ios.m @@ -11,6 +11,7 @@ #include "LWidgets.h" #include "LScreens.h" #include "LWeb.h" +#include "Funcs.h" #include #include #include @@ -304,32 +305,6 @@ void Window_Create2D(int width, int height) { controller.view = view_handle; } -static CGContextRef win_ctx; -static struct Bitmap fb_bmp; -void Window_AllocFramebuffer(struct Bitmap* bmp) { - bmp->scan0 = (BitmapCol*)Mem_Alloc(bmp->width * bmp->height, 4, "window pixels"); - fb_bmp = *bmp; - - win_ctx = CGBitmapContextCreate(bmp->scan0, bmp->width, bmp->height, 8, bmp->width * 4, - CGColorSpaceCreateDeviceRGB(), kCGBitmapByteOrder32Host | kCGImageAlphaNoneSkipFirst); -} - -void Window_DrawFramebuffer(Rect2D r) { - CGRect rect; - rect.origin.x = r.X; - rect.origin.y = WindowInfo.Height - r.Y - r.Height; - rect.size.width = r.Width; - rect.size.height = r.Height; - view_handle.layer.contents = CFBridgingRelease(CGBitmapContextCreateImage(win_ctx)); - // TODO always redraws entire launcher which is quite terrible performance wise - //[win_handle setNeedsDisplayInRect:rect]; -} - -void Window_FreeFramebuffer(struct Bitmap* bmp) { - Mem_Free(bmp->scan0); - CGContextRelease(win_ctx); -} - /*#########################################################################################################################* *--------------------------------------------------------3D window--------------------------------------------------------* @@ -459,7 +434,8 @@ cc_result Process_StartOpen(const cc_string* args) { } cc_result Process_StartGame2(const cc_string* args, int numArgs) { - for (int i = 0; i < numArgs; i++) { + for (int i = 0; i < numArgs; i++) + { String_CopyToRawArray(gameArgs[i], &args[i]); } @@ -469,7 +445,8 @@ cc_result Process_StartGame2(const cc_string* args, int numArgs) { int Platform_GetCommandLineArgs(int argc, STRING_REF char** argv, cc_string* args) { int count = gameNumArgs; - for (int i = 0; i < count; i++) { + for (int i = 0; i < count; i++) + { args[i] = String_FromRawArray(gameArgs[i]); } @@ -495,7 +472,8 @@ cc_result Platform_SetDefaultCurrentDirectory(int argc, char **argv) { int len = String_CalcLen(path, NATIVE_STR_LEN); // get rid of filename at end of directory - for (int i = len - 1; i >= 0; i--, len--) { + for (int i = len - 1; i >= 0; i--, len--) + { if (path[i] == '/') break; } @@ -586,11 +564,9 @@ void LBackend_WidgetRepositioned(struct LWidget* w) { [view setFrame:rect]; } -struct LScreen* active; void LBackend_SetScreen(struct LScreen* s) { - active = s; - - for (int i = 0; i < s->numWidgets; i++) { + for (int i = 0; i < s->numWidgets; i++) + { void* obj = s->widgets[i]->meta; if (!obj) continue; @@ -604,7 +580,8 @@ void LBackend_CloseScreen(struct LScreen* s) { // remove all widgets from previous screen NSArray* elems = [view_handle subviews]; - for (UIView* view in elems) { + for (UIView* view in elems) + { [view removeFromSuperview]; } } @@ -618,11 +595,13 @@ static void AssignView(void* widget, UIView* view) { } static struct LWidget* FindWidgetForView(id obj) { - for (int i = 0; i < active->numWidgets; i++) { - void* meta = active->widgets[i]->meta; + struct LScreen* s = Launcher_Active; + for (int i = 0; i < s->numWidgets; i++) + { + void* meta = s->widgets[i]->meta; if (meta != (__bridge void*)obj) continue; - return active->widgets[i]; + return s->widgets[i]; } return NULL; } @@ -713,11 +692,29 @@ void LBackend_Init(void) { CFBridgingRetain(ui_controller); // prevent GC TODO even needed? } +void LBackend_MarkDirty(void* widget) { } +void LBackend_Tick(void) { } void LBackend_Free(void) { } -void LBackend_RedrawScreen(struct LScreen* s) { - s->DrawBackground(s, &Launcher_Framebuffer); - Launcher_MarkAllDirty(); +static CGContextRef win_ctx; +void LBackend_InitFramebuffer(void) { } +void LBackend_FreeFramebuffer(void) { } + +void LBackend_Redraw(void) { + struct Bitmap fb_bmp; + fb_bmp.width = max(WindowInfo.Width, 1); + fb_bmp.height = max(WindowInfo.Height, 1); + fb_bmp.scan0 = (BitmapCol*)Mem_Alloc(fb_bmp.width * fb_bmp.height, 4, "window pixels"); + + win_ctx = CGBitmapContextCreate(fb_bmp.scan0, fb_bmp.width, fb_bmp.height, 8, fb_bmp.width * 4, + CGColorSpaceCreateDeviceRGB(), kCGBitmapByteOrder32Host | kCGImageAlphaNoneSkipFirst); + + struct LScreen* s = Launcher_Active; + s->DrawBackground(s, &fb_bmp); + view_handle.layer.contents = CFBridgingRelease(CGBitmapContextCreateImage(win_ctx)); + + Mem_Free(fb_bmp.scan0); + CGContextRelease(win_ctx); } /*########################################################################################################################*