Fix window resize;

This commit is contained in:
bjorn 2022-11-07 22:45:10 -08:00
parent 3775ed1be6
commit 9783140725
12 changed files with 207 additions and 132 deletions

View File

@ -135,7 +135,7 @@ function lovr.run()
if lovr.system.isWindowOpen() then
if lovr.mirror then
local pass = lovr.graphics.getWindowPass()
local skip = lovr.mirror(pass)
local skip = not pass or lovr.mirror(pass)
if not skip then lovr.graphics.submit(pass) end
end
lovr.graphics.present()
@ -213,9 +213,11 @@ function lovr.errhand(message)
if lovr.system.isWindowOpen() then
local pass = lovr.graphics.getWindowPass()
render(pass)
lovr.graphics.submit(pass)
lovr.graphics.present()
if pass then
render(pass)
lovr.graphics.submit(pass)
lovr.graphics.present()
end
end
end
end

View File

@ -165,18 +165,24 @@ static int l_lovrSystemIsWindowOpen(lua_State* L) {
}
static int l_lovrSystemGetWindowWidth(lua_State* L) {
lua_pushnumber(L, lovrSystemGetWindowWidth());
uint32_t width, height;
lovrSystemGetWindowSize(&width, &height);
lua_pushnumber(L, width);
return 1;
}
static int l_lovrSystemGetWindowHeight(lua_State* L) {
lua_pushnumber(L, lovrSystemGetWindowHeight());
uint32_t width, height;
lovrSystemGetWindowSize(&width, &height);
lua_pushnumber(L, height);
return 1;
}
static int l_lovrSystemGetWindowDimensions(lua_State* L) {
lua_pushnumber(L, lovrSystemGetWindowWidth());
lua_pushnumber(L, lovrSystemGetWindowHeight());
uint32_t width, height;
lovrSystemGetWindowSize(&width, &height);
lua_pushnumber(L, width);
lua_pushnumber(L, height);
return 2;
}

View File

@ -142,6 +142,7 @@ bool gpu_texture_init(gpu_texture* texture, gpu_texture_info* info);
bool gpu_texture_init_view(gpu_texture* texture, gpu_texture_view_info* info);
void gpu_texture_destroy(gpu_texture* texture);
gpu_texture* gpu_surface_acquire(void);
void gpu_surface_resize(uint32_t width, uint32_t height);
void gpu_xr_acquire(gpu_stream* stream, gpu_texture* texture);
void gpu_xr_release(gpu_stream* stream, gpu_texture* texture);

View File

@ -169,11 +169,13 @@ static struct {
VkQueue queue;
uint32_t queueFamilyIndex;
VkSurfaceKHR surface;
VkSurfaceCapabilitiesKHR surfaceCapabilities;
VkSurfaceFormatKHR surfaceFormat;
bool swapchainValid;
VkSwapchainKHR swapchain;
VkFormat surfaceFormat;
VkSemaphore surfaceSemaphore;
uint32_t currentSurfaceTexture;
gpu_texture surfaceTextures[8];
VkSemaphore swapchainSemaphore;
uint32_t currentSwapchainTexture;
gpu_texture swapchainTextures[8];
VkPipelineCache pipelineCache;
VkDebugUtilsMessengerEXT messenger;
gpu_cache_entry renderpasses[16][4];
@ -208,6 +210,7 @@ static gpu_memory* gpu_allocate(gpu_memory_type type, VkMemoryRequirements info,
static void gpu_release(gpu_memory* memory);
static void condemn(void* handle, VkObjectType type);
static void expunge(void);
static void createSwapchain(uint32_t width, uint32_t height);
static VkRenderPass getCachedRenderPass(gpu_pass_info* pass, bool exact);
static VkFramebuffer getCachedFramebuffer(VkRenderPass pass, VkImageView images[9], uint32_t imageCount, uint32_t size[2]);
static VkImageLayout getNaturalLayout(uint32_t usage, VkImageAspectFlags aspect);
@ -738,11 +741,28 @@ void gpu_texture_destroy(gpu_texture* texture) {
gpu_release(state.memory + texture->memory);
}
gpu_texture* gpu_surface_acquire(void) {
gpu_texture* gpu_surface_acquire() {
if (!state.swapchainValid) {
return NULL;
}
gpu_tick* tick = &state.ticks[state.tick[CPU] & TICK_MASK];
state.surfaceSemaphore = tick->semaphores[0];
VK(vkAcquireNextImageKHR(state.device, state.swapchain, UINT64_MAX, state.surfaceSemaphore, VK_NULL_HANDLE, &state.currentSurfaceTexture), "Surface image acquisition failed") return NULL;
return &state.surfaceTextures[state.currentSurfaceTexture];
VkResult result = vkAcquireNextImageKHR(state.device, state.swapchain, UINT64_MAX, tick->semaphores[0], VK_NULL_HANDLE, &state.currentSwapchainTexture);
if (result == VK_ERROR_OUT_OF_DATE_KHR) {
state.currentSwapchainTexture = ~0u;
state.swapchainValid = false;
return NULL;
} else {
vcheck(result, "Failed to acquire swapchain");
}
state.swapchainSemaphore = tick->semaphores[0];
return &state.swapchainTextures[state.currentSwapchainTexture];
}
void gpu_surface_resize(uint32_t width, uint32_t height) {
createSwapchain(width, height);
}
// The barriers here are a bit lazy (oversynchronized) and can be improved
@ -2219,68 +2239,26 @@ bool gpu_init(gpu_config* config) {
}
}
// Swapchain
if (state.surface) {
VkSurfaceCapabilitiesKHR surfaceCapabilities;
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(state.adapter, state.surface, &surfaceCapabilities);
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(state.adapter, state.surface, &state.surfaceCapabilities);
VkSurfaceFormatKHR formats[16];
VkSurfaceFormatKHR formats[32];
uint32_t formatCount = COUNTOF(formats);
VkSurfaceFormatKHR surfaceFormat = { .format = VK_FORMAT_UNDEFINED };
vkGetPhysicalDeviceSurfaceFormatsKHR(state.adapter, state.surface, &formatCount, formats);
for (uint32_t i = 0; i < formatCount; i++) {
if (formats[i].format == VK_FORMAT_R8G8B8A8_SRGB || formats[i].format == VK_FORMAT_B8G8R8A8_SRGB) {
surfaceFormat = formats[i];
state.surfaceFormat = formats[i];
break;
}
}
VK(surfaceFormat.format == VK_FORMAT_UNDEFINED ? VK_ERROR_FORMAT_NOT_SUPPORTED : VK_SUCCESS, "No supported surface formats") return gpu_destroy(), false;
state.surfaceFormat = surfaceFormat.format;
VK(state.surfaceFormat.format == VK_FORMAT_UNDEFINED ? VK_ERROR_FORMAT_NOT_SUPPORTED : VK_SUCCESS, "No supported surface formats") return gpu_destroy(), false;
VkSwapchainCreateInfoKHR swapchainInfo = {
.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
.surface = state.surface,
.minImageCount = surfaceCapabilities.minImageCount,
.imageFormat = surfaceFormat.format,
.imageColorSpace = surfaceFormat.colorSpace,
.imageExtent = surfaceCapabilities.currentExtent,
.imageArrayLayers = 1,
.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR,
.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
.presentMode = state.config.vk.vsync ? VK_PRESENT_MODE_FIFO_KHR : VK_PRESENT_MODE_IMMEDIATE_KHR,
.clipped = VK_TRUE
};
uint32_t width = state.surfaceCapabilities.currentExtent.width;
uint32_t height = state.surfaceCapabilities.currentExtent.height;
VK(vkCreateSwapchainKHR(state.device, &swapchainInfo, NULL, &state.swapchain), "Swapchain creation failed") return gpu_destroy(), false;
uint32_t imageCount;
VkImage images[COUNTOF(state.surfaceTextures)];
VK(vkGetSwapchainImagesKHR(state.device, state.swapchain, &imageCount, NULL), "Failed to get swapchain images") return gpu_destroy(), false;
VK(imageCount > COUNTOF(images) ? VK_ERROR_TOO_MANY_OBJECTS : VK_SUCCESS, "Failed to get swapchain images") return gpu_destroy(), false;
VK(vkGetSwapchainImagesKHR(state.device, state.swapchain, &imageCount, images), "Failed to get swapchain images") return gpu_destroy(), false;
for (uint32_t i = 0; i < imageCount; i++) {
gpu_texture* texture = &state.surfaceTextures[i];
texture->handle = images[i];
texture->aspect = VK_IMAGE_ASPECT_COLOR_BIT;
texture->layout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
texture->samples = 1;
texture->memory = ~0u;
texture->layers = 1;
texture->format = GPU_FORMAT_SURFACE;
texture->srgb = true;
gpu_texture_view_info view = {
.source = texture,
.type = GPU_TEXTURE_2D
};
CHECK(gpu_texture_init_view(texture, &view), "Swapchain texture view creation failed") return gpu_destroy(), false;
}
createSwapchain(width, height);
}
// Ticks
@ -2338,7 +2316,7 @@ bool gpu_init(gpu_config* config) {
VK(vkCreatePipelineCache(state.device, &cacheInfo, NULL, &state.pipelineCache), "Pipeline cache creation failed") return gpu_destroy(), false;
state.tick[CPU] = COUNTOF(state.ticks) - 1;
state.currentSurfaceTexture = ~0u;
state.currentSwapchainTexture = ~0u;
return true;
}
@ -2371,8 +2349,8 @@ void gpu_destroy(void) {
for (uint32_t i = 0; i < COUNTOF(state.memory); i++) {
if (state.memory[i].handle) vkFreeMemory(state.device, state.memory[i].handle, NULL);
}
for (uint32_t i = 0; i < COUNTOF(state.surfaceTextures); i++) {
if (state.surfaceTextures[i].view) vkDestroyImageView(state.device, state.surfaceTextures[i].view, NULL);
for (uint32_t i = 0; i < COUNTOF(state.swapchainTextures); i++) {
if (state.swapchainTextures[i].view) vkDestroyImageView(state.device, state.swapchainTextures[i].view, NULL);
}
if (state.swapchain) vkDestroySwapchainKHR(state.device, state.swapchain, NULL);
if (state.device) vkDestroyDevice(state.device, NULL);
@ -2411,15 +2389,15 @@ void gpu_submit(gpu_stream** streams, uint32_t count) {
VkSubmitInfo submit = {
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
.waitSemaphoreCount = !!state.surfaceSemaphore,
.pWaitSemaphores = &state.surfaceSemaphore,
.waitSemaphoreCount = !!state.swapchainSemaphore,
.pWaitSemaphores = &state.swapchainSemaphore,
.pWaitDstStageMask = &waitStage,
.commandBufferCount = count,
.pCommandBuffers = commands
};
VK(vkQueueSubmit(state.queue, 1, &submit, tick->fence), "Queue submit failed") {}
state.surfaceSemaphore = VK_NULL_HANDLE;
state.swapchainSemaphore = VK_NULL_HANDLE;
}
void gpu_present() {
@ -2439,11 +2417,18 @@ void gpu_present() {
.pWaitSemaphores = &semaphore,
.swapchainCount = 1,
.pSwapchains = &state.swapchain,
.pImageIndices = &state.currentSurfaceTexture
.pImageIndices = &state.currentSwapchainTexture
};
VK(vkQueuePresentKHR(state.queue, &present), "Queue present failed") {}
state.currentSurfaceTexture = ~0u;
VkResult result = vkQueuePresentKHR(state.queue, &present);
if (result == VK_ERROR_OUT_OF_DATE_KHR) {
state.swapchainValid = false;
} else {
vcheck(result, "Queue present failed");
}
state.currentSwapchainTexture = ~0u;
}
bool gpu_is_complete(uint32_t tick) {
@ -2601,6 +2586,76 @@ static void expunge() {
}
}
static void createSwapchain(uint32_t width, uint32_t height) {
if (width == 0 || height == 0) {
state.swapchainValid = false;
return;
}
VkSwapchainKHR oldSwapchain = state.swapchain;
if (oldSwapchain) {
vkDeviceWaitIdle(state.device);
}
VkSwapchainCreateInfoKHR swapchainInfo = {
.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
.surface = state.surface,
.minImageCount = state.surfaceCapabilities.minImageCount,
.imageFormat = state.surfaceFormat.format,
.imageColorSpace = state.surfaceFormat.colorSpace,
.imageExtent = { width, height },
.imageArrayLayers = 1,
.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR,
.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
.presentMode = state.config.vk.vsync ? VK_PRESENT_MODE_FIFO_KHR : VK_PRESENT_MODE_IMMEDIATE_KHR,
.clipped = VK_TRUE,
.oldSwapchain = oldSwapchain
};
VK(vkCreateSwapchainKHR(state.device, &swapchainInfo, NULL, &state.swapchain), "Swapchain creation failed") return;
if (oldSwapchain) {
for (uint32_t i = 0; i < COUNTOF(state.swapchainTextures); i++) {
if (state.swapchainTextures[i].view) {
vkDestroyImageView(state.device, state.swapchainTextures[i].view, NULL);
}
}
memset(state.swapchainTextures, 0, sizeof(state.swapchainTextures));
vkDestroySwapchainKHR(state.device, oldSwapchain, NULL);
}
uint32_t imageCount;
VkImage images[COUNTOF(state.swapchainTextures)];
VK(vkGetSwapchainImagesKHR(state.device, state.swapchain, &imageCount, NULL), "Failed to get swapchain images") return;
VK(imageCount > COUNTOF(images) ? VK_ERROR_TOO_MANY_OBJECTS : VK_SUCCESS, "Failed to get swapchain images") return;
VK(vkGetSwapchainImagesKHR(state.device, state.swapchain, &imageCount, images), "Failed to get swapchain images") return;
for (uint32_t i = 0; i < imageCount; i++) {
gpu_texture* texture = &state.swapchainTextures[i];
texture->handle = images[i];
texture->aspect = VK_IMAGE_ASPECT_COLOR_BIT;
texture->layout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
texture->samples = 1;
texture->memory = ~0u;
texture->layers = 1;
texture->format = GPU_FORMAT_SURFACE;
texture->srgb = true;
gpu_texture_view_info view = {
.source = texture,
.type = GPU_TEXTURE_2D
};
CHECK(gpu_texture_init_view(texture, &view), "Swapchain texture view creation failed") return;
}
state.swapchainValid = true;
}
// Ugliness until we can use dynamic rendering
static VkRenderPass getCachedRenderPass(gpu_pass_info* pass, bool exact) {
bool depth = pass->depth.layout != VK_IMAGE_LAYOUT_UNDEFINED;
@ -2684,7 +2739,7 @@ static VkRenderPass getCachedRenderPass(gpu_pass_info* pass, bool exact) {
for (uint32_t i = 0; i < count; i++) {
references[i].attachment = i;
references[i].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
bool surface = pass->color[i].format == state.surfaceFormat;
bool surface = pass->color[i].format == state.surfaceFormat.format; // FIXME
bool discard = surface || pass->color[i].load != GPU_LOAD_OP_KEEP;
attachments[i] = (VkAttachmentDescription) {
.format = pass->color[i].format,
@ -2701,7 +2756,7 @@ static VkRenderPass getCachedRenderPass(gpu_pass_info* pass, bool exact) {
uint32_t index = count + i;
references[index].attachment = index;
references[index].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
bool surface = pass->color[i].format == state.surfaceFormat;
bool surface = pass->color[i].format == state.surfaceFormat.format; // FIXME
attachments[index] = (VkAttachmentDescription) {
.format = pass->color[i].format,
.samples = VK_SAMPLE_COUNT_1_BIT,
@ -2879,7 +2934,7 @@ static VkFormat convertFormat(gpu_texture_format format, int colorspace) {
};
if (format == GPU_FORMAT_SURFACE) {
return state.surfaceFormat;
return state.surfaceFormat.format;
}
return formats[format][colorspace];

View File

@ -128,7 +128,7 @@ typedef enum {
typedef void fn_gl_proc(void);
typedef void fn_quit(void);
typedef void fn_focus(bool focused);
typedef void fn_resize(int width, int height);
typedef void fn_resize(uint32_t width, uint32_t height);
typedef void fn_key(os_button_action action, os_key key, uint32_t scancode, bool repeat);
typedef void fn_text(uint32_t codepoint);
typedef void fn_permission(os_permission permission, bool granted);
@ -157,8 +157,8 @@ void os_on_permission(fn_permission* callback);
bool os_window_open(const os_window_config* config);
bool os_window_is_open(void);
void os_window_get_size(int* width, int* height);
void os_window_get_fbsize(int* width, int* height);
void os_window_get_size(uint32_t* width, uint32_t* height);
void os_window_get_fbsize(uint32_t* width, uint32_t* height);
size_t os_get_home_directory(char* buffer, size_t size);
size_t os_get_data_directory(char* buffer, size_t size);

View File

@ -319,12 +319,12 @@ bool os_window_is_open() {
return false;
}
void os_window_get_size(int* width, int* height) {
void os_window_get_size(uint32_t* width, uint32_t* height) {
if (width) *width = 0;
if (height) *height = 0;
}
void os_window_get_fbsize(int* width, int* height) {
void os_window_get_fbsize(uint32_t* width, uint32_t* height) {
*width = 0;
*height = 0;
}

View File

@ -248,21 +248,27 @@ bool os_window_is_open() {
return glfwState.window;
}
void os_window_get_size(int* width, int* height) {
void os_window_get_size(uint32_t* width, uint32_t* height) {
if (glfwState.window) {
glfwGetWindowSize(glfwState.window, width, height);
int w, h;
glfwGetWindowSize(glfwState.window, &w, &h);
*width = w;
*height = h;
} else {
if (*width) *width = 0;
if (*height) *height = 0;
*width = 0;
*height = 0;
}
}
void os_window_get_fbsize(int* width, int* height) {
void os_window_get_fbsize(uint32_t* width, uint32_t* height) {
if (glfwState.window) {
glfwGetFramebufferSize(glfwState.window, width, height);
int w, h;
glfwGetFramebufferSize(glfwState.window, &w, &h);
*width = w;
*height = h;
} else {
if (*width) *width = 0;
if (*height) *height = 0;
*width = 0;
*height = 0;
}
}

View File

@ -19,10 +19,10 @@ static struct {
os_mouse_mode mouseMode;
long mouseX;
long mouseY;
int width;
int height;
int framebufferWidth;
int framebufferHeight;
uint32_t width;
uint32_t height;
uint32_t framebufferWidth;
uint32_t framebufferHeight;
} state;
static const char* onBeforeUnload(int type, const void* unused, void* userdata) {
@ -45,7 +45,7 @@ static EM_BOOL onResize(int type, const EmscriptenUiEvent* data, void* userdata)
int newWidth, newHeight;
emscripten_get_canvas_element_size(CANVAS, &newWidth, &newHeight);
if (state.width != newWidth || state.height != newHeight) {
if (state.width != (uint32_t) newWidth || state.height != (uint32_t) newHeight) {
state.width = newWidth;
state.height = newHeight;
if (state.onWindowResize) {
@ -298,12 +298,12 @@ bool os_window_is_open() {
return state.context > 0;
}
void os_window_get_size(int* width, int* height) {
void os_window_get_size(uint32_t* width, uint32_t* height) {
*width = state.width;
*height = state.height;
}
void os_window_get_fbsize(int* width, int* height) {
void os_window_get_fbsize(uint32_t* width, uint32_t* height) {
*width = state.framebufferWidth;
*height = state.framebufferHeight;
}

View File

@ -3,6 +3,7 @@
#include "data/image.h"
#include "data/modelData.h"
#include "data/rasterizer.h"
#include "event/event.h"
#include "headset/headset.h"
#include "math/math.h"
#include "core/gpu.h"
@ -426,6 +427,7 @@ static void trackTexture(Pass* pass, Texture* texture, gpu_phase phase, gpu_cach
static void trackMaterial(Pass* pass, Material* material, gpu_phase phase, gpu_cache cache);
static void updateModelTransforms(Model* model, uint32_t nodeIndex, float* parent);
static void checkShaderFeatures(uint32_t* features, uint32_t count);
static void onResize(uint32_t width, uint32_t height);
static void onMessage(void* context, const char* message, bool severe);
// Entry
@ -450,6 +452,7 @@ bool lovrGraphicsInit(GraphicsConfig* config) {
gpu.vk.cacheSize = config->cacheSize;
if (os_window_is_open()) {
os_on_resize(onResize);
gpu.vk.getInstanceExtensions = os_vk_get_instance_extensions;
gpu.vk.createSurface = os_vk_create_surface;
gpu.vk.surface = true;
@ -632,17 +635,12 @@ bool lovrGraphicsInit(GraphicsConfig* config) {
state.window = malloc(sizeof(Texture));
lovrAssert(state.window, "Out of memory");
int width, height;
os_window_get_fbsize(&width, &height);
state.window->ref = 1;
state.window->gpu = NULL;
state.window->renderView = NULL;
state.window->info = (TextureInfo) {
.type = TEXTURE_2D,
.format = GPU_FORMAT_SURFACE,
.width = width,
.height = height,
.layers = 1,
.mipmaps = 1,
.samples = 1,
@ -650,6 +648,8 @@ bool lovrGraphicsInit(GraphicsConfig* config) {
.srgb = true
};
os_window_get_size(&state.window->info.width, &state.window->info.height);
state.depthFormat = config->stencil ? FORMAT_D32FS8 : FORMAT_D32F;
if (config->stencil && !lovrGraphicsIsFormatSupported(state.depthFormat, TEXTURE_FEATURE_RENDER)) {
@ -1104,7 +1104,7 @@ Buffer* lovrGraphicsGetBuffer(BufferInfo* info, void** data) {
arr_push(&state.scratchBufferHandles, handles);
}
uint32_t index = state.scratchBufferIndex++;
size_t index = state.scratchBufferIndex++;
Buffer* buffer = &state.scratchBuffers.data[index / BUFFERS_PER_CHUNK][index % BUFFERS_PER_CHUNK];
buffer->ref = 1;
@ -1191,8 +1191,14 @@ void lovrBufferClear(Buffer* buffer, uint32_t offset, uint32_t size) {
Texture* lovrGraphicsGetWindowTexture() {
if (!state.window->gpu) {
beginFrame();
state.window->gpu = gpu_surface_acquire();
state.window->renderView = state.window->gpu;
// Window texture may be unavailable during a resize
if (!state.window->gpu) {
return NULL;
}
}
return state.window;
@ -3209,10 +3215,17 @@ static void lovrPassCheckValid(Pass* pass) {
Pass* lovrGraphicsGetWindowPass() {
if (!state.windowPass && state.window) {
Texture* window = lovrGraphicsGetWindowTexture();
// The window texture (and therefore the window pass) may become unavailable during a resize
if (!window) {
return NULL;
}
PassInfo info = {
.type = PASS_RENDER,
.canvas.count = 1,
.canvas.textures[0] = state.window,
.canvas.textures[0] = window,
.canvas.depth.format = state.depthFormat,
.canvas.samples = state.config.antialias ? 4 : 1,
.label = "Window"
@ -3333,10 +3346,6 @@ Pass* lovrGraphicsGetPass(PassInfo* info) {
};
for (uint32_t i = 0; i < canvas->count; i++) {
if (canvas->textures[i] == state.window) {
canvas->textures[i] = lovrGraphicsGetWindowTexture(); // Make sure swapchain handle is updated
}
if (t->samples == 1 && canvas->samples > 1) {
scratchTextureInfo.format = canvas->textures[i]->info.format;
scratchTextureInfo.srgb = canvas->textures[i]->info.srgb;
@ -5891,6 +5900,19 @@ static void checkShaderFeatures(uint32_t* features, uint32_t count) {
}
}
static void onResize(uint32_t width, uint32_t height) {
state.window->info.width = width;
state.window->info.height = height;
gpu_surface_resize(width, height);
lovrEventPush((Event) {
.type = EVENT_RESIZE,
.data.resize.width = width,
.data.resize.height = height
});
}
static void onMessage(void* context, const char* message, bool severe) {
if (severe) {
lovrThrow("GPU error: %s", message);

View File

@ -84,10 +84,7 @@ static double desktop_getDeltaTime(void) {
}
static void desktop_getDisplayDimensions(uint32_t* width, uint32_t* height) {
int w, h;
os_window_get_fbsize(&w, &h);
*width = (uint32_t) w;
*height = (uint32_t) h;
os_window_get_fbsize(width, height);
}
static uint32_t desktop_getViewCount(void) {
@ -244,10 +241,10 @@ static double desktop_update(void) {
float turnspeed = 3.f * (float) dt;
float damping = MAX(1.f - 20.f * (float) dt, 0);
int width, height;
double mx, my;
os_window_get_fbsize(&width, &height);
uint32_t width, height;
os_get_mouse_position(&mx, &my);
os_window_get_fbsize(&width, &height);
double aspect = (width > 0 && height > 0) ? ((double) width / height) : 1.;

View File

@ -6,8 +6,6 @@
static struct {
bool initialized;
int windowWidth;
int windowHeight;
bool pressedKeys[KEY_COUNT];
} state;
@ -45,11 +43,6 @@ static void onQuit(void) {
});
}
static void onResize(int width, int height) {
state.windowWidth = width;
state.windowHeight = height;
}
bool lovrSystemInit() {
if (state.initialized) return false;
os_on_key(onKey);
@ -85,25 +78,19 @@ void lovrSystemRequestPermission(Permission permission) {
void lovrSystemOpenWindow(os_window_config* window) {
lovrAssert(os_window_open(window), "Could not open window");
os_on_resize(onResize);
os_on_quit(onQuit);
os_window_get_fbsize(&state.windowWidth, &state.windowHeight);
}
bool lovrSystemIsWindowOpen() {
return os_window_is_open();
}
uint32_t lovrSystemGetWindowWidth() {
return state.windowWidth;
}
uint32_t lovrSystemGetWindowHeight() {
return state.windowHeight;
void lovrSystemGetWindowSize(uint32_t* width, uint32_t* height) {
os_window_get_fbsize(width, height);
}
float lovrSystemGetWindowDensity() {
int width, height, fbwidth, fbheight;
uint32_t width, height, fbwidth, fbheight;
os_window_get_size(&width, &height);
os_window_get_fbsize(&fbwidth, &fbheight);
return (width == 0 || fbwidth == 0) ? 0.f : (float) fbwidth / width;

View File

@ -16,7 +16,6 @@ uint32_t lovrSystemGetCoreCount(void);
void lovrSystemRequestPermission(Permission permission);
void lovrSystemOpenWindow(struct os_window_config* config);
bool lovrSystemIsWindowOpen(void);
uint32_t lovrSystemGetWindowWidth(void);
uint32_t lovrSystemGetWindowHeight(void);
void lovrSystemGetWindowSize(uint32_t* width, uint32_t* height);
float lovrSystemGetWindowDensity(void);
bool lovrSystemIsKeyDown(int keycode);