summaryrefslogtreecommitdiff
path: root/src/screen/drm/resources.zig
blob: 6128f37e8143fe4ec910a0722b3ebda9f4bce07e (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
const std = @import("std");
const os = std.os.linux;
const cerror = @import("../cerror.zig");
const Card = @import("card.zig").Card;
const Drm = @import("request.zig").Drm;

const RawResources = extern struct {
    fb_ids: ?*u32,
    crtc_ids: ?*u32,
    connector_ids: ?*u32,
    encoder_ids: ?*u32,
    count_fbs: u32,
    count_crtcs: u32,
    count_connectors: u32,
    count_encoders: u32,
    min_width: u32,
    max_width: u32,
    min_height: u32,
    max_height: u32,
};

pub const Resources = struct {
    const Self = @This();
    const Range = struct { min: u32, max: u32 };

    card: *Card,

    fb_ids: []u32,
    crtc_ids: []u32,
    connector_ids: []u32,
    encoder_ids: []u32,
    width: Range,
    height: Range,

    pub fn raw_without_ids(card: *Card) !RawResources {
        var result = std.mem.zeroes(RawResources);
        try Drm.get_resources.request(card.file.handle, RawResources, &result);
        return result;
    }

    // NOTE: This function does not take in account
    //       that there might be some hot-plugging going
    //       on. This might have to change in the future.
    pub fn init(card: *Card) !Self {
        var raw = try Self.raw_without_ids(card);
        const resources = .{
            .fb_ids = try card.allocator.alloc(u32, raw.count_fbs),
            .crtc_ids = try card.allocator.alloc(u32, raw.count_crtcs),
            .connector_ids = try card.allocator.alloc(u32, raw.count_connectors),
            .encoder_ids = try card.allocator.alloc(u32, raw.count_encoders),
            .width = .{ .min = raw.min_width, .max = raw.max_width },
            .height = .{ .min = raw.min_height, .max = raw.max_height },
            .card = card,
        };

        @memset(resources.fb_ids, 0);
        @memset(resources.crtc_ids, 0);
        @memset(resources.connector_ids, 0);
        @memset(resources.encoder_ids, 0);

        raw.fb_ids = @ptrCast(resources.fb_ids);
        raw.crtc_ids = @ptrCast(resources.crtc_ids);
        raw.connector_ids = @ptrCast(resources.connector_ids);
        raw.encoder_ids = @ptrCast(resources.encoder_ids);
        try Drm.get_resources.request(card.file.handle, RawResources, &raw);

        return resources;
    }

    pub fn deinit(self: *Self) void {
        self.card.allocator.free(self.fb_ids);
        self.card.allocator.free(self.crtc_ids);
        self.card.allocator.free(self.connector_ids);
        self.card.allocator.free(self.encoder_ids);
    }
};