1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
#include "renderer.hpp"
renderer::renderer(
daguerre::image<daguerre::hilbert_color> &&fb,
daguerre::image<daguerre::hilbert_color> &&bg,
daguerre::hilbert_color bgc,
daguerre::image<daguerre::hilbert_color> &&c,
daguerre::hilbert_color cbg)
: framebuffer(std::move(fb)),
double_buffer(framebuffer.width, framebuffer.height),
background(std::move(bg)), cursor(std::move(c)), cursor_background(cbg),
cursor_x(framebuffer.width / 2), cursor_y(framebuffer.height / 2) {
euler::syscall::create_private_socket(dispatcher_handle_1, dispatcher_handle_2);
if (background.width != framebuffer.width ||
background.height != framebuffer.height) {
daguerre::image<daguerre::hilbert_color>
new_background(framebuffer.width, framebuffer.height);
new_background.fill(bgc);
int from_x = 0;
int from_y = 0;
int to_x = framebuffer.width / 2 - background.width / 2;
int to_y = framebuffer.height / 2 - background.height / 2;
int width = background.width;
int height = background.height;
daguerre::make_safe(to_x, from_x, width, 0, framebuffer.width);
daguerre::make_safe(to_y, from_y, height, 0, framebuffer.height);
new_background.copy_from(background, to_x, to_y, from_x, from_y, width, height);
background = std::move(new_background);
}
}
template <class color_t>
void overlay_trans(color_t &to, const color_t &from, const color_t ¶m) {
if (from != param)
to = from;
}
void renderer::do_render() {
double_buffer.copy_from(background, 0, 0);
for (auto it = windows.begin(); it != windows.end(); ++it)
double_buffer.copy_from(
(*it)->contents, (*it)->x, (*it)->y, 0, 0,
std::min((*it)->contents.width, double_buffer.width - (*it)->x),
std::min((*it)->contents.height, double_buffer.height - (*it)->y));
double_buffer.convert_from(
cursor_background, cursor, cursor_x, cursor_y, 0, 0,
std::min(cursor.width, framebuffer.width - cursor_x),
std::min(cursor.height, framebuffer.height - cursor_y),
&overlay_trans);
}
[[noreturn]] void renderer::render_thread_main() {
euler::syscall::set_thread_name("render thread");
while (true) {
uint8_t byte;
euler::syscall::read_from_stream(dispatcher_handle_2, 1, &byte);
mut.lock();
euler::syscall::clear_socket_read_queue(dispatcher_handle_2);
do_render();
mut.unlock();
framebuffer.copy_from(double_buffer, 0, 0);
}
}
void renderer::bump_cursor(int x_offset, int y_offset) {
cursor_x += x_offset;
if (cursor_x < 0)
cursor_x = 0;
else if (cursor_x >= framebuffer.width)
cursor_x = framebuffer.width - 1;
cursor_y += y_offset;
if (cursor_y < 0)
cursor_y = 0;
else if (cursor_y >= framebuffer.height)
cursor_y = framebuffer.height - 1;
}
void renderer::add_window(const window *w) {
windows.push_back(w);
}
void renderer::remove_window(const window *w) {
windows.remove(w);
}
|