Skip to content

Commit

Permalink
[docs] Update Component docs + explain main concepts (#289)
Browse files Browse the repository at this point in the history
  • Loading branch information
wkozyra95 authored Dec 7, 2023
1 parent 2823954 commit 59b770d
Show file tree
Hide file tree
Showing 32 changed files with 613 additions and 195 deletions.
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ target/
# Generated during runtime
/shmem
/failed_snapshot_tests
# TODO: /components will be removed in the near future (next PR).
/docs/pages/api/components
/docs/pages/api/generated

/video_compositor.app
Expand Down
8 changes: 4 additions & 4 deletions compositor_render/src/scene/components.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,13 +195,13 @@ pub struct RescalerComponent {
pub position: Position,
pub transition: Option<Transition>,

pub mode: ResizeMode,
pub mode: RescaleMode,
pub horizontal_align: HorizontalAlign,
pub vertical_align: VerticalAlign,
}

#[derive(Debug, Clone, Copy)]
pub enum ResizeMode {
pub enum RescaleMode {
Fit,
Fill,
}
Expand All @@ -218,6 +218,6 @@ pub struct TilesComponent {
pub tile_aspect_ratio: (u32, u32),
pub margin: f32,
pub padding: f32,
pub horizontal_alignment: HorizontalAlign,
pub vertical_alignment: VerticalAlign,
pub horizontal_align: HorizontalAlign,
pub vertical_align: VerticalAlign,
}
4 changes: 2 additions & 2 deletions compositor_render/src/scene/rescaler_component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::transformations::layout::NestedLayout;

use super::{
components::RescalerComponent, layout::StatefulLayoutComponent, scene_state::BuildStateTreeCtx,
Component, ComponentId, IntermediateNode, Position, ResizeMode, SceneError, Size,
Component, ComponentId, IntermediateNode, Position, RescaleMode, SceneError, Size,
StatefulComponent, Transition,
};

Expand All @@ -30,7 +30,7 @@ struct RescalerComponentParam {
id: Option<ComponentId>,

position: Position,
mode: ResizeMode,
mode: RescaleMode,
horizontal_align: HorizontalAlign,
vertical_align: VerticalAlign,
}
Expand Down
6 changes: 3 additions & 3 deletions compositor_render/src/scene/rescaler_component/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::time::Duration;
use compositor_common::util::align::{HorizontalAlign, VerticalAlign};

use crate::{
scene::{layout::StatefulLayoutComponent, ResizeMode, Size, StatefulComponent},
scene::{layout::StatefulLayoutComponent, RescaleMode, Size, StatefulComponent},
transformations::layout::{Crop, LayoutContent, NestedLayout},
};

Expand All @@ -28,10 +28,10 @@ impl RescalerComponentParam {
}
(Some(child_width), Some(child_height)) => {
let scale = match self.mode {
ResizeMode::Fit => {
RescaleMode::Fit => {
f32::min(size.width / child_width, size.height / child_height)
}
ResizeMode::Fill => {
RescaleMode::Fill => {
f32::max(size.width / child_width, size.height / child_height)
}
};
Expand Down
8 changes: 4 additions & 4 deletions compositor_render/src/scene/tiles_component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ struct TilesComponentParams {
tile_aspect_ratio: (u32, u32),
margin: f32,
padding: f32,
horizontal_alignment: HorizontalAlign,
vertical_alignment: VerticalAlign,
horizontal_align: HorizontalAlign,
vertical_align: VerticalAlign,
}

impl StatefulTilesComponent {
Expand Down Expand Up @@ -93,8 +93,8 @@ impl TilesComponent {
tile_aspect_ratio: self.tile_aspect_ratio,
margin: self.margin,
padding: self.padding,
horizontal_alignment: self.horizontal_alignment,
vertical_alignment: self.vertical_alignment,
horizontal_align: self.horizontal_align,
vertical_align: self.vertical_align,
},
children: self
.children
Expand Down
4 changes: 2 additions & 2 deletions compositor_render/src/scene/tiles_component/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ impl TilesComponentParams {
- (tile_size.height + 2.0 * self.padding) * rows_cols.rows as f32
- (self.margin * (rows_cols.rows as f32 + 1.0));

let (additional_top_padding, justified_padding_y) = match self.vertical_alignment {
let (additional_top_padding, justified_padding_y) = match self.vertical_align {
VerticalAlign::Top => (0.0, 0.0),
VerticalAlign::Center => (additional_y_padding / 2.0, 0.0),
VerticalAlign::Bottom => (additional_y_padding, 0.0),
Expand All @@ -180,7 +180,7 @@ impl TilesComponentParams {
- (tile_size.width + 2.0 * self.padding) * tiles_in_row as f32
- (self.margin * (tiles_in_row as f32 + 1.0));

let (additional_left_padding, justified_padding_x) = match self.horizontal_alignment {
let (additional_left_padding, justified_padding_x) = match self.horizontal_align {
HorizontalAlign::Left => (0.0, 0.0),
HorizontalAlign::Right => (additional_x_padding, 0.0),
HorizontalAlign::Justified => {
Expand Down
14 changes: 14 additions & 0 deletions docs/pages/api/components/Image.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
sidebar_position: 7
---
import Docs from "@site/pages/api/generated/component-Image.md"

# Image

A component for rendering images.

:::note
To use this component, you need to first register the image with matching `image_id` using [`RegisterRenderer`](../routes#register-renderer) request.
:::

<Docs />
15 changes: 15 additions & 0 deletions docs/pages/api/components/InputStream.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
sidebar_position: 1
---

import Docs from "@site/pages/api/generated/component-InputStream.md"

# InputStream

`InputStream` represents an incoming RTP stream.

:::note
To use this component, you need to first register the stream with matching `input_id` using [`RegisterInputStream`](../routes#register-input-stream) request.
:::

<Docs />
23 changes: 23 additions & 0 deletions docs/pages/api/components/Rescaler.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
sidebar_position: 3
---
import Docs from "@site/pages/api/generated/component-Rescaler.md"

# Rescaler

`Rescaler` is a layout component responsible for rescaling other components.

### Absolute positioning

A component is absolutely positioned if it defines fields like `top`, `left`, `right`, `bottom`, or `rotation`.
Those fields define the component's position relative to its parent. However, to respect those
values, the parent component has to be a layout component that supports absolute positioning.

- `Rescaler` **does not** support absolute positioning for its child components. All children will still be rendered, but all fields like `top`, `left`, `right`, `bottom`, and `rotation` will be ignored.
- `Rescaler` can be absolutely positioned relative to its parent, if the parent component supports it.

### Static positioning

`Rescaler` always have exactly one child that will be proportionally rescaled to match the parent.

<Docs />
14 changes: 14 additions & 0 deletions docs/pages/api/components/Shader.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
sidebar_position: 6
---
import Docs from "@site/pages/api/generated/component-Shader.md"

# Shader

`Shader` applies transformation defined via WGSL shader on its children. [Learn more.](../../concept/shaders)

:::note
To use this component, you need to first register the shader with matching `shader_id` using [`RegisterRenderer`](../routes#register-renderer) request.
:::

<Docs />
10 changes: 10 additions & 0 deletions docs/pages/api/components/Text.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
sidebar_position: 5
---
import Docs from "@site/pages/api/generated/component-Text.md"

# Text

A component for rendering text.

<Docs />
28 changes: 28 additions & 0 deletions docs/pages/api/components/Tiles.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
sidebar_position: 4
---
import Docs from "@site/pages/api/generated/component-Tiles.md"

# Tiles

`Tiles` is a layout component that places all the child components next to each other while maximizing the use of available space. The component divides its area into multiple rectangles/tiles, one for each child component. All of those rectangles are the same size and do not overlap over each other.

### Absolute positioning

- `Tiles` **does not** support absolute positioning for its child components. All children will still be rendered, but all fields like `top`, `left`, `right`, `bottom`, and `rotation` will be ignored.
- `Tiles` **can not** be absolutely positioned relative to it's parent.

### Static positioning

The component calculates the number of rows and columns that children should be divided into. The result is based on:
- The size of the `Tiles` component.
- Aspect ratio of a single tile (`tile_aspect_ratio` field).
- Number of children components.

An optimal number of rows and columns should result in a layout that covers the biggest part of its area. Children components are placed based on their order, from left to right, and row-by-row from top to bottom.

When placing a child component inside a tile, the component might change its size.
- Non-layout component scales proportionally to fit inside the parent. If the aspect ratios of a child and its parent do not match, then the component will be centered vertically or horizontally.
- Layout component takes the `width` and `height` of a tile. It ignores its own `width`/`height` fields if they are defined.

<Docs />
37 changes: 37 additions & 0 deletions docs/pages/api/components/View.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
sidebar_position: 2
---
import Docs from "@site/pages/api/generated/component-View.md"

# View

`View` is the compositor's core layout mechanism. Its role is analogous to the
`<div>` tag in HTML. It provides a container with basic styling that can be further composed.

### Absolute positioning

A component is absolutely positioned if it defines fields like `top`, `left`, `right`, `bottom`, or `rotation`.
Those fields define the component's position relative to its parent. However, to respect those
values, the parent component has to be a layout component that supports absolute positioning.

- `View` supports absolute positioning for its child components.
- `View` can be absolutely positioned relative to its parent if the parent component supports it.

### Static positioning

When children of a `View` component have a static position, they are placed next to each other.

#### For `direction=row`:

Children of a `View` component form a row, with items aligned to the top. The size of each child will be calculated in the following way:
- If the `width` or `height` of a child component is defined, then those values take priority.
- If the `height` is not defined, the component will have the same `height` as its parent.
- If the `width` is not defined, we calculate the sum `width` of all components with that value defined.
- If it is larger than the parent's `width`, then the `width` of the rest of the components is zero.
- If it is smaller than the parent's `width`, calculate the difference and divide the resulting value equally between all children with unknown widths.

#### For `direction=column`:

Analogous to the `direction=row` case, but children form a column instead, with items aligned to the left.

<Docs/>
18 changes: 18 additions & 0 deletions docs/pages/api/components/WebView.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
sidebar_position: 8
---
import Docs from "@site/pages/api/generated/component-WebView.md"

# WebView

`WebView` renders a website using Chromium engine embedded inside the compositor.

:::note
To use this component, you need to first register the web renderer instance with matching `instance_id` using [`RegisterRenderer`](../routes#register-renderer) request.
:::

:::warning
Only one component can use specific `instance_id` at the time.
:::

<Docs />
5 changes: 5 additions & 0 deletions docs/pages/api/renderers/image.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import Docs from "@site/pages/api/generated/renderer-Image.md"

# Image

<Docs />
4 changes: 4 additions & 0 deletions docs/pages/api/renderers/shader.md
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
import Docs from "@site/pages/api/generated/renderer-Shader.md"

# Shader

<Docs />
5 changes: 5 additions & 0 deletions docs/pages/api/renderers/web.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import Docs from "@site/pages/api/generated/renderer-WebRenderer.md"

# Web Renderer

<Docs />
63 changes: 63 additions & 0 deletions docs/pages/concept/component.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Component

A component is a basic block used to define how video streams are composed.

## Layout Components

Layout component is a type of component responsible for defining the size and position of other components.

Currently, we support the following layout components:
- [View](../api/components/View)
- [Tiles](../api/components/Tiles)
- [Rescaler](../api/components/Rescaler)

Learn more about layouts [here](./layouts).

## Non-layout components

Non-layout components have their unique behaviors. In most cases, they do not support or interact with mechanisms introduced by layouts. Sometimes, they even override the behavior of other components.

For example, if you create a `Shader` component with a `View` component as its child, the properties like `width`, `top`, `rotation` ..., will be ignored. A `Shader` component, when rendering, receives all its children as GPU textures. It will just execute whatever the user-provided shader source implements without applying any layout properties that component might have.

## Scene

Component tree that represents what will be rendered for a specific output.

Example scene:
```typescript
{
"outputs": [
{
"output_id": "example_output_1"
"root": {
"type": "view",
"background_color_rgba": "#0000FFFF"
"children": [
{
"type": "input-stream",
"input_id": "example_input_1",
}
]
}
}
]
}
```

In the example above, we define a scene for a single output `example_output_1` where an input stream `example_input_1` is rendered inside a [`View` component](../api/components/View).

:::note
You need to register `"example_output_1"` and `"example_input_1"` before using them in the scene definition.
:::

### Renderers

Renderers are entities capable of producing frames (in some cases based on some provided input). The renderer could be a WGSL shader, web renderer instance, or an image. They are not directly part of the scene definition. Instead, components are using them as part of their internal implementation.

For example:
- [The `Shader` component](../api/components/Shader) has a field `shader_id` that identifies a [`Shader` renderer](../api/renderers/Shader).
- [The `Image` component](../api/components/Image) has a field `image_id` that identifies an [`Image` renderer](../api/renderers/Image).

Every renderer, except [`WebRenderer`](../api/renderers/web), can be used in multiple components. For example, you can create a single `Shader` renderer that applies some effect and use that `shader_id` in multiple `Shader` components.


Loading

0 comments on commit 59b770d

Please sign in to comment.