diff --git a/src/xrt/compositor/main/comp_target_swapchain.c b/src/xrt/compositor/main/comp_target_swapchain.c index 16612cae2..55951cea4 100644 --- a/src/xrt/compositor/main/comp_target_swapchain.c +++ b/src/xrt/compositor/main/comp_target_swapchain.c @@ -150,6 +150,16 @@ select_extent(struct comp_target_swapchain *cts, uint32_t preferred_width, uint32_t preferred_height) { + /* + * A sub-class wants us to use these extents over the ones the + * compositor preferred, this is probably due to the target only + * upporting this size so we better respect those wishes. + */ + if (cts->override.compositor_extent) { + preferred_width = cts->override.extent.width; + preferred_height = cts->override.extent.height; + } + // If width (and height) equals the special value 0xFFFFFFFF, // the size of the surface will be set by the swapchain if (caps.currentExtent.width == (uint32_t)-1) { @@ -1032,6 +1042,25 @@ comp_target_swapchain_info_gpu( * */ +void +comp_target_swapchain_override_extents(struct comp_target_swapchain *cts, VkExtent2D extent) +{ + VkExtent2D old = cts->override.extent; + + COMP_INFO( // + cts->base.c, // + "Target '%s' overrides compositor extents with (%ux%u) was (%ux%u %s)", // + cts->base.name, // + extent.width, // + extent.height, // + old.width, // + old.height, // + cts->override.compositor_extent ? "true" : "false"); // + + cts->override.compositor_extent = true; + cts->override.extent = extent; +} + void comp_target_swapchain_cleanup(struct comp_target_swapchain *cts) { diff --git a/src/xrt/compositor/main/comp_target_swapchain.h b/src/xrt/compositor/main/comp_target_swapchain.h index 7098fcab4..24ddb400e 100644 --- a/src/xrt/compositor/main/comp_target_swapchain.h +++ b/src/xrt/compositor/main/comp_target_swapchain.h @@ -47,6 +47,22 @@ struct comp_target_swapchain //! Also works as a frame index. int64_t current_frame_id; + struct + { + /*! + * Should we ignore the compositor's preferred extents. Some + * targets, like the direct mode ones, requires a particular + * set of dimensions. + */ + bool compositor_extent; + + /*! + * The extents that a sub-class wants us to use, + * see @p ignore_compositor_extent above. + */ + VkExtent2D extent; + } override; + struct { VkSwapchainKHR handle; @@ -129,6 +145,17 @@ void comp_target_swapchain_init_and_set_fnptrs(struct comp_target_swapchain *cts, enum comp_target_display_timing_usage timing_usage); +/*! + * Set that any size from the compositor should be ignored and that given size + * must be used for the @p VkSwapchain the helper code creates. + * + * @protected @memberof comp_target_swapchain + * + * @ingroup comp_main + */ +void +comp_target_swapchain_override_extents(struct comp_target_swapchain *cts, VkExtent2D extent); + /*! * Free all managed resources on the given @ref comp_target_swapchain, * does not free the struct itself. diff --git a/src/xrt/compositor/main/comp_window_direct_nvidia.c b/src/xrt/compositor/main/comp_window_direct_nvidia.c index 95c12335b..a65c27a2a 100644 --- a/src/xrt/compositor/main/comp_window_direct_nvidia.c +++ b/src/xrt/compositor/main/comp_window_direct_nvidia.c @@ -160,8 +160,7 @@ append_nvidia_entry_on_match(struct comp_window_direct_nvidia *w, */ // Make the compositor use this size. - w->base.base.c->settings.preferred.width = disp->physicalResolution.width; - w->base.base.c->settings.preferred.height = disp->physicalResolution.height; + comp_target_swapchain_override_extents(&w->base, disp->physicalResolution); // Create the entry. struct comp_window_direct_nvidia_display d = { diff --git a/src/xrt/compositor/main/comp_window_direct_randr.c b/src/xrt/compositor/main/comp_window_direct_randr.c index f6f9a727a..fc570467c 100644 --- a/src/xrt/compositor/main/comp_window_direct_randr.c +++ b/src/xrt/compositor/main/comp_window_direct_randr.c @@ -223,8 +223,8 @@ comp_window_direct_randr_init(struct comp_target *ct) struct comp_window_direct_randr_display *d = comp_window_direct_randr_current_display(w_direct); // Make the compositor use this size. - ct->c->settings.preferred.width = d->primary_mode.width; - ct->c->settings.preferred.height = d->primary_mode.height; + VkExtent2D extent = {d->primary_mode.width, d->primary_mode.height}; + comp_target_swapchain_override_extents(&w_direct->base, extent); return true; } diff --git a/src/xrt/compositor/main/comp_window_vk_display.c b/src/xrt/compositor/main/comp_window_vk_display.c index 01631b261..abc867394 100644 --- a/src/xrt/compositor/main/comp_window_vk_display.c +++ b/src/xrt/compositor/main/comp_window_vk_display.c @@ -128,8 +128,7 @@ static bool append_vk_display_entry(struct comp_window_vk_display *w, struct VkDisplayPropertiesKHR *disp) { // Make the compositor use this size. - w->base.base.c->settings.preferred.width = disp->physicalResolution.width; - w->base.base.c->settings.preferred.height = disp->physicalResolution.height; + comp_target_swapchain_override_extents(&w->base, disp->physicalResolution); // Create the entry. struct vk_display d = { diff --git a/src/xrt/compositor/main/comp_window_xcb.c b/src/xrt/compositor/main/comp_window_xcb.c index a6bd31a97..3e643669d 100644 --- a/src/xrt/compositor/main/comp_window_xcb.c +++ b/src/xrt/compositor/main/comp_window_xcb.c @@ -90,7 +90,7 @@ static int comp_window_xcb_connect(struct comp_window_xcb *w); static void -comp_window_xcb_create_window(struct comp_window_xcb *w, uint32_t width, uint32_t height); +comp_window_xcb_create_window(struct comp_window_xcb *w, VkExtent2D extent); static void comp_window_xcb_get_randr_outputs(struct comp_window_xcb *w); @@ -237,17 +237,23 @@ comp_window_xcb_init(struct comp_target *ct) } if (d->size.width != 0 && d->size.height != 0) { - ct->c->settings.preferred.width = d->size.width; - ct->c->settings.preferred.height = d->size.height; COMP_DEBUG(ct->c, "Setting window size %dx%d.", d->size.width, d->size.height); - // TODO: size cb - // set_size_cb(settings->width, settings->height); + VkExtent2D extent = {d->size.width, d->size.height}; + comp_target_swapchain_override_extents(&w_xcb->base, extent); } } + // The extent of the window we are about to create. + VkExtent2D extent = {ct->c->settings.preferred.width, ct->c->settings.preferred.height}; + + // If we require a particular size, use that. + if (w_xcb->base.override.compositor_extent) { + extent = w_xcb->base.override.extent; + } + // We can now create the window. - comp_window_xcb_create_window(w_xcb, ct->c->settings.preferred.width, ct->c->settings.preferred.height); + comp_window_xcb_create_window(w_xcb, extent); comp_window_xcb_connect_delete_event(w_xcb); @@ -294,7 +300,7 @@ comp_window_xcb_connect(struct comp_window_xcb *w) } static void -comp_window_xcb_create_window(struct comp_window_xcb *w, uint32_t width, uint32_t height) +comp_window_xcb_create_window(struct comp_window_xcb *w, VkExtent2D extent) { w->window = xcb_generate_id(w->connection); @@ -315,8 +321,8 @@ comp_window_xcb_create_window(struct comp_window_xcb *w, uint32_t width, uint32_ w->screen->root, // parent x, // x y, // y - width, // width - height, // height + extent.width, // width + extent.height, // height 0, // border_width XCB_WINDOW_CLASS_INPUT_OUTPUT, // _class w->screen->root_visual, // visual