glium/
lib.rs

1/*!
2Easy-to-use, high-level, OpenGL3+ wrapper.
3
4Glium is based on glutin - a cross-platform crate for building an OpenGL window and handling
5application events.
6
7Glium provides a [`Display`] which uses `glutin` for the Window and its associated GL Context.
8
9# Initialization
10
11The initialisation of a simple glium display occurs in two steps.
12
13```no_run
14extern crate glium;
15// Use the re-exported winit dependency to avoid version mismatches.
16// Requires the `simple_window_builder` feature.
17use glium::winit;
18
19fn main() {
20    // 1. The **winit::EventLoop** for handling events.
21    let event_loop = winit::event_loop::EventLoopBuilder::new().build().unwrap();
22    // 2. Create a glutin context and glium Display
23    let (window, display) = glium::backend::glutin::SimpleWindowBuilder::new().build(&event_loop);
24}
25```
26
27The `display` object is the most important object of this library and is used when you build
28buffers, textures, etc. and when you draw.
29
30You can clone it and pass it around. However it doesn't implement the `Send` and `Sync` traits,
31meaning that you can't pass it to another thread.
32
33The display has ownership of both the window and context, and also provides some methods related to
34domains such as events handling.
35
36# Overview
37
38OpenGL is similar to drawing software: you draw something, then draw over it, then over it
39again, etc. until you are satisfied of the result.
40
41Once you have a `display`, you can call `let mut frame = display.draw();` to start drawing. This
42`frame` object implements [the `Surface` trait](`Surface`) and provides some functions
43such as `clear_color`, but also allows you to draw with the rendering pipeline.
44
45In order to draw something, you will need to pass:
46
47 - A source of vertices (see the [`vertex`](`vertex`) module)
48 - A source of indices (see the [`index`](`index`) module)
49 - A program that contains the shader that the GPU will execute (see the
50   [`program`](`mod@program`) module)
51 - A list of uniforms for the program (see the [`uniforms`](`uniforms`) module)
52 - Draw parameters to customize the drawing process (see the
53   [`draw_parameters`](`draw_parameters`) module)
54
55Once you have finished drawing, you can call `frame.finish()` to swap buffers and present the
56result to the user.
57
58# OpenGL equivalents in glium
59
60 - **Bind points**: Glium automatically binds and unbinds buffers, textures, etc. in an optimized
61   way.
62 - **Buffers**: Buffers are strongly typed and can be used through `vertex::VertexBuffer`,
63   `index::IndexBuffer` or `uniforms::UniformBuffer`.
64 - **Debug output**: If you compile in debug mode, glium registers a debug output callback and
65   panics if an OpenGL error happens.
66 - **Framebuffer Objects**: FBOs are automatically managed by glium and are stored in the `Context`
67   object. You can specify the attachments that you wish with the `framebuffer` module.
68 - **Instancing**: Instancing is done either by passing a `vertex::EmptyInstanceAttributes` marker
69   or one or several references to vertex buffers wrapped inside a `PerInstance` struct. See the
70   `vertex` module for more infos.
71 - **Memory barriers**: Calling `glMemoryBarrier` is automatically handled by glium, however you
72   still need to call `memoryBarrier()` in your GLSL code in some situations.
73 - **Programs**: See the `program` module.
74 - **Query objects**: The corresponding structs are in the `draw_parameters` module. They are
75   passed as draw parameters.
76 - **Renderbuffer**: See the `framebuffer` module.
77 - **Render to texture**: If you just want to draw on a texture, you can call
78   `texture.as_surface()`. For more advanced options, see the `framebuffer` module.
79 - **Samplers**: Samplers are automatically managed by glium and are stored in the `Context`
80   object. You can specify how a texture should be sampled by using a `Sampler` dummy object
81   in the `uniforms` module.
82 - **Shaders**: You can't manually create individual shaders. Instead you must create whole
83   programs at once.
84 - **Textures**: Textures are strongly typed and are found in the `texture` module.
85 - **Uniform blocks**: If your program uses uniform blocks, you must pass a reference to a
86   uniform buffer for the name of the block when drawing.
87 - **Vertex array objects**: VAOs are automatically managed by glium if the backend supports them.
88
89*/
90#![warn(missing_docs)]
91
92// TODO: remove these when everything is implemented
93#![allow(dead_code)]
94#![allow(unused_variables)]
95#![allow(
96    clippy::unused_unit,
97    clippy::too_many_arguments,
98    clippy::type_complexity,
99    clippy::module_inception,
100    clippy::neg_cmp_op_on_partial_ord,
101    clippy::missing_safety_doc,
102    clippy::new_without_default,
103    clippy::len_zero,
104    clippy::len_without_is_empty,
105    clippy::if_same_then_else,
106    // Maybe we'll fix these later, but not right now
107    // (Would require API change)
108    clippy::wrong_self_convention,
109)]
110
111#[cfg(feature = "glutin")]
112pub use crate::backend::glutin::glutin;
113#[cfg(feature = "simple_window_builder")]
114pub use crate::backend::winit;
115pub use crate::context::{Capabilities, ExtensionsList, Profile, UuidError};
116pub use crate::draw_parameters::{Blend, BlendingFunction, LinearBlendingFactor, BackfaceCullingMode};
117pub use crate::draw_parameters::{Depth, DepthTest, PolygonMode, DrawParameters, StencilTest, StencilOperation};
118pub use crate::draw_parameters::Smooth;
119pub use crate::index::IndexBuffer;
120pub use crate::vertex::{VertexBuffer, Vertex, VertexFormat};
121pub use crate::program::{Program, ProgramCreationError};
122pub use crate::program::ProgramCreationError::{CompilationError, LinkingError, ShaderTypeNotSupported};
123pub use crate::sync::{LinearSyncFence, SyncFence};
124pub use crate::texture::Texture2d;
125pub use crate::version::{Api, Version, get_supported_glsl_version};
126pub use crate::ops::ReadError;
127
128use std::rc::Rc;
129use std::thread;
130use std::error::Error;
131use std::fmt;
132use std::hash::BuildHasherDefault;
133use std::collections::HashMap;
134
135use fnv::FnvHasher;
136
137use crate::context::Context;
138use crate::context::CommandContext;
139
140#[macro_use]
141mod macros;
142
143pub mod backend;
144pub mod buffer;
145pub mod debug;
146pub mod draw_parameters;
147pub mod framebuffer;
148pub mod index;
149pub mod memory_object;
150pub mod pixel_buffer;
151pub mod program;
152pub mod uniforms;
153pub mod vertex;
154pub mod semaphore;
155pub mod texture;
156pub mod field;
157
158mod context;
159mod fbo;
160mod image_format;
161mod ops;
162mod sampler_object;
163mod sync;
164mod utils;
165mod version;
166mod vertex_array_object;
167
168mod gl {
169    #![allow(clippy::all)]
170    include!(concat!(env!("OUT_DIR"), "/gl_bindings.rs"));
171}
172
173#[doc(hidden)]
174pub use memoffset::offset_of as __glium_offset_of;
175
176/// The main object of this library. Controls the whole display.
177///
178/// This object contains a smart pointer to the real implementation.
179/// Cloning the display allows you to easily share the `Display` object throughout
180/// your program.
181#[cfg(feature = "glutin")]
182pub use crate::backend::glutin::Display;
183
184use crate::uniforms::MagnifySamplerFilter;
185
186/// Trait for objects that describe the capabilities of an OpenGL backend.
187pub trait CapabilitiesSource {
188    /// Returns the version of the backend.
189    fn get_version(&self) -> &version::Version;
190
191    /// Returns the list of extensions that are supported.
192    fn get_extensions(&self) -> &context::ExtensionsList;
193
194    /// Returns the capabilities of the backend.
195    fn get_capabilities(&self) -> &context::Capabilities;
196}
197
198/// Trait for objects that are OpenGL objects.
199pub trait GlObject {
200    /// The type of identifier for this object.
201    type Id;
202
203    /// Returns the id of the object.
204    fn get_id(&self) -> Self::Id;
205}
206
207/// Handle to a shader or a program.
208// TODO: Handle(null()) is equal to Id(0)
209#[derive(PartialEq, Eq, Copy, Clone, Debug, Hash)]
210pub enum Handle {
211    /// A numeric identifier.
212    Id(gl::types::GLuint),
213    /// A `GLhandleARB`.
214    Handle(gl::types::GLhandleARB),
215}
216
217unsafe impl Send for Handle {}
218
219/// Internal trait for enums that can be turned into GLenum.
220trait ToGlEnum {
221    /// Returns the value.
222    fn to_glenum(&self) -> gl::types::GLenum;
223}
224
225/// Internal trait for subbuffers.
226trait BufferExt {
227    /// Returns the number of bytes from the start of the buffer to this subbuffer.
228    fn get_offset_bytes(&self) -> usize;
229
230    /// Calls `glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT)` if necessary.
231    fn prepare_for_vertex_attrib_array(&self, _: &mut CommandContext<'_>);
232
233    /// Calls `glMemoryBarrier(ELEMENT_ARRAY_BARRIER_BIT)` if necessary.
234    fn prepare_for_element_array(&self, _: &mut CommandContext<'_>);
235
236    /// Binds the buffer to `GL_ELEMENT_ARRAY_BUFFER` regardless of the current vertex array object.
237    fn bind_to_element_array(&self, _: &mut CommandContext<'_>);
238
239    /// Makes sure that the buffer is bound to the `GL_PIXEL_PACK_BUFFER` and calls
240    /// `glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT)` if necessary.
241    fn prepare_and_bind_for_pixel_pack(&self, _: &mut CommandContext<'_>);
242
243    /// Makes sure that nothing is bound to `GL_PIXEL_PACK_BUFFER`.
244    fn unbind_pixel_pack(_: &mut CommandContext<'_>);
245
246    /// Makes sure that the buffer is bound to the `GL_PIXEL_UNPACK_BUFFER` and calls
247    /// `glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT)` if necessary.
248    fn prepare_and_bind_for_pixel_unpack(&self, _: &mut CommandContext<'_>);
249
250    /// Makes sure that nothing is bound to `GL_PIXEL_UNPACK_BUFFER`.
251    fn unbind_pixel_unpack(_: &mut CommandContext<'_>);
252
253    /// Makes sure that the buffer is bound to the `GL_QUERY_BUFFER` and calls
254    /// `glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT)` if necessary.
255    fn prepare_and_bind_for_query(&self, _: &mut CommandContext<'_>);
256
257    /// Makes sure that nothing is bound to `GL_QUERY_BUFFER`.
258    fn unbind_query(_: &mut CommandContext<'_>);
259
260    /// Makes sure that the buffer is bound to the `GL_DRAW_INDIRECT_BUFFER` and calls
261    /// `glMemoryBarrier(GL_COMMAND_BARRIER_BIT)` if necessary.
262    fn prepare_and_bind_for_draw_indirect(&self, _: &mut CommandContext<'_>);
263
264    /// Makes sure that the buffer is bound to the `GL_DISPATCH_INDIRECT_BUFFER` and calls
265    /// `glMemoryBarrier(GL_COMMAND_BARRIER_BIT)` if necessary.
266    fn prepare_and_bind_for_dispatch_indirect(&self, _: &mut CommandContext<'_>);
267
268    /// Makes sure that the buffer is bound to the indexed `GL_UNIFORM_BUFFER` point and calls
269    /// `glMemoryBarrier(GL_UNIFORM_BARRIER_BIT)` if necessary.
270    fn prepare_and_bind_for_uniform(&self, _: &mut CommandContext<'_>, index: gl::types::GLuint);
271
272    /// Makes sure that the buffer is bound to the indexed `GL_SHARED_STORAGE_BUFFER` point and calls
273    /// `glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT)` if necessary.
274    fn prepare_and_bind_for_shared_storage(&self, _: &mut CommandContext<'_>, index: gl::types::GLuint);
275
276    /// Makes sure that the buffer is bound to the indexed `GL_ATOMIC_COUNTER_BUFFER` point and calls
277    /// `glMemoryBarrier(GL_ATOMIC_COUNTER_BARRIER_BIT)` if necessary.
278    fn prepare_and_bind_for_atomic_counter(&self, _: &mut CommandContext<'_>, index: gl::types::GLuint);
279
280    /// Binds the buffer to `GL_TRANSFORM_FEEDBACk_BUFFER` regardless of the current transform
281    /// feedback object.
282    fn bind_to_transform_feedback(&self, _: &mut CommandContext<'_>, index: gl::types::GLuint);
283}
284
285/// Internal trait for subbuffer slices.
286trait BufferSliceExt<'a> {
287    /// Tries to get an object where to write a fence.
288    ///
289    /// If this function returns `None`, no fence will be created nor written.
290    fn add_fence(&self) -> Option<buffer::Inserter<'a>>;
291}
292
293/// Internal trait for contexts.
294trait ContextExt {
295    /// Sets whether the context's debug output callback should take errors into account.
296    fn set_report_debug_output_errors(&self, value: bool);
297
298    /// Start executing OpenGL commands by checking the current context.
299    fn make_current(&self) -> context::CommandContext<'_>;
300
301    /// Returns the capabilities of the backend.
302    fn capabilities(&self) -> &context::Capabilities;
303}
304
305/// Internal trait for programs.
306trait ProgramExt {
307    /// Calls `glUseProgram` and enables/disables `GL_PROGRAM_POINT_SIZE` and
308    /// `GL_FRAMEBUFFER_SRGB`.
309    fn use_program(&self, ctxt: &mut context::CommandContext<'_>);
310
311    /// Changes the value of a uniform of the program.
312    fn set_uniform(&self, ctxt: &mut context::CommandContext<'_>, uniform_location: gl::types::GLint,
313                   value: &RawUniformValue);
314
315    /// Changes the uniform block binding of the program.
316    fn set_uniform_block_binding(&self, ctxt: &mut context::CommandContext<'_>,
317                                 block_location: gl::types::GLuint, value: gl::types::GLuint);
318
319    /// Changes the shader storage block binding of the program.
320    fn set_shader_storage_block_binding(&self, ctxt: &mut context::CommandContext<'_>,
321                                        block_location: gl::types::GLuint,
322                                        value: gl::types::GLuint);
323
324    /// Changes the subroutine uniform bindings of a program.
325    fn set_subroutine_uniforms_for_stage(&self, ctxt: &mut context::CommandContext<'_>,
326                                         stage: program::ShaderStage,
327                                         indices: &[gl::types::GLuint]);
328
329    fn get_uniform(&self, name: &str) -> Option<&program::Uniform>;
330
331    fn get_uniform_blocks(&self) -> &HashMap<String, program::UniformBlock, BuildHasherDefault<FnvHasher>>;
332
333    fn get_shader_storage_blocks(&self) -> &HashMap<String, program::UniformBlock, BuildHasherDefault<FnvHasher>>;
334
335    fn get_atomic_counters(&self) -> &HashMap<String, program::UniformBlock, BuildHasherDefault<FnvHasher>>;
336
337    fn get_subroutine_data(&self) -> &program::SubroutineData;
338}
339
340/// Internal trait for queries.
341trait QueryExt {
342    fn begin_query(&self, ctxt: &mut CommandContext<'_>) -> Result<(), DrawError>;
343
344    fn end_samples_passed_query(ctxt: &mut CommandContext<'_>);
345
346    fn end_time_elapsed_query(ctxt: &mut CommandContext<'_>);
347
348    fn end_primitives_generated_query(ctxt: &mut CommandContext<'_>);
349
350    fn end_transform_feedback_primitives_written_query(ctxt: &mut CommandContext<'_>);
351
352    fn begin_conditional_render(&self, ctxt: &mut CommandContext<'_>, wait: bool, per_region: bool);
353
354    fn end_conditional_render(ctxt: &mut CommandContext<'_>);
355
356    /// Returns true if the query has never been used.
357    fn is_unused(&self) -> bool;
358}
359
360/// Internal trait for textures.
361trait TextureExt {
362    /// Returns the ID of the texture.
363    fn get_texture_id(&self) -> gl::types::GLuint;
364
365    /// Returns the context associated to this texture.
366    fn get_context(&self) -> &Rc<Context>;
367
368    /// Returns the bind point of the texture.
369    fn get_bind_point(&self) -> gl::types::GLenum;
370
371    /// Makes sure that the texture is bound to the current texture unit and returns the
372    /// bind point to use to access the texture (eg. `GL_TEXTURE_2D`, `GL_TEXTURE_3D`, etc.).
373    fn bind_to_current(&self, _: &mut CommandContext<'_>) -> gl::types::GLenum;
374
375    /// Prepares the texture to be accessed, after possibly being modified in a shader
376    /// with image load/store
377    fn prepare_for_access(&self, _: &mut CommandContext<'_>, access_type: TextureAccess);
378}
379
380/// Ways a texture could possibly be accessed after being written to in a shader via an image unit
381enum TextureAccess {
382    /// Regular texture fetches within shaders
383    TextureFetch,
384    /// Texture being used as an image unit inside of a shader
385    ImageUnit { will_write: bool },
386    /// Texture being used as a framebuffer object
387    Framebuffer,
388}
389
390/// Internal trait for textures.
391trait TextureMipmapExt {
392    /// Changes some parts of the texture.
393    fn upload_texture<'a, P>(&self, x_offset: u32, y_offset: u32, z_offset: u32,
394                             _: (image_format::ClientFormatAny, std::borrow::Cow<'a, [P]>), width: u32,
395                             height: Option<u32>, depth: Option<u32>,
396                             regen_mipmaps: bool)
397                             -> Result<(), ()>   // TODO return a better Result!?
398                             where P: Send + Copy + Clone + 'a;
399
400    fn download_compressed_data(&self) -> Option<(image_format::ClientFormatAny, Vec<u8>)>;
401}
402
403/// Internal trait for transform feedback sessions.
404trait TransformFeedbackSessionExt {
405    /// Updates the state of OpenGL to make the transform feedback session current.
406    ///
407    /// The second parameter must be the primitive type of the input vertex data.
408    fn bind(&self, _: &mut CommandContext<'_>, _: index::PrimitiveType);
409
410    /// Ensures that transform feedback is disabled.
411    fn unbind(_: &mut CommandContext<'_>);
412
413    /// Ensures that a buffer isn't used by transform feedback.
414    fn ensure_buffer_out_of_transform_feedback(_: &mut CommandContext<'_>, _: gl::types::GLuint);
415}
416
417/// Internal trait for uniforms handling.
418trait UniformsExt {
419    /// Binds the uniforms to a given program.
420    ///
421    /// Will replace texture and buffer bind points.
422    fn bind_uniforms<'a, P>(&'a self, _: &mut CommandContext<'_>, _: &P, _: &mut Vec<buffer::Inserter<'a>>)
423                            -> Result<(), DrawError> where P: ProgramExt;
424}
425
426
427/// A raw value of a uniform. "Raw" means that it's passed directly with `glUniform`. Textures
428/// for example are just passed as integers.
429///
430/// Blocks and subroutines are not included.
431#[derive(Copy, Clone, Debug)]
432#[allow(missing_docs)]
433pub enum RawUniformValue {
434    SignedInt(gl::types::GLint),
435    UnsignedInt(gl::types::GLuint),
436    Float(gl::types::GLfloat),
437    /// 2x2 column-major matrix.
438    Mat2([[gl::types::GLfloat; 2]; 2]),
439    /// 3x3 column-major matrix.
440    Mat3([[gl::types::GLfloat; 3]; 3]),
441    /// 4x4 column-major matrix.
442    Mat4([[gl::types::GLfloat; 4]; 4]),
443    Vec2([gl::types::GLfloat; 2]),
444    Vec3([gl::types::GLfloat; 3]),
445    Vec4([gl::types::GLfloat; 4]),
446    IntVec2([gl::types::GLint; 2]),
447    IntVec3([gl::types::GLint; 3]),
448    IntVec4([gl::types::GLint; 4]),
449    UnsignedIntVec2([gl::types::GLuint; 2]),
450    UnsignedIntVec3([gl::types::GLuint; 3]),
451    UnsignedIntVec4([gl::types::GLuint; 4]),
452
453    // Double precision primitives
454    Double(gl::types::GLdouble),
455    DoubleMat2([[gl::types::GLdouble; 2]; 2]),
456    DoubleMat3([[gl::types::GLdouble; 3]; 3]),
457    DoubleMat4([[gl::types::GLdouble; 4]; 4]),
458    DoubleVec2([gl::types::GLdouble; 2]),
459    DoubleVec3([gl::types::GLdouble; 3]),
460    DoubleVec4([gl::types::GLdouble; 4]),
461    Int64(gl::types::GLint64),
462    Int64Vec2([gl::types::GLint64; 2]),
463    Int64Vec3([gl::types::GLint64; 3]),
464    Int64Vec4([gl::types::GLint64; 4]),
465    UnsignedInt64(gl::types::GLuint64),
466    UnsignedInt64Vec2([gl::types::GLuint64; 2]),
467    UnsignedInt64Vec3([gl::types::GLuint64; 3]),
468    UnsignedInt64Vec4([gl::types::GLuint64; 4]),
469}
470
471/// Area of a surface in pixels.
472///
473/// In the OpenGL ecosystem, the (0,0) coordinate is at the bottom-left hand corner of the images.
474#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
475pub struct Rect {
476    /// Number of pixels between the left border of the surface and the left border of
477    /// the rectangle.
478    pub left: u32,
479    /// Number of pixels between the bottom border of the surface and the bottom border
480    /// of the rectangle.
481    pub bottom: u32,
482    /// Width of the area in pixels.
483    pub width: u32,
484    /// Height of the area in pixels.
485    pub height: u32,
486}
487
488/// Area of a surface in pixels. Similar to a `Rect` except that dimensions can be negative.
489///
490/// In the OpenGL ecosystem, the (0,0) coordinate is at the bottom-left hand corner of the images.
491#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
492pub struct BlitTarget {
493    /// Number of pixels between the left border of the surface and the left border of
494    /// the rectangle.
495    pub left: u32,
496    /// Number of pixels between the bottom border of the surface and the bottom border
497    /// of the rectangle.
498    pub bottom: u32,
499    /// Width of the area in pixels. Can be negative.
500    pub width: i32,
501    /// Height of the area in pixels. Can be negative.
502    pub height: i32,
503}
504
505/// Mask specifying, which kinds of buffers to copy when blitting between two frame buffers.
506#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
507pub struct BlitMask {
508
509    /// If the color buffer should be copied.
510    pub color: bool,
511
512    /// If the depth buffer should be copied.
513    pub depth: bool,
514
515    /// If the stencil buffer should be copied.
516    pub stencil: bool,
517}
518
519impl BlitMask {
520
521    /// Constructs a bit mask, that will only copy the color buffer
522    pub fn color() -> Self {
523        BlitMask { color: true, depth: false, stencil: false }
524    }
525
526    /// Constructs a bit mask, that will only copy the depth buffer
527    pub fn depth() -> Self {
528        BlitMask { color: false, depth: true, stencil: false }
529    }
530
531    /// Constructs a bit mask, that will only copy the stencil buffer
532    pub fn stencil() -> Self {
533        BlitMask { color: false, depth: false, stencil: true }
534    }
535
536    /// Constructs a bit mask, that will copy the color and the depth buffer.
537    pub fn color_and_depth() -> Self {
538        BlitMask { color: true, depth: true, stencil: false }
539    }
540
541    /// Constructs a bit mask, that will copy the color and the stencil buffer.
542    pub fn color_and_stencil() -> Self {
543        BlitMask { color: true, depth: false, stencil: true }
544    }
545
546    /// Constructs a bit mask, that will copy the depth and the stencil buffer.
547    pub fn depth_and_stencil() -> Self {
548        BlitMask { color: false, depth: true, stencil: true }
549    }
550
551    /// Constructs a bit mask, that will copy the color, depth and stencil buffer.
552    pub fn color_and_depth_and_stencil() -> Self {
553        BlitMask { color: true, depth: true, stencil: true }
554    }
555}
556
557impl ToGlEnum for BlitMask {
558    #[inline]
559    fn to_glenum(&self) -> gl::types::GLenum {
560        let mut mask = 0;
561        if self.color {
562            mask = mask | gl::COLOR_BUFFER_BIT;
563        }
564        if self.depth {
565            mask = mask | gl::DEPTH_BUFFER_BIT;
566        }
567        if self.stencil {
568            mask = mask | gl::STENCIL_BUFFER_BIT;
569        }
570        mask
571    }
572}
573
574/// Object that can be drawn upon.
575///
576/// # What does the GPU do when you draw?
577///
578/// This is a summary of everything that happens when you call the `draw` function. Note that
579/// this is not necessarily *exactly* what happens. Backends are free to do whatever they want
580/// as long as it always matches the expected outcome.
581///
582/// ## Step 1: Vertex shader
583///
584/// For each vertex in the vertices source, the GPU invokes the vertex shader that is part
585/// of the program, and passes the corresponding vertex's attributes to it.
586///
587/// The vertex shader *must* write the special `gl_Position` variable in order to indicate
588/// the four-dimensions coordinates of the vertex. In order to understand what these coordinates
589/// mean, see the "vertex post-processing" step below.
590///
591/// In addition to the position of the vertex, the vertex shader can also specify the values of
592/// various vertex attributes.
593///
594/// ## Step 2: Tessellation (optional)
595///
596///
597/// ## Step 3: Geometry shader (optional)
598///
599/// If you specify a geometry shader, then the GPU will invoke it once for each primitive.
600///
601/// The geometry shader can output multiple primitives.
602///
603/// ## Step 4: Transform feedback (optional)
604///
605/// TODO:
606/// TODO: talk about `transform_feedback_primitives_written_query` as well
607///
608/// ## Step 5: Vertex post-processing
609///
610/// The vertex shader step told the GPU what the coordinates of each vertex are, but these
611/// coordinates have four dimensions, named `x`, `y`, `z` and `w`.
612///
613/// The GPU then computes the position of the vertex on the 2D surface you are drawing on, and
614/// the depth of this vertex:
615///
616/// ```notrust
617/// window_x = viewport_left + viewport_width * ((x / w) + 1.0) / 2.0
618/// window_y = viewport_bottom + viewport_height * ((y / w) + 1.0) / 2.0
619/// depth = depth_near + (depth_far - depth_near) * ((z / w) + 1.0) / 2.0
620/// ```
621///
622/// *`viewport_left`, `viewport_width`, `viewport_bottom` and `viewport_height` correspond to
623/// the `viewport` member of the draw parameters, and `depth_near` and `depth_far` correspond
624/// to the `depth_range` member*.
625///
626/// This means that if `x / w`, `y / w` or `z / w` are equal to `-1.0`, then the result will be
627/// `viewport_left`, `viewport_bottom` or `depth_near`. If they are equal to `1.0`, the result
628/// will be `viewport_left + viewport_width` (the right of the viewport),
629/// `viewport_bottom + viewport_height` (the top of the viewport) or `depth_far`.
630///
631/// For example if you want to draw a rectangle that covers the whole screen, it should be made
632/// of four vertices whose coordinates are `(-1.0, -1.0, 0.0, 1.0)` (bottom-left corner),
633/// `(-1.0, 1.0, 0.0, 1.0)` (top-left corner), `(1.0, 1.0, 0.0, 1.0)` (top-right corner) and
634/// `(1.0, -1.0, 0.0, 1.0)` (bottom-right corner).
635///
636/// ## Step 6: Primitive assembly
637///
638/// The next step consists in building the primitives. Triangle strips, triangle fans and line
639/// strips are turned into individual triangles or lines.
640///
641/// Triangle strips obey certain rules for the order of indices. For example the triangle strip
642/// `0, 1, 2, 3, 4, 5` does *not* correspond to `0, 1, 2`, `1, 2, 3`, `2, 3, 4`, `3, 4, 5` as you
643/// would expect, but to `0, 1, 2`, `1, 3, 2`, `2, 3, 4`, `3, 5, 4` (some indices are reversed).
644/// This is important with regards to the face culling step below.
645///
646/// Then, if you did specify `PrimitiveMode`, it is used. If you specified `Line`, triangles are
647/// turned into lines. If specified `Point`, triangles and lines are turned into points.
648///
649/// The GPU then looks at the screen coordinates of each primitive, and discards primitives that
650/// are entirely outside of the window.
651///
652/// Note that points whose centers are outside of the viewport are discarded, even if the point
653/// width would be big enough for the point to be visible. However this standard behavior is not
654/// respected by nVidia drivers, which show the points anyway.
655///
656/// If a query has been specified through `primitives_generated_query`, then its value is updated.
657///
658/// ## Step 7: Face culling (triangles only)
659///
660/// This step is purely an optimization step and only concerns triangles.
661///
662/// If you specify a value for `backface_culling` other than `CullingDisabled`, the GPU will
663/// discard triangles depending on the way that the vertices are arranged on the window. You can
664/// either discard triangles whose vertices are clockwise or counterclockwise.
665///
666/// For more information, see the `BackfaceCullingMode` documentation.
667///
668/// ## Step 8: Rasterization
669///
670/// Now that the GPU knows where on the window the various triangles, points or lines are, it will
671/// determine which pixels of the surface are part of each primitive.
672///
673/// For points and lines, this step depends on the points width and line width that you specified
674/// in the draw parameters. If you specify the `smooth` parameter, then the borders of the
675/// primitives will see their alpha value adjusted.
676///
677/// <img alt="" src="data:image/png;base64,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" />
678///
679/// The attributes of each vertex that are marked as `smooth` (which is the default value) are
680/// being interpolated, and the GPU assigns a value for each attribute for each pixel.
681///
682/// ## Step 9: Fragment shader
683///
684/// The GPU now executes the fragment shader once for each pixel of each primitive.
685/// The vertex attributes that were interpolated at the previous step are passed to the fragment
686/// shader.
687///
688/// The fragment shader must return the color to write by setting the value of `gl_FragColor`.
689///
690/// If the target framebuffer has multisampling enabled, then each pixel of the target image is
691/// in turn split into four subpixels. The output of the fragment shader is copied and written into
692/// each subpixel. If `multisampling` in the draw parameters is `true` (its default value), only
693/// subpixels that belong to the triangle are written.
694///
695/// If a query has been specified through `samples_passed_query`, then its value is updated.
696///
697/// ## Step 10: Pixel ownership
698///
699/// This step is mostly an implementation detail. If the window you are drawing on is not on the
700/// foreground, or if it is partially obstructed, then the pixels that are not on the
701/// foreground will be discarded.
702///
703/// This is only relevant if you draw to the default framebuffer.
704///
705/// This step has to be taken into account in some situations. For example if you query the number
706/// of samples that have been written, the ones that don't pass the pixel ownership test won't
707/// count.
708///
709/// ## Step 11: Scissor test
710///
711/// If `scissor` has been specified, then all the pixels that are outside of this rect
712/// are discarded.
713///
714/// ## Step 12: Depth test
715///
716/// In addition to the colors, surfaces can also have a depth buffer attached to it. In this
717/// situation, just like each pixel has a color, each pixel of the surface also has an associated
718/// depth value.
719///
720/// If a depth buffer is present, the GPU will compare the depth value of the pixel currently
721/// being processed, with the existing depth value. Depending on the value of `depth_test`
722/// in the draw parameters, the depth test will either pass, in which case the pipeline
723/// continues, or fail, in which case the pixel is discarded. If the value of `depth_write`
724/// is true and the test passed, it will then also write the depth value of the pixel on the
725/// depth buffer.
726///
727/// The purpose of this test is to avoid drawing elements that are in the background of the
728/// scene over elements that are in the foreground.
729///
730/// See the documentation of `DepthTest` for more informations.
731///
732/// ## Step 13: Stencil test
733///
734/// Similar to the depth buffer, surfaces can also have a stencil buffer.
735///
736/// The `stencil_test_clockwise` and `stencil_test_counter_clockwise` draw parameters specify
737/// the operation to use to check whether or not each pixel passes the stencil test. Pixels that
738/// fail the stencil test won't be drawn on the screen.
739///
740/// The `*_clockwise` members are relevant for polygons that are displayed clockwise, and the
741/// `*_counter_clockwise` members are relevant for polygons that are displayed counterclockwise.
742/// See also the `face culling` step for more infos. Lines and points always use the `*_clockwise`
743/// members.
744///
745/// There are three possibilities for each pixel: either it fails the stencil test, or it passes
746/// the stencil test but failed the depth test, or it passes both the stencil test and depth test.
747/// You can specify for each of these three situations what to do with the value in the stencil
748/// buffer with the draw parameters.
749///
750/// ## Step 14: Blending
751///
752/// For each pixel to write, the GPU takes the RGBA color that the fragment shader has returned
753/// and the existing RGBA color already written on the surface, and merges the two.
754///
755/// The way they are merged depends on the value of `blending_function`. This allows you to choose
756/// how alpha colors are merged together.
757///
758/// See the documentation of `BlendingFunction` fore more informations.
759///
760/// ## Step 15: Dithering (optional)
761///
762/// If `dithering` is `true` in the draw parameters, then a dithering algorithm is applied.
763///
764/// When you draw a gradient of colors, the boundary between each individual color value is
765/// visible. Thanks to an optical illusion, a dithering algorithm will change the color values
766/// of some pixels and hide the boundaries.
767///
768/// ## Step 16: Conversion to sRGB
769///
770/// If the target has sRGB enabled, then the output of the fragment will get some gamma correction.
771///
772/// Monitors don't show colors linearly. For example a value of `0.5` isn't shown half as bright
773/// as a value of `1.0`. Instead the monitor will show colors as darker than they should be.
774/// In order to fix this problem, each pixel is modified to be made slightly brighter with the same
775/// factor as the monitor makes them darker.
776///
777/// ## Step 17: End
778///
779/// This is finally the step where colors are being written. The `color_mask` parameter allow you
780/// to specify whether each color component (red, green, blue and alpha) is written to the color
781/// buffer.
782///
783pub trait Surface {
784    /// Clears some attachments of the target.
785    fn clear(&mut self, rect: Option<&Rect>, color: Option<(f32, f32, f32, f32)>, color_srgb: bool,
786             depth: Option<f32>, stencil: Option<i32>);
787
788    /// Clears the color attachment of the target. The color is converted to sRGB when the target has sRGB format.
789    fn clear_color(&mut self, red: f32, green: f32, blue: f32, alpha: f32) {
790        self.clear(None, Some((red, green, blue, alpha)), false, None, None);
791    }
792
793    /// Clears the color attachment of the target. The color is in sRGB format and is not converted in the target.
794    fn clear_color_srgb(&mut self, red: f32, green: f32, blue: f32, alpha: f32) {
795        self.clear(None, Some((red, green, blue, alpha)), true, None, None);
796    }
797
798    /// Clears the depth attachment of the target.
799    fn clear_depth(&mut self, value: f32) {
800        self.clear(None, None, false, Some(value), None);
801    }
802
803    /// Clears the stencil attachment of the target.
804    fn clear_stencil(&mut self, value: i32) {
805        self.clear(None, None, false, None, Some(value));
806    }
807
808    /// Clears the color and depth attachments of the target.
809    fn clear_color_and_depth(&mut self, color: (f32, f32, f32, f32), depth: f32) {
810        self.clear(None, Some(color), false, Some(depth), None);
811    }
812
813    /// Clears the color and depth attachments of the target. The color is in sRGB format.
814    fn clear_color_srgb_and_depth(&mut self, color: (f32, f32, f32, f32), depth: f32) {
815        self.clear(None, Some(color), true, Some(depth), None);
816    }
817
818    /// Clears the color and stencil attachments of the target.
819    fn clear_color_and_stencil(&mut self, color: (f32, f32, f32, f32), stencil: i32) {
820        self.clear(None, Some(color), false, None, Some(stencil));
821    }
822
823    /// Clears the color and stencil attachments of the target. The color is in sRGB format.
824    fn clear_color_srgb_and_stencil(&mut self, color: (f32, f32, f32, f32), stencil: i32) {
825        self.clear(None, Some(color), true, None, Some(stencil));
826    }
827
828    /// Clears the depth and stencil attachments of the target.
829    fn clear_depth_and_stencil(&mut self, depth: f32, stencil: i32) {
830        self.clear(None, None, false, Some(depth), Some(stencil));
831    }
832
833    /// Clears the color, depth and stencil attachments of the target.
834    fn clear_all(&mut self, color: (f32, f32, f32, f32), depth: f32, stencil: i32) {
835        self.clear(None, Some(color), false, Some(depth), Some(stencil));
836    }
837
838    /// Clears the color, depth and stencil attachments of the target. The color is in sRGB format.
839    fn clear_all_srgb(&mut self, color: (f32, f32, f32, f32), depth: f32, stencil: i32) {
840        self.clear(None, Some(color), true, Some(depth), Some(stencil));
841    }
842
843    /// Returns the dimensions in pixels of the target.
844    fn get_dimensions(&self) -> (u32, u32);
845
846    /// Returns the number of bits of each pixel of the depth buffer.
847    ///
848    /// Returns `None` if there is no depth buffer.
849    fn get_depth_buffer_bits(&self) -> Option<u16>;
850
851    /// Returns true if the surface has a depth buffer available.
852    fn has_depth_buffer(&self) -> bool {
853        self.get_depth_buffer_bits().is_some()
854    }
855
856    /// Returns the number of bits of each pixel of the stencil buffer.
857    ///
858    /// Returns `None` if there is no stencil buffer.
859    fn get_stencil_buffer_bits(&self) -> Option<u16>;
860
861    /// Returns true if the surface has a stencil buffer available.
862    fn has_stencil_buffer(&self) -> bool {
863        self.get_stencil_buffer_bits().is_some()
864    }
865
866    /// Draws.
867    ///
868    /// This is probably the most complex function of glium. Check out the rest of the
869    /// documentation for example how to use it.
870    ///
871    /// See above for what happens exactly on the GPU when you draw.
872    fn draw<'a, 'b, V, I, U>(&mut self, _: V, _: I, program: &Program, uniforms: &U,
873        draw_parameters: &DrawParameters<'_>) -> Result<(), DrawError> where
874        V: vertex::MultiVerticesSource<'b>, I: Into<index::IndicesSource<'a>>,
875        U: uniforms::Uniforms;
876
877    /// Blits from the default framebuffer.
878    #[inline]
879    fn blit_from_frame(&self, source_rect: &Rect, target_rect: &BlitTarget,
880                       filter: uniforms::MagnifySamplerFilter)
881    {
882        self.blit_buffers_from_frame(source_rect, target_rect, filter, BlitMask::color())
883    }
884
885    /// Blits from a simple framebuffer.
886    #[inline]
887    fn blit_from_simple_framebuffer(&self, source: &framebuffer::SimpleFrameBuffer<'_>,
888                                    source_rect: &Rect, target_rect: &BlitTarget,
889                                    filter: uniforms::MagnifySamplerFilter)
890    {
891        self.blit_buffers_from_simple_framebuffer(source, source_rect, target_rect, filter,
892                                                  BlitMask::color())
893    }
894
895    /// Blits from a multi-output framebuffer.
896    #[inline]
897    fn blit_from_multioutput_framebuffer(&self, source: &framebuffer::MultiOutputFrameBuffer<'_>,
898                                         source_rect: &Rect, target_rect: &BlitTarget,
899                                         filter: uniforms::MagnifySamplerFilter)
900    {
901        self.blit_buffers_from_multioutput_framebuffer(source, source_rect, target_rect, filter,
902                                                       BlitMask::color())
903    }
904
905    /// Blits from the default framebuffer.
906    fn blit_buffers_from_frame(&self, source_rect: &Rect, target_rect: &BlitTarget,
907                               filter: uniforms::MagnifySamplerFilter, mask: BlitMask);
908
909    /// Blits from a simple framebuffer.
910    fn blit_buffers_from_simple_framebuffer(&self, source: &framebuffer::SimpleFrameBuffer<'_>,
911                                            source_rect: &Rect, target_rect: &BlitTarget,
912                                            filter: uniforms::MagnifySamplerFilter,
913                                            mask: BlitMask);
914
915    /// Blits from a multi-output framebuffer.
916    fn blit_buffers_from_multioutput_framebuffer(&self, source: &framebuffer::MultiOutputFrameBuffer<'_>,
917                                                 source_rect: &Rect, target_rect: &BlitTarget,
918                                                 filter: uniforms::MagnifySamplerFilter,
919                                                 mask: BlitMask);
920
921
922    /// Copies a rectangle of pixels from this surface to another surface.
923    ///
924    /// The `source_rect` defines the area of the source (`self`) that will be copied, and the
925    /// `target_rect` defines the area where the copied image will be pasted. If the source and
926    /// target areas don't have the same dimensions, the image will be resized to match.
927    /// The `filter` parameter is relevant only in this situation.
928    ///
929    /// It is possible for the source and the target to be the same surface. However if the
930    /// rectangles overlap, then the behavior is undefined.
931    ///
932    /// Note that there is no alpha blending, depth/stencil checking, etc. This function just
933    /// copies pixels.
934    fn blit_color<S>(&self, source_rect: &Rect, target: &S, target_rect: &BlitTarget,
935                     filter: uniforms::MagnifySamplerFilter) where S: Surface;
936
937
938    /// Copies the entire surface to a target surface. See `blit_color`.
939    #[inline]
940    fn blit_whole_color_to<S>(&self, target: &S, target_rect: &BlitTarget,
941        filter: uniforms::MagnifySamplerFilter) where S: Surface
942    {
943        let src_dim = self.get_dimensions();
944        let src_rect = Rect { left: 0, bottom: 0, width: src_dim.0 as u32, height: src_dim.1 as u32 };
945        self.blit_color(&src_rect, target, target_rect, filter)
946    }
947
948    /// Copies the entire surface to the entire target. See `blit_color`.
949    #[inline]
950    fn fill<S>(&self, target: &S, filter: uniforms::MagnifySamplerFilter) where S: Surface {
951        let src_dim = self.get_dimensions();
952        let src_rect = Rect { left: 0, bottom: 0, width: src_dim.0 as u32, height: src_dim.1 as u32 };
953        let target_dim = target.get_dimensions();
954        let target_rect = BlitTarget { left: 0, bottom: 0, width: target_dim.0 as i32, height: target_dim.1 as i32 };
955        self.blit_color(&src_rect, target, &target_rect, filter)
956    }
957}
958
959/// Private trait for framebuffer-like objects that provide attachments.
960trait FboAttachments {
961    /// Returns the list of attachments of this FBO, or `None` if it is the default framebuffer.
962    fn get_attachments(&self) -> Option<&fbo::ValidatedAttachments<'_>>;
963}
964
965/// Error that can happen while drawing.
966#[derive(Clone, Debug)]
967pub enum DrawError {
968    /// A depth function has been requested but no depth buffer is available.
969    NoDepthBuffer,
970
971    /// The type of a vertex attribute in the vertices source doesn't match what the
972    /// program requires.
973    AttributeTypeMismatch,
974
975    /// One of the attributes required by the program is missing from the vertex format.
976    ///
977    /// Note that it is perfectly valid to have an attribute in the vertex format that is
978    /// not used by the program.
979    AttributeMissing,
980
981    /// The viewport's dimensions are not supported by the backend.
982    ViewportTooLarge,
983
984    /// The depth range is outside of the `(0, 1)` range.
985    InvalidDepthRange,
986
987    /// The type of a uniform doesn't match what the program requires.
988    UniformTypeMismatch {
989        /// Name of the uniform you are trying to bind.
990        name: String,
991        /// The expected type.
992        expected: uniforms::UniformType,
993    },
994
995    /// Tried to bind a uniform buffer to a single uniform value.
996    UniformBufferToValue {
997        /// Name of the uniform you are trying to bind.
998        name: String,
999    },
1000
1001    /// Tried to bind a single uniform value to a uniform block.
1002    UniformValueToBlock {
1003        /// Name of the uniform you are trying to bind.
1004        name: String,
1005    },
1006
1007    /// The layout of the content of the uniform buffer does not match the layout of the block.
1008    UniformBlockLayoutMismatch {
1009        /// Name of the block you are trying to bind.
1010        name: String,
1011        /// The error giving more details about the mismatch.
1012        err: uniforms::LayoutMismatchError,
1013    },
1014
1015    /// Tried to bind a subroutine uniform like a regular uniform value.
1016    SubroutineUniformToValue {
1017        /// Name of the uniform you are trying to bind.
1018        name: String,
1019    },
1020
1021    /// Not all subroutine uniforms of a shader stage were set.
1022    SubroutineUniformMissing {
1023        /// Shader stage with missing bindings.
1024        stage: program::ShaderStage,
1025        /// The expected number of bindings.
1026        expected_count: usize,
1027        /// The number of bindings defined by the user.
1028        real_count: usize,
1029
1030    },
1031
1032    /// A non-existent subroutine was referenced.
1033    SubroutineNotFound {
1034        /// The stage the subroutine was searched for.
1035        stage: program::ShaderStage,
1036        /// The invalid name of the subroutine.
1037        name: String
1038    },
1039
1040    /// The number of vertices per patch that has been requested is not supported.
1041    UnsupportedVerticesPerPatch,
1042
1043    /// Trying to use tessellation, but this is not supported by the underlying hardware.
1044    TessellationNotSupported,
1045
1046    /// Using a program which contains tessellation shaders, but without submitting patches.
1047    TessellationWithoutPatches,
1048
1049    /// Trying to use a sampler, but they are not supported by the backend.
1050    SamplersNotSupported,
1051
1052    /// When you use instancing, all vertices sources must have the same size.
1053    InstancesCountMismatch,
1054
1055    /// If you don't use indices, then all vertices sources must have the same size.
1056    VerticesSourcesLengthMismatch,
1057
1058    /// You requested not to draw primitives, but this is not supported by the backend.
1059    TransformFeedbackNotSupported,
1060
1061    /// See the documentation of the `draw_parameters` module for infos.
1062    WrongQueryOperation,
1063
1064    /// You requested smoothing, but this is not supported by the backend.
1065    SmoothingNotSupported,
1066
1067    /// The requested provoking vertex is not supported by the backend.
1068    ProvokingVertexNotSupported,
1069
1070    /// Discarding rasterizer output isn't supported by the backend.
1071    RasterizerDiscardNotSupported,
1072
1073    /// Depth clamping isn't supported by the backend.
1074    DepthClampNotSupported,
1075
1076    /// One of the blending parameters is not supported by the backend.
1077    BlendingParameterNotSupported,
1078
1079    /// Restarting indices (multiple objects per draw call) is not supported by the backend.
1080    FixedIndexRestartingNotSupported,
1081
1082    /// Changing the clip volume definition (origin and depth mode) is not supported by the backend.
1083    ClipControlNotSupported,
1084
1085    /// Tried to enable a clip plane that does not exist.
1086    ClipPlaneIndexOutOfBounds,
1087
1088    /// Tried to use too many image units simultaneously
1089    InsufficientImageUnits,
1090}
1091
1092impl Error for DrawError {
1093    fn source(&self) -> Option<&(dyn Error + 'static)> {
1094        use self::DrawError::*;
1095        match *self {
1096            UniformBlockLayoutMismatch { ref err, .. } => Some(err),
1097            _ => None,
1098        }
1099    }
1100}
1101
1102
1103impl fmt::Display for DrawError {
1104    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
1105        use self::DrawError::*;
1106        let desc = match self {
1107            NoDepthBuffer =>
1108                "A depth function has been requested but no depth buffer is available",
1109            AttributeTypeMismatch =>
1110                "The type of a vertex attribute in the vertices source doesn't match what the program requires",
1111            AttributeMissing =>
1112                "One of the attributes required by the program is missing from the vertex format",
1113            ViewportTooLarge =>
1114                "The viewport's dimensions are not supported by the backend",
1115            InvalidDepthRange =>
1116                "The depth range is outside of the `(0, 1)` range",
1117            UniformTypeMismatch { .. } =>
1118                "The type of a uniform doesn't match what the program requires",
1119            UniformBufferToValue { .. } =>
1120                "Tried to bind a uniform buffer to a single uniform value",
1121            UniformValueToBlock { .. } =>
1122                "Tried to bind a single uniform value to a uniform block",
1123            UniformBlockLayoutMismatch { .. } =>
1124                "The layout of the content of the uniform buffer does not match the layout of the block",
1125            SubroutineUniformToValue { .. } =>
1126                "Tried to bind a subroutine uniform like a regular uniform value",
1127            SubroutineUniformMissing { .. } =>
1128                "Not all subroutine uniforms of a shader stage were set",
1129            SubroutineNotFound { .. } =>
1130                "A non-existent subroutine was referenced",
1131            UnsupportedVerticesPerPatch =>
1132                "The number of vertices per patch that has been requested is not supported",
1133            TessellationNotSupported =>
1134                "Trying to use tessellation, but this is not supported by the underlying hardware",
1135            TessellationWithoutPatches =>
1136                "Using a program which contains tessellation shaders, but without submitting patches",
1137            SamplersNotSupported => "
1138                Trying to use a sampler, but they are not supported by the backend",
1139            InstancesCountMismatch =>
1140                "When you use instancing, all vertices sources must have the same size",
1141            VerticesSourcesLengthMismatch =>
1142                "If you don't use indices, then all vertices sources must have the same size",
1143            TransformFeedbackNotSupported =>
1144                "Requested not to draw primitives, but this is not supported by the backend",
1145            WrongQueryOperation =>
1146                "Wrong query operation",
1147            SmoothingNotSupported =>
1148                "Trying to use smoothing, but this is not supported by the backend",
1149            ProvokingVertexNotSupported =>
1150                "Trying to set the provoking vertex, but this is not supported by the backend",
1151            RasterizerDiscardNotSupported =>
1152                "Discarding rasterizer output is not supported by the backend",
1153            DepthClampNotSupported =>
1154                "The depth clamp mode is not supported by the backend",
1155            BlendingParameterNotSupported =>
1156                "One the blending parameters is not supported by the backend",
1157            FixedIndexRestartingNotSupported =>
1158                "Restarting indices (multiple objects per draw call) is not supported by the backend",
1159            ClipControlNotSupported =>
1160                "Changing the clip volume definition (origin and depth mode) is not supported by the backend",
1161            ClipPlaneIndexOutOfBounds =>
1162                "Tried to enable a clip plane that does not exist.",
1163            InsufficientImageUnits =>
1164                "Tried to use more image uniforms that the implementation has support for",
1165        };
1166        match self {
1167            UniformTypeMismatch { ref name, ref expected } =>
1168                write!(
1169                    fmt,
1170                    "{}, got: {:?}, expected: {:?}",
1171                    desc,
1172                    name,
1173                    expected,
1174                ),
1175            UniformBufferToValue { name } =>
1176                write!(
1177                    fmt,
1178                    "{}: {}",
1179                    desc,
1180                    name,
1181                ),
1182            UniformValueToBlock { name } =>
1183                write!(
1184                    fmt,
1185                    "{}: {}",
1186                    desc,
1187                    name,
1188                ),
1189            UniformBlockLayoutMismatch { name, err } =>
1190                write!(
1191                    fmt,
1192                    "{}: {}, caused by {}",
1193                    desc,
1194                    name,
1195                    err,
1196                ),
1197            _ =>
1198                fmt.write_str(desc),
1199        }
1200    }
1201}
1202
1203/// Error that can happen when swapping buffers.
1204#[derive(Debug, Copy, Clone, PartialEq, Eq)]
1205pub enum SwapBuffersError {
1206    /// The OpenGL context has been lost and needs to be recreated. The `Display` and all the
1207    /// objects associated to it (textures, buffers, programs, etc.) need to be recreated from
1208    /// scratch.
1209    ///
1210    /// Operations will have no effect. Functions that read textures, buffers, etc. from OpenGL
1211    /// will return uninitialized data instead.
1212    ///
1213    /// A context loss usually happens on mobile devices when the user puts the application on
1214    /// sleep and wakes it up later. However any OpenGL implementation can theoretically lose the
1215    /// context at any time. Can only happen if calling `is_context_loss_possible()` returns true.
1216    ContextLost,
1217    /// The buffers have already been swapped.
1218    ///
1219    /// This error can be returned when `set_finish()` is called multiple times, or `finish()` is
1220    /// called after `set_finish()`.
1221    AlreadySwapped,
1222}
1223
1224impl Error for SwapBuffersError {}
1225
1226impl fmt::Display for SwapBuffersError {
1227    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
1228        use self::SwapBuffersError::*;
1229        let desc = match *self {
1230            ContextLost =>
1231                "the OpenGL context has been lost and needs to be recreated",
1232            AlreadySwapped =>
1233                "the buffers have already been swapped",
1234        };
1235        fmt.write_str(desc)
1236    }
1237}
1238
1239/// Implementation of `Surface`, targeting the default framebuffer.
1240///
1241/// The back- and front-buffers are swapped when you call `finish`.
1242///
1243/// You **must** call either `finish` or `set_finish` or else the destructor will panic.
1244pub struct Frame {
1245    context: Rc<Context>,
1246    dimensions: (u32, u32),
1247    destroyed: bool,        // TODO: use a linear type instead.
1248}
1249
1250impl Frame {
1251    /// Builds a new `Frame`. Use the `draw` function on `Display` instead of this function.
1252    #[inline]
1253    pub fn new(context: Rc<Context>, dimensions: (u32, u32)) -> Frame {
1254        Frame {
1255            context,
1256            dimensions,
1257            destroyed: false,
1258        }
1259    }
1260
1261    /// Stop drawing, swap the buffers, and consume the Frame.
1262    ///
1263    /// See the documentation of `SwapBuffersError` about what is being returned.
1264    #[inline]
1265    pub fn finish(mut self) -> Result<(), SwapBuffersError> {
1266        self.set_finish()
1267    }
1268
1269    /// Stop drawing, swap the buffers.
1270    ///
1271    /// The Frame can now be dropped regularly.  Calling `finish()` or `set_finish()` again will
1272    /// cause `Err(SwapBuffersError::AlreadySwapped)` to be returned.
1273    #[inline]
1274    pub fn set_finish(&mut self) -> Result<(), SwapBuffersError> {
1275        if self.destroyed {
1276            return Err(SwapBuffersError::AlreadySwapped);
1277        }
1278
1279        self.destroyed = true;
1280        self.context.swap_buffers()
1281    }
1282}
1283
1284impl Surface for Frame {
1285    #[inline]
1286    fn clear(&mut self, rect: Option<&Rect>, color: Option<(f32, f32, f32, f32)>, color_srgb: bool,
1287             depth: Option<f32>, stencil: Option<i32>)
1288    {
1289        ops::clear(&self.context, None, rect, color, color_srgb, depth, stencil);
1290    }
1291
1292    fn get_dimensions(&self) -> (u32, u32) {
1293        self.dimensions
1294    }
1295
1296    fn get_depth_buffer_bits(&self) -> Option<u16> {
1297        self.context.capabilities().depth_bits
1298    }
1299
1300    fn get_stencil_buffer_bits(&self) -> Option<u16> {
1301        self.context.capabilities().stencil_bits
1302    }
1303
1304    fn draw<'a, 'b, V, I, U>(&mut self, vertex_buffer: V,
1305                         index_buffer: I, program: &Program, uniforms: &U,
1306                         draw_parameters: &DrawParameters<'_>) -> Result<(), DrawError>
1307                         where I: Into<index::IndicesSource<'a>>, U: uniforms::Uniforms,
1308                         V: vertex::MultiVerticesSource<'b>
1309    {
1310        if !self.has_depth_buffer() && (draw_parameters.depth.test.requires_depth_buffer() ||
1311                draw_parameters.depth.write)
1312        {
1313            return Err(DrawError::NoDepthBuffer);
1314        }
1315
1316        if let Some(viewport) = draw_parameters.viewport {
1317            if viewport.width > self.context.capabilities().max_viewport_dims.0
1318                    as u32
1319            {
1320                return Err(DrawError::ViewportTooLarge);
1321            }
1322            if viewport.height > self.context.capabilities().max_viewport_dims.1
1323                    as u32
1324            {
1325                return Err(DrawError::ViewportTooLarge);
1326            }
1327        }
1328
1329        ops::draw(&self.context, None, vertex_buffer, index_buffer.into(), program,
1330                  uniforms, draw_parameters, self.dimensions)
1331    }
1332
1333    #[inline]
1334    fn blit_color<S>(&self, source_rect: &Rect, target: &S, target_rect: &BlitTarget,
1335                     filter: uniforms::MagnifySamplerFilter) where S: Surface
1336    {
1337        target.blit_from_frame(source_rect, target_rect, filter)
1338    }
1339
1340    fn blit_buffers_from_frame(&self, source_rect: &Rect, target_rect: &BlitTarget, filter: MagnifySamplerFilter, mask: BlitMask) {
1341        ops::blit(&self.context, None, self.get_attachments(),
1342                  mask.to_glenum(), source_rect, target_rect, filter.to_glenum())
1343    }
1344
1345    fn blit_buffers_from_simple_framebuffer(&self, source: &framebuffer::SimpleFrameBuffer<'_>,
1346                                            source_rect: &Rect, target_rect: &BlitTarget,
1347                                            filter: uniforms::MagnifySamplerFilter,
1348                                            mask: BlitMask) {
1349        ops::blit(&self.context, source.get_attachments(), self.get_attachments(),
1350                  mask.to_glenum(), source_rect, target_rect, filter.to_glenum())
1351    }
1352
1353    fn blit_buffers_from_multioutput_framebuffer(&self,
1354                                                 source: &framebuffer::MultiOutputFrameBuffer<'_>,
1355                                                 source_rect: &Rect, target_rect: &BlitTarget,
1356                                                 filter: uniforms::MagnifySamplerFilter,
1357                                                 mask: BlitMask) {
1358        ops::blit(&self.context, source.get_attachments(), self.get_attachments(),
1359                  mask.to_glenum(), source_rect, target_rect, filter.to_glenum())
1360    }
1361}
1362
1363impl FboAttachments for Frame {
1364    #[inline]
1365    fn get_attachments(&self) -> Option<&fbo::ValidatedAttachments<'_>> {
1366        None
1367    }
1368}
1369
1370impl Drop for Frame {
1371    #[inline]
1372    fn drop(&mut self) {
1373        if !thread::panicking() {
1374            assert!(self.destroyed, "The `Frame` object must be explicitly destroyed \
1375                                     by calling `.finish()`");
1376        }
1377    }
1378}
1379
1380/// Returned during Context creation if the OpenGL implementation is too old.
1381#[derive(Clone, Debug, PartialEq, Eq)]
1382pub struct IncompatibleOpenGl(pub String);
1383
1384impl fmt::Display for IncompatibleOpenGl {
1385    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1386        fmt.write_str("The OpenGL implementation is too old to work with glium")
1387    }
1388}
1389
1390impl Error for IncompatibleOpenGl {}
1391
1392#[allow(dead_code)]
1393#[inline]
1394fn get_gl_error(ctxt: &mut context::CommandContext<'_>) -> Option<&'static str> {
1395    match unsafe { ctxt.gl.GetError() } {
1396        gl::NO_ERROR => None,
1397        gl::INVALID_ENUM => Some("GL_INVALID_ENUM"),
1398        gl::INVALID_VALUE => Some("GL_INVALID_VALUE"),
1399        gl::INVALID_OPERATION => Some("GL_INVALID_OPERATION"),
1400        gl::INVALID_FRAMEBUFFER_OPERATION => Some("GL_INVALID_FRAMEBUFFER_OPERATION"),
1401        gl::OUT_OF_MEMORY => Some("GL_OUT_OF_MEMORY"),
1402        gl::STACK_UNDERFLOW => Some("GL_STACK_UNDERFLOW"),
1403        gl::STACK_OVERFLOW => Some("GL_STACK_OVERFLOW"),
1404        gl::CONTEXT_LOST => Some("GL_CONTEXT_LOST"),
1405        _ => Some("Unknown glGetError return value")
1406    }
1407}
1408