The open source OpenXR runtime
1// Copyright 2019-2021, Collabora, Ltd.
2// SPDX-License-Identifier: BSL-1.0
3/*!
4 * @file
5 * @brief An @ref xrt_frame_sink splitter.
6 * @author Jakob Bornecrantz <jakob@collabora.com>
7 * @ingroup aux_util
8 */
9
10#include "util/u_misc.h"
11#include "util/u_sink.h"
12#include "util/u_trace_marker.h"
13
14
15/*!
16 * An @ref xrt_frame_sink splitter.
17 * @implements xrt_frame_sink
18 * @implements xrt_frame_node
19 */
20struct u_sink_split
21{
22 struct xrt_frame_sink base;
23 struct xrt_frame_node node;
24
25 struct xrt_frame_sink *downstreams[U_SINK_MAX_SPLIT_DOWNSTREAMS];
26 size_t downstream_count;
27};
28
29static void
30split_frame(struct xrt_frame_sink *xfs, struct xrt_frame *xf)
31{
32 SINK_TRACE_MARKER();
33
34 struct u_sink_split *s = (struct u_sink_split *)xfs;
35
36 for (size_t i = 0; i < s->downstream_count; i++) {
37 if (s->downstreams[i]) {
38 xrt_sink_push_frame(s->downstreams[i], xf);
39 }
40 }
41}
42
43static void
44split_break_apart(struct xrt_frame_node *node)
45{
46 // Noop
47}
48
49static void
50split_destroy(struct xrt_frame_node *node)
51{
52 struct u_sink_split *s = container_of(node, struct u_sink_split, node);
53
54 free(s);
55}
56
57
58/*
59 *
60 * Exported functions.
61 *
62 */
63
64void
65u_sink_split_multi_create(struct xrt_frame_context *xfctx,
66 struct xrt_frame_sink **downstreams,
67 size_t downstream_count,
68 struct xrt_frame_sink **out_xfs)
69{
70 assert(downstream_count <= U_SINK_MAX_SPLIT_DOWNSTREAMS);
71
72 struct u_sink_split *s = U_TYPED_CALLOC(struct u_sink_split);
73
74 s->base.push_frame = split_frame;
75 s->node.break_apart = split_break_apart;
76 s->node.destroy = split_destroy;
77
78 memcpy(s->downstreams, downstreams, sizeof(s->downstreams[0]) * downstream_count);
79 s->downstream_count = downstream_count;
80
81 xrt_frame_context_add(xfctx, &s->node);
82
83 *out_xfs = &s->base;
84}
85
86void
87u_sink_split_create(struct xrt_frame_context *xfctx,
88 struct xrt_frame_sink *left,
89 struct xrt_frame_sink *right,
90 struct xrt_frame_sink **out_xfs)
91{
92 struct xrt_frame_sink *downstreams[2] = {left, right};
93
94 u_sink_split_multi_create(xfctx, downstreams, 2, out_xfs);
95}