mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2025-03-03 05:06:31 +00:00
c/renderer+ipc: Use layer renderer.
Make the renderer and IPC aware of multiple projection and quad layers using the layer renderer. Remove redundant code related to idle images and imported buffers and command buffer rebuild, since we now always just display the layer renderer's frame buffer. Get view and projection properties from xrt_device.
This commit is contained in:
parent
aedd4d9ff8
commit
d0539161dc
src/xrt
|
@ -360,11 +360,13 @@ compositor_layer_commit(struct xrt_compositor *xc)
|
|||
|
||||
left = &stereo->l.sc->images[stereo->l.image_index];
|
||||
right = &stereo->l.sc->images[stereo->r.image_index];
|
||||
uint32_t l_array_index = stereo->l.array_index;
|
||||
uint32_t r_array_index = stereo->r.array_index;
|
||||
|
||||
comp_renderer_frame(c->r, left, l_array_index, right, r_array_index,
|
||||
layer->flip_y);
|
||||
comp_renderer_destroy_layers(c->r);
|
||||
comp_renderer_allocate_layers(c->r, 1);
|
||||
|
||||
comp_renderer_set_projection_layer(c->r, left, right, layer->flip_y, 0);
|
||||
|
||||
comp_renderer_draw(c->r);
|
||||
|
||||
compositor_add_frame_timing(c);
|
||||
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
|
||||
#include "xrt/xrt_compositor.h"
|
||||
#include "main/comp_distortion.h"
|
||||
|
||||
#include "main/comp_layer_renderer.h"
|
||||
#include "math/m_api.h"
|
||||
|
||||
/*
|
||||
*
|
||||
|
@ -32,8 +33,6 @@
|
|||
*/
|
||||
struct comp_renderer
|
||||
{
|
||||
bool one_buffer_imported[2];
|
||||
|
||||
uint32_t current_buffer;
|
||||
|
||||
VkQueue queue;
|
||||
|
@ -52,11 +51,11 @@ struct comp_renderer
|
|||
VkFence *fences;
|
||||
uint32_t num_buffers;
|
||||
|
||||
struct comp_swapchain_image dummy_images[2];
|
||||
|
||||
struct comp_compositor *c;
|
||||
struct comp_settings *settings;
|
||||
struct comp_distortion *distortion;
|
||||
|
||||
struct comp_layer_renderer *lr;
|
||||
};
|
||||
|
||||
|
||||
|
@ -72,25 +71,12 @@ renderer_create(struct comp_renderer *r, struct comp_compositor *c);
|
|||
static void
|
||||
renderer_init(struct comp_renderer *r);
|
||||
|
||||
static void
|
||||
renderer_set_swapchain_image(struct comp_renderer *r,
|
||||
uint32_t eye,
|
||||
struct comp_swapchain_image *image,
|
||||
uint32_t layer,
|
||||
bool flip_y);
|
||||
|
||||
static void
|
||||
renderer_render(struct comp_renderer *r);
|
||||
|
||||
static void
|
||||
renderer_submit_queue(struct comp_renderer *r);
|
||||
|
||||
static void
|
||||
renderer_build_command_buffers(struct comp_renderer *r);
|
||||
|
||||
static void
|
||||
renderer_rebuild_command_buffers(struct comp_renderer *r);
|
||||
|
||||
static void
|
||||
renderer_build_command_buffer(struct comp_renderer *r,
|
||||
VkCommandBuffer command_buffer,
|
||||
|
@ -99,9 +85,6 @@ renderer_build_command_buffer(struct comp_renderer *r,
|
|||
static void
|
||||
renderer_init_descriptor_pool(struct comp_renderer *r);
|
||||
|
||||
static void
|
||||
renderer_init_dummy_images(struct comp_renderer *r);
|
||||
|
||||
static void
|
||||
renderer_create_frame_buffer(struct comp_renderer *r,
|
||||
VkFramebuffer *frame_buffer,
|
||||
|
@ -156,25 +139,6 @@ comp_renderer_create(struct comp_compositor *c)
|
|||
return r;
|
||||
}
|
||||
|
||||
void
|
||||
comp_renderer_frame(struct comp_renderer *r,
|
||||
struct comp_swapchain_image *left,
|
||||
uint32_t left_layer,
|
||||
struct comp_swapchain_image *right,
|
||||
uint32_t right_layer,
|
||||
bool flip_y)
|
||||
{
|
||||
renderer_set_swapchain_image(r, 0, left, left_layer, flip_y);
|
||||
renderer_set_swapchain_image(r, 1, right, right_layer, flip_y);
|
||||
renderer_render(r);
|
||||
}
|
||||
|
||||
void
|
||||
comp_renderer_frame_cached(struct comp_renderer *r)
|
||||
{
|
||||
renderer_render(r);
|
||||
}
|
||||
|
||||
void
|
||||
comp_renderer_destroy(struct comp_renderer *r)
|
||||
{
|
||||
|
@ -182,13 +146,6 @@ comp_renderer_destroy(struct comp_renderer *r)
|
|||
free(r);
|
||||
}
|
||||
|
||||
void
|
||||
comp_renderer_reset(struct comp_renderer *r)
|
||||
{
|
||||
r->one_buffer_imported[0] = false;
|
||||
r->one_buffer_imported[1] = false;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* Functions.
|
||||
|
@ -201,8 +158,6 @@ renderer_create(struct comp_renderer *r, struct comp_compositor *c)
|
|||
r->c = c;
|
||||
r->settings = &c->settings;
|
||||
|
||||
r->one_buffer_imported[0] = false;
|
||||
r->one_buffer_imported[1] = false;
|
||||
r->current_buffer = 0;
|
||||
r->queue = VK_NULL_HANDLE;
|
||||
r->render_pass = VK_NULL_HANDLE;
|
||||
|
@ -211,11 +166,6 @@ renderer_create(struct comp_renderer *r, struct comp_compositor *c)
|
|||
r->semaphores.present_complete = VK_NULL_HANDLE;
|
||||
r->semaphores.render_complete = VK_NULL_HANDLE;
|
||||
|
||||
U_ZERO(&r->dummy_images[0]);
|
||||
U_ZERO(&r->dummy_images[1]);
|
||||
r->dummy_images[0].views = U_TYPED_CALLOC(VkImageView);
|
||||
r->dummy_images[1].views = U_TYPED_CALLOC(VkImageView);
|
||||
|
||||
r->distortion = NULL;
|
||||
r->cmd_buffers = NULL;
|
||||
r->frame_buffers = NULL;
|
||||
|
@ -266,17 +216,6 @@ renderer_build_command_buffers(struct comp_renderer *r)
|
|||
r->frame_buffers[i]);
|
||||
}
|
||||
|
||||
static void
|
||||
renderer_rebuild_command_buffers(struct comp_renderer *r)
|
||||
{
|
||||
renderer_destroy_command_buffers(r);
|
||||
|
||||
r->num_buffers = r->c->window->swapchain.image_count;
|
||||
|
||||
renderer_allocate_command_buffers(r);
|
||||
renderer_build_command_buffers(r);
|
||||
}
|
||||
|
||||
static void
|
||||
renderer_set_viewport_scissor(float scale_x,
|
||||
float scale_y,
|
||||
|
@ -430,85 +369,6 @@ renderer_init_descriptor_pool(struct comp_renderer *r)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_set_image_layout(struct vk_bundle *vk,
|
||||
VkCommandBuffer cmd_buffer,
|
||||
VkImage image,
|
||||
VkAccessFlags src_access_mask,
|
||||
VkAccessFlags dst_access_mask,
|
||||
VkImageLayout old_layout,
|
||||
VkImageLayout new_layout,
|
||||
VkImageSubresourceRange subresource_range)
|
||||
{
|
||||
VkImageMemoryBarrier barrier = {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
.srcAccessMask = src_access_mask,
|
||||
.dstAccessMask = dst_access_mask,
|
||||
.oldLayout = old_layout,
|
||||
.newLayout = new_layout,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.image = image,
|
||||
.subresourceRange = subresource_range,
|
||||
};
|
||||
|
||||
vk->vkCmdPipelineBarrier(cmd_buffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
||||
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, NULL,
|
||||
0, NULL, 1, &barrier);
|
||||
}
|
||||
|
||||
static void
|
||||
renderer_init_dummy_images(struct comp_renderer *r)
|
||||
{
|
||||
struct vk_bundle *vk = &r->c->vk;
|
||||
VkCommandBuffer cmd_buffer;
|
||||
if (vk_init_cmd_buffer(vk, &cmd_buffer) != VK_SUCCESS)
|
||||
return;
|
||||
|
||||
VkImageSubresourceRange subresource_range = {
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.baseMipLevel = 0,
|
||||
.levelCount = 1,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1};
|
||||
|
||||
VkClearColorValue color = {.float32 = {0.3, 0.3, 0.3, 1}};
|
||||
VkExtent2D extent = {.width = 640, .height = 800};
|
||||
|
||||
VkImageUsageFlags usage =
|
||||
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
||||
|
||||
for (uint32_t i = 0; i < 2; i++) {
|
||||
vk_create_image_simple(
|
||||
&r->c->vk, extent, VK_FORMAT_B8G8R8A8_SRGB, usage,
|
||||
&r->dummy_images[i].memory, &r->dummy_images[i].image);
|
||||
|
||||
_set_image_layout(
|
||||
vk, cmd_buffer, r->dummy_images[i].image, 0,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, subresource_range);
|
||||
|
||||
vk->vkCmdClearColorImage(cmd_buffer, r->dummy_images[i].image,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
&color, 1, &subresource_range);
|
||||
|
||||
vk_set_image_layout(vk, cmd_buffer, r->dummy_images[i].image,
|
||||
VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
VK_ACCESS_SHADER_READ_BIT,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
subresource_range);
|
||||
|
||||
vk_create_sampler(vk, &r->dummy_images[i].sampler);
|
||||
vk_create_view(vk, r->dummy_images[i].image,
|
||||
VK_FORMAT_B8G8R8A8_SRGB, subresource_range,
|
||||
&r->dummy_images[i].views[0]);
|
||||
}
|
||||
|
||||
vk_submit_cmd_buffer(vk, cmd_buffer);
|
||||
}
|
||||
|
||||
static void
|
||||
_create_fences(struct comp_renderer *r)
|
||||
{
|
||||
|
@ -531,12 +391,41 @@ _create_fences(struct comp_renderer *r)
|
|||
}
|
||||
|
||||
static void
|
||||
_set_dummy_images(struct comp_renderer *r)
|
||||
_get_view_projection(struct comp_renderer *r)
|
||||
{
|
||||
for (uint32_t i = 0; i < 2; i++)
|
||||
comp_distortion_update_descriptor_set(
|
||||
r->distortion, r->dummy_images[i].sampler,
|
||||
r->dummy_images[i].views[0], i, false);
|
||||
struct xrt_space_relation relation;
|
||||
uint64_t out_timestamp;
|
||||
|
||||
xrt_device_get_tracked_pose(r->c->xdev, XRT_INPUT_GENERIC_HEAD_POSE,
|
||||
r->c->last_frame_time_ns, &out_timestamp,
|
||||
&relation);
|
||||
|
||||
struct xrt_vec3 eye_relation = {
|
||||
0.063000f, /* TODO: get actual ipd_meters */
|
||||
0.0f,
|
||||
0.0f,
|
||||
};
|
||||
|
||||
struct xrt_pose base_space_pose = {
|
||||
.position = (struct xrt_vec3){0, 0, 0},
|
||||
.orientation = (struct xrt_quat){0, 0, 0, 1},
|
||||
};
|
||||
|
||||
for (uint32_t i = 0; i < 2; i++) {
|
||||
struct xrt_fov fov = r->c->xdev->hmd->views[i].fov;
|
||||
|
||||
comp_layer_renderer_set_fov(r->lr, &fov, i);
|
||||
|
||||
struct xrt_pose view_pose;
|
||||
xrt_device_get_view_pose(r->c->xdev, &eye_relation, i,
|
||||
&view_pose);
|
||||
|
||||
struct xrt_pose pose;
|
||||
math_pose_openxr_locate(&view_pose, &relation.pose,
|
||||
&base_space_pose, &pose);
|
||||
|
||||
comp_layer_renderer_set_pose(r->lr, &pose, i);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -558,8 +447,6 @@ renderer_init(struct comp_renderer *r)
|
|||
renderer_create_frame_buffers(r);
|
||||
renderer_allocate_command_buffers(r);
|
||||
|
||||
renderer_init_dummy_images(r);
|
||||
|
||||
renderer_init_descriptor_pool(r);
|
||||
|
||||
r->distortion = U_TYPED_CALLOC(struct comp_distortion);
|
||||
|
@ -569,47 +456,67 @@ renderer_init(struct comp_renderer *r)
|
|||
r->c->xdev->hmd, r->descriptor_pool,
|
||||
r->settings->flip_y);
|
||||
|
||||
_set_dummy_images(r);
|
||||
VkExtent2D extent = {
|
||||
.width = r->c->xdev->hmd->screens[0].w_pixels,
|
||||
.height = r->c->xdev->hmd->screens[0].h_pixels,
|
||||
};
|
||||
|
||||
r->lr = comp_layer_renderer_create(vk, extent, VK_FORMAT_B8G8R8A8_SRGB);
|
||||
|
||||
for (uint32_t i = 0; i < 2; i++) {
|
||||
comp_distortion_update_descriptor_set(
|
||||
r->distortion, r->lr->framebuffers[i].sampler,
|
||||
r->lr->framebuffers[i].view, i, false);
|
||||
}
|
||||
|
||||
renderer_build_command_buffers(r);
|
||||
}
|
||||
|
||||
void
|
||||
comp_renderer_set_idle_images(struct comp_renderer *r)
|
||||
{
|
||||
_set_dummy_images(r);
|
||||
renderer_rebuild_command_buffers(r);
|
||||
}
|
||||
|
||||
static void
|
||||
renderer_set_swapchain_image(struct comp_renderer *r,
|
||||
uint32_t eye,
|
||||
comp_renderer_set_quad_layer(struct comp_renderer *r,
|
||||
struct comp_swapchain_image *image,
|
||||
uint32_t layer,
|
||||
bool flip_y)
|
||||
struct xrt_pose *pose,
|
||||
struct xrt_vec2 *size,
|
||||
bool flip_y,
|
||||
uint32_t layer)
|
||||
{
|
||||
if (eye > 1) {
|
||||
COMP_ERROR(r->c, "Swapchain image %p %u not found",
|
||||
(void *)image, eye);
|
||||
return;
|
||||
}
|
||||
comp_layer_update_descriptors(r->lr->layers[layer], image->sampler,
|
||||
image->views[0]);
|
||||
|
||||
if (!r->one_buffer_imported[eye]) {
|
||||
COMP_DEBUG(r->c,
|
||||
"Updating descriptor set for"
|
||||
" swapchain image %p and eye %u",
|
||||
(void *)image, eye);
|
||||
comp_distortion_update_descriptor_set(
|
||||
r->distortion, image->sampler, image->views[layer],
|
||||
(uint32_t)eye, flip_y);
|
||||
renderer_rebuild_command_buffers(r);
|
||||
r->one_buffer_imported[eye] = true;
|
||||
}
|
||||
struct xrt_matrix_4x4 model_matrix;
|
||||
math_matrix_4x4_quad_model(pose, size, &model_matrix);
|
||||
|
||||
comp_layer_set_model_matrix(r->lr->layers[layer], &model_matrix);
|
||||
|
||||
r->lr->layers[layer]->type = COMP_LAYER_QUAD;
|
||||
comp_layer_set_flip_y(r->lr->layers[layer], flip_y);
|
||||
|
||||
r->c->vk.vkDeviceWaitIdle(r->c->vk.device);
|
||||
}
|
||||
|
||||
static void
|
||||
renderer_render(struct comp_renderer *r)
|
||||
void
|
||||
comp_renderer_set_projection_layer(struct comp_renderer *r,
|
||||
struct comp_swapchain_image *left_image,
|
||||
struct comp_swapchain_image *right_image,
|
||||
bool flip_y,
|
||||
uint32_t layer)
|
||||
{
|
||||
comp_layer_update_stereo_descriptors(
|
||||
r->lr->layers[layer], left_image->sampler, right_image->sampler,
|
||||
left_image->views[0], right_image->views[0]);
|
||||
|
||||
comp_layer_set_flip_y(r->lr->layers[layer], flip_y);
|
||||
|
||||
r->lr->layers[layer]->type = COMP_LAYER_STEREO_PROJECTION;
|
||||
}
|
||||
|
||||
void
|
||||
comp_renderer_draw(struct comp_renderer *r)
|
||||
{
|
||||
_get_view_projection(r);
|
||||
comp_layer_renderer_draw(r->lr);
|
||||
r->c->vk.vkDeviceWaitIdle(r->c->vk.device);
|
||||
|
||||
r->c->window->flush(r->c->window);
|
||||
renderer_acquire_swapchain_image(r);
|
||||
renderer_submit_queue(r);
|
||||
|
@ -898,11 +805,6 @@ renderer_destroy(struct comp_renderer *r)
|
|||
r->distortion = NULL;
|
||||
}
|
||||
|
||||
// Dummy images
|
||||
for (uint32_t i = 0; i < 2; i++) {
|
||||
comp_swapchain_image_cleanup(vk, 1, &r->dummy_images[i]);
|
||||
}
|
||||
|
||||
// Discriptor pool
|
||||
if (r->descriptor_pool != VK_NULL_HANDLE) {
|
||||
vk->vkDestroyDescriptorPool(vk->device, r->descriptor_pool,
|
||||
|
@ -956,4 +858,18 @@ renderer_destroy(struct comp_renderer *r)
|
|||
r->semaphores.render_complete, NULL);
|
||||
r->semaphores.render_complete = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
comp_layer_renderer_destroy(r->lr);
|
||||
}
|
||||
|
||||
void
|
||||
comp_renderer_allocate_layers(struct comp_renderer *self, uint32_t num_layers)
|
||||
{
|
||||
comp_layer_renderer_allocate_layers(self->lr, num_layers);
|
||||
}
|
||||
|
||||
void
|
||||
comp_renderer_destroy_layers(struct comp_renderer *self)
|
||||
{
|
||||
comp_layer_renderer_destroy_layers(self->lr);
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "xrt/xrt_compiler.h"
|
||||
#include "xrt/xrt_defines.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -29,25 +30,11 @@ struct comp_swapchain_image;
|
|||
struct comp_renderer *
|
||||
comp_renderer_create(struct comp_compositor *c);
|
||||
|
||||
/*!
|
||||
* Render a distorted stereo frame.
|
||||
*
|
||||
* @ingroup comp_main
|
||||
*/
|
||||
void
|
||||
comp_renderer_frame(struct comp_renderer *r,
|
||||
struct comp_swapchain_image *left,
|
||||
uint32_t left_layer,
|
||||
struct comp_swapchain_image *right,
|
||||
uint32_t right_layer,
|
||||
bool flip_y);
|
||||
|
||||
/*!
|
||||
* Reset renderer as input has changed.
|
||||
*
|
||||
* @ingroup comp_main
|
||||
*/
|
||||
|
||||
void
|
||||
comp_renderer_reset(struct comp_renderer *r);
|
||||
|
||||
|
@ -60,20 +47,34 @@ void
|
|||
comp_renderer_destroy(struct comp_renderer *r);
|
||||
|
||||
/*!
|
||||
* Set dummy images in renderer.
|
||||
* Render frame.
|
||||
*
|
||||
* @ingroup comp_main
|
||||
*/
|
||||
void
|
||||
comp_renderer_set_idle_images(struct comp_renderer *r);
|
||||
comp_renderer_draw(struct comp_renderer *r);
|
||||
|
||||
/*!
|
||||
* Render frame without setting new images.
|
||||
*
|
||||
* @ingroup comp_main
|
||||
*/
|
||||
void
|
||||
comp_renderer_frame_cached(struct comp_renderer *r);
|
||||
comp_renderer_set_projection_layer(struct comp_renderer *r,
|
||||
struct comp_swapchain_image *left_image,
|
||||
struct comp_swapchain_image *right_image,
|
||||
bool flip_y,
|
||||
uint32_t layer);
|
||||
|
||||
void
|
||||
comp_renderer_set_quad_layer(struct comp_renderer *r,
|
||||
struct comp_swapchain_image *image,
|
||||
struct xrt_pose *pose,
|
||||
struct xrt_vec2 *size,
|
||||
bool flip_y,
|
||||
uint32_t layer);
|
||||
|
||||
|
||||
void
|
||||
comp_renderer_allocate_layers(struct comp_renderer *self, uint32_t num_layers);
|
||||
|
||||
void
|
||||
comp_renderer_destroy_layers(struct comp_renderer *self);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
|
||||
#include "os/os_threading.h"
|
||||
|
||||
#include "ipc_protocol.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -81,6 +83,35 @@ struct ipc_swapchain_data
|
|||
uint32_t num_images;
|
||||
};
|
||||
|
||||
struct ipc_quad_render_state
|
||||
{
|
||||
uint32_t swapchain_index;
|
||||
uint32_t image_index;
|
||||
|
||||
struct xrt_pose pose;
|
||||
struct xrt_vec2 size;
|
||||
};
|
||||
|
||||
struct ipc_stereo_projection_render_state
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t swapchain_index;
|
||||
uint32_t image_index;
|
||||
} l, r;
|
||||
};
|
||||
|
||||
struct ipc_layer_render_state
|
||||
{
|
||||
enum ipc_layer_type type;
|
||||
bool flip_y;
|
||||
|
||||
union {
|
||||
struct ipc_quad_render_state quad;
|
||||
struct ipc_stereo_projection_render_state stereo;
|
||||
};
|
||||
};
|
||||
|
||||
/*!
|
||||
* Render state for a client.
|
||||
*
|
||||
|
@ -89,11 +120,9 @@ struct ipc_swapchain_data
|
|||
struct ipc_render_state
|
||||
{
|
||||
bool rendering;
|
||||
bool flip_y;
|
||||
uint32_t l_swapchain_index;
|
||||
uint32_t l_image_index;
|
||||
uint32_t r_swapchain_index;
|
||||
uint32_t r_image_index;
|
||||
enum xrt_blend_mode env_blend_mode;
|
||||
uint32_t num_layers;
|
||||
struct ipc_layer_render_state layers[IPC_MAX_LAYERS];
|
||||
};
|
||||
|
||||
/*!
|
||||
|
|
|
@ -101,14 +101,35 @@ ipc_handle_compositor_layer_sync(volatile struct ipc_client_state *cs,
|
|||
{
|
||||
struct ipc_shared_memory *ism = cs->server->ism;
|
||||
struct ipc_layer_slot *slot = &ism->slots[slot_id];
|
||||
struct ipc_layer_entry *layer = &slot->layers[0];
|
||||
struct ipc_layer_stereo_projection *stereo = &layer->stereo;
|
||||
|
||||
cs->render_state.flip_y = layer->flip_y;
|
||||
cs->render_state.l_swapchain_index = stereo->l.swapchain_id;
|
||||
cs->render_state.l_image_index = stereo->l.image_index;
|
||||
cs->render_state.r_swapchain_index = stereo->r.swapchain_id;
|
||||
cs->render_state.r_image_index = stereo->r.image_index;
|
||||
for (uint32_t i = 0; i < slot->num_layers; i++) {
|
||||
cs->render_state.layers[i].type = slot->layers[i].type;
|
||||
|
||||
struct ipc_layer_entry *sl = &slot->layers[i];
|
||||
volatile struct ipc_layer_render_state *rl =
|
||||
&cs->render_state.layers[i];
|
||||
|
||||
rl->flip_y = sl->flip_y;
|
||||
|
||||
switch (slot->layers[i].type) {
|
||||
case IPC_LAYER_STEREO_PROJECTION:
|
||||
rl->stereo.l.swapchain_index =
|
||||
sl->stereo.l.swapchain_id;
|
||||
rl->stereo.l.image_index = sl->stereo.l.image_index;
|
||||
rl->stereo.r.swapchain_index =
|
||||
sl->stereo.r.swapchain_id;
|
||||
rl->stereo.r.image_index = sl->stereo.r.image_index;
|
||||
break;
|
||||
case IPC_LAYER_QUAD:
|
||||
rl->quad.swapchain_index = sl->quad.swapchain_id;
|
||||
rl->quad.image_index = sl->quad.image_index;
|
||||
rl->quad.pose = sl->quad.pose;
|
||||
rl->quad.size = sl->quad.size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cs->render_state.num_layers = slot->num_layers;
|
||||
cs->render_state.rendering = true;
|
||||
|
||||
*out_free_slot_id = (slot_id + 1) % IPC_MAX_SLOTS;
|
||||
|
@ -415,13 +436,22 @@ client_loop(volatile struct ipc_client_state *cs)
|
|||
cs->num_swapchains = 0;
|
||||
|
||||
// Make sure to reset the renderstate fully.
|
||||
cs->render_state.flip_y = false;
|
||||
cs->render_state.l_swapchain_index = 0;
|
||||
cs->render_state.l_image_index = 0;
|
||||
cs->render_state.r_swapchain_index = 0;
|
||||
cs->render_state.r_image_index = 0;
|
||||
cs->render_state.num_layers = 0;
|
||||
cs->render_state.rendering = false;
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(cs->render_state.layers); ++i) {
|
||||
volatile struct ipc_layer_render_state *rl =
|
||||
&cs->render_state.layers[i];
|
||||
|
||||
rl->flip_y = false;
|
||||
rl->stereo.l.swapchain_index = 0;
|
||||
rl->stereo.l.image_index = 0;
|
||||
rl->stereo.r.swapchain_index = 0;
|
||||
rl->stereo.r.image_index = 0;
|
||||
rl->quad.swapchain_index = 0;
|
||||
rl->quad.image_index = 0;
|
||||
}
|
||||
|
||||
// Destroy all swapchains now.
|
||||
for (uint32_t j = 0; j < IPC_MAX_CLIENT_SWAPCHAINS; j++) {
|
||||
xrt_swapchain_destroy((struct xrt_swapchain **)&cs->xscs[j]);
|
||||
cs->swapchain_handles[j] = -1;
|
||||
|
|
|
@ -515,37 +515,71 @@ check_epoll(struct ipc_server *vs)
|
|||
}
|
||||
|
||||
static void
|
||||
set_rendering_state(volatile struct ipc_client_state *active_client,
|
||||
struct comp_swapchain_image **l,
|
||||
struct comp_swapchain_image **r,
|
||||
bool *using_idle_images,
|
||||
bool *flip_y)
|
||||
_update_projection_layer(struct comp_compositor *c,
|
||||
volatile struct ipc_client_state *active_client,
|
||||
volatile struct ipc_layer_render_state *layer,
|
||||
uint32_t i)
|
||||
{
|
||||
uint32_t lsi = layer->stereo.l.swapchain_index;
|
||||
uint32_t rsi = layer->stereo.r.swapchain_index;
|
||||
struct comp_swapchain *cl = comp_swapchain(active_client->xscs[lsi]);
|
||||
struct comp_swapchain *cr = comp_swapchain(active_client->xscs[rsi]);
|
||||
|
||||
struct comp_swapchain_image *l = NULL;
|
||||
struct comp_swapchain_image *r = NULL;
|
||||
l = &cl->images[layer->stereo.l.image_index];
|
||||
r = &cr->images[layer->stereo.r.image_index];
|
||||
|
||||
comp_renderer_set_projection_layer(c->r, l, r, layer->flip_y, i);
|
||||
}
|
||||
|
||||
static void
|
||||
_update_quad_layer(struct comp_compositor *c,
|
||||
volatile struct ipc_client_state *active_client,
|
||||
volatile struct ipc_layer_render_state *layer,
|
||||
uint32_t i)
|
||||
{
|
||||
uint32_t sci = layer->quad.swapchain_index;
|
||||
struct comp_swapchain *sc = comp_swapchain(active_client->xscs[sci]);
|
||||
struct comp_swapchain_image *image = NULL;
|
||||
image = &sc->images[layer->quad.image_index];
|
||||
|
||||
struct xrt_pose pose = layer->quad.pose;
|
||||
struct xrt_vec2 size = layer->quad.size;
|
||||
|
||||
comp_renderer_set_quad_layer(c->r, image, &pose, &size, layer->flip_y,
|
||||
i);
|
||||
}
|
||||
|
||||
static void
|
||||
_update_layers(struct comp_compositor *c,
|
||||
volatile struct ipc_client_state *active_client,
|
||||
uint32_t *num_layers)
|
||||
{
|
||||
// our ipc server thread will fill in l & r
|
||||
// swapchain indices and toggle wait to false
|
||||
// when the client calls end_frame, signalling
|
||||
// us to render.
|
||||
volatile struct ipc_render_state *render_state =
|
||||
&active_client->render_state;
|
||||
|
||||
if (!render_state->rendering) {
|
||||
return;
|
||||
if (*num_layers != render_state->num_layers) {
|
||||
// TODO: Resizing here would be faster
|
||||
*num_layers = render_state->num_layers;
|
||||
comp_renderer_destroy_layers(c->r);
|
||||
comp_renderer_allocate_layers(c->r, render_state->num_layers);
|
||||
}
|
||||
|
||||
uint32_t li = render_state->l_swapchain_index;
|
||||
uint32_t ri = render_state->r_swapchain_index;
|
||||
struct comp_swapchain *cl = comp_swapchain(active_client->xscs[li]);
|
||||
struct comp_swapchain *cr = comp_swapchain(active_client->xscs[ri]);
|
||||
*l = &cl->images[render_state->l_image_index];
|
||||
*r = &cr->images[render_state->r_image_index];
|
||||
*flip_y = render_state->flip_y;
|
||||
|
||||
// set our client state back to waiting.
|
||||
render_state->rendering = false;
|
||||
|
||||
// comp_compositor_garbage_collect(c);
|
||||
|
||||
*using_idle_images = false;
|
||||
for (uint32_t i = 0; i < render_state->num_layers; i++) {
|
||||
volatile struct ipc_layer_render_state *layer =
|
||||
&render_state->layers[i];
|
||||
switch (layer->type) {
|
||||
case IPC_LAYER_STEREO_PROJECTION: {
|
||||
_update_projection_layer(c, active_client, layer, i);
|
||||
break;
|
||||
}
|
||||
case IPC_LAYER_QUAD: {
|
||||
_update_quad_layer(c, active_client, layer, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -559,10 +593,7 @@ main_loop(struct ipc_server *vs)
|
|||
vs->thread_state.server = vs;
|
||||
vs->thread_state.xc = xc;
|
||||
|
||||
struct comp_swapchain_image *last_l = NULL;
|
||||
struct comp_swapchain_image *last_r = NULL;
|
||||
|
||||
bool using_idle_images = true;
|
||||
uint32_t num_layers = 0;
|
||||
|
||||
while (vs->running) {
|
||||
|
||||
|
@ -571,7 +602,6 @@ main_loop(struct ipc_server *vs)
|
|||
*/
|
||||
check_epoll(vs);
|
||||
|
||||
|
||||
/*
|
||||
* Update active client.
|
||||
*/
|
||||
|
@ -581,43 +611,34 @@ main_loop(struct ipc_server *vs)
|
|||
active_client = &vs->thread_state;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Render the swapchains.
|
||||
*/
|
||||
|
||||
struct comp_swapchain_image *l = NULL;
|
||||
struct comp_swapchain_image *r = NULL;
|
||||
bool flip_y = false;
|
||||
|
||||
if (active_client == NULL || !active_client->active ||
|
||||
active_client->num_swapchains == 0) {
|
||||
if (!using_idle_images) {
|
||||
COMP_DEBUG(c, "Resetting to idle images.");
|
||||
comp_renderer_reset(c->r);
|
||||
comp_renderer_set_idle_images(c->r);
|
||||
using_idle_images = true;
|
||||
last_l = NULL;
|
||||
last_r = NULL;
|
||||
if (num_layers != 0) {
|
||||
COMP_DEBUG(c, "Destroying layers.");
|
||||
comp_renderer_destroy_layers(c->r);
|
||||
num_layers = 0;
|
||||
}
|
||||
} else {
|
||||
set_rendering_state(active_client, &l, &r,
|
||||
&using_idle_images, &flip_y);
|
||||
// our ipc server thread will fill in l & r
|
||||
// swapchain indices and toggle wait to false
|
||||
// when the client calls end_frame, signalling
|
||||
// us to render.
|
||||
volatile struct ipc_render_state *render_state =
|
||||
&active_client->render_state;
|
||||
|
||||
if (render_state->rendering) {
|
||||
_update_layers(c, active_client, &num_layers);
|
||||
|
||||
// set our client state back to waiting.
|
||||
render_state->rendering = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Render the idle images or already cached images state.
|
||||
if ((l == NULL || r == NULL) || (l == last_l && r == last_r)) {
|
||||
comp_renderer_frame_cached(c->r);
|
||||
comp_compositor_garbage_collect(c);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Rebuild command buffers if we are showing new buffers.
|
||||
comp_renderer_reset(c->r);
|
||||
comp_renderer_frame(c->r, l, 0, r, 0, flip_y);
|
||||
|
||||
last_l = l;
|
||||
last_r = r;
|
||||
comp_renderer_draw(c->r);
|
||||
|
||||
// Now is a good time to destroy objects.
|
||||
comp_compositor_garbage_collect(c);
|
||||
|
|
Loading…
Reference in a new issue