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:
Lubosz Sarnecki 2020-05-08 21:24:21 +02:00 committed by Jakob Bornecrantz
parent aedd4d9ff8
commit d0539161dc
6 changed files with 285 additions and 286 deletions

View file

@ -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);

View file

@ -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);
}

View file

@ -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
}

View file

@ -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];
};
/*!

View file

@ -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;

View file

@ -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);