aboutsummaryrefslogtreecommitdiffstats
path: root/src/headless.rs
blob: 9d9cd8de10294470203c403f5ccfec05205f14e2 (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
use Api;
use BuilderAttribs;
use CreationError;

use gl_common;
use libc;

use winimpl;

/// Object that allows you to build headless contexts.
pub struct HeadlessRendererBuilder {
    attribs: BuilderAttribs<'static>,
}

impl HeadlessRendererBuilder {
    /// Initializes a new `HeadlessRendererBuilder` with default values.
    pub fn new(width: u32, height: u32) -> HeadlessRendererBuilder {
        HeadlessRendererBuilder {
            attribs: BuilderAttribs {
                headless: true,
                dimensions: Some((width, height)),
                .. BuilderAttribs::new()
            },
        }
    }

    /// Requests to use a specific OpenGL version.
    ///
    /// Version is a (major, minor) pair. For example to request OpenGL 3.3
    ///  you would pass `(3, 3)`.
    pub fn with_gl_version(mut self, version: (u32, u32)) -> HeadlessRendererBuilder {
        self.attribs.gl_version = Some(version);
        self
    }

    /// Sets the *debug* flag for the OpenGL context.
    ///
    /// The default value for this flag is `cfg!(ndebug)`, which means that it's enabled
    /// when you run `cargo build` and disabled when you run `cargo build --release`.
    pub fn with_gl_debug_flag(mut self, flag: bool) -> HeadlessRendererBuilder {
        self.attribs.gl_debug = flag;
        self
    }

    /// Builds the headless context.
    ///
    /// Error should be very rare and only occur in case of permission denied, incompatible system,
    ///  out of memory, etc.
    pub fn build(self) -> Result<HeadlessContext, CreationError> {
        winimpl::HeadlessContext::new(self.attribs).map(|w| HeadlessContext { context: w })
    }

    /// Builds the headless context.
    ///
    /// The context is build in a *strict* way. That means that if the backend couldn't give
    /// you what you requested, an `Err` will be returned.
    pub fn build_strict(mut self) -> Result<HeadlessContext, CreationError> {
        self.attribs.strict = true;
        self.build()
    }
}

/// Represents a headless OpenGL context.
pub struct HeadlessContext {
    context: winimpl::HeadlessContext,
}

impl HeadlessContext {
    /// Creates a new OpenGL context
    /// Sets the context as the current context.
    #[inline]
    pub unsafe fn make_current(&self) {
        self.context.make_current()
    }

    /// Returns the address of an OpenGL function.
    ///
    /// Contrary to `wglGetProcAddress`, all available OpenGL functions return an address.
    #[inline]
    pub fn get_proc_address(&self, addr: &str) -> *const libc::c_void {
        self.context.get_proc_address(addr) as *const libc::c_void
    }

    /// Returns the API that is currently provided by this window.
    ///
    /// See `Window::get_api` for more infos.
    pub fn get_api(&self) -> Api {
        self.context.get_api()
    }

    pub fn set_window_resize_callback(&mut self, _: Option<fn(u32, u32)>) {
    }
}

impl gl_common::GlFunctionsSource for HeadlessContext {
    fn get_proc_addr(&self, addr: &str) -> *const libc::c_void {
        self.get_proc_address(addr)
    }
}