improve & optimise window decoration code

This commit is contained in:
koniifer 2024-11-14 16:43:23 +00:00
parent b6261d014d
commit 95b4a921dc
5 changed files with 48 additions and 33 deletions

4
Cargo.lock generated
View file

@ -82,9 +82,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.2.0" version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1aeb932158bd710538c73702db6945cb68a8fb08c519e6e12706b94263b36db8" checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47"
dependencies = [ dependencies = [
"shlex", "shlex",
] ]

View file

@ -14,18 +14,6 @@ server := @use("./server.hb")
message := @use("./message.hb") message := @use("./message.hb")
permissions := @use("./permissions.hb") permissions := @use("./permissions.hb")
opaque := fn(i: uint): bool {
if i == 0 {
return true
}
return false
}
sleep := fn(): void {
i := 10000000
loop if opaque(i) break else i -= 1
}
$send_message := fn($Expr: type, kind: uint, msg: Expr, buffer_id: uint): void { $send_message := fn($Expr: type, kind: uint, msg: Expr, buffer_id: uint): void {
buffer.write(?Message(Expr), buffer_id, &@as(?Message(Expr), .(.(kind), msg))) buffer.write(?Message(Expr), buffer_id, &@as(?Message(Expr), .(.(kind), msg)))
} }

View file

@ -6,7 +6,7 @@ WindowServer := struct {
window_count: uint, window_count: uint,
channel: Channel, channel: Channel,
// ! replace this with a collection when we get an allocator // ! replace this with a collection when we get an allocator
windows: [?WindowData; 10], windows: [?Window; 10],
font: text.Font, font: text.Font,
} }
@ -42,34 +42,51 @@ incoming := fn(): bool {
// ! do inspection of requested props here // ! do inspection of requested props here
data := WindowData.(props.body, channel, permissions.default) data := WindowData.(props.body, channel, permissions.default)
send_message(WindowData, message.ack, data, channel.client) send_message(WindowData, message.ack, data, channel.client)
server.windows[server.window_count] = data surface := new_window_decorations(data.props.dimensions)
put_filled_rect(surface, .(0, 0), data.props.dimensions + .(DECO_WIDTH, DECO_HEIGHT_TOP + DECO_HEIGHT_BOTTOM), DECO_COLOUR)
put_filled_rect(surface, .(0, 0), .(data.props.dimensions.x + DECO_WIDTH, DECO_HEIGHT_TOP), DECO_COLOUR)
put_text(surface, server.font, .(2, 1), .(0, 0, 0, 255), data.props.title)
server.windows[server.window_count] = .(data, surface)
server.window_count += 1 server.window_count += 1
} }
return true return true
} }
render_clients := fn(screen: Surface): void { $DECO_WIDTH := 2
// support one window for test case $DECO_HEIGHT_TOP := 20
$DECO_HEIGHT_BOTTOM := 1
$DECO_COLOUR := Color.(100, 200, 255, 255)
new_window_decorations := fn(dimensions: math.Vec2(uint)): Surface {
return new_surface(dimensions.x + DECO_WIDTH, dimensions.y + DECO_HEIGHT_TOP + DECO_HEIGHT_BOTTOM)
}
// ! compositor code. this currently disallows tearing.
collect_frames := fn(): void {
window := server.windows[0] window := server.windows[0]
if window == null { if window == null {
return return
} }
header := recv_header(window.channel.server) header := recv_header(window.data.channel.server)
if header == null { if header == null | @unwrap(header).kind != message.frame_ready {
return return
} }
if header.kind != message.frame_ready { send_header(message.ack, window.data.channel.client)
ptr := await_message(^Color, window.data.channel.server)
// ! weird compiler error
// if ptr.header.kind != message.ack {
// return
// }
put_surface(window.surface, Surface.(ptr.body, window.data.props.dimensions.x, window.data.props.dimensions.y, window.data.props.dimensions.x * window.data.props.dimensions.y), .(DECO_WIDTH / 2, DECO_HEIGHT_TOP), false)
send_header(message.ack, window.data.channel.client)
}
render_clients := fn(screen: Surface): void {
window := server.windows[0]
if window == null {
return return
} }
send_header(message.ack, window.channel.client) put_surface(screen, window.surface, window.data.props.position, false)
ptr := await_message(^Color, window.channel.server)
if ptr.header.kind != message.ack {
return
}
put_surface(screen, .(ptr.body, window.props.dimensions.x, window.props.dimensions.y, window.props.dimensions.x * window.props.dimensions.y), window.props.position, false)
put_rect(screen, window.props.position - .(1, 1), window.props.dimensions + .(1, 1), .(255, 255, 255, 255))
put_filled_rect(screen, window.props.position - .(1, 21), .(window.props.dimensions.x + 2, 20), .(255, 255, 255, 255))
put_text(screen, server.font, window.props.position - .(-2, 20), .(0, 0, 0, 255), window.props.title)
sync(screen) sync(screen)
send_header(message.ack, window.channel.client)
} }

View file

@ -2,9 +2,18 @@
sunset := @use("../../../libraries/sunset_proto/src/lib.hb") sunset := @use("../../../libraries/sunset_proto/src/lib.hb")
render := @use("../../../libraries/render/src/lib.hb") render := @use("../../../libraries/render/src/lib.hb")
bmp := @embed("../../../assets/mini.bmp")
main := fn(): void { main := fn(): void {
sunset.client.find_server() sunset.client.find_server()
window := sunset.client.new(.(.(100, 100), .(700, 100), "Hello, World!\0"))
image := render.image.from(@bitcast(&bmp))
if image == null {
log.error("got no image\0")
return
}
window := sunset.client.new(.(.(100, 100), .(480, 200), "sunset windowing demo paddingpaddingpadding\0"))
if window == null { if window == null {
log.error("got no window\0") log.error("got no window\0")
return return
@ -12,7 +21,7 @@ main := fn(): void {
x := 0 x := 0
loop { loop {
render.clear(window.surface, render.cyan) render.clear(window.surface, render.cyan)
render.put_filled_circle(window.surface, .(50 + x % window.data.props.dimensions.x, 50), 25, render.magenta) render.put_surface(window.surface, image, .(image.width + x % window.data.props.dimensions.x, 20), false)
if sunset.client.send_frame(window) == false { if sunset.client.send_frame(window) == false {
log.error("did not send frame\0") log.error("did not send frame\0")
} }

View file

@ -5,6 +5,7 @@ main := fn(): void {
screen := render.init(true) screen := render.init(true)
sunset.server.start() sunset.server.start()
loop if sunset.server.incoming() { loop if sunset.server.incoming() {
sunset.server.collect_frames()
sunset.server.render_clients(screen) sunset.server.render_clients(screen)
} }
} }