ios: Free framebuffer after it has been blitted to the UIWindow's background, instead of wastefully keeping it around

This commit is contained in:
UnknownShadow200 2022-04-24 10:03:42 +10:00
parent 5338115bf2
commit 3e8db412fd
7 changed files with 63 additions and 67 deletions

View file

@ -26,7 +26,6 @@
#include "Event.h" #include "Event.h"
struct FontDesc titleFont, textFont, hintFont; struct FontDesc titleFont, textFont, hintFont;
static struct LScreen* activeScreen;
/* Contains the pixels that are drawn to the window */ /* Contains the pixels that are drawn to the window */
static struct Bitmap framebuffer; static struct Bitmap framebuffer;
/* The area/region of the window that needs to be redrawn and presented to the screen. */ /* 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); Font_Free(&hintFont);
} }
void LBackend_SetScreen(struct LScreen* s) { activeScreen = s; } void LBackend_SetScreen(struct LScreen* s) { }
void LBackend_CloseScreen(struct LScreen* s) { activeScreen = NULL; } void LBackend_CloseScreen(struct LScreen* s) { }
void LBackend_WidgetRepositioned(struct LWidget* w) { void LBackend_WidgetRepositioned(struct LWidget* w) {
} }
@ -165,7 +164,7 @@ static CC_NOINLINE void DrawWidget(struct LWidget* w) {
} }
static CC_NOINLINE void RedrawAll(void) { static CC_NOINLINE void RedrawAll(void) {
struct LScreen* s = activeScreen; struct LScreen* s = Launcher_Active;
int i; int i;
s->DrawBackground(s, &framebuffer); s->DrawBackground(s, &framebuffer);
@ -176,7 +175,7 @@ static CC_NOINLINE void RedrawAll(void) {
} }
static CC_NOINLINE void RedrawDirty(void) { static CC_NOINLINE void RedrawDirty(void) {
struct LScreen* s = activeScreen; struct LScreen* s = Launcher_Active;
struct LWidget* w; struct LWidget* w;
int i; int i;
@ -201,8 +200,6 @@ void LBackend_Redraw(void) {
} }
void LBackend_Tick(void) { void LBackend_Tick(void) {
activeScreen->Tick(activeScreen);
if (pendingRedraw & REDRAW_ALL) { if (pendingRedraw & REDRAW_ALL) {
RedrawAll(); RedrawAll();
pendingRedraw = 0; pendingRedraw = 0;
@ -224,16 +221,16 @@ void LBackend_Tick(void) {
static void ReqeustRedraw(void* obj) { LBackend_Redraw(); } static void ReqeustRedraw(void* obj) { LBackend_Redraw(); }
static void OnPointerDown(void* obj, int idx) { static void OnPointerDown(void* obj, int idx) {
activeScreen->MouseDown(activeScreen, idx); Launcher_Active->MouseDown(Launcher_Active, idx);
} }
static void OnPointerUp(void* obj, int 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) { static void OnPointerMove(void* obj, int idx) {
if (!activeScreen) return; if (!Launcher_Active) return;
activeScreen->MouseMove(activeScreen, idx); Launcher_Active->MouseMove(Launcher_Active, idx);
} }
static void HookEvents(void) { static void HookEvents(void) {
@ -391,7 +388,7 @@ void LBackend_InputInit(struct LInput* w, int width) {
} }
static void LInput_DrawOuterBorder(struct LInput* w) { static void LInput_DrawOuterBorder(struct LInput* w) {
struct LScreen* s = activeScreen; struct LScreen* s = Launcher_Active;
struct Bitmap* bmp = &framebuffer; struct Bitmap* bmp = &framebuffer;
BitmapCol color = BitmapCol_Make(97, 81, 110, 255); BitmapCol color = BitmapCol_Make(97, 81, 110, 255);

View file

@ -1469,7 +1469,7 @@ static struct LWidget* settings_classic[] = {
static void SettingsScreen_LockOrientation(struct LCheckbox* w) { static void SettingsScreen_LockOrientation(struct LCheckbox* w) {
Options_SetBool(OPT_LANDSCAPE_MODE, w->value); Options_SetBool(OPT_LANDSCAPE_MODE, w->value);
Window_LockLandscapeOrientation(w->value); Window_LockLandscapeOrientation(w->value);
Launcher_Redraw(); LBackend_Redraw();
} }
#else #else
static void SettingsScreen_AutoClose(struct LCheckbox* w) { static void SettingsScreen_AutoClose(struct LCheckbox* w) {

View file

@ -161,8 +161,7 @@ void LCheckbox_Init(struct LCheckbox* w, const char* text) {
w->VTABLE = &lcheckbox_VTABLE; w->VTABLE = &lcheckbox_VTABLE;
w->tabSelectable = true; w->tabSelectable = true;
String_InitArray(w->text, w->_textBuffer); w->text = String_FromReadonly(text);
String_AppendConst(&w->text, text);
LBackend_CheckboxInit(w); LBackend_CheckboxInit(w);
} }

View file

@ -68,7 +68,6 @@ struct LCheckbox {
LWidget_Layout LWidget_Layout
cc_bool value; cc_bool value;
cc_string text; cc_string text;
char _textBuffer[STRING_SIZE];
void (*ValueChanged)(struct LCheckbox* w); void (*ValueChanged)(struct LCheckbox* w);
}; };
CC_NOINLINE void LCheckbox_Init(struct LCheckbox* w, const char* text); CC_NOINLINE void LCheckbox_Init(struct LCheckbox* w, const char* text);

View file

@ -21,7 +21,7 @@
#include "LBackend.h" #include "LBackend.h"
#include "PackedCol.h" #include "PackedCol.h"
static struct LScreen* activeScreen; struct LScreen* Launcher_Active;
struct FontDesc Launcher_LogoFont; struct FontDesc Launcher_LogoFont;
cc_bool Launcher_ShouldExit, Launcher_ShouldUpdate; cc_bool Launcher_ShouldExit, Launcher_ShouldUpdate;
@ -36,16 +36,17 @@ static struct Bitmap dirtBmp, stoneBmp;
static void CloseActiveScreen(void) { static void CloseActiveScreen(void) {
Window_CloseKeyboard(); Window_CloseKeyboard();
if (!activeScreen) return; if (!Launcher_Active) return;
activeScreen->Free(activeScreen); Launcher_Active->Free(Launcher_Active);
LBackend_CloseScreen(activeScreen); LBackend_CloseScreen(Launcher_Active);
Launcher_Active = NULL;
} }
void Launcher_SetScreen(struct LScreen* screen) { void Launcher_SetScreen(struct LScreen* screen) {
int i; int i;
CloseActiveScreen(); CloseActiveScreen();
activeScreen = screen; Launcher_Active = screen;
if (!screen->numWidgets) screen->Init(screen); if (!screen->numWidgets) screen->Init(screen);
screen->Show(screen); screen->Show(screen);
@ -168,7 +169,7 @@ static void OnResize(void* obj) {
LBackend_FreeFramebuffer(); LBackend_FreeFramebuffer();
LBackend_InitFramebuffer(); LBackend_InitFramebuffer();
if (activeScreen) activeScreen->Layout(activeScreen); if (Launcher_Active) Launcher_Active->Layout(Launcher_Active);
LBackend_Redraw(); LBackend_Redraw();
} }
@ -185,19 +186,19 @@ static cc_bool IsShutdown(int key) {
static void OnInputDown(void* obj, int key, cc_bool was) { static void OnInputDown(void* obj, int key, cc_bool was) {
if (IsShutdown(key)) Launcher_ShouldExit = true; 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) { 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) { 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) { 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; hasBitmappedFont = false;
CloseActiveScreen(); CloseActiveScreen();
activeScreen = NULL;
LBackend_FreeFramebuffer(); LBackend_FreeFramebuffer();
} }
@ -275,6 +275,7 @@ void Launcher_Run(void) {
Window_ProcessEvents(); Window_ProcessEvents();
if (!WindowInfo.Exists || Launcher_ShouldExit) break; if (!WindowInfo.Exists || Launcher_ShouldExit) break;
Launcher_Active->Tick(Launcher_Active);
LBackend_Tick(); LBackend_Tick();
Thread_Sleep(10); Thread_Sleep(10);
} }

View file

@ -7,8 +7,11 @@
struct LScreen; struct LScreen;
struct FontDesc; struct FontDesc;
/* The screen/menu currently being shown */
extern struct LScreen* Launcher_Active;
/* Default font for screen/menu titles */ /* Default font for screen/menu titles */
extern struct FontDesc Launcher_LogoFont; extern struct FontDesc Launcher_LogoFont;
/* Whether at the next tick, the launcher window should proceed to stop displaying frames and subsequently exit */ /* Whether at the next tick, the launcher window should proceed to stop displaying frames and subsequently exit */
extern cc_bool Launcher_ShouldExit; extern cc_bool Launcher_ShouldExit;
/* Whether game should be updated on exit */ /* Whether game should be updated on exit */

View file

@ -11,6 +11,7 @@
#include "LWidgets.h" #include "LWidgets.h"
#include "LScreens.h" #include "LScreens.h"
#include "LWeb.h" #include "LWeb.h"
#include "Funcs.h"
#include <mach-o/dyld.h> #include <mach-o/dyld.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <UIKit/UIPasteboard.h> #include <UIKit/UIPasteboard.h>
@ -304,32 +305,6 @@ void Window_Create2D(int width, int height) {
controller.view = view_handle; 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--------------------------------------------------------* *--------------------------------------------------------3D window--------------------------------------------------------*
@ -459,7 +434,8 @@ cc_result Process_StartOpen(const cc_string* args) {
} }
cc_result Process_StartGame2(const cc_string* args, int numArgs) { 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]); 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 Platform_GetCommandLineArgs(int argc, STRING_REF char** argv, cc_string* args) {
int count = gameNumArgs; int count = gameNumArgs;
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++)
{
args[i] = String_FromRawArray(gameArgs[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); int len = String_CalcLen(path, NATIVE_STR_LEN);
// get rid of filename at end of directory // 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; if (path[i] == '/') break;
} }
@ -586,11 +564,9 @@ void LBackend_WidgetRepositioned(struct LWidget* w) {
[view setFrame:rect]; [view setFrame:rect];
} }
struct LScreen* active;
void LBackend_SetScreen(struct LScreen* s) { 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; void* obj = s->widgets[i]->meta;
if (!obj) continue; if (!obj) continue;
@ -604,7 +580,8 @@ void LBackend_CloseScreen(struct LScreen* s) {
// remove all widgets from previous screen // remove all widgets from previous screen
NSArray<UIView*>* elems = [view_handle subviews]; NSArray<UIView*>* elems = [view_handle subviews];
for (UIView* view in elems) { for (UIView* view in elems)
{
[view removeFromSuperview]; [view removeFromSuperview];
} }
} }
@ -618,11 +595,13 @@ static void AssignView(void* widget, UIView* view) {
} }
static struct LWidget* FindWidgetForView(id obj) { static struct LWidget* FindWidgetForView(id obj) {
for (int i = 0; i < active->numWidgets; i++) { struct LScreen* s = Launcher_Active;
void* meta = active->widgets[i]->meta; for (int i = 0; i < s->numWidgets; i++)
{
void* meta = s->widgets[i]->meta;
if (meta != (__bridge void*)obj) continue; if (meta != (__bridge void*)obj) continue;
return active->widgets[i]; return s->widgets[i];
} }
return NULL; return NULL;
} }
@ -713,11 +692,29 @@ void LBackend_Init(void) {
CFBridgingRetain(ui_controller); // prevent GC TODO even needed? CFBridgingRetain(ui_controller); // prevent GC TODO even needed?
} }
void LBackend_MarkDirty(void* widget) { }
void LBackend_Tick(void) { }
void LBackend_Free(void) { } void LBackend_Free(void) { }
void LBackend_RedrawScreen(struct LScreen* s) { static CGContextRef win_ctx;
s->DrawBackground(s, &Launcher_Framebuffer); void LBackend_InitFramebuffer(void) { }
Launcher_MarkAllDirty(); 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);
} }
/*########################################################################################################################* /*########################################################################################################################*