window layer working
This commit is contained in:
parent
c724b79c2c
commit
6beb910f98
@ -55,6 +55,7 @@ Struct(SharedArenaCtx)
|
||||
#define PopStructNoCopy(a, type) PopBytesNoCopy((a), sizeof(type))
|
||||
#define PopStructsNoCopy(a, type, n) PopBytesNoCopy((a), sizeof(type) * (n))
|
||||
|
||||
/* TOOD: Replace ArenaBase with 'ArenaFirst(type)' for dynamic-array-style uses */
|
||||
#define ArenaBase(arena) ((u8 *)(arena) + ArenaHeaderSize)
|
||||
#define ArenaCount(arena, type) ((arena)->pos / sizeof(type))
|
||||
|
||||
|
||||
@ -2071,8 +2071,8 @@ GPU_D12_Swapchain *GPU_D12_AcquireSwapchain(HWND hwnd, GPU_Format format, Vec2I3
|
||||
{
|
||||
DXGI_SWAP_CHAIN_DESC1 desc = ZI;
|
||||
desc.Format = GPU_D12_DxgiFormatFromGpuFormat(format);
|
||||
desc.Width = size.x;
|
||||
desc.Height = size.y;
|
||||
desc.Width = MaxI32(size.x, 1);
|
||||
desc.Height = MaxI32(size.y, 1);
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.SampleDesc.Quality = 0;
|
||||
desc.BufferUsage = DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
@ -2159,11 +2159,6 @@ i64 GPU_D12_PresentSwapchain(GPU_D12_Swapchain *gpu_swapchain, GPU_Resource *gpu
|
||||
/* Present */
|
||||
{
|
||||
__profn("Present");
|
||||
if (vsync)
|
||||
{
|
||||
/* FIXME: Only flush if windowed mode? */
|
||||
DwmFlush();
|
||||
}
|
||||
HRESULT hr = IDXGISwapChain3_Present(swapchain->swapchain, vsync, present_flags);
|
||||
if (!SUCCEEDED(hr))
|
||||
{
|
||||
|
||||
375
src/pp/pp.c
375
src/pp/pp.c
@ -30,8 +30,13 @@ void StartupUser(void)
|
||||
g->local_to_user_client_store = AcquireClientStore();
|
||||
g->local_to_user_client = AcquireClient(g->local_to_user_client_store);
|
||||
|
||||
g->world_to_ui_xf = XformIdentity;
|
||||
g->world_to_render_xf = XformIdentity;
|
||||
/* Default persistent state */
|
||||
{
|
||||
g->world_to_ui_xf = XformIdentity;
|
||||
g->world_to_render_xf = XformIdentity;
|
||||
// g->desired_window.flags = WND_Flag_Fullscreen;
|
||||
g->desired_window.restore_p1 = VEC2I32(1920, 1080);
|
||||
}
|
||||
|
||||
/* Init from swap */
|
||||
if (IsSwappedIn());
|
||||
@ -42,7 +47,7 @@ void StartupUser(void)
|
||||
{
|
||||
SwappedUserState *swap = (SwappedUserState *)swap_str.text;
|
||||
SharedUserState *old = &swap->s;
|
||||
CopyStructRegion(g, old, PERSIST_START, PERSIST_END);
|
||||
CopyStructRegion(g, old, AUTO_PERSIST_START, AUTO_PERSIST_END);
|
||||
}
|
||||
EndScratch(scratch);
|
||||
}
|
||||
@ -53,7 +58,7 @@ void StartupUser(void)
|
||||
|
||||
/* Create job pools */
|
||||
JobPoolId user_pool = InitJobPool(1, Lit("User"), JobPoolPriority_Graphics);
|
||||
JobPoolId sim_pool = InitJobPool(4, Lit("Simulation"), JobPoolPriority_Simulation);
|
||||
JobPoolId sim_pool = InitJobPool(1, Lit("Simulation"), JobPoolPriority_Simulation);
|
||||
|
||||
/* Start jobs */
|
||||
g->shutdown_jobs_count += RunJob(UpdateUserOrSleep, .pool = user_pool, .fence = &g->shutdown_jobs_fence);
|
||||
@ -308,114 +313,111 @@ P_LogEventCallbackFuncDef(ConsoleLogCallback, log)
|
||||
}
|
||||
|
||||
//- Draw console
|
||||
void DrawDebugConsole(i32 level, b32 minimized)
|
||||
void DrawDebugConsole(b32 minimized)
|
||||
{
|
||||
/* FIXME: Enable this */
|
||||
#if 0
|
||||
/* TODO: Remove this whole thing */
|
||||
__prof;
|
||||
SharedUserState *g = &shared_user_state;
|
||||
TempArena scratch = BeginScratchNoConflict();
|
||||
|
||||
Vec2 desired_start_pos = VEC2(10, minimized ? 100 : 600);
|
||||
i64 fade_time_ns = NsFromSeconds(10);
|
||||
f32 fade_curve = 0.5;
|
||||
f32 spacing = 0;
|
||||
f32 bg_margin = 5;
|
||||
// i32 console_level = minimized ? P_LogLevel_Success : P_LogLevel_Debug;
|
||||
i32 console_level = P_LogLevel_Debug;
|
||||
|
||||
u32 colors[P_LogLevel_Count][2] = ZI;
|
||||
SetBytes(colors, 0xFF, sizeof(colors));
|
||||
#if 1
|
||||
colors[P_LogLevel_Debug][0] = Rgb32F(0.4, 0.1, 0.4); colors[P_LogLevel_Debug][1] = Rgb32F(0.5, 0.2, 0.5);
|
||||
colors[P_LogLevel_Info][0] = Rgb32F(0.4, 0.4, 0.4); colors[P_LogLevel_Info][1] = Rgb32F(0.5, 0.5, 0.5);
|
||||
colors[P_LogLevel_Success][0] = Rgb32F(0.1, 0.3, 0.1); colors[P_LogLevel_Success][1] = Rgb32F(0.2, 0.4, 0.2);
|
||||
colors[P_LogLevel_Warning][0] = Rgb32F(0.4, 0.4, 0.1); colors[P_LogLevel_Warning][1] = Rgb32F(0.5, 0.5, 0.2);
|
||||
colors[P_LogLevel_Error][0] = Rgb32F(0.4, 0.1, 0.1); colors[P_LogLevel_Error][1] = Rgb32F(0.5, 0.2, 0.2);
|
||||
#else
|
||||
u32 info_colors[2] = { Rgb32F(0.4, 0.4, 0.4), Rgb32F(0.5, 0.5, 0.5) };
|
||||
u32 success_colors[2] = { Rgb32F(0.1, 0.3, 0.1), Rgb32F(0.2, 0.4, 0.2) };
|
||||
u32 warning_colors[2] = { Rgb32F(0.4, 0.4, 0.1), Rgb32F(0.5, 0.5, 0.2) };
|
||||
u32 error_colors[2] = { Rgb32F(0.4, 0.1, 0.1), Rgb32F(0.5, 0.2, 0.2) };
|
||||
#endif
|
||||
|
||||
Vec2 draw_pos = desired_start_pos;
|
||||
f32 bounds_top = F32Infinity;
|
||||
f32 bounds_bottom = -F32Infinity;
|
||||
|
||||
if (g->console_logs_height < desired_start_pos.y)
|
||||
i64 max_time_ns = I64Max;
|
||||
i64 fade_time_ns = max_time_ns;
|
||||
if (minimized)
|
||||
{
|
||||
draw_pos.y = g->console_logs_height;
|
||||
max_time_ns = NsFromSeconds(10);
|
||||
fade_time_ns = max_time_ns;
|
||||
}
|
||||
g->console_logs_height = 0;
|
||||
f32 fade_curve = 0.5;
|
||||
f32 spacing = 0;
|
||||
f32 bg_margin = 5;
|
||||
|
||||
i64 now_ns = TimeNs();
|
||||
F_Font *font = F_LoadFontAsync(ResourceKeyFromStore(&GameResources, Lit("font/fixedsys.ttf")), 12.0f);
|
||||
if (font)
|
||||
UI_PushCheckpoint();
|
||||
{
|
||||
UI_Box *console_box = 0;
|
||||
{
|
||||
UI_SetNext(LayoutAxis, Axis_Y);
|
||||
UI_SetNext(Tint, 0);
|
||||
console_box = UI_BuildBox(0, UI_NilKey);
|
||||
}
|
||||
UI_Push(Parent, console_box);
|
||||
UI_Push(Width, UI_TextSize(0));
|
||||
UI_Push(Height, UI_TextSize(0));
|
||||
UI_Push(BorderColor, Rgba32F(0.25, 0.25, 0.25, 1));
|
||||
UI_Push(Border, 2);
|
||||
UI_Push(Rounding, 0.5);
|
||||
UI_Push(TextPadding, 6);
|
||||
Lock lock = LockE(&g->console_logs_mutex);
|
||||
{
|
||||
for (ConsoleLog *log = g->last_console_log; log; log = log->prev)
|
||||
/* Gather display logs */
|
||||
u64 max = 20;
|
||||
u64 display_count = 0;
|
||||
ConsoleLog **display_logs = PushStructs(scratch.arena, ConsoleLog *, max);
|
||||
{
|
||||
f32 opacity = 0.75;
|
||||
b32 done = 0;
|
||||
if (minimized)
|
||||
{
|
||||
f32 lin = 1.0 - ClampF64((f64)(now_ns - log->time_ns) / (f64)fade_time_ns, 0, 1);
|
||||
opacity *= PowF32(lin, fade_curve);
|
||||
max = 5;
|
||||
}
|
||||
if (draw_pos.y > -desired_start_pos.y && opacity > 0)
|
||||
for (ConsoleLog *log = g->last_console_log; log && display_count < max && !done; log = log->prev)
|
||||
{
|
||||
if (log->level <= level)
|
||||
if (log->time_ns > (now_ns - max_time_ns))
|
||||
{
|
||||
/* Draw background */
|
||||
u32 color = colors[log->level][log->color_index];
|
||||
D_DrawQuad(g->render_sig, QuadFromRect(log->bounds), Alpha32F(color, opacity));
|
||||
|
||||
/* Draw text */
|
||||
String text = log->msg;
|
||||
if (!minimized)
|
||||
if (log->level <= console_level)
|
||||
{
|
||||
P_DateTime datetime = log->datetime;
|
||||
text = StringF(
|
||||
scratch.arena,
|
||||
"[%F:%F:%F.%F] %F",
|
||||
FmtUintZ(datetime.hour, 2),
|
||||
FmtUintZ(datetime.minute, 2),
|
||||
FmtUintZ(datetime.second, 2),
|
||||
FmtUintZ(datetime.milliseconds, 3),
|
||||
FmtString(text));
|
||||
display_logs[display_count] = log;
|
||||
++display_count;
|
||||
}
|
||||
|
||||
D_TextParams params = D_TEXTPARAMS(.font = font, .pos = draw_pos, .offset_y = DRAW_TEXT_OFFSET_Y_BOTTOM, .color = Alpha32F(Color_White, opacity), .str = text);
|
||||
Rect bounds = draw_text(g->render_sig, params);
|
||||
|
||||
Rect draw_bounds = bounds;
|
||||
draw_bounds.x -= bg_margin;
|
||||
draw_bounds.y -= bg_margin;
|
||||
draw_bounds.width += bg_margin * 2.f;
|
||||
draw_bounds.height += bg_margin * 2.f;
|
||||
draw_pos.y -= draw_bounds.height + spacing;
|
||||
log->bounds = draw_bounds;
|
||||
|
||||
bounds_top = MinF32(bounds_top, draw_bounds.y);
|
||||
bounds_bottom = MaxF32(bounds_bottom, draw_bounds.y + draw_bounds.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
done = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
}
|
||||
|
||||
/* Display logs in reverse */
|
||||
for (u64 i = display_count; i-- > 0;)
|
||||
{
|
||||
ConsoleLog *log = display_logs[i];
|
||||
f32 opacity = 0.75;
|
||||
f32 lin = 1.0 - ClampF64((f64)(now_ns - log->time_ns) / (f64)fade_time_ns, 0, 1);
|
||||
opacity *= PowF32(lin, fade_curve);
|
||||
String text = log->msg;
|
||||
if (!minimized)
|
||||
{
|
||||
break;
|
||||
P_DateTime datetime = log->datetime;
|
||||
text = StringF(
|
||||
scratch.arena,
|
||||
"[%F:%F:%F.%F] %F",
|
||||
FmtUintZ(datetime.hour, 2),
|
||||
FmtUintZ(datetime.minute, 2),
|
||||
FmtUintZ(datetime.second, 2),
|
||||
FmtUintZ(datetime.milliseconds, 3),
|
||||
FmtString(text));
|
||||
}
|
||||
u32 color = colors[log->level][log->color_index];
|
||||
UI_SetNext(BackgroundColor, color);
|
||||
UI_SetNext(Tint, Alpha32F(0xFFFFFFFF, opacity));
|
||||
UI_Box *log_box = UI_BuildBox(UI_BoxFlag_DrawText, UI_NilKey);
|
||||
UI_SetDisplayText(log_box, text);
|
||||
}
|
||||
}
|
||||
Unlock(&lock);
|
||||
}
|
||||
if (bounds_top < F32Infinity && bounds_bottom > -F32Infinity)
|
||||
{
|
||||
g->console_logs_height = bounds_bottom - bounds_top;
|
||||
}
|
||||
UI_PopCheckpoint();
|
||||
EndScratch(scratch);
|
||||
#else
|
||||
LAX level;
|
||||
LAX minimized;
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
@ -486,19 +488,25 @@ void UpdateUser(void)
|
||||
TempArena scratch = BeginScratchNoConflict();
|
||||
|
||||
//- Begin frame
|
||||
WND_Event win_event = WND_BeginUpdate(scratch.arena);
|
||||
WND_Event window_event = WND_BeginUpdate(scratch.arena);
|
||||
|
||||
u64 inputs_count = win_event.inputs_count;
|
||||
Input *inputs = win_event.inputs;
|
||||
u64 inputs_count = window_event.inputs_count;
|
||||
Input *inputs = window_event.inputs;
|
||||
|
||||
g->real_dt_ns = TimeNs() - g->real_time_ns;
|
||||
g->real_time_ns += g->real_dt_ns;
|
||||
|
||||
g->screen_size = SubVec2I32(g->window_settings.p1, g->window_settings.p0);
|
||||
if (EqVec2I32(g->screen_size, VEC2I32(0, 0)))
|
||||
//- Begin window
|
||||
WND_Settings cur_window = window_event.settings;
|
||||
if (window_event.os_gen > g->window_os_gen && window_event.cmd_gen > 0)
|
||||
{
|
||||
g->screen_size = VEC2I32(1920, 1080);
|
||||
/* Window was modified outside of program. Reflect this in our own state. */
|
||||
g->desired_window = cur_window;
|
||||
}
|
||||
g->window_os_gen = window_event.os_gen;
|
||||
g->screen_size = SubVec2I32(window_event.draw_p1, window_event.draw_p0);
|
||||
g->screen_size.x = MaxI32(g->screen_size.x, 1);
|
||||
g->screen_size.y = MaxI32(g->screen_size.y, 1);
|
||||
|
||||
//- Begin UI
|
||||
UI_BeginBuild();
|
||||
@ -516,7 +524,6 @@ void UpdateUser(void)
|
||||
}
|
||||
|
||||
//- Pull latest local sim snapshot
|
||||
|
||||
{
|
||||
__profn("Pull snapshot");
|
||||
Lock lock = LockE(&g->local_to_user_client_mutex);
|
||||
@ -534,7 +541,6 @@ void UpdateUser(void)
|
||||
}
|
||||
|
||||
//- Create user world from blended snapshots
|
||||
|
||||
{
|
||||
__profn("Blend snapshots");
|
||||
/* Determine how far along are we between sim ticks (0 = start of tick, 1 = end of tick) */
|
||||
@ -640,7 +646,6 @@ void UpdateUser(void)
|
||||
}
|
||||
|
||||
//- Process inputs into user bind state
|
||||
|
||||
{
|
||||
__profn("Process inputs");
|
||||
|
||||
@ -719,13 +724,11 @@ void UpdateUser(void)
|
||||
}
|
||||
|
||||
//- Find local entities
|
||||
|
||||
Entity *local_player = EntityFromId(g->ss_blended, g->ss_blended->local_player);
|
||||
Entity *local_control = EntityFromId(g->ss_blended, local_player->player_control_ent);
|
||||
Entity *local_camera = EntityFromId(g->ss_blended, local_player->player_camera_ent);
|
||||
|
||||
//- Find hovered entity
|
||||
|
||||
Entity *hovered_ent = NilEntity();
|
||||
{
|
||||
Xform mouse_xf = XformFromPos(g->world_cursor);
|
||||
@ -754,12 +757,10 @@ void UpdateUser(void)
|
||||
}
|
||||
|
||||
//- Update user state from binds
|
||||
|
||||
/* Test fullscreen */
|
||||
{
|
||||
if (g->bind_states[BindKind_Fullscreen].num_presses && g->bind_states[BindKind_FullscreenMod].is_held)
|
||||
{
|
||||
g->window_settings.flags ^= WND_Flag_Fullscreen;
|
||||
g->desired_window.flags ^= WND_Flag_Fullscreen;
|
||||
}
|
||||
}
|
||||
|
||||
@ -770,7 +771,7 @@ void UpdateUser(void)
|
||||
|
||||
if (g->bind_states[BindKind_DebugToggleTopmost].num_presses > 0)
|
||||
{
|
||||
g->window_settings.flags ^= WND_Flag_ForcedTop;
|
||||
g->desired_window.flags ^= WND_Flag_ForcedTop;
|
||||
P_LogSuccessF("Toggle topmost");
|
||||
}
|
||||
|
||||
@ -822,7 +823,6 @@ void UpdateUser(void)
|
||||
}
|
||||
|
||||
//- Apply shake
|
||||
|
||||
for (u64 ent_index = 0; ent_index < g->ss_blended->num_ents_reserved; ++ent_index)
|
||||
{
|
||||
Entity *ent = &g->ss_blended->ents[ent_index];
|
||||
@ -853,7 +853,6 @@ void UpdateUser(void)
|
||||
}
|
||||
|
||||
//- Update ui to screen xform from screen size
|
||||
|
||||
if (g->debug_camera)
|
||||
{
|
||||
g->ui_size = g->screen_size;
|
||||
@ -895,7 +894,6 @@ void UpdateUser(void)
|
||||
g->ui_cursor = MulXformV2(InvertXform(g->ui_to_screen_xf), g->screen_cursor);
|
||||
|
||||
//- Update world to ui xform from camera
|
||||
|
||||
if (g->debug_camera)
|
||||
{
|
||||
g->world_to_ui_xf = XformWithWorldRotation(g->world_to_ui_xf, 0);
|
||||
@ -998,7 +996,6 @@ void UpdateUser(void)
|
||||
}
|
||||
|
||||
//- Update render to ui xform
|
||||
|
||||
{
|
||||
Xform world_to_ui_xf = g->world_to_ui_xf;
|
||||
Xform world_to_render_xf = g->world_to_render_xf;
|
||||
@ -1008,7 +1005,6 @@ void UpdateUser(void)
|
||||
}
|
||||
|
||||
//- Update listener from view
|
||||
|
||||
{
|
||||
Vec2 up = VEC2(0, -1);
|
||||
Vec2 ui_center = MulVec2(VEC2(g->ui_size.x, g->ui_size.y), 0.5f);
|
||||
@ -1018,7 +1014,6 @@ void UpdateUser(void)
|
||||
}
|
||||
|
||||
//- Draw grid
|
||||
|
||||
{
|
||||
f32 thickness = 2;
|
||||
|
||||
@ -1155,7 +1150,6 @@ void UpdateUser(void)
|
||||
#endif
|
||||
|
||||
//- Sort drawable entities
|
||||
|
||||
Entity **sorted = PushDry(scratch.arena, Entity *);
|
||||
u64 sorted_count = 0;
|
||||
{
|
||||
@ -1180,7 +1174,6 @@ void UpdateUser(void)
|
||||
}
|
||||
|
||||
//- Draw entities
|
||||
|
||||
{
|
||||
__profn("Draw entities");
|
||||
for (u64 sorted_index = 0; sorted_index < sorted_count; ++sorted_index)
|
||||
@ -2042,9 +2035,7 @@ void UpdateUser(void)
|
||||
//////////////////////////////
|
||||
//- Debug draw
|
||||
|
||||
/* FIXME: Enable this */
|
||||
#if 1
|
||||
#if 1
|
||||
/* Draw debug info */
|
||||
if (g->debug_draw)
|
||||
{
|
||||
__profn("Draw debug info");
|
||||
@ -2115,144 +2106,15 @@ void UpdateUser(void)
|
||||
UI_BuildSpacer(UI_PixelSize(20, 0));
|
||||
UI_BuildLabelF("Debug steps: %F", FmtUint(GetGstat(GSTAT_DEBUG_STEPS)));
|
||||
//UI_BuildLabelF(\n"));
|
||||
|
||||
#endif
|
||||
//draw_text(g->render_sig, font, pos, StringF(scratch.arena, "blended world entities: %F/%F", FmtUint(g->ss_blended->num_ents_allocated), FmtUint(g->ss_blended->num_ents_reserved)));
|
||||
//draw_text(g->render_sig, font, pos, text);
|
||||
|
||||
#if 0
|
||||
Vec2 pos = VEC2(10, g->ui_size.y);
|
||||
D_TextOffsetY offset_y = DRAW_TEXT_OFFSET_Y_BOTTOM;
|
||||
draw_text(g->render_sig, D_TEXTPARAMS(.font = font, .pos = pos, .str = text, .offset_y = offset_y, .color = Color_White));
|
||||
#endif
|
||||
}
|
||||
UI_PopCheckpoint();
|
||||
}
|
||||
#else
|
||||
if (g->debug_draw)
|
||||
|
||||
/* Draw console */
|
||||
{
|
||||
__profn("Draw debug info");
|
||||
F_Font *font = F_LoadFontAsync(ResourceKeyFromStore(&GameResources, Lit("font/fixedsys.ttf")), 12.0f);
|
||||
if (font)
|
||||
{
|
||||
TempArena temp = BeginTempArena(scratch.arena);
|
||||
String text = ZI;
|
||||
text.text = PushDry(temp.arena, u8);
|
||||
|
||||
#if BITBUFF_DEBUG
|
||||
text.len += StringF(temp.arena, "(bitbuff debug enabled)").len;
|
||||
text.len += StringF(temp.arena, "\n").len;
|
||||
#endif
|
||||
|
||||
text.len += StringF(temp.arena, "blended world entities: %F/%F", FmtUint(g->ss_blended->num_ents_allocated), FmtUint(g->ss_blended->num_ents_reserved)).len;
|
||||
text.len += StringF(temp.arena, "\n").len;
|
||||
|
||||
text.len += StringF(temp.arena, "blended world tick: %F", FmtUint(g->ss_blended->tick)).len;
|
||||
text.len += StringF(temp.arena, "\n").len;
|
||||
|
||||
text.len += StringF(temp.arena, "blended world time: %F", FmtFloat(SecondsFromNs(g->ss_blended->sim_time_ns))).len;
|
||||
text.len += StringF(temp.arena, "\n").len;
|
||||
text.len += StringF(temp.arena, "\n").len;
|
||||
|
||||
text.len += StringF(temp.arena, "average local sim publish dt: %F", FmtFloat(SecondsFromNs(g->average_local_to_user_snapshot_publish_dt_ns))).len;
|
||||
text.len += StringF(temp.arena, "\n").len;
|
||||
|
||||
text.len += StringF(temp.arena, "local sim last known tick: %F", FmtUint(g->local_sim_last_known_tick)).len;
|
||||
text.len += StringF(temp.arena, "\n").len;
|
||||
|
||||
text.len += StringF(temp.arena, "local sim last known time: %F", FmtFloat(SecondsFromNs(g->local_sim_last_known_time_ns))).len;
|
||||
text.len += StringF(temp.arena, "\n").len;
|
||||
|
||||
text.len += StringF(temp.arena, "local sim predicted time: %F", FmtFloat(SecondsFromNs(g->local_sim_predicted_time_ns))).len;
|
||||
text.len += StringF(temp.arena, "\n").len;
|
||||
|
||||
text.len += StringF(temp.arena, "render time target: %F", FmtFloat(SecondsFromNs(g->render_time_target_ns))).len;
|
||||
text.len += StringF(temp.arena, "\n").len;
|
||||
|
||||
text.len += StringF(temp.arena, "render time: %F", FmtFloat(SecondsFromNs(g->render_time_ns))).len;
|
||||
text.len += StringF(temp.arena, "\n").len;
|
||||
text.len += StringF(temp.arena, "\n").len;
|
||||
|
||||
text.len += StringF(temp.arena, "local player: [%F]", FmtUid(local_player->id.uid)).len;
|
||||
text.len += StringF(temp.arena, "\n").len;
|
||||
text.len += StringF(temp.arena, "\n").len;
|
||||
|
||||
Vec2 world_cursor = g->world_cursor;
|
||||
text.len += StringF(temp.arena, "cursor world: %F, %F", FmtFloat(world_cursor.x), FmtFloat(world_cursor.y)).len;
|
||||
text.len += StringF(temp.arena, "\n").len;
|
||||
|
||||
Vec2I32 world_tile_cursor = WorldTileIndexFromPos(world_cursor);
|
||||
text.len += StringF(temp.arena, "cursor world tile: %F, %F", FmtSint(world_tile_cursor.x), FmtSint(world_tile_cursor.y)).len;
|
||||
text.len += StringF(temp.arena, "\n").len;
|
||||
|
||||
Vec2I32 local_tile_cursor = LocalTileIndexFromWorldTileIndex(world_tile_cursor);
|
||||
text.len += StringF(temp.arena, "cursor local tile: %F, %F", FmtSint(local_tile_cursor.x), FmtSint(local_tile_cursor.y)).len;
|
||||
text.len += StringF(temp.arena, "\n").len;
|
||||
|
||||
Vec2I32 tile_chunk_cursor = TileChunkIndexFromWorldTileIndex(world_tile_cursor);
|
||||
text.len += StringF(temp.arena, "cursor tile chunk: %F, %F", FmtSint(tile_chunk_cursor.x), FmtSint(tile_chunk_cursor.y)).len;
|
||||
text.len += StringF(temp.arena, "\n").len;
|
||||
text.len += StringF(temp.arena, "\n").len;
|
||||
|
||||
text.len += StringF(temp.arena, "Network read: %F mbit/s", FmtFloat((f64)g->net_bytes_read.last_second * 8 / 1000 / 1000)).len;
|
||||
text.len += StringF(temp.arena, "\n").len;
|
||||
|
||||
text.len += StringF(temp.arena, "Network write: %F mbit/s", FmtFloat((f64)g->net_bytes_sent.last_second * 8 / 1000 / 1000)).len;
|
||||
text.len += StringF(temp.arena, "\n").len;
|
||||
|
||||
text.len += StringF(temp.arena, "Ping (real): %F ms", FmtFloat(SecondsFromNs(local_player->player_last_rtt_ns) * 1000)).len;
|
||||
text.len += StringF(temp.arena, "\n").len;
|
||||
|
||||
text.len += StringF(temp.arena, "Ping (average): %F ms", FmtFloat(local_player->player_average_rtt_seconds * 1000)).len;
|
||||
text.len += StringF(temp.arena, "\n").len;
|
||||
text.len += StringF(temp.arena, "\n").len;
|
||||
|
||||
text.len += StringF(temp.arena, "Memory committed: %F MiB", FmtFloat((f64)GetGstat(GSTAT_MEMORY_COMMITTED) / 1024 / 1024)).len;
|
||||
text.len += StringF(temp.arena, "\n").len;
|
||||
|
||||
text.len += StringF(temp.arena, "Virtual memory reserved: %F TiB", FmtFloat((f64)GetGstat(GSTAT_MEMORY_RESERVED) / 1024 / 1024 / 1024 / 1024)).len;
|
||||
text.len += StringF(temp.arena, "\n").len;
|
||||
|
||||
text.len += StringF(temp.arena, "Arenas allocated: %F", FmtUint(GetGstat(GSTAT_NUM_ARENAS))).len;
|
||||
text.len += StringF(temp.arena, "\n").len;
|
||||
text.len += StringF(temp.arena, "\n").len;
|
||||
|
||||
text.len += StringF(temp.arena, "Video memory (GPU): %F MiB", FmtFloat((f64)vram.local_used / 1024 / 1024)).len;
|
||||
text.len += StringF(temp.arena, "\n").len;
|
||||
text.len += StringF(temp.arena, "Video memory (shared): %F MiB", FmtFloat((f64)vram.non_local_used / 1024 / 1024)).len;
|
||||
//text.len += StringF(temp.arena, \n")).len;
|
||||
//text.len += StringF(temp.arena, \n")).len;
|
||||
|
||||
#if RtcIsEnabled
|
||||
text.len += StringF(temp.arena, "\n").len;
|
||||
text.len += StringF(temp.arena, "\n").len;
|
||||
text.len += StringF(temp.arena, "Debug steps: %F", FmtUint(GetGstat(GSTAT_DEBUG_STEPS))).len;
|
||||
//text.len += StringF(temp.arena, \n")).len;
|
||||
|
||||
#endif
|
||||
//draw_text(g->render_sig, font, pos, StringF(temp.arena, "blended world entities: %F/%F", FmtUint(g->ss_blended->num_ents_allocated), FmtUint(g->ss_blended->num_ents_reserved)));
|
||||
//draw_text(g->render_sig, font, pos, text);
|
||||
|
||||
Vec2 pos = VEC2(10, g->ui_size.y);
|
||||
D_TextOffsetY offset_y = DRAW_TEXT_OFFSET_Y_BOTTOM;
|
||||
draw_text(g->render_sig, D_TEXTPARAMS(.font = font, .pos = pos, .str = text, .offset_y = offset_y, .color = Color_White));
|
||||
EndTempArena(temp);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
{
|
||||
#if DeveloperIsEnabled
|
||||
b32 console_minimized = !g->debug_console;
|
||||
i32 console_level = console_minimized ? P_LogLevel_Success : P_LogLevel_Debug;
|
||||
DrawDebugConsole(console_level, console_minimized);
|
||||
#else
|
||||
if (g->debug_draw)
|
||||
{
|
||||
DrawDebugConsole(P_LogLevel_Info, 0);
|
||||
}
|
||||
#endif
|
||||
DrawDebugConsole(console_minimized);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
@ -2261,7 +2123,7 @@ void UpdateUser(void)
|
||||
Rect ui_viewport = RectFromVec2(VEC2(0, 0), VEC2(g->ui_size.x, g->ui_size.y));
|
||||
Rect render_viewport = RectFromVec2(VEC2(0, 0), VEC2(g->render_size.x, g->render_size.y));
|
||||
GPU_QueueKind gpu_render_queue = GPU_QueueKind_Direct;
|
||||
Fence *render_fence = GPU_FenceFromQueue(gpu_render_queue);
|
||||
Fence *submit_fence = GPU_FenceFromQueue(gpu_render_queue);
|
||||
{
|
||||
__profn("Render");
|
||||
|
||||
@ -2270,7 +2132,7 @@ void UpdateUser(void)
|
||||
if (g->shade_target && !EqVec2I32(g->render_size, GPU_GetTextureSize2D(g->shade_target)))
|
||||
{
|
||||
__profn("Release render resources");
|
||||
YieldOnFence(render_fence, g->gpu_render_fence_target);
|
||||
YieldOnFence(submit_fence, g->gpu_submit_fence_target);
|
||||
GPU_ReleaseResource(g->albedo, GPU_ReleaseFlag_None);
|
||||
GPU_ReleaseResource(g->emittance, GPU_ReleaseFlag_None);
|
||||
GPU_ReleaseResource(g->emittance_flood_read, GPU_ReleaseFlag_None);
|
||||
@ -2290,6 +2152,21 @@ void UpdateUser(void)
|
||||
g->shade_target = AcquireGbuffer(GPU_Format_R16G16B16A16_Float, g->render_size);
|
||||
}
|
||||
|
||||
/* Acquire ui target */
|
||||
if (g->ui_target && !EqVec2I32(g->ui_size, GPU_GetTextureSize2D(g->ui_target)))
|
||||
{
|
||||
__profn("Release ui target");
|
||||
YieldOnFence(submit_fence, g->gpu_submit_fence_target);
|
||||
GPU_ReleaseResource(g->ui_target, GPU_ReleaseFlag_None);
|
||||
g->ui_target = 0;
|
||||
}
|
||||
if (!g->ui_target)
|
||||
{
|
||||
__profn("Acquire ui target");
|
||||
GPU_ResourceDesc desc = UI_GetRenderTargetDesc(g->ui_size);
|
||||
g->ui_target = GPU_AcquireResource(desc);
|
||||
}
|
||||
|
||||
/* Upload transient buffers */
|
||||
GPU_Resource *material_instances_buffer = GPU_UploadTransientBufferFromArena(&g->material_instances_tbuff, g->material_instances_arena);
|
||||
GPU_Resource *grids_buffer = GPU_UploadTransientBufferFromArena(&g->grids_tbuff, g->grids_arena);
|
||||
@ -2452,11 +2329,11 @@ void UpdateUser(void)
|
||||
GPU_TransitionToReadable(cl, g->shade_read);
|
||||
GPU_TransitionToReadable(cl, g->shade_target);
|
||||
}
|
||||
g->gpu_render_fence_target = GPU_EndCommandList(cl);
|
||||
g->gpu_submit_fence_target = GPU_EndCommandList(cl);
|
||||
|
||||
/* Reset render data */
|
||||
GPU_ResetTransientBuffer(&g->material_instances_tbuff, g->gpu_render_fence_target);
|
||||
GPU_ResetTransientBuffer(&g->grids_tbuff, g->gpu_render_fence_target);
|
||||
GPU_ResetTransientBuffer(&g->material_instances_tbuff, g->gpu_submit_fence_target);
|
||||
GPU_ResetTransientBuffer(&g->grids_tbuff, g->gpu_submit_fence_target);
|
||||
ResetArena(g->material_instances_arena);
|
||||
ResetArena(g->grids_arena);
|
||||
}
|
||||
@ -2472,35 +2349,23 @@ void UpdateUser(void)
|
||||
}
|
||||
|
||||
/* Render UI */
|
||||
GPU_Resource *ui_render = UI_EndBuild(ui_viewport);
|
||||
g->gpu_submit_fence_target = UI_EndBuild(g->ui_target);
|
||||
|
||||
#if 0
|
||||
//////////////////////////////
|
||||
//- Present
|
||||
|
||||
Vec2 backbuffer_dst_f = MulXformV2(g->ui_to_screen_xf, VEC2(0, 0));
|
||||
Vec2I32 backbuffer_dst = VEC2I32(RoundF32ToI32(backbuffer_dst_f.x), RoundF32ToI32(backbuffer_dst_f.y));
|
||||
g->gpu_render_fence_target = GPU_PresentSwapchain(g->swapchain, ui_render, g->screen_size, backbuffer_dst, VSYNC);
|
||||
// g->gpu_render_fence_target = GPU_PresentSwapchain(g->swapchain, g->ui_target, g->screen_size, backbuffer_dst, VSYNC);
|
||||
#else
|
||||
//////////////////////////////
|
||||
//- End window update
|
||||
|
||||
g->window_settings.vsync = VSYNC;
|
||||
g->window_settings.p0 = VEC2I32(0, 0);
|
||||
g->window_settings.p1 = g->screen_size;
|
||||
{
|
||||
WND_Cmd cmd = ZI;
|
||||
cmd.settings = g->window_settings;
|
||||
cmd.texture = ui_render;
|
||||
cmd.desired_settings = g->desired_window;
|
||||
cmd.texture = g->ui_target;
|
||||
cmd.vsync = VSYNC;
|
||||
{
|
||||
Vec2 backbuffer_dst_f = MulXformV2(g->ui_to_screen_xf, VEC2(0, 0));
|
||||
cmd.backbuffer_dst = VEC2I32(RoundF32ToI32(backbuffer_dst_f.x), RoundF32ToI32(backbuffer_dst_f.y));
|
||||
}
|
||||
WND_EndUpdate(cmd);
|
||||
g->gpu_submit_fence_target = WND_EndUpdateAndPresent(cmd);
|
||||
}
|
||||
#endif
|
||||
|
||||
++g->user_tick;
|
||||
EndScratch(scratch);
|
||||
}
|
||||
|
||||
|
||||
18
src/pp/pp.h
18
src/pp/pp.h
@ -115,7 +115,6 @@ Struct(ConsoleLog)
|
||||
i32 color_index;
|
||||
P_DateTime datetime;
|
||||
i64 time_ns;
|
||||
Rect bounds;
|
||||
ConsoleLog *prev;
|
||||
ConsoleLog *next;
|
||||
};
|
||||
@ -165,6 +164,9 @@ Struct(SharedUserState)
|
||||
Client *user_blended_client; /* Contains single snapshot from result of blending local sim snapshots */
|
||||
Snapshot *ss_blended; /* Points to blended snapshot contained in blended client */
|
||||
|
||||
u64 user_tick;
|
||||
u64 window_os_gen;
|
||||
|
||||
//- Usage stats
|
||||
i64 last_second_reset_ns;
|
||||
SecondsStat net_bytes_read;
|
||||
@ -178,6 +180,9 @@ Struct(SharedUserState)
|
||||
GPU_Resource *shade_read;
|
||||
GPU_Resource *shade_target;
|
||||
|
||||
//- Renderer target
|
||||
GPU_Resource *ui_target;
|
||||
|
||||
//- Renderer transient buffers
|
||||
GPU_TransientBuffer material_instances_tbuff;
|
||||
GPU_TransientBuffer grids_tbuff;
|
||||
@ -187,7 +192,7 @@ Struct(SharedUserState)
|
||||
//- Renderer state
|
||||
RandState frame_rand;
|
||||
u64 frame_index;
|
||||
i64 gpu_render_fence_target;
|
||||
i64 gpu_submit_fence_target;
|
||||
|
||||
//- Bind state
|
||||
BindState bind_states[BindKind_Count];
|
||||
@ -198,7 +203,6 @@ Struct(SharedUserState)
|
||||
ConsoleLog *first_console_log;
|
||||
ConsoleLog *last_console_log;
|
||||
i32 console_log_color_indices[P_LogLevel_Count];
|
||||
f32 console_logs_height;
|
||||
b32 debug_console;
|
||||
|
||||
//- Window -> user
|
||||
@ -238,11 +242,11 @@ Struct(SharedUserState)
|
||||
|
||||
//////////////////////////////
|
||||
//- Persist start
|
||||
StructRegion(PERSIST_START);
|
||||
StructRegion(AUTO_PERSIST_START);
|
||||
|
||||
//- Window
|
||||
|
||||
WND_Settings window_settings;
|
||||
WND_Settings desired_window;
|
||||
|
||||
//- Debug camera
|
||||
|
||||
@ -270,7 +274,7 @@ Struct(SharedUserState)
|
||||
|
||||
Vec2 focus_send;
|
||||
|
||||
StructRegion(PERSIST_END);
|
||||
StructRegion(AUTO_PERSIST_END);
|
||||
//- Persist end
|
||||
//////////////////////////////
|
||||
|
||||
@ -306,7 +310,7 @@ String DebugStringFromEntity(Arena *arena, Entity *ent);
|
||||
//~ Console draw operations
|
||||
|
||||
P_LogEventCallbackFuncDef(ConsoleLogCallback, log);
|
||||
void DrawDebugConsole(i32 level, b32 minimized);
|
||||
void DrawDebugConsole(b32 minimized);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Gpu buffer helpers
|
||||
|
||||
@ -60,6 +60,7 @@ void UI_PushCheckpoint(void)
|
||||
{
|
||||
cp = PushStruct(g->build_arena, UI_Checkpoint);
|
||||
}
|
||||
cp->next = g->top_checkpoint;
|
||||
cp->v = g->top_checkpoint->v + 1;
|
||||
g->top_checkpoint = cp;
|
||||
}
|
||||
@ -69,6 +70,10 @@ void UI_PopCheckpoint(void)
|
||||
UI_SharedState *g = &UI_shared_state;
|
||||
UI_Checkpoint *cp = g->top_checkpoint;
|
||||
u64 v = cp->v;
|
||||
if (v == 0)
|
||||
{
|
||||
DEBUGBREAKABLE;
|
||||
}
|
||||
for (UI_StyleKind kind = UI_StyleKind_None; kind < UI_StyleKind_Count; ++kind)
|
||||
{
|
||||
UI_StyleNode *n = g->style_tops[kind];
|
||||
@ -81,6 +86,7 @@ void UI_PopCheckpoint(void)
|
||||
n = next;
|
||||
}
|
||||
}
|
||||
g->top_checkpoint = cp->next;
|
||||
cp->next = g->first_free_checkpoint;
|
||||
g->first_free_checkpoint = cp;
|
||||
}
|
||||
@ -256,6 +262,7 @@ void UI_BeginBuild(void)
|
||||
ResetArena(g->build_arena);
|
||||
g->boxes_count = 0;
|
||||
g->first_free_style_node = 0;
|
||||
g->first_free_checkpoint = 0;
|
||||
|
||||
/* Init bins */
|
||||
g->box_bins = PushStructs(g->build_arena, UI_BoxBin, UI_NumBoxLookupBins);
|
||||
@ -299,11 +306,26 @@ void UI_BeginBuild(void)
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ End build
|
||||
|
||||
GPU_Resource *UI_EndBuild(Rect render_viewport)
|
||||
GPU_ResourceDesc UI_GetRenderTargetDesc(Vec2I32 size)
|
||||
{
|
||||
GPU_ResourceDesc desc = ZI;
|
||||
desc.kind = GPU_ResourceKind_Texture2D;
|
||||
desc.flags = GPU_ResourceFlag_Renderable | GPU_ResourceFlag_Writable;
|
||||
desc.texture.format = GPU_Format_R8G8B8A8_Unorm;
|
||||
desc.texture.size = VEC3I32(size.x, size.y, 1);
|
||||
return desc;
|
||||
}
|
||||
|
||||
i64 UI_EndBuild(GPU_Resource *render_target)
|
||||
{
|
||||
TempArena scratch = BeginScratchNoConflict();
|
||||
UI_SharedState *g = &UI_shared_state;
|
||||
|
||||
Vec2I32 render_target_size = GPU_GetTextureSize2D(render_target);
|
||||
Rect render_viewport = ZI;
|
||||
render_viewport.pos = VEC2(0, 0);
|
||||
render_viewport.size = VEC2(render_target_size.x, render_target_size.y);
|
||||
|
||||
/* TODO: Ensure root is parent */
|
||||
|
||||
//////////////////////////////
|
||||
@ -311,9 +333,9 @@ GPU_Resource *UI_EndBuild(Rect render_viewport)
|
||||
|
||||
/* Init root size */
|
||||
g->root_box->pref_size[Axis_X].kind = UI_SizeKind_Pixel;
|
||||
g->root_box->pref_size[Axis_X].v = render_viewport.size.x;
|
||||
g->root_box->pref_size[Axis_X].v = render_viewport.size.x;
|
||||
g->root_box->pref_size[Axis_Y].kind = UI_SizeKind_Pixel;
|
||||
g->root_box->pref_size[Axis_Y].v = render_viewport.size.y;
|
||||
g->root_box->pref_size[Axis_Y].v = render_viewport.size.y;
|
||||
|
||||
/* Build pre-order & post-order box arrays */
|
||||
u64 boxes_count = g->boxes_count;
|
||||
@ -554,23 +576,6 @@ GPU_Resource *UI_EndBuild(Rect render_viewport)
|
||||
//////////////////////////////
|
||||
//- Render
|
||||
|
||||
/* Init render target */
|
||||
if (g->render_target && !EqVec2I32(VEC2I32(render_viewport.size.x, render_viewport.size.y), GPU_GetTextureSize2D(g->render_target)))
|
||||
{
|
||||
YieldOnFence(render_fence, g->render_fence_target);
|
||||
GPU_ReleaseResource(g->render_target, GPU_ReleaseFlag_None);
|
||||
g->render_target = 0;
|
||||
}
|
||||
if (!g->render_target)
|
||||
{
|
||||
GPU_ResourceDesc desc = ZI;
|
||||
desc.kind = GPU_ResourceKind_Texture2D;
|
||||
desc.flags = GPU_ResourceFlag_Renderable | GPU_ResourceFlag_Writable;
|
||||
desc.texture.format = GPU_Format_R8G8B8A8_Unorm;
|
||||
desc.texture.size = VEC3I32(render_viewport.size.x, render_viewport.size.y, 1);
|
||||
g->render_target = GPU_AcquireResource(desc);
|
||||
}
|
||||
|
||||
/* Upload transient buffers */
|
||||
GPU_Resource *draw_rects_buffer = GPU_UploadTransientBufferFromArena(&g->draw_rects_tbuff, g->draw_rects_arena);
|
||||
u32 draw_rects_count = GPU_GetBufferCount(draw_rects_buffer);
|
||||
@ -582,8 +587,8 @@ GPU_Resource *UI_EndBuild(Rect render_viewport)
|
||||
{
|
||||
__profn("Clear target");
|
||||
GPU_ProfN(cl, Lit("Clear target"));
|
||||
GPU_TransitionToRenderable(cl, g->render_target, 0);
|
||||
GPU_ClearRenderable(cl, g->render_target);
|
||||
GPU_TransitionToRenderable(cl, render_target, 0);
|
||||
GPU_ClearRenderable(cl, render_target);
|
||||
}
|
||||
|
||||
//- Rect pass
|
||||
@ -612,7 +617,7 @@ GPU_Resource *UI_EndBuild(Rect render_viewport)
|
||||
|
||||
//- Prep post pass
|
||||
{
|
||||
GPU_TransitionToWritable(cl, g->render_target);
|
||||
GPU_TransitionToWritable(cl, render_target);
|
||||
}
|
||||
|
||||
//- Post pass
|
||||
@ -622,17 +627,17 @@ GPU_Resource *UI_EndBuild(Rect render_viewport)
|
||||
Vec2I32 viewport_size = RoundVec2ToVec2I32(render_viewport.size);
|
||||
UI_PostSig sig = ZI;
|
||||
sig.tex_size = viewport_size;
|
||||
sig.tex = GPU_RWTexture2DRidFromResource(g->render_target);
|
||||
sig.tex = GPU_RWTexture2DRidFromResource(render_target);
|
||||
sig.gamma = 2.2f;
|
||||
GPU_Compute(cl, &sig, UI_PostCS, (viewport_size.x + 7) / 8, (viewport_size.y + 7) / 8, 1);
|
||||
}
|
||||
}
|
||||
g->render_fence_target = GPU_EndCommandList(cl);
|
||||
i64 submit_fence_target = GPU_EndCommandList(cl);
|
||||
|
||||
/* Reset render data */
|
||||
GPU_ResetTransientBuffer(&g->draw_rects_tbuff, g->render_fence_target);
|
||||
GPU_ResetTransientBuffer(&g->draw_rects_tbuff, submit_fence_target);
|
||||
ResetArena(g->draw_rects_arena);
|
||||
|
||||
EndScratch(scratch);
|
||||
return g->render_target;
|
||||
return submit_fence_target;
|
||||
}
|
||||
|
||||
@ -180,9 +180,7 @@ Struct(UI_SharedState)
|
||||
UI_StyleNode *first_free_style_node;
|
||||
|
||||
//- Render state
|
||||
GPU_Resource *render_target;
|
||||
i64 render_fence_target;
|
||||
|
||||
i64 gpu_submit_fence_target;
|
||||
GPU_TransientBuffer draw_rects_tbuff;
|
||||
Arena *draw_rects_arena;
|
||||
|
||||
@ -249,4 +247,5 @@ void UI_BeginBuild(void);
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ End build
|
||||
|
||||
GPU_Resource *UI_EndBuild(Rect render_viewport);
|
||||
GPU_ResourceDesc UI_GetRenderTargetDesc(Vec2I32 size);
|
||||
i64 UI_EndBuild(GPU_Resource *render_target);
|
||||
|
||||
@ -3,35 +3,44 @@
|
||||
|
||||
Enum(WND_Flag)
|
||||
{
|
||||
WND_Flag_None = (0),
|
||||
WND_Flag_Fullscreen = (1 << 0),
|
||||
WND_Flag_ForcedTop = (1 << 1),
|
||||
WND_Flag_None = (0),
|
||||
WND_Flag_ForcedTop = (1 << 0),
|
||||
WND_Flag_RestoreToMaximized = (1 << 1),
|
||||
WND_Flag_Fullscreen = (1 << 2),
|
||||
WND_Flag_Maximized = (1 << 3),
|
||||
WND_Flag_Minimized = (1 << 4),
|
||||
};
|
||||
|
||||
Struct(WND_Settings)
|
||||
{
|
||||
WND_Flag flags;
|
||||
Vec2I32 p0;
|
||||
Vec2I32 p1;
|
||||
i32 vsync;
|
||||
};
|
||||
|
||||
Struct(WND_Cmd)
|
||||
{
|
||||
WND_Settings settings;
|
||||
|
||||
GPU_Resource *texture;
|
||||
Vec2I32 backbuffer_dst;
|
||||
Vec2I32 restore_p0;
|
||||
Vec2I32 restore_p1;
|
||||
};
|
||||
|
||||
Struct(WND_Event)
|
||||
{
|
||||
WND_Settings settings;
|
||||
u64 inputs_count;
|
||||
Input *inputs;
|
||||
WND_Settings settings;
|
||||
|
||||
/* The backbuffer src texture is no longer in use once the direct queue fence reaches this target */
|
||||
i64 backbuffer_fence_target;
|
||||
Vec2I32 monitor_p0;
|
||||
Vec2I32 monitor_p1;
|
||||
|
||||
Vec2I32 draw_p0;
|
||||
Vec2I32 draw_p1;
|
||||
|
||||
u64 cmd_gen; /* How many times has a window cmd changed the window state */
|
||||
u64 os_gen; /* How many times has the OS changed window state (e.g. mouse drags OS window border) */
|
||||
};
|
||||
|
||||
Struct(WND_Cmd)
|
||||
{
|
||||
WND_Settings desired_settings;
|
||||
|
||||
GPU_Resource *texture;
|
||||
Vec2I32 backbuffer_dst;
|
||||
i32 vsync;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
@ -43,4 +52,4 @@ void WND_Startup(void);
|
||||
//~ @hookdecl Window hooks
|
||||
|
||||
WND_Event WND_BeginUpdate(Arena *arena);
|
||||
void WND_EndUpdate(WND_Cmd cmd);
|
||||
i64 WND_EndUpdateAndPresent(WND_Cmd cmd);
|
||||
|
||||
@ -86,22 +86,10 @@ void WND_Startup(void)
|
||||
}
|
||||
|
||||
//- Start message processing job
|
||||
JobPoolId message_job_pool = InitJobPool(1, Lit("Win32 message loop"), JobPoolPriority_Background);
|
||||
JobPoolId message_job_pool = InitJobPool(1, Lit("Win32 message loop"), JobPoolPriority_Graphics);
|
||||
RunJob(WND_W32_ProcessMessagesForever, .pool = message_job_pool);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Input helpers
|
||||
|
||||
void WND_W32_PushInput(WND_W32_Window *window, Input input)
|
||||
{
|
||||
LockTicketMutex(&window->inputs_tm);
|
||||
{
|
||||
*PushStructNoZero(window->inputs_arena, Input) = input;
|
||||
}
|
||||
UnlockTicketMutex(&window->inputs_tm);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Initialization
|
||||
|
||||
@ -110,7 +98,7 @@ JobDef(WND_W32_ProcessMessagesForever, sig, id)
|
||||
{
|
||||
WND_W32_SharedState *g = &WND_W32_shared_state;
|
||||
WND_W32_Window *window = &g->window;
|
||||
window->inputs_arena = AcquireArena(Gibi(64));
|
||||
window->w2u_inputs_arena = AcquireArena(Gibi(64));
|
||||
|
||||
//- Init hwnd
|
||||
HWND hwnd = 0;
|
||||
@ -170,18 +158,21 @@ JobDef(WND_W32_ProcessMessagesForever, sig, id)
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Message processing
|
||||
|
||||
void WND_W32_PushInput(WND_W32_Window *window, Input input)
|
||||
{
|
||||
LockTicketMutex(&window->w2u_tm);
|
||||
{
|
||||
*PushStructNoZero(window->w2u_inputs_arena, Input) = input;
|
||||
}
|
||||
UnlockTicketMutex(&window->w2u_tm);
|
||||
}
|
||||
|
||||
LRESULT CALLBACK WND_W32_WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
WND_W32_SharedState *g = &WND_W32_shared_state;
|
||||
WND_W32_Window *window = &g->window;
|
||||
++window->proc_depth;
|
||||
LRESULT result = 0;
|
||||
|
||||
Lock lock = ZI;
|
||||
if (window->proc_depth == 1)
|
||||
{
|
||||
lock = LockE(&window->update_mutex);
|
||||
}
|
||||
{
|
||||
switch(msg)
|
||||
{
|
||||
@ -199,18 +190,6 @@ LRESULT CALLBACK WND_W32_WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM l
|
||||
WND_W32_PushInput(window, (Input) { .kind = InputKind_Quit });
|
||||
} break;
|
||||
|
||||
//- Resizing
|
||||
case WM_ENTERSIZEMOVE:
|
||||
case WM_MOVE:
|
||||
case WM_MOVING:
|
||||
case WM_SIZE:
|
||||
case WM_SIZING:
|
||||
{
|
||||
/* TODO */
|
||||
// P_W32_UpdateWindowFromSystem(window);
|
||||
result = DefWindowProcW(hwnd, msg, wparam, lparam);
|
||||
} break;
|
||||
|
||||
//- Keyboard button
|
||||
case WM_SYSKEYUP:
|
||||
case WM_SYSKEYDOWN:;
|
||||
@ -390,14 +369,202 @@ LRESULT CALLBACK WND_W32_WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM l
|
||||
}
|
||||
EndScratch(scratch);
|
||||
} break;
|
||||
|
||||
//- Process command
|
||||
case WND_CmdMsgId:
|
||||
{
|
||||
P_LogWarningF("RAAAAH");
|
||||
|
||||
WND_Event user_event = ZI;
|
||||
WND_Cmd user_cmd = ZI;
|
||||
{
|
||||
LockTicketMutex(&window->u2w_tm);
|
||||
{
|
||||
user_event = window->u2w_update_end_event;
|
||||
user_cmd = window->u2w_update_end_cmd;
|
||||
}
|
||||
UnlockTicketMutex(&window->u2w_tm);
|
||||
}
|
||||
|
||||
/* Determine old settings */
|
||||
Vec2I32 old_draw_p0 = ZI;
|
||||
Vec2I32 old_draw_p1 = ZI;
|
||||
Vec2I32 old_restore_p0 = ZI;
|
||||
Vec2I32 old_restore_p1 = ZI;
|
||||
b32 old_is_visible = 0;
|
||||
b32 old_has_border = 0;
|
||||
{
|
||||
{
|
||||
RECT screen_rect = ZI;
|
||||
GetClientRect(hwnd, (LPRECT)&screen_rect);
|
||||
ClientToScreen(hwnd, (LPPOINT)&screen_rect.left);
|
||||
ClientToScreen(hwnd, (LPPOINT)&screen_rect.right);
|
||||
old_draw_p0 = VEC2I32(screen_rect.left, screen_rect.top);
|
||||
old_draw_p1 = VEC2I32(screen_rect.right, screen_rect.bottom);
|
||||
}
|
||||
{
|
||||
WINDOWPLACEMENT placement = { .length = sizeof(placement) };
|
||||
GetWindowPlacement(hwnd, &placement);
|
||||
RECT placement_rect = placement.rcNormalPosition;
|
||||
old_restore_p0 = VEC2I32(placement_rect.left, placement_rect.top);
|
||||
old_restore_p1 = VEC2I32(placement_rect.right, placement_rect.bottom);
|
||||
}
|
||||
{
|
||||
DWORD style = (DWORD)GetWindowLongPtr(hwnd, GWL_STYLE);
|
||||
old_is_visible = !!(style & WS_VISIBLE);
|
||||
old_has_border = !(style & WS_POPUP);
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine new settings */
|
||||
Vec2I32 new_draw_p0 = old_draw_p0;
|
||||
Vec2I32 new_draw_p1 = old_draw_p1;
|
||||
Vec2I32 new_restore_p0 = old_restore_p0;
|
||||
Vec2I32 new_restore_p1 = old_restore_p1;
|
||||
b32 new_is_visible = old_is_visible;
|
||||
b32 new_has_border = old_has_border;
|
||||
{
|
||||
WND_Settings desired_settings = user_cmd.desired_settings;
|
||||
if (desired_settings.flags & WND_Flag_Fullscreen)
|
||||
{
|
||||
new_has_border = 0;
|
||||
new_draw_p0 = user_event.monitor_p0;
|
||||
new_draw_p1 = user_event.monitor_p1;
|
||||
}
|
||||
else if (desired_settings.flags & WND_Flag_Maximized)
|
||||
{
|
||||
// show_cmd = SW_MAXIMIZE;
|
||||
}
|
||||
else if (desired_settings.flags & WND_Flag_Minimized)
|
||||
{
|
||||
// show_cmd = SW_MINIMIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_has_border = 1;
|
||||
new_restore_p0 = desired_settings.restore_p0;
|
||||
new_restore_p1 = desired_settings.restore_p1;
|
||||
}
|
||||
new_is_visible = 1;
|
||||
}
|
||||
|
||||
/* Determine new style & placement */
|
||||
b32 has_user_seen_os_settings = user_event.os_gen == (u64)Atomic64Fetch(&window->os_gen);
|
||||
if (has_user_seen_os_settings)
|
||||
{
|
||||
/* Calculate style */
|
||||
b32 dirty_style = 0;
|
||||
DWORD new_style = (DWORD)GetWindowLongPtr(hwnd, GWL_STYLE);
|
||||
{
|
||||
if (new_is_visible != old_is_visible)
|
||||
{
|
||||
dirty_style = 1;
|
||||
if (new_is_visible)
|
||||
{
|
||||
new_style |= WS_VISIBLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_style &= ~WS_VISIBLE;
|
||||
}
|
||||
}
|
||||
if (new_has_border != old_has_border)
|
||||
{
|
||||
dirty_style = 1;
|
||||
if (new_has_border)
|
||||
{
|
||||
new_style &= ~WS_POPUP;
|
||||
new_style |= WS_OVERLAPPEDWINDOW;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_style &= ~WS_OVERLAPPEDWINDOW;
|
||||
new_style |= WS_POPUP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate placement */
|
||||
b32 dirty_placement = 0;
|
||||
WINDOWPLACEMENT new_placement = { .length = sizeof(new_placement) };
|
||||
GetWindowPlacement(hwnd, &new_placement);
|
||||
{
|
||||
if (!EqVec2I32(new_restore_p0, old_restore_p0) || !EqVec2I32(new_restore_p1, old_restore_p1))
|
||||
{
|
||||
dirty_placement = 1;
|
||||
new_placement.rcNormalPosition.left = new_restore_p0.x;
|
||||
new_placement.rcNormalPosition.top = new_restore_p0.y;
|
||||
new_placement.rcNormalPosition.right = new_restore_p1.x;
|
||||
new_placement.rcNormalPosition.bottom = new_restore_p1.y;
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate draw position */
|
||||
b32 dirty_draw_rect = 0;
|
||||
RECT new_draw_rect = ZI;
|
||||
if (!EqVec2I32(new_draw_p0, old_draw_p0) || !EqVec2I32(new_draw_p1, old_draw_p1))
|
||||
{
|
||||
dirty_draw_rect = 1;
|
||||
new_draw_rect.left = new_draw_p0.x;
|
||||
new_draw_rect.top = new_draw_p0.y;
|
||||
new_draw_rect.right = new_draw_p1.x;
|
||||
new_draw_rect.bottom = new_draw_p1.y;
|
||||
AdjustWindowRect(&new_draw_rect, new_style, 0);
|
||||
}
|
||||
|
||||
/* Apply changes */
|
||||
if (dirty_style || dirty_placement || dirty_draw_rect)
|
||||
{
|
||||
if (dirty_style)
|
||||
{
|
||||
++window->cmd_depth;
|
||||
SetWindowLongPtrW(hwnd, GWL_STYLE, new_style);
|
||||
}
|
||||
if (dirty_placement)
|
||||
{
|
||||
++window->cmd_depth;
|
||||
SetWindowPlacement(hwnd, &new_placement);
|
||||
}
|
||||
if (dirty_draw_rect)
|
||||
{
|
||||
u32 pflags = 0;
|
||||
Vec2I32 size = VEC2I32(new_draw_rect.right - new_draw_rect.left, new_draw_rect.bottom - new_draw_rect.top);
|
||||
++window->cmd_depth;
|
||||
SetWindowPos(hwnd, 0, new_draw_rect.left, new_draw_rect.top, size.x, size.y, pflags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Bring window to front on first show */
|
||||
if (!window->first_shown)
|
||||
{
|
||||
SetForegroundWindow(hwnd);
|
||||
BringWindowToTop(hwnd);
|
||||
window->first_shown = 1;
|
||||
}
|
||||
} break;
|
||||
|
||||
//- Detect changes
|
||||
case WM_WINDOWPOSCHANGED:
|
||||
{
|
||||
if (window->cmd_depth == 0)
|
||||
{
|
||||
/* This change occurred outside of a user window command, so it must come from the OS */
|
||||
Atomic64FetchAdd(&window->os_gen, 1);
|
||||
P_LogInfoF("OS change");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME: In order for this to truly be the result of a user cmd we should clear the message queue after cmd submission */
|
||||
P_LogDebugF("Cmd change");
|
||||
Atomic64FetchAdd(&window->cmd_gen, 1);
|
||||
--window->cmd_depth;
|
||||
}
|
||||
result = DefWindowProcW(hwnd, msg, wparam, lparam);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
if (window->proc_depth == 1)
|
||||
{
|
||||
Unlock(&lock);
|
||||
}
|
||||
|
||||
--window->proc_depth;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -410,72 +577,150 @@ WND_Event WND_BeginUpdate(Arena *arena)
|
||||
WND_W32_Window *window = &g->window;
|
||||
WND_Event result = ZI;
|
||||
|
||||
/* TODO: Yield on swapchain instead */
|
||||
while (!Atomic32Fetch(&window->is_ready))
|
||||
{
|
||||
_mm_pause();
|
||||
}
|
||||
HWND hwnd = window->hwnd;
|
||||
|
||||
/* FIXME: Don't use TM */
|
||||
Lock *lock = &window->user_update_lock;
|
||||
*lock = LockE(&window->update_mutex);
|
||||
/* Wait on swapchain */
|
||||
if (window->swapchain)
|
||||
{
|
||||
GPU_D12_YieldOnSwapchain(window->swapchain);
|
||||
}
|
||||
|
||||
/* Pop inputs */
|
||||
LockTicketMutex(&window->inputs_tm);
|
||||
{
|
||||
Input *src = (Input *)ArenaBase(window->inputs_arena);
|
||||
result.inputs_count = ArenaCount(window->inputs_arena, Input);
|
||||
result.inputs = PushStructsNoZero(arena, Input, result.inputs_count);
|
||||
CopyStructs(result.inputs, src, result.inputs_count);
|
||||
ResetArena(window->inputs_arena);
|
||||
LockTicketMutex(&window->w2u_tm);
|
||||
{
|
||||
Input *src = (Input *)ArenaBase(window->w2u_inputs_arena);
|
||||
result.inputs_count = ArenaCount(window->w2u_inputs_arena, Input);
|
||||
result.inputs = PushStructsNoZero(arena, Input, result.inputs_count);
|
||||
CopyStructs(result.inputs, src, result.inputs_count);
|
||||
ResetArena(window->w2u_inputs_arena);
|
||||
}
|
||||
UnlockTicketMutex(&window->w2u_tm);
|
||||
}
|
||||
UnlockTicketMutex(&window->inputs_tm);
|
||||
|
||||
/* FIXME: Remove this */
|
||||
result.settings.p0 = window->previous_cmd.settings.p0;
|
||||
result.settings.p1 = window->previous_cmd.settings.p1;
|
||||
/* Grab monitor info */
|
||||
{
|
||||
MONITORINFO monitor_info = { .cbSize = sizeof(monitor_info) };
|
||||
GetMonitorInfo(MonitorFromWindow(hwnd, MONITOR_DEFAULTTOPRIMARY), &monitor_info);
|
||||
RECT monitor_rect = monitor_info.rcMonitor;
|
||||
result.monitor_p0.x = monitor_rect.left;
|
||||
result.monitor_p0.y = monitor_rect.top;
|
||||
result.monitor_p1.x = monitor_rect.right;
|
||||
result.monitor_p1.y = monitor_rect.bottom;
|
||||
}
|
||||
|
||||
/* Grab window info */
|
||||
WND_Settings settings = ZI;
|
||||
{
|
||||
/* Draw size */
|
||||
{
|
||||
RECT screen_rect = ZI;
|
||||
GetClientRect(hwnd, (LPRECT)&screen_rect);
|
||||
ClientToScreen(hwnd, (LPPOINT)&screen_rect.left);
|
||||
ClientToScreen(hwnd, (LPPOINT)&screen_rect.right);
|
||||
result.draw_p0 = VEC2I32(screen_rect.left, screen_rect.top);
|
||||
result.draw_p1 = VEC2I32(screen_rect.right, screen_rect.bottom);
|
||||
}
|
||||
|
||||
/* Clamp */
|
||||
// {
|
||||
// RECT virt_rect = ZI;
|
||||
// virt_rect.left = GetSystemMetrics(SM_XVIRTUALSCREEN);
|
||||
// virt_rect.top = GetSystemMetrics(SM_YVIRTUALSCREEN);
|
||||
// virt_rect.right = virt_rect.left + GetSystemMetrics(SM_CXVIRTUALSCREEN);
|
||||
// virt_rect.bottom = virt_rect.top + GetSystemMetrics(SM_CYVIRTUALSCREEN);
|
||||
// result.draw_p0.x = MaxI32(result.draw_p0.x, virt_rect.left);
|
||||
// result.draw_p0.y = MaxI32(result.draw_p0.y, virt_rect.top);
|
||||
// result.draw_p1.x = MinI32(result.draw_p1.x, virt_rect.right);
|
||||
// result.draw_p1.y = MinI32(result.draw_p1.y, virt_rect.bottom);
|
||||
// }
|
||||
// result.draw_p1.x = MaxI32(result.draw_p1.x, result.draw_p0.x + 320);
|
||||
// result.draw_p1.y = MaxI32(result.draw_p1.y, result.draw_p0.y + 180);
|
||||
|
||||
/* Minimized / maximized */
|
||||
WINDOWPLACEMENT placement = { .length = sizeof(placement) };
|
||||
GetWindowPlacement(hwnd, &placement);
|
||||
if (placement.showCmd == SW_MAXIMIZE)
|
||||
{
|
||||
settings.flags |= WND_Flag_Maximized;
|
||||
}
|
||||
if (placement.showCmd == SW_MINIMIZE)
|
||||
{
|
||||
settings.flags |= WND_Flag_Minimized;
|
||||
}
|
||||
if (placement.flags & WPF_RESTORETOMAXIMIZED)
|
||||
{
|
||||
settings.flags |= WND_Flag_RestoreToMaximized;
|
||||
}
|
||||
|
||||
/* Restore size */
|
||||
{
|
||||
RECT placement_rect = placement.rcNormalPosition;
|
||||
settings.restore_p0 = VEC2I32(placement_rect.left, placement_rect.top);
|
||||
settings.restore_p1 = VEC2I32(placement_rect.right, placement_rect.bottom);
|
||||
}
|
||||
|
||||
/* Fullscreen */
|
||||
/* TODO: Verify WS_POPUP as well */
|
||||
if (EqVec2I32(result.draw_p0, result.monitor_p0) && EqVec2I32(result.draw_p1, result.monitor_p1))
|
||||
{
|
||||
settings.flags |= WND_Flag_Fullscreen;
|
||||
}
|
||||
|
||||
result.settings = settings;
|
||||
}
|
||||
|
||||
result.os_gen = Atomic64Fetch(&window->os_gen);
|
||||
result.cmd_gen = Atomic64Fetch(&window->cmd_gen);
|
||||
|
||||
window->update_begin_event = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
void WND_EndUpdate(WND_Cmd cmd)
|
||||
i64 WND_EndUpdateAndPresent(WND_Cmd cmd)
|
||||
{
|
||||
WND_W32_SharedState *g = &WND_W32_shared_state;
|
||||
WND_W32_Window *window = &g->window;
|
||||
HWND hwnd = window->hwnd;
|
||||
|
||||
Unlock(&window->user_update_lock);
|
||||
WND_Event begin_event = window->update_begin_event;
|
||||
WND_Settings draw_settings = begin_event.settings;
|
||||
Vec2I32 draw_size = SubVec2I32(begin_event.draw_p1, begin_event.draw_p0);
|
||||
|
||||
|
||||
|
||||
WND_Settings old = window->previous_cmd.settings;
|
||||
WND_Settings new = cmd.settings;
|
||||
|
||||
Vec2I32 new_size = SubVec2I32(new.p1, new.p0);
|
||||
|
||||
/* Acquire swapchain */
|
||||
if (!window->swapchain)
|
||||
{
|
||||
window->swapchain = GPU_D12_AcquireSwapchain(window->hwnd, GPU_Format_R8G8B8A8_Unorm, new_size);
|
||||
window->swapchain = GPU_D12_AcquireSwapchain(window->hwnd, GPU_Format_R8G8B8A8_Unorm, draw_size);
|
||||
}
|
||||
|
||||
/* Present */
|
||||
/* TODO: Get fence */
|
||||
i64 present_fence_target = 0;
|
||||
if (cmd.texture != 0)
|
||||
{
|
||||
Vec2I32 backbuffer_dst = cmd.backbuffer_dst;
|
||||
i32 vsync = new.vsync;
|
||||
GPU_D12_PresentSwapchain(window->swapchain, cmd.texture, new_size, backbuffer_dst, vsync);
|
||||
if (cmd.vsync != 0)
|
||||
{
|
||||
/* FIXME: Don't flush in fullscreen mode? */
|
||||
DwmFlush();
|
||||
}
|
||||
present_fence_target = GPU_D12_PresentSwapchain(window->swapchain, cmd.texture, draw_size, backbuffer_dst, cmd.vsync);
|
||||
}
|
||||
|
||||
/* Show window */
|
||||
if (!window->first_shown)
|
||||
/* Push cmd to window */
|
||||
b32 desires_change = !EqStruct(&cmd.desired_settings, &begin_event.settings);
|
||||
if (desires_change)
|
||||
{
|
||||
i32 show_cmd = SW_SHOWMAXIMIZED;
|
||||
ShowWindow(window->hwnd, show_cmd);
|
||||
SetForegroundWindow(window->hwnd);
|
||||
BringWindowToTop(window->hwnd);
|
||||
window->first_shown = 1;
|
||||
LockTicketMutex(&window->u2w_tm);
|
||||
{
|
||||
window->u2w_update_end_cmd = cmd;
|
||||
window->u2w_update_end_event = begin_event;
|
||||
PostMessageW(window->hwnd, WND_CmdMsgId, 0, 0);
|
||||
}
|
||||
UnlockTicketMutex(&window->u2w_tm);
|
||||
}
|
||||
|
||||
window->previous_cmd = cmd;
|
||||
return present_fence_target;
|
||||
}
|
||||
|
||||
@ -1,29 +1,36 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Window types
|
||||
|
||||
#define WND_CmdMsgId (WM_USER + 1)
|
||||
|
||||
Struct(WND_W32_Window)
|
||||
{
|
||||
Atomic32 is_ready;
|
||||
HWND hwnd;
|
||||
GPU_D12_Swapchain *swapchain;
|
||||
Atomic32 is_ready;
|
||||
|
||||
TicketMutex inputs_tm;
|
||||
Arena *inputs_arena;
|
||||
|
||||
|
||||
/* TODO: Remove this */
|
||||
// TicketMutex update_tm;
|
||||
Mutex update_mutex;
|
||||
Lock user_update_lock;
|
||||
i32 proc_depth;
|
||||
|
||||
|
||||
/* TODO: Remove this */
|
||||
b32 first_shown;
|
||||
|
||||
WND_Cmd previous_cmd;
|
||||
Atomic64 cmd_gen;
|
||||
Atomic64 os_gen;
|
||||
|
||||
/* Window state */
|
||||
u16 previous_utf16_high_surrogate;
|
||||
b32 first_shown;
|
||||
i64 cmd_depth;
|
||||
|
||||
/* User state */
|
||||
WND_Event update_begin_event;
|
||||
|
||||
/* Window -> User */
|
||||
/* Reads outside of window thread must lock */
|
||||
TicketMutex w2u_tm;
|
||||
Arena *w2u_inputs_arena;
|
||||
|
||||
|
||||
/* User -> Window */
|
||||
/* Reads outside of user thread must lock */
|
||||
TicketMutex u2w_tm;
|
||||
WND_Event u2w_update_end_event; /* The user's processed event at end of update */
|
||||
WND_Cmd u2w_update_end_cmd; /* The user's cmd at the end of update */
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
@ -38,11 +45,6 @@ Struct(WND_W32_SharedState)
|
||||
WND_W32_Window window; /* Only single-window for now */
|
||||
} extern WND_W32_shared_state;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Input helpers
|
||||
|
||||
void WND_W32_PushInput(WND_W32_Window *window, Input input);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Initialization
|
||||
|
||||
@ -51,4 +53,5 @@ JobDecl(WND_W32_ProcessMessagesForever, EmptySig);
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Message processing
|
||||
|
||||
void WND_W32_PushInput(WND_W32_Window *window, Input input);
|
||||
LRESULT CALLBACK WND_W32_WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user