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"
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);

View file

@ -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) {

View file

@ -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);
}

View file

@ -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);

View file

@ -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);
}

View file

@ -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 */

View file

@ -11,6 +11,7 @@
#include "LWidgets.h"
#include "LScreens.h"
#include "LWeb.h"
#include "Funcs.h"
#include <mach-o/dyld.h>
#include <sys/stat.h>
#include <UIKit/UIPasteboard.h>
@ -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<UIView*>* 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);
}
/*########################################################################################################################*