Try to simplify launcher framebuffer drawing, hopefully doesn't break

This commit is contained in:
UnknownShadow200 2024-02-03 14:20:41 +11:00
parent 2955330e49
commit 61e901ec10
22 changed files with 56 additions and 87 deletions

View File

@ -453,7 +453,7 @@ void Gfx_BeginFrame(void) { }
void Gfx_EndFrame(void) {
Rect2D r = { 0, 0, width, height };
Window_DrawFramebuffer(r);
Window_DrawFramebuffer(r, &fb_bmp);
}
void Gfx_SetFpsLimit(cc_bool vsync, float minFrameMs) {

View File

@ -270,7 +270,7 @@ void LBackend_Tick(void) {
DoRedraw();
if (!dirty_rect.Width) return;
Window_DrawFramebuffer(dirty_rect);
Window_DrawFramebuffer(dirty_rect, &framebuffer.bmp);
dirty_rect.x = 0; dirty_rect.Width = 0;
dirty_rect.y = 0; dirty_rect.Height = 0;
}

View File

@ -562,7 +562,7 @@ void Launcher_DrawTitle(struct FontDesc* font, const char* text, struct Context2
DrawTitleText(font, text, ctx, ANCHOR_CENTRE, ANCHOR_CENTRE);
Rect2D rect = { 0, 0, bmp.width, bmp.height };
Window_DrawFramebuffer(rect);
Window_DrawFramebuffer(rect, &bmp);
Window_3DS_SetRenderScreen(scr);
Window_FreeFramebuffer(&bmp);
}

View File

@ -168,8 +168,9 @@ cc_result Window_SaveFileDialog(const struct SaveFileDialogArgs* args);
/* NOTE: This MUST be called whenever the window is resized. */
void Window_AllocFramebuffer(struct Bitmap* bmp);
/* Transfers pixels from the allocated framebuffer to the on-screen window. */
/* r can be used to only update a small region of pixels (may be ignored) */
void Window_DrawFramebuffer(Rect2D r);
/* r can be used to only update a small region of pixels (may be ignored) */
/* NOTE: bmp must have come from Window_AllocFramebuffer */
void Window_DrawFramebuffer(Rect2D r, struct Bitmap* bmp);
/* Frees the previously allocated framebuffer. */
void Window_FreeFramebuffer(struct Bitmap* bmp);

View File

@ -178,24 +178,16 @@ void Window_UpdateRawMouse(void) { }
/*########################################################################################################################*
*------------------------------------------------------Framebuffer--------------------------------------------------------*
*#########################################################################################################################*/
static struct Bitmap top_fb_bmp, btm_fb_bmp;
void Window_AllocFramebuffer(struct Bitmap* bmp) {
bmp->scan0 = (BitmapCol*)Mem_Alloc(bmp->width * bmp->height, 4, "window pixels");
if (renderScreen == TOP_SCREEN) {
top_fb_bmp = *bmp;
} else {
btm_fb_bmp = *bmp;
}
}
void Window_DrawFramebuffer(Rect2D r) {
void Window_DrawFramebuffer(Rect2D r, struct Bitmap* bmp) {
u16 width, height;
gfxScreen_t screen = (renderScreen == TOP_SCREEN) ? GFX_TOP : GFX_BOTTOM;
gfxSetDoubleBuffering(screen, false);
u8* fb = gfxGetFramebuffer(screen, GFX_LEFT, &width, &height);
struct Bitmap *bmp = (renderScreen == TOP_SCREEN) ? &top_fb_bmp : &btm_fb_bmp;
// SRC y = 0 to 240
// SRC x = 0 to 400
// DST X = 0 to 240
@ -223,9 +215,6 @@ void Window_DrawFramebuffer(Rect2D r) {
}
void Window_FreeFramebuffer(struct Bitmap* bmp) {
if (top_fb_bmp.scan0 == bmp->scan0) top_fb_bmp.scan0 = NULL;
if (btm_fb_bmp.scan0 == bmp->scan0) btm_fb_bmp.scan0 = NULL;
Mem_Free(bmp->scan0);
}

View File

@ -453,13 +453,11 @@ cc_result Window_SaveFileDialog(const struct SaveFileDialogArgs* save_args) {
return OK ? 0 : ERR_INVALID_ARGUMENT;
}
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;
}
void Window_DrawFramebuffer(Rect2D r) {
void Window_DrawFramebuffer(Rect2D r, struct Bitmap* bmp) {
ANativeWindow_Buffer buffer;
cc_uint32* src;
cc_uint32* dst;
@ -479,15 +477,16 @@ void Window_DrawFramebuffer(Rect2D r) {
/* In some rare cases, the returned locked region will be entire area of the surface */
/* This can cause a crash if the surface has been resized (i.e. device rotated), */
/* but the framebuffer has not been resized yet. So always constrain bounds. */
b.left = min(b.left, fb_bmp.width); b.right = min(b.right, fb_bmp.width);
b.top = min(b.top, fb_bmp.height); b.bottom = min(b.bottom, fb_bmp.height);
b.left = min(b.left, bmp->width); b.right = min(b.right, bmp->width);
b.top = min(b.top, bmp->height); b.bottom = min(b.bottom, bmp->height);
src = (cc_uint32*)fb_bmp.scan0 + b.left;
dst = (cc_uint32*)buffer.bits + b.left;
src = (cc_uint32*)bmp->scan0 + b.left;
dst = (cc_uint32*)buffer.bits + b.left;
size = (b.right - b.left) * 4;
for (y = b.top; y < b.bottom; y++) {
Mem_Copy(dst + y * buffer.stride, src + y * fb_bmp.width, size);
for (y = b.top; y < b.bottom; y++)
{
Mem_Copy(dst + y * buffer.stride, src + y * bmp->width, size);
}
res = ANativeWindow_unlockAndPost(win_handle);
if (res) Logger_Abort2(res, "Unlocking window pixels");

View File

@ -602,7 +602,6 @@ cc_result Window_SaveFileDialog(const struct SaveFileDialogArgs* args) {
}
static CGrafPtr fb_port;
static struct Bitmap fb_bmp;
static CGColorSpaceRef colorSpace;
void Window_AllocFramebuffer(struct Bitmap* bmp) {
@ -610,10 +609,9 @@ void Window_AllocFramebuffer(struct Bitmap* bmp) {
bmp->scan0 = Mem_Alloc(bmp->width * bmp->height, 4, "window pixels");
colorSpace = CGColorSpaceCreateDeviceRGB();
fb_bmp = *bmp;
}
void Window_DrawFramebuffer(Rect2D r) {
void Window_DrawFramebuffer(Rect2D r, struct Bitmap* bmp) {
CGContextRef context = NULL;
CGDataProviderRef provider;
CGImageRef image;
@ -633,9 +631,9 @@ void Window_DrawFramebuffer(Rect2D r) {
if (err) Logger_Abort2(err, "Begin draw");
/* TODO: REPLACE THIS AWFUL HACK */
provider = CGDataProviderCreateWithData(NULL, fb_bmp.scan0,
Bitmap_DataSize(fb_bmp.width, fb_bmp.height), NULL);
image = CGImageCreate(fb_bmp.width, fb_bmp.height, 8, 32, fb_bmp.width * 4, colorSpace,
provider = CGDataProviderCreateWithData(NULL, bmp->scan0,
Bitmap_DataSize(bmp->width, bmp->height), NULL);
image = CGImageCreate(bmp->width, bmp->height, 8, 32, bmp->width * 4, colorSpace,
kCGBitmapByteOrder32Host | kCGImageAlphaNoneSkipFirst, provider, NULL, 0, 0);
CGContextDrawImage(context, rect, image);

View File

@ -231,14 +231,11 @@ void Window_UpdateRawMouse(void) { }
/*########################################################################################################################*
*------------------------------------------------------Framebuffer--------------------------------------------------------*
*#########################################################################################################################*/
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;
}
void Window_DrawFramebuffer(Rect2D r) {
void Window_DrawFramebuffer(Rect2D r, struct Bitmap* bmp) {
// TODO: double buffering ??
// https://dcemulation.org/phpBB/viewtopic.php?t=99999
// https://dcemulation.org/phpBB/viewtopic.php?t=43214
@ -246,7 +243,7 @@ void Window_DrawFramebuffer(Rect2D r) {
for (int y = r.y; y < r.y + r.Height; y++)
{
BitmapCol* src = Bitmap_GetRow(&fb_bmp, y);
BitmapCol* src = Bitmap_GetRow(bmp, y);
uint16_t* dst = vram_s + vid_mode->width * y;
for (int x = r.x; x < r.x + r.Width; x++)

View File

@ -449,10 +449,8 @@ void Window_DisableRawMouse(void) { Input.RawMode = false; }
/*########################################################################################################################*
*------------------------------------------------------Framebuffer--------------------------------------------------------*
*#########################################################################################################################*/
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;
}
// TODO: Get rid of this complexity and use the 3D API instead..
@ -475,7 +473,7 @@ static u32 CvtRGB (u8 r1, u8 g1, u8 b1, u8 r2, u8 g2, u8 b2)
return (y1 << 24) | (cb << 16) | (y2 << 8) | cr;
}
void Window_DrawFramebuffer(Rect2D r) {
void Window_DrawFramebuffer(Rect2D r, struct Bitmap* bmp) {
// When coming back from the 3D game, framebuffer might have changed
if (needsFBUpdate) {
VIDEO_SetNextFramebuffer(xfb);
@ -489,8 +487,8 @@ void Window_DrawFramebuffer(Rect2D r) {
// TODO XFB is raw yuv, but is absolutely a pain to work with..
for (int y = r.y; y < r.y + r.Height; y++)
{
cc_uint32* src = fb_bmp.scan0 + y * fb_bmp.width + r.x;
u16* dst = (u16*)xfb + y * rmode->fbWidth + r.x;
cc_uint32* src = bmp->scan0 + y * bmp->width + r.x;
u16* dst = (u16*)xfb + y * rmode->fbWidth + r.x;
for (int x = 0; x < r.Width / 2; x++) {
cc_uint32 rgb0 = src[(x<<1) + 0];

View File

@ -125,22 +125,20 @@ void Window_UpdateRawMouse(void) { }
/*########################################################################################################################*
*------------------------------------------------------Framebuffer--------------------------------------------------------*
*#########################################################################################################################*/
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;
}
void Window_DrawFramebuffer(Rect2D r) {
void Window_DrawFramebuffer(Rect2D r, struct Bitmap* bmp) {
surface_t* fb = display_get();
cc_uint32* src = (cc_uint32*)fb_bmp.scan0;
cc_uint32* src = (cc_uint32*)bmp->scan0;
cc_uint8* dst = (cc_uint8*)fb->buffer;
for (int y = 0; y < fb_bmp.height; y++)
for (int y = 0; y < bmp->height; y++)
{
Mem_Copy(dst + y * fb->stride,
src + y * fb_bmp.width,
fb_bmp.width * 4);
src + y * bmp->width,
bmp->width * 4);
}
display_show(fb);

View File

@ -163,7 +163,6 @@ void Window_DisableRawMouse(void) { Input.RawMode = false; }
*------------------------------------------------------Framebuffer--------------------------------------------------------*
*#########################################################################################################################*/
static framebuffer_t win_fb;
static struct Bitmap fb_bmp;
void Window_Create2D(int width, int height) {
ResetGfxState();
@ -180,10 +179,9 @@ void Window_Create2D(int width, int height) {
void Window_AllocFramebuffer(struct Bitmap* bmp) {
bmp->scan0 = (BitmapCol*)Mem_Alloc(bmp->width * bmp->height, 4, "window pixels");
fb_bmp = *bmp;
}
void Window_DrawFramebuffer(Rect2D r) {
void Window_DrawFramebuffer(Rect2D r, struct Bitmap* bmp) {
// FlushCache bios call https://psi-rockin.github.io/ps2tek/
// mode=0: Flush data cache (invalidate+writeback dirty contents to memory)
FlushCache(0);
@ -191,7 +189,7 @@ void Window_DrawFramebuffer(Rect2D r) {
packet_t* packet = packet_init(50,PACKET_NORMAL);
qword_t* q = packet->data;
q = draw_texture_transfer(q, fb_bmp.scan0, fb_bmp.width, fb_bmp.height, GS_PSM_32,
q = draw_texture_transfer(q, bmp->scan0, bmp->width, bmp->height, GS_PSM_32,
win_fb.address, win_fb.width);
q = draw_texture_flush(q);

View File

@ -318,7 +318,6 @@ void Window_DisableRawMouse(void) { Input.RawMode = false; }
/*########################################################################################################################*
*------------------------------------------------------Framebuffer--------------------------------------------------------*
*#########################################################################################################################*/
static struct Bitmap fb_bmp;
static u32 fb_offset;
extern u32* Gfx_AllocImage(u32* offset, s32 w, s32 h);
@ -327,17 +326,16 @@ extern void Gfx_TransferImage(u32 offset, s32 w, s32 h);
void Window_AllocFramebuffer(struct Bitmap* bmp) {
u32* pixels = Gfx_AllocImage(&fb_offset, bmp->width, bmp->height);
bmp->scan0 = pixels;
fb_bmp = *bmp;
Gfx_ClearCol(PackedCol_Make(0x40, 0x60, 0x80, 0xFF));
}
void Window_DrawFramebuffer(Rect2D r) {
void Window_DrawFramebuffer(Rect2D r, struct Bitmap* bmp) {
// TODO test
Gfx_BeginFrame();
Gfx_Clear();
// TODO: Only transfer dirty region instead of the entire bitmap
Gfx_TransferImage(fb_offset, fb_bmp.width, fb_bmp.height);
Gfx_TransferImage(fb_offset, bmp->width, bmp->height);
Gfx_EndFrame();
}

View File

@ -114,25 +114,23 @@ void Window_UpdateRawMouse(void) { }
/*########################################################################################################################*
*------------------------------------------------------Framebuffer--------------------------------------------------------*
*#########################################################################################################################*/
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;
}
void Window_DrawFramebuffer(Rect2D r) {
void Window_DrawFramebuffer(Rect2D r, struct Bitmap* bmp) {
void* fb = sceGeEdramGetAddr();
sceDisplayWaitVblankStart();
sceDisplaySetMode(0, SCREEN_WIDTH, SCREEN_HEIGHT);
sceDisplaySetFrameBuf(fb, BUFFER_WIDTH, PSP_DISPLAY_PIXEL_FORMAT_8888, PSP_DISPLAY_SETBUF_IMMEDIATE);
cc_uint32* src = (cc_uint32*)fb_bmp.scan0 + r.x;
cc_uint32* dst = (cc_uint32*)fb + r.x;
cc_uint32* src = (cc_uint32*)bmp->scan0 + r.x;
cc_uint32* dst = (cc_uint32*)fb + r.x;
for (int y = r.y; y < r.y + r.Height; y++)
{
Mem_Copy(dst + y * BUFFER_WIDTH, src + y * fb_bmp.width, r.Width * 4);
Mem_Copy(dst + y * BUFFER_WIDTH, src + y * bmp->width, r.Width * 4);
}
}
@ -147,7 +145,7 @@ void Window_FreeFramebuffer(struct Bitmap* bmp) {
bmp->height = SCREEN_HEIGHT;
}
void Window_DrawFramebuffer(Rect2D r) {
void Window_DrawFramebuffer(Rect2D r, struct Bitmap* bmp) {
//sceDisplayWaitVblankStart();
//sceDisplaySetMode(0, SCREEN_WIDTH, SCREEN_HEIGHT);
//sceDisplaySetFrameBuf(sceGeEdramGetAddr(), BUFFER_WIDTH, PSP_DISPLAY_PIXEL_FORMAT_8888, PSP_DISPLAY_SETBUF_IMMEDIATE);

View File

@ -193,7 +193,7 @@ void Window_AllocFramebuffer(struct Bitmap* bmp) {
fb_bmp = *bmp;
}
void Window_DrawFramebuffer(Rect2D r) {
void Window_DrawFramebuffer(Rect2D r, struct Bitmap* bmp) {
sceDisplayWaitVblankStart();
Gfx_NextFramebuffer();
}

View File

@ -317,7 +317,7 @@ void Window_AllocFramebuffer(struct Bitmap* bmp) {
}
}
void Window_DrawFramebuffer(Rect2D r) {
void Window_DrawFramebuffer(Rect2D r, struct Bitmap* bmp) {
SDL_Rect rect;
rect.x = r.x; rect.w = r.Width;
rect.y = r.y; rect.h = r.Height;

View File

@ -669,7 +669,7 @@ cc_result Window_SaveFileDialog(const struct SaveFileDialogArgs* args) {
}
void Window_AllocFramebuffer(struct Bitmap* bmp) { }
void Window_DrawFramebuffer(Rect2D r) { }
void Window_DrawFramebuffer(Rect2D r, struct Bitmap* bmp) { }
void Window_FreeFramebuffer(struct Bitmap* bmp) { }
extern void interop_OpenKeyboard(const char* text, int type, const char* placeholder);

View File

@ -683,7 +683,7 @@ void Window_AllocFramebuffer(struct Bitmap* bmp) {
if (!draw_DIB) Logger_Abort2(GetLastError(), "Failed to create DIB");
}
void Window_DrawFramebuffer(Rect2D r) {
void Window_DrawFramebuffer(Rect2D r, struct Bitmap* bmp) {
HGDIOBJ oldSrc = SelectObject(draw_DC, draw_DIB);
BitBlt(win_DC, r.x, r.y, r.Width, r.Height, draw_DC, r.x, r.y, SRCCOPY);
SelectObject(draw_DC, oldSrc);

View File

@ -1053,7 +1053,6 @@ cc_result Window_SaveFileDialog(const struct SaveFileDialogArgs* args) {
static GC fb_gc;
static XImage* fb_image;
static struct Bitmap fb_bmp;
static void* fb_data;
static int fb_fast;
@ -1067,13 +1066,12 @@ void Window_AllocFramebuffer(struct Bitmap* bmp) {
fb_fast = win_visual.depth == 24 || win_visual.depth == 32;
fb_data = fb_fast ? bmp->scan0 : Mem_Alloc(bmp->width * bmp->height, 4, "window blit");
fb_bmp = *bmp;
fb_image = XCreateImage(win_display, win_visual.visual,
win_visual.depth, ZPixmap, 0, fb_data,
bmp->width, bmp->height, 32, 0);
}
static void BlitFramebuffer(int x1, int y1, int width, int height) {
static void BlitFramebuffer(int x1, int y1, int width, int height, struct Bitmap* bmp) {
unsigned char* dst;
BitmapCol* row;
BitmapCol src;
@ -1082,7 +1080,7 @@ static void BlitFramebuffer(int x1, int y1, int width, int height) {
int x, y;
for (y = y1; y < y1 + height; y++) {
row = Bitmap_GetRow(&fb_bmp, y);
row = Bitmap_GetRow(bmp, y);
dst = ((unsigned char*)fb_image->data) + y * fb_image->bytes_per_line;
for (x = x1; x < x1 + width; x++) {
@ -1115,9 +1113,9 @@ static void BlitFramebuffer(int x1, int y1, int width, int height) {
}
}
void Window_DrawFramebuffer(Rect2D r) {
void Window_DrawFramebuffer(Rect2D r, struct Bitmap* bmp) {
/* Convert 32 bit depth to window depth when required */
if (!fb_fast) BlitFramebuffer(r.x, r.y, r.Width, r.Height);
if (!fb_fast) BlitFramebuffer(r.x, r.y, r.Width, r.Height, bmp);
XPutImage(win_display, win_handle, fb_gc, fb_image,
r.x, r.y, r.x, r.y, r.Width, r.Height);

View File

@ -179,25 +179,23 @@ void Window_UpdateRawMouse(void) { }
/*########################################################################################################################*
*------------------------------------------------------Framebuffer--------------------------------------------------------*
*#########################################################################################################################*/
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;
}
void Window_DrawFramebuffer(Rect2D r) {
void Window_DrawFramebuffer(Rect2D r, struct Bitmap* bmp) {
void* fb = XVideoGetFB();
//XVideoWaitForVBlank();
// XVideoWaitForVBlank installs an interrupt handler for VBlank -
// however this will cause pbkit's attempt to install an interrupt
// handler fail - so instead just accept tearing in the launcher
cc_uint32* src = (cc_uint32*)fb_bmp.scan0 + r.x;
cc_uint32* dst = (cc_uint32*)fb + r.x;
cc_uint32* src = (cc_uint32*)bmp->scan0 + r.x;
cc_uint32* dst = (cc_uint32*)fb + r.x;
for (int y = r.y; y < r.y + r.Height; y++)
{
Mem_Copy(dst + y * fb_bmp.width, src + y * fb_bmp.width, r.Width * 4);
Mem_Copy(dst + y * bmp->width, src + y * bmp->width, r.Width * 4);
}
}

View File

@ -124,22 +124,21 @@ void Window_UpdateRawMouse(void) { }
/*########################################################################################################################*
*------------------------------------------------------Framebuffer--------------------------------------------------------*
*#########################################################################################################################*/
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;
}
void Window_DrawFramebuffer(Rect2D r) {return;
void Window_DrawFramebuffer(Rect2D r, struct Bitmap* bmp) {
return;
//void* fb = XVideoGetFB();
//XVideoWaitForVBlank();
/*cc_uint32* src = (cc_uint32*)fb_bmp.scan0 + r.X;
/*cc_uint32* src = (cc_uint32*)bmp->scan0 + r.X;
cc_uint32* dst = (cc_uint32*)fb + r.X;
for (int y = r.Y; y < r.Y + r.Height; y++)
{
Mem_Copy(dst + y * fb_bmp.width, src + y * fb_bmp.width, r.Width * 4);
Mem_Copy(dst + y * bmp->width, src + y * bmp->width, r.Width * 4);
}*/
}

View File

@ -705,7 +705,7 @@ void Window_AllocFramebuffer(struct Bitmap* bmp) {
bmp->scan0 = (BitmapCol*)win_framebuffer->Bits();
}
void Window_DrawFramebuffer(Rect2D r) {
void Window_DrawFramebuffer(Rect2D r, struct Bitmap* bmp) {
// TODO rect should maybe subtract -1 too ????
BRect rect(r.x, r.y, r.x + r.Width, r.y + r.Height);
win_handle->Lock();

View File

@ -709,7 +709,7 @@ static void DoDrawFramebuffer(NSRect dirty) {
CGColorSpaceRelease(colorSpace);
}
void Window_DrawFramebuffer(Rect2D r) {
void Window_DrawFramebuffer(Rect2D r, struct Bitmap* bmp) {
NSRect rect;
rect.origin.x = r.x;
rect.origin.y = Window_Main.Height - r.y - r.Height;