summaryrefslogtreecommitdiff
path: root/src/screen/main.zig
blob: f11f62875190a26d9e8e92a4104704d99c7755d9 (plain)
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
const std = @import("std");
const drm = @import("drm/card.zig");
const Event = @import("drm/event.zig").Event;

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    const allocator = gpa.allocator();

    var card = try drm.Card.open("card0", allocator);
    defer card.close();

    var resources = try card.resources();
    defer resources.deinit();

    var connector = try card.connector(resources.connector_ids[0]);
    defer connector.deinit();

    std.debug.print("connector = {}\n", .{ connector.id });

    const mode = connector.modes[0];

    std.debug.print("mode = {s}@{d}Hz\n", .{ mode.name, mode.frame_rate() });

    var crtc = try crtc: {
        for (connector.encoder_ids) |encoder_id| {
            var encoder = try card.encoder(encoder_id);
            defer encoder.deinit();

            for (resources.crtc_ids, 0..) |crtc_id, index| {
                if ((encoder.possible_crtcs & (@as(u32, 1) << @intCast(index))) != 0) {
                    break :crtc card.crtc(crtc_id);
                }
            }
        }

        break :crtc error.CrtcNotFound;
    };
    defer crtc.detach();

    std.debug.print("crtc = {}\n", .{ crtc.id });

    var double_buffer = try card.create_double_buffer(mode.horizontal.size, mode.vertical.size, 32);
    defer double_buffer.deinit();

    std.debug.print("buffer = {}, {}x{}, stride = {}\n", .{
        double_buffer.buffer().id,
        double_buffer.buffer().width,
        double_buffer.buffer().height,
        double_buffer.buffer().stride,
    });

    try crtc.attach(double_buffer.crtc_buffer(), &connector, mode);

    const Pos = struct { x: f32, y: f32 };

    var vec = Pos { .x = 10, .y = 10 };
    var pos = Pos { .x = 0, .y = 0 };
    var delta: f32 = 0;
    const size = 100;

    const width: f32 = @floatFromInt(double_buffer.buffer().width);
    const height: f32 = @floatFromInt(double_buffer.buffer().height);

    while (true) {
        const start = try std.time.Instant.now();

        double_buffer.buffer().fill(.{ .red = 0, .green = 0, .blue = 0 });

        pos.x += vec.x * delta;
        pos.y += vec.y * delta;

        if (pos.x < 0) {
            pos.x = -pos.x;
            vec.x = -vec.x;
        } else if (pos.x + size >= width) {
            pos.x = width - size;
            vec.x = -vec.x;
        }

        if (pos.y < 0) {
            pos.y = -pos.y;
            vec.y = -vec.y;
        } else if (pos.y + size >= height) {
            pos.y = height - size;
            vec.y = -vec.y;
        }

        for (0..size) |w| {
            for (0..size) |h| {
                double_buffer.buffer().set(
                    @as(u32, @intFromFloat(pos.x)) + @as(u32, @intCast(w)),
                    @as(u32, @intFromFloat(pos.y)) + @as(u32, @intCast(h)),
                    .{
                    .red = 0xff,
                    .green = 0,
                    .blue = 0,
                });
            }
        }

        const end = try std.time.Instant.now();
        const elapsed = (@as(f32, @floatFromInt(end.since(start))) / std.time.ns_per_s);
        std.debug.print("FPS: {d:.2}\r", .{ 1 / elapsed });
        delta = elapsed * 60;

        try crtc.page_flip(&double_buffer);

        while (true) {
            var event: ?Event = null;
            while (event == null) {
                event = try card.poll_event(5000);
            }

            switch ((event orelse unreachable).type) {
                .page_flip_complete => break,
                else => {},
            }
        }
    }
}