mirror of
https://github.com/wolfpld/tracy.git
synced 2026-06-13 10:49:05 +00:00
136 lines
4.4 KiB
C++
136 lines
4.4 KiB
C++
// platform_windows.cpp — Windows backend (Win32)
|
|
//
|
|
// Compile flags (MSVC, console subsystem):
|
|
// cl /std:c++17 spinning_triangle.cpp platform_windows.cpp \
|
|
// /I\path\to\wgpu\include \path\to\wgpu\lib\wgpu_native.lib \
|
|
// user32.lib gdi32.lib /Fe:spinning_triangle.exe
|
|
//
|
|
// MinGW/Clang equivalent:
|
|
// clang++ -std=c++17 spinning_triangle.cpp platform_windows.cpp \
|
|
// -I/path/to/wgpu/include -L/path/to/wgpu/lib -lwgpu_native \
|
|
// -luser32 -lgdi32 -o spinning_triangle.exe
|
|
|
|
#ifndef WIN32_LEAN_AND_MEAN
|
|
#define WIN32_LEAN_AND_MEAN
|
|
#endif
|
|
#include <windows.h>
|
|
#include <webgpu/webgpu.h>
|
|
#include <stdio.h>
|
|
#include "platform.h"
|
|
|
|
#pragma comment(lib, "user32.lib")
|
|
#pragma comment(lib, "gdi32.lib")
|
|
#pragma comment(lib, "dxguid.lib") // Dawn: WKPDID_D3DDebugObjectName
|
|
#pragma comment(lib, "OneCore") // Dawn: CompareObjectHandles
|
|
#pragma comment(lib, "ntdll.lib") // wgpu-native: NtReadFile et al.
|
|
|
|
static HWND sHwnd = nullptr;
|
|
static bool sRunning = false;
|
|
static LARGE_INTEGER sFreq = {};
|
|
static LARGE_INTEGER sStartTime = {};
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Win32 window procedure
|
|
// ---------------------------------------------------------------------------
|
|
|
|
static LRESULT CALLBACK wndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) {
|
|
switch (msg) {
|
|
case WM_KEYDOWN:
|
|
if (wp == VK_ESCAPE) { sRunning = false; return 0; }
|
|
break;
|
|
case WM_CLOSE:
|
|
case WM_DESTROY:
|
|
sRunning = false;
|
|
PostQuitMessage(0);
|
|
return 0;
|
|
}
|
|
return DefWindowProcA(hwnd, msg, wp, lp);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Platform interface implementation
|
|
// ---------------------------------------------------------------------------
|
|
|
|
bool platformInit(int width, int height, const char* title) {
|
|
WNDCLASSEXA wc = {};
|
|
wc.cbSize = sizeof(wc);
|
|
wc.style = CS_HREDRAW | CS_VREDRAW;
|
|
wc.lpfnWndProc = wndProc;
|
|
wc.hInstance = GetModuleHandleA(nullptr);
|
|
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
|
|
wc.lpszClassName = "SpinningTriangle";
|
|
if (!RegisterClassExA(&wc)) {
|
|
fprintf(stderr, "RegisterClassExA failed (%lu)\n", GetLastError());
|
|
return false;
|
|
}
|
|
|
|
// Adjust client area to match the requested dimensions
|
|
RECT rect = { 0, 0, width, height };
|
|
AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW & ~(WS_THICKFRAME | WS_MAXIMIZEBOX), FALSE);
|
|
|
|
sHwnd = CreateWindowExA(
|
|
0, "SpinningTriangle", title,
|
|
WS_OVERLAPPEDWINDOW & ~(WS_THICKFRAME | WS_MAXIMIZEBOX),
|
|
CW_USEDEFAULT, CW_USEDEFAULT,
|
|
rect.right - rect.left, rect.bottom - rect.top,
|
|
nullptr, nullptr, GetModuleHandleA(nullptr), nullptr);
|
|
if (!sHwnd) {
|
|
fprintf(stderr, "CreateWindowExA failed (%lu)\n", GetLastError());
|
|
return false;
|
|
}
|
|
|
|
ShowWindow(sHwnd, SW_SHOW);
|
|
UpdateWindow(sHwnd);
|
|
|
|
QueryPerformanceFrequency(&sFreq);
|
|
QueryPerformanceCounter(&sStartTime);
|
|
return true;
|
|
}
|
|
|
|
WGPUSurface platformCreateSurface(WGPUInstance instance) {
|
|
WGPUSurfaceSourceWindowsHWND hwndSrc = {};
|
|
hwndSrc.chain.sType = WGPUSType_SurfaceSourceWindowsHWND;
|
|
hwndSrc.hinstance = GetModuleHandleA(nullptr);
|
|
hwndSrc.hwnd = sHwnd;
|
|
|
|
WGPUSurfaceDescriptor surfDesc = {};
|
|
surfDesc.nextInChain = (WGPUChainedStruct*)&hwndSrc;
|
|
return wgpuInstanceCreateSurface(instance, &surfDesc);
|
|
}
|
|
|
|
double platformGetTime() {
|
|
LARGE_INTEGER now;
|
|
QueryPerformanceCounter(&now);
|
|
return (double)(now.QuadPart - sStartTime.QuadPart) / (double)sFreq.QuadPart;
|
|
}
|
|
|
|
void platformRunLoop(void (*render)(), void (*shutdown)()) {
|
|
// Target ~16.67 ms per frame (60 fps)
|
|
static const double kFrameTime = 1.0 / 60.0;
|
|
|
|
sRunning = true;
|
|
while (sRunning) {
|
|
double frameStart = platformGetTime();
|
|
|
|
// Drain the Win32 message queue
|
|
MSG msg;
|
|
while (PeekMessageA(&msg, nullptr, 0, 0, PM_REMOVE)) {
|
|
if (msg.message == WM_QUIT) { sRunning = false; break; }
|
|
TranslateMessage(&msg);
|
|
DispatchMessageA(&msg);
|
|
}
|
|
|
|
if (sRunning) render();
|
|
|
|
// Sleep for the remainder of the frame budget
|
|
double elapsed = platformGetTime() - frameStart;
|
|
if (elapsed < kFrameTime) {
|
|
DWORD ms = (DWORD)((kFrameTime - elapsed) * 1000.0);
|
|
if (ms > 0) Sleep(ms);
|
|
}
|
|
}
|
|
|
|
shutdown();
|
|
if (sHwnd) DestroyWindow(sHwnd);
|
|
}
|