Split up Window_InitRaw into Window_AllocFramebuffer/Window_FreeFramebuffer, and call Window_FreeFramebuffer when closing launcher

This commit is contained in:
UnknownShadow200 2019-07-14 10:35:52 +10:00
parent 9b92a5a2c0
commit c1fdca87b9
3 changed files with 82 additions and 101 deletions

View File

@ -105,7 +105,8 @@ static void Launcher_OnResize(void* obj) {
Launcher_Framebuffer.Width = Game.Width; Launcher_Framebuffer.Width = Game.Width;
Launcher_Framebuffer.Height = Game.Height; Launcher_Framebuffer.Height = Game.Height;
Window_InitRaw(&Launcher_Framebuffer); Window_FreeFramebuffer(&Launcher_Framebuffer);
Window_AllocFramebuffer(&Launcher_Framebuffer);
if (Launcher_Screen) Launcher_Screen->Reposition(Launcher_Screen); if (Launcher_Screen) Launcher_Screen->Reposition(Launcher_Screen);
Launcher_Redraw(); Launcher_Redraw();
} }
@ -158,7 +159,7 @@ static void Launcher_Display(void) {
} }
Launcher_Screen->OnDisplay(Launcher_Screen); Launcher_Screen->OnDisplay(Launcher_Screen);
Window_DrawRaw(Launcher_Dirty); Window_DrawFramebuffer(Launcher_Dirty);
Launcher_Dirty.X = 0; Launcher_Dirty.Width = 0; Launcher_Dirty.X = 0; Launcher_Dirty.Width = 0;
Launcher_Dirty.Y = 0; Launcher_Dirty.Height = 0; Launcher_Dirty.Y = 0; Launcher_Dirty.Height = 0;
@ -210,6 +211,7 @@ static void Launcher_Free(void) {
Launcher_Screen->Free(Launcher_Screen); Launcher_Screen->Free(Launcher_Screen);
Launcher_Screen = NULL; Launcher_Screen = NULL;
Window_FreeFramebuffer(&Launcher_Framebuffer);
} }
void Launcher_Run(void) { void Launcher_Run(void) {
@ -229,7 +231,7 @@ void Launcher_Run(void) {
Launcher_Framebuffer.Width = Game.Width; Launcher_Framebuffer.Width = Game.Width;
Launcher_Framebuffer.Height = Game.Height; Launcher_Framebuffer.Height = Game.Height;
Window_InitRaw(&Launcher_Framebuffer); Window_AllocFramebuffer(&Launcher_Framebuffer);
Http_Component.Init(); Http_Component.Init();
Resources_CheckExistence(); Resources_CheckExistence();

View File

@ -550,27 +550,29 @@ void Window_ShowDialog(const char* title, const char* msg) {
static HDC draw_DC; static HDC draw_DC;
static HBITMAP draw_DIB; static HBITMAP draw_DIB;
void Window_InitRaw(Bitmap* bmp) { void Window_AllocFramebuffer(Bitmap* bmp) {
BITMAPINFO hdr = { 0 }; BITMAPINFO hdr = { 0 };
if (!draw_DC) draw_DC = CreateCompatibleDC(win_DC); if (!draw_DC) draw_DC = CreateCompatibleDC(win_DC);
if (draw_DIB) DeleteObject(draw_DIB);
hdr.bmiHeader.biSize = sizeof(BITMAPINFO); hdr.bmiHeader.biSize = sizeof(BITMAPINFO);
hdr.bmiHeader.biWidth = bmp->Width; hdr.bmiHeader.biWidth = bmp->Width;
hdr.bmiHeader.biHeight = -bmp->Height; hdr.bmiHeader.biHeight = -bmp->Height;
hdr.bmiHeader.biBitCount = 32; hdr.bmiHeader.biBitCount = 32;
hdr.bmiHeader.biPlanes = 1; hdr.bmiHeader.biPlanes = 1;
draw_DIB = CreateDIBSection(draw_DC, &hdr, 0, (void**)&bmp->Scan0, NULL, 0); draw_DIB = CreateDIBSection(draw_DC, &hdr, DIB_RGB_COLORS, (void**)&bmp->Scan0, NULL, 0);
} }
void Window_DrawRaw(Rect2D r) { void Window_DrawFramebuffer(Rect2D r) {
HGDIOBJ oldSrc = SelectObject(draw_DC, draw_DIB); HGDIOBJ oldSrc = SelectObject(draw_DC, draw_DIB);
BOOL success = BitBlt(win_DC, r.X, r.Y, r.Width, r.Height, draw_DC, r.X, r.Y, SRCCOPY); BitBlt(win_DC, r.X, r.Y, r.Width, r.Height, draw_DC, r.X, r.Y, SRCCOPY);
SelectObject(draw_DC, oldSrc); SelectObject(draw_DC, oldSrc);
} }
void Window_FreeFramebuffer(Bitmap* bmp) {
DeleteObject(draw_DIB);
}
static void Window_InitRawMouse(void) { static void Window_InitRawMouse(void) {
RAWINPUTDEVICE rid; RAWINPUTDEVICE rid;
_registerRawInput = (FUNC_RegisterRawInput)DynamicLib_GetFrom("USER32.DLL", "RegisterRawInputDevices"); _registerRawInput = (FUNC_RegisterRawInput)DynamicLib_GetFrom("USER32.DLL", "RegisterRawInputDevices");
@ -1406,25 +1408,27 @@ void Window_ShowDialog(const char* title, const char* msg) {
X11Window_Free(&w); X11Window_Free(&w);
} }
static GC win_gc; static GC fb_gc;
static XImage* win_image; static XImage* fb_image;\
void Window_InitRaw(Bitmap* bmp) { void Window_AllocFramebuffer(Bitmap* bmp) {
if (!win_gc) win_gc = XCreateGC(win_display, win_handle, 0, NULL); if (!fb_gc) fb_gc = XCreateGC(win_display, win_handle, 0, NULL);
if (win_image) XFree(win_image);
Mem_Free(bmp->Scan0);
bmp->Scan0 = (uint8_t*)Mem_Alloc(bmp->Width * bmp->Height, 4, "window pixels"); bmp->Scan0 = (uint8_t*)Mem_Alloc(bmp->Width * bmp->Height, 4, "window pixels");
fb_image = XCreateImage(win_display, win_visual.visual,
win_image = XCreateImage(win_display, win_visual.visual,
win_visual.depth, ZPixmap, 0, (char*)bmp->Scan0, win_visual.depth, ZPixmap, 0, (char*)bmp->Scan0,
bmp->Width, bmp->Height, 32, 0); bmp->Width, bmp->Height, 32, 0);
} }
void Window_DrawRaw(Rect2D r) { void Window_DrawFramebuffer(Rect2D r) {
XPutImage(win_display, win_handle, win_gc, win_image, XPutImage(win_display, win_handle, fb_gc, fb_image,
r.X, r.Y, r.X, r.Y, r.Width, r.Height); r.X, r.Y, r.X, r.Y, r.Width, r.Height);
} }
void Window_FreeFramebuffer(Bitmap* bmp) {
XFree(fb_image);
Mem_Free(bmp->Scan0);
}
void Window_EnableRawMouse(void) { Window_DefaultEnableRawMouse(); } void Window_EnableRawMouse(void) { Window_DefaultEnableRawMouse(); }
void Window_UpdateRawMouse(void) { Window_DefaultUpdateRawMouse(); } void Window_UpdateRawMouse(void) { Window_DefaultUpdateRawMouse(); }
void Window_DisableRawMouse(void) { Window_DefaultDisableRawMouse(); } void Window_DisableRawMouse(void) { Window_DefaultDisableRawMouse(); }
@ -1931,95 +1935,57 @@ void Window_ShowDialog(const char* title, const char* msg) {
RunStandardAlert(dialog, NULL, &itemHit); RunStandardAlert(dialog, NULL, &itemHit);
} }
static CGrafPtr fb_port;
/* TODO: WORK OUT WHY THIS IS BROKEN!!!! static Bitmap fb_bmp;
static CGrafPtr win_winPort;
static CGImageRef win_image;
void Window_InitRaw(Bitmap* bmp) {
CGColorSpaceRef colorSpace;
CGDataProviderRef provider;
if (!win_winPort) win_winPort = GetWindowPort(win_handle);
Mem_Free(bmp->Scan0);
bmp->Scan0 = Mem_Alloc(bmp->Width * bmp->Height, 4, "window pixels");
colorSpace = CGColorSpaceCreateDeviceRGB();
provider = CGDataProviderCreateWithData(NULL, bmp->Scan0,
Bitmap_DataSize(bmp->Width, bmp->Height), NULL);
win_image = CGImageCreate(bmp->Width, bmp->Height, 8, 32, bmp->Width * 4, colorSpace,
kCGBitmapByteOrder32Little | kCGImageAlphaFirst, provider, NULL, 0, 0);
CGColorSpaceRelease(colorSpace);
CGDataProviderRelease(provider);
}
void Window_DrawRaw(Rect2D r) {
CGContextRef context = NULL;
CGRect rect;
OSStatus err;
err = QDBeginCGContext(win_winPort, &context);
if (err) Logger_Abort2(err, "Begin draw");
// TODO: Only update changed bit..
rect.origin.x = 0; rect.origin.y = 0;
rect.size.width = Window_Width;
rect.size.height = Window_Height;
CGContextDrawImage(context, rect, win_image);
CGContextSynchronize(context);
err = QDEndCGContext(win_winPort, &context);
if (err) Logger_Abort2(err, "End draw");
}
*/
static CGrafPtr win_winPort;
static CGImageRef win_image;
static Bitmap* bmp_;
static CGColorSpaceRef colorSpace; static CGColorSpaceRef colorSpace;
static CGDataProviderRef provider;
void Window_InitRaw(Bitmap* bmp) { void Window_AllocFramebuffer(Bitmap* bmp) {
if (!win_winPort) win_winPort = GetWindowPort(win_handle); if (!fb_port) fb_port = GetWindowPort(win_handle);
Mem_Free(bmp->Scan0);
bmp->Scan0 = Mem_Alloc(bmp->Width * bmp->Height, 4, "window pixels"); bmp->Scan0 = Mem_Alloc(bmp->Width * bmp->Height, 4, "window pixels");
colorSpace = CGColorSpaceCreateDeviceRGB(); colorSpace = CGColorSpaceCreateDeviceRGB();
fb_bmp = *bmp;
bmp_ = bmp;
//CGColorSpaceRelease(colorSpace);
} }
void Window_DrawRaw(Rect2D r) { void Window_DrawFramebuffer(Rect2D r) {
CGContextRef context = NULL; CGContextRef context = NULL;
CGDataProviderRef provider;
GImageRef image;
CGRect rect; CGRect rect;
OSStatus err; OSStatus err;
err = QDBeginCGContext(win_winPort, &context); /* Unfortunately CGImageRef is immutable, so changing the */
if (err) Logger_Abort2(err, "Begin draw"); /* underlying data doesn't change what shows when drawing. */
/* TODO: REPLACE THIS AWFUL HACK */ /* TODO: Use QuickDraw alternative instead */
/* TODO: Only update changed bit.. */ /* TODO: Only update changed bit.. */
rect.origin.x = 0; rect.origin.y = 0; rect.origin.x = 0; rect.origin.y = 0;
rect.size.width = Window_Width; rect.size.width = Window_Width;
rect.size.height = Window_Height; rect.size.height = Window_Height;
provider = CGDataProviderCreateWithData(NULL, bmp_->Scan0, err = QDBeginCGContext(fb_port, &context);
Bitmap_DataSize(bmp_->Width, bmp_->Height), NULL); if (err) Logger_Abort2(err, "Begin draw");
win_image = CGImageCreate(bmp_->Width, bmp_->Height, 8, 32, bmp_->Width * 4, colorSpace, /* 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,
kCGBitmapByteOrder32Little | kCGImageAlphaFirst, provider, NULL, 0, 0); kCGBitmapByteOrder32Little | kCGImageAlphaFirst, provider, NULL, 0, 0);
CGContextDrawImage(context, rect, win_image); CGContextDrawImage(context, rect, image);
CGContextSynchronize(context); CGContextSynchronize(context);
err = QDEndCGContext(win_winPort, &context); err = QDEndCGContext(fb_port, &context);
if (err) Logger_Abort2(err, "End draw"); if (err) Logger_Abort2(err, "End draw");
CGImageRelease(win_image); CGImageRelease(image);
CGDataProviderRelease(provider); CGDataProviderRelease(provider);
} }
void Window_FreeFramebuffer(Bitmap* bmp) {
Mem_Free(bmp->Scan0);
CGColorSpaceRelease(colorSpace);
}
void Window_EnableRawMouse(void) { Window_DefaultEnableRawMouse(); } void Window_EnableRawMouse(void) { Window_DefaultEnableRawMouse(); }
void Window_UpdateRawMouse(void) { Window_DefaultUpdateRawMouse(); } void Window_UpdateRawMouse(void) { Window_DefaultUpdateRawMouse(); }
void Window_DisableRawMouse(void) { Window_DefaultDisableRawMouse(); } void Window_DisableRawMouse(void) { Window_DefaultDisableRawMouse(); }
@ -2307,7 +2273,7 @@ void Window_ShowDialog(const char* title, const char* msg) {
} }
static SDL_Surface* surface; static SDL_Surface* surface;
void Window_InitRaw(Bitmap* bmp) { void Window_AllocFramebuffer(Bitmap* bmp) {
surface = SDL_GetWindowSurface(win_handle); surface = SDL_GetWindowSurface(win_handle);
if (!surface) Window_SDLFail("getting window surface"); if (!surface) Window_SDLFail("getting window surface");
@ -2318,13 +2284,19 @@ void Window_InitRaw(Bitmap* bmp) {
bmp->Scan0 = surface->pixels; bmp->Scan0 = surface->pixels;
} }
void Window_DrawRaw(Rect2D r) { void Window_DrawFramebuffer(Rect2D r) {
SDL_Rect rect; SDL_Rect rect;
rect.x = r.X; rect.w = r.Width; rect.x = r.X; rect.w = r.Width;
rect.y = r.Y; rect.h = r.Height; rect.y = r.Y; rect.h = r.Height;
SDL_UpdateWindowSurfaceRects(win_handle, &rect, 1); SDL_UpdateWindowSurfaceRects(win_handle, &rect, 1);
} }
void Window_FreeFramebuffer(Bitmap* bmp) {
/* SDL docs explicitly say to NOT free the surface */
/* https://wiki.libsdl.org/SDL_GetWindowSurface */
/* TODO: Do we still need to unlock it though? */
}
void Window_EnableRawMouse(void) { void Window_EnableRawMouse(void) {
Window_RegrabMouse(); Window_RegrabMouse();
SDL_SetRelativeMouseMode(true); SDL_SetRelativeMouseMode(true);
@ -2754,8 +2726,9 @@ void Window_ShowDialog(const char* title, const char* msg) {
EM_ASM_({ alert(UTF8ToString($0) + "\n\n" + UTF8ToString($1)); }, title, msg); EM_ASM_({ alert(UTF8ToString($0) + "\n\n" + UTF8ToString($1)); }, title, msg);
} }
void Window_InitRaw(Bitmap* bmp) { Logger_Abort("Unsupported"); } void Window_AllocFramebuffer(Bitmap* bmp) { }
void Window_DrawRaw(Rect2D r) { Logger_Abort("Unsupported"); } void Window_DrawFramebuffer(Rect2D r) { }
void Window_FreeFramebuffer(Bitmap* bmp) { }
void Window_EnableRawMouse(void) { void Window_EnableRawMouse(void) {
Window_RegrabMouse(); Window_RegrabMouse();
@ -2957,14 +2930,14 @@ void Window_ShowDialog(const char* title, const char* msg) {
(*env)->DeleteLocalRef(env, args[1].l); (*env)->DeleteLocalRef(env, args[1].l);
} }
static Bitmap srcBmp; static Bitmap fb_bmp;
void Window_InitRaw(Bitmap* bmp) { void Window_AllocFramebuffer(Bitmap* bmp) {
Mem_Free(bmp->Scan0); Mem_Free(bmp->Scan0);
bmp->Scan0 = Mem_Alloc(bmp->Width * bmp->Height, 4, "window pixels"); bmp->Scan0 = Mem_Alloc(bmp->Width * bmp->Height, 4, "window pixels");
srcBmp = *bmp; fb_bmp = *bmp;
} }
void Window_DrawRaw(Rect2D r) { void Window_DrawFramebuffer(Rect2D r) {
ANativeWindow_Buffer buffer; ANativeWindow_Buffer buffer;
uint32_t* src; uint32_t* src;
uint32_t* dst; uint32_t* dst;
@ -2990,17 +2963,21 @@ void Window_DrawRaw(Rect2D r) {
Platform_Log3("WIN SIZE: %i,%i %i", &width, &height, &format); Platform_Log3("WIN SIZE: %i,%i %i", &width, &height, &format);
Platform_Log4("BUF SIZE: %i,%i %i/%i", &buffer.width, &buffer.height, &buffer.format, &buffer.stride); Platform_Log4("BUF SIZE: %i,%i %i/%i", &buffer.width, &buffer.height, &buffer.format, &buffer.stride);
src = (uint32_t*)srcBmp.Scan0 + b.left; src = (uint32_t*)fb_bmp.Scan0 + b.left;
dst = (uint32_t*)buffer.bits + b.left; dst = (uint32_t*)buffer.bits + b.left;
size = (b.right - b.left) * 4; size = (b.right - b.left) * 4;
for (y = b.top; y < b.bottom; y++) { for (y = b.top; y < b.bottom; y++) {
Mem_Copy(dst + y * buffer.stride, src + y * srcBmp.Width, size); Mem_Copy(dst + y * buffer.stride, src + y * fb_bmp.Width, size);
} }
res = ANativeWindow_unlockAndPost(win_handle); res = ANativeWindow_unlockAndPost(win_handle);
if (res) Logger_Abort2(res, "Unlocking window pixels"); if (res) Logger_Abort2(res, "Unlocking window pixels");
} }
void Window_FreeFramebuffer(Bitmap* bmp) {
Mem_Free(bmp->Scan0);
}
void Window_EnableRawMouse(void) { void Window_EnableRawMouse(void) {
Window_DefaultEnableRawMouse(); Window_DefaultEnableRawMouse();
win_rawMouse = true; win_rawMouse = true;

View File

@ -101,13 +101,15 @@ void Cursor_SetVisible(bool visible);
/* Shows a dialog box window. */ /* Shows a dialog box window. */
CC_API void Window_ShowDialog(const char* title, const char* msg); CC_API void Window_ShowDialog(const char* title, const char* msg);
/* Initialises the internal state for being able to set window's pixels. */ /* Allocates a framebuffer that can be drawn/transferred to the window. */
/* NOTE: Do not manually free bmp->Scan0 - it may be allocated by system. */ /* NOTE: Do NOT free bmp->Scan0, use Window_FreeFramebuffer. */
/* NOTE: This function must also be called whenever the window is resized. */ /* NOTE: This MUST be called whenever the window is resized. */
void Window_InitRaw(Bitmap* bmp); void Window_AllocFramebuffer(Bitmap* bmp);
/* Updates the window's pixels using the bitmap from Window_InitRaw. */ /* 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) */ /* r can be used to only update a small region of pixels (may be ignored) */
void Window_DrawRaw(Rect2D r); void Window_DrawFramebuffer(Rect2D r);
/* Frees the previously allocated framebuffer. */
void Window_FreeFramebuffer(Bitmap* bmp);
/* Begins listening for raw input and starts raising MouseEvents.RawMoved. */ /* Begins listening for raw input and starts raising MouseEvents.RawMoved. */
/* NOTE: Some backends only raise it when Window_UpdateRawMouse is called. */ /* NOTE: Some backends only raise it when Window_UpdateRawMouse is called. */