Skip to content

Commit

Permalink
Finish implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
sbernauer committed Jun 11, 2024
1 parent 04138e3 commit 0e2b06a
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file.

### Added

- Support binary protocol ([#XX])
- Try to improve performance by calling `madvise` to inform Kernel we are reading sequentially ([#24])
- Expose metric on denied connection counts ([#26])
- Print nicer error messages ([#32])
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ Commands must be sent newline-separated, for more details see [Pixelflut](https:
* `PX x y rrggbbaa`: Color the pixel (x,y) with the given hexadecimal color rrggbb (alpha channel is ignored for now), e.g. `PX 10 10 ff0000ff`
* `PX x y gg`: Color the pixel (x,y) with the hexadecimal color gggggg. Basically this is the same as the other commands, but is a more efficient way of filling white, black or gray areas, e.g. `PX 10 10 00` to paint black
* `PX x y`: Get the color value of the pixel (x,y), e.g. `PX 10 10`
* `PBxxyyrgba`: Binary version of the `PX` command. `x` and `y` are little-endian 16 bit coordinates, `r`, `g`, `b` and `a` are a byte each. There is **no** newline after the command.
Tipp: For most use-cases this is the most efficient format with 10 bytes per pixel ;)
* `SIZE`: Get the size of the drawing surface, e.g. `SIZE 1920 1080`
* `OFFSET x y`: Apply offset (x,y) to all further pixel draws on this connection. This can e.g. be used to pre-calculate an image/animation and simply use the OFFSET command to move it around the screen without the need to re-calculate it, e.g. `OFFSET 100 100`

Expand Down Expand Up @@ -60,6 +62,8 @@ Options:
Height of the drawing surface [default: 720]
-f, --fps <FPS>
Frames per second the server should aim for [default: 30]
--network-buffer-size <NETWORK_BUFFER_SIZE>
The size in bytes of the network buffer used for each open TCP connection. Please use at least 64 KB (64_000 bytes) [default: 262144]
-t, --text <TEXT>
Text to display on the screen. The text will be followed by "on <listen_address>" [default: "Pixelflut server (breakwater)"]
--font <FONT>
Expand All @@ -78,6 +82,8 @@ Options:
Enable dump of video stream into file. File location will be `<VIDEO_SAVE_FOLDER>/pixelflut_dump_{timestamp}.mp4
-v, --vnc-port <VNC_PORT>
Port of the VNC server [default: 5900]
-c, --connections-per-ip <CONNECTIONS_PER_IP>
Allow only a certain number of connections per ip address
-h, --help
Print help
-V, --version
Expand Down
2 changes: 1 addition & 1 deletion breakwater-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ if cfg!(feature = "alpha") {
"PX x y rrggbbaa: Color the pixel (x,y) with the given hexadecimal color rrggbb. The alpha part is discarded for performance reasons, as breakwater was compiled without the alpha feature"
},
if cfg!(feature = "binary-commands") {
"PBxxyyrgba: Binary version of the PX command. x and y are little-endian 16 bit coordinates, r, g, b and are a byte each. There is *no* newline after the command.\n"
"PBxxyyrgba: Binary version of the PX command. x and y are little-endian 16 bit coordinates, r, g, b and a are a byte each. There is *no* newline after the command.\n"
} else {
""
}
Expand Down
1 change: 1 addition & 0 deletions breakwater-parser/src/original.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ impl Parser for OriginalParser {
let y = u16::from_le((command_bytes >> 16) as u16);
let rgba = u32::from_le((command_bytes >> 32) as u32);

// TODO: Support alpha channel (behind alpha feature flag)
self.fb.set(x as usize, y as usize, rgba & 0x00ff_ffff);

i += 10;
Expand Down
25 changes: 24 additions & 1 deletion breakwater-parser/src/refactored.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ use breakwater_core::{framebuffer::FrameBuffer, HELP_TEXT};

use crate::{
original::{
parse_pixel_coordinates, simd_unhex, HELP_PATTERN, OFFSET_PATTERN, PX_PATTERN, SIZE_PATTERN,
parse_pixel_coordinates, simd_unhex, HELP_PATTERN, OFFSET_PATTERN, PB_PATTERN, PX_PATTERN,
SIZE_PATTERN,
},
Parser,
};
Expand Down Expand Up @@ -83,6 +84,24 @@ impl RefactoredParser {
}
}

#[inline(always)]
fn handle_binary_pixel(&self, buffer: &[u8], mut idx: usize) -> (usize, usize) {
let previous = idx;
idx += 2;

let command_bytes = unsafe { (buffer.as_ptr().add(idx) as *const u64).read_unaligned() };

let x = u16::from_le((command_bytes) as u16);
let y = u16::from_le((command_bytes >> 16) as u16);
let rgba = u32::from_le((command_bytes >> 32) as u32);

// TODO: Support alpha channel (behind alpha feature flag)
self.fb.set(x as usize, y as usize, rgba & 0x00ff_ffff);

idx += 8;
(idx, previous)
}

#[inline(always)]
fn handle_offset(&mut self, idx: &mut usize, buffer: &[u8]) {
let (x, y, present) = parse_pixel_coordinates(buffer.as_ptr(), idx);
Expand Down Expand Up @@ -185,6 +204,10 @@ impl Parser for RefactoredParser {
unsafe { (buffer.as_ptr().add(i) as *const u64).read_unaligned() };
if current_command & 0x00ff_ffff == PX_PATTERN {
(i, last_byte_parsed) = self.handle_pixel(buffer, i, response);
} else if cfg!(feature = "binary-commands")
&& current_command & 0x0000_ffff == PB_PATTERN
{
(i, last_byte_parsed) = self.handle_binary_pixel(buffer, i);
} else if current_command & 0x00ff_ffff_ffff_ffff == OFFSET_PATTERN {
i += 7;
self.handle_offset(&mut i, buffer);
Expand Down

0 comments on commit 0e2b06a

Please sign in to comment.