mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-01-23 01:21:57 -05:00
ios: Free framebuffer after it has been blitted to the UIWindow's background, instead of wastefully keeping it around
This commit is contained in:
parent
5338115bf2
commit
3e8db412fd
7 changed files with 63 additions and 67 deletions
|
@ -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);
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*########################################################################################################################*
|
||||
|
|
Loading…
Reference in a new issue