rosalina: Dynamically alloc/free fb cache, exempt rosalina from reslimiting

This commit is contained in:
TuxSH 2020-05-08 01:17:46 +01:00
parent 0da90f61fc
commit 09fd199487
6 changed files with 89 additions and 28 deletions

View File

@ -38,7 +38,10 @@ void Manager_RegisterKips(void)
process->flags = PROCESSFLAG_KIP;
process->terminationStatus = TERMSTATUS_RUNNING;
assertSuccess(svcSetProcessResourceLimits(processHandle, g_manager.reslimits[RESLIMIT_CATEGORY_OTHER]));
if (i < 5) {
// Exempt rosalina from being resource-limited at all
assertSuccess(svcSetProcessResourceLimits(processHandle, g_manager.reslimits[RESLIMIT_CATEGORY_OTHER]));
}
}
ProcessList_Unlock(&g_manager.processList);

View File

@ -57,6 +57,8 @@
#define FB_BOTTOM_VRAM_ADDR ((void *)0x1F48F000) // cached
#define FB_BOTTOM_VRAM_PA 0x1848F000
#define FB_BOTTOM_SIZE (320 * 240 * 2)
#define FB_SCREENSHOT_SIZE (52 + 400 * 240 * 2)
#define SCREEN_BOT_WIDTH 320
#define SCREEN_BOT_HEIGHT 240
@ -72,6 +74,8 @@
#define DRAW_MAX_FORMATTED_STRING_SIZE 512
void Draw_Init(void);
void Draw_Lock(void);
void Draw_Unlock(void);
@ -81,7 +85,11 @@ u32 Draw_DrawFormattedString(u32 posX, u32 posY, u32 color, const char *fmt, ...
void Draw_FillFramebuffer(u32 value);
void Draw_ClearFramebuffer(void);
void Draw_SetupFramebuffer(void);
u32 Draw_AllocateFramebufferCache(void);
void Draw_FreeFramebufferCache(void);
void *Draw_GetFramebufferCache(void);
u32 Draw_GetFramebufferCacheSize(void);
u32 Draw_SetupFramebuffer(void);
void Draw_RestoreFramebuffer(void);
void Draw_FlushFramebuffer(void);
u32 Draw_GetCurrentFramebufferAddress(bool top, bool left);

View File

@ -33,21 +33,18 @@
#include "menu.h"
#include "utils.h"
u8 framebufferCache[FB_BOTTOM_SIZE];
static u32 gpuSavedFramebufferAddr1, gpuSavedFramebufferAddr2, gpuSavedFramebufferFormat, gpuSavedFramebufferStride;
static u32 framebufferCacheSize;
static void *framebufferCache;
static RecursiveLock lock;
void Draw_Init(void)
{
RecursiveLock_Init(&lock);
}
void Draw_Lock(void)
{
static bool lockInitialized = false;
if(!lockInitialized)
{
RecursiveLock_Init(&lock);
lockInitialized = true;
}
RecursiveLock_Lock(&lock);
}
@ -129,34 +126,78 @@ void Draw_ClearFramebuffer(void)
Draw_FillFramebuffer(0);
}
void Draw_SetupFramebuffer(void)
u32 Draw_AllocateFramebufferCache(void)
{
// Try to see how much we can allocate...
// Can't use fbs in FCRAM when Home Menu is active (AXI config related maybe?)
u32 addr = 0x0D000000;
u32 tmp;
u32 minSize = (FB_BOTTOM_SIZE + 0xFFF) & ~0xFFF;
u32 maxSize = (FB_SCREENSHOT_SIZE + 0xFFF) & ~0xFFF;
u32 remaining = (u32)osGetMemRegionFree(MEMREGION_SYSTEM);
u32 size = remaining < maxSize ? remaining : maxSize;
if (size < minSize || R_FAILED(svcControlMemory(&tmp, addr, 0, size, MEMOP_ALLOC, MEMPERM_READ | MEMPERM_WRITE)))
{
framebufferCache = NULL;
framebufferCacheSize = 0;
}
else
{
framebufferCache = (u32 *)addr;
framebufferCacheSize = size;
}
return framebufferCacheSize;
}
void Draw_FreeFramebufferCache(void)
{
u32 tmp;
svcControlMemory(&tmp, (u32)framebufferCache, 0, framebufferCacheSize, MEMOP_FREE, 0);
framebufferCacheSize = 0;
framebufferCache = NULL;
}
void *Draw_GetFramebufferCache(void)
{
return framebufferCache;
}
u32 Draw_GetFramebufferSize(void)
{
return framebufferCacheSize;
}
u32 Draw_SetupFramebuffer(void)
{
while((GPU_PSC0_CNT | GPU_PSC1_CNT | GPU_TRANSFER_CNT | GPU_CMDLIST_CNT) & 1);
svcFlushEntireDataCache();
Draw_FlushFramebuffer();
memcpy(framebufferCache, FB_BOTTOM_VRAM_ADDR, FB_BOTTOM_SIZE);
Draw_ClearFramebuffer();
Draw_FlushFramebuffer();
gpuSavedFramebufferAddr1 = GPU_FB_BOTTOM_ADDR_1;
gpuSavedFramebufferAddr2 = GPU_FB_BOTTOM_ADDR_2;
gpuSavedFramebufferFormat = GPU_FB_BOTTOM_FMT;
gpuSavedFramebufferStride = GPU_FB_BOTTOM_STRIDE;
GPU_FB_BOTTOM_ADDR_1 = GPU_FB_BOTTOM_ADDR_2 = FB_BOTTOM_VRAM_PA;
GPU_FB_BOTTOM_FMT = (GPU_FB_BOTTOM_FMT & ~7) | 2;
GPU_FB_BOTTOM_FMT = (GPU_FB_BOTTOM_FMT & ~7) | GSP_RGB565_OES;
GPU_FB_BOTTOM_STRIDE = 240 * 2;
Draw_FlushFramebuffer();
return framebufferCacheSize;
}
void Draw_RestoreFramebuffer(void)
{
memcpy(FB_BOTTOM_VRAM_ADDR, framebufferCache, FB_BOTTOM_SIZE);
Draw_FlushFramebuffer();
GPU_FB_BOTTOM_ADDR_1 = gpuSavedFramebufferAddr1;
GPU_FB_BOTTOM_ADDR_2 = gpuSavedFramebufferAddr2;
GPU_FB_BOTTOM_FMT = gpuSavedFramebufferFormat;
GPU_FB_BOTTOM_STRIDE = gpuSavedFramebufferStride;
Draw_FlushFramebuffer();
}
void Draw_FlushFramebuffer(void)

View File

@ -41,6 +41,7 @@
#include "menus/sysconfig.h"
#include "input_redirection.h"
#include "minisoc.h"
#include "draw.h"
#include "task_runner.h"
@ -219,6 +220,7 @@ int main(void)
if(R_FAILED(svcCreateEvent(&terminationRequestEvent, RESET_STICKY)))
svcBreak(USERBREAK_ASSERT);
Draw_Init();
Cheat_SeedRng(svcGetSystemTick());
MyThread *menuThread = menuCreateThread();

View File

@ -175,30 +175,39 @@ void menuThreadMain(void)
}
}
static s32 menuRefCount = 0;
static u32 menuRefCount = 0;
void menuEnter(void)
{
if(AtomicPostIncrement(&menuRefCount) == 0)
Draw_Lock();
if(menuRefCount++ == 0)
{
svcKernelSetState(0x10000, 1);
svcSleepThread(5 * 1000 * 100LL);
if (Draw_AllocateFramebufferCache() == 0)
{
// Oops
menuRefCount = 0;
svcKernelSetState(0x10000, 1);
svcSleepThread(5 * 1000 * 100LL);
}
Draw_SetupFramebuffer();
Draw_ClearFramebuffer();
}
Draw_Unlock();
}
void menuLeave(void)
{
svcSleepThread(50 * 1000 * 1000);
if(AtomicDecrement(&menuRefCount) == 0)
Draw_Lock();
if(--menuRefCount == 0)
{
Draw_Lock();
Draw_FlushFramebuffer();
Draw_RestoreFramebuffer();
Draw_Unlock();
Draw_FreeFramebufferCache();
svcKernelSetState(0x10000, 1);
}
Draw_Unlock();
}
static void menuDraw(Menu *menu, u32 selected)

View File

@ -151,9 +151,9 @@ void RosalinaMenu_PowerOff(void) // Soft shutdown.
while(!terminationRequest);
}
extern u8 framebufferCache[FB_BOTTOM_SIZE];
void RosalinaMenu_TakeScreenshot(void)
{
u8 *framebufferCache = (u8 *)Draw_GetFramebufferCache();
#define TRY(expr) if(R_FAILED(res = (expr))) goto end;
u64 total;
@ -280,8 +280,6 @@ end:
IFile_Close(&file);
svcFlushEntireDataCache();
Draw_SetupFramebuffer();
Draw_ClearFramebuffer();
Draw_FlushFramebuffer();
Draw_Unlock();
do