<commit_before>use gl;
use libc;
use std::{ffi, fmt, mem, ptr};
use std::collections::HashMap;
use std::sync::{Arc, Mutex, StaticMutex, MUTEX_INIT};
use std::sync::mpsc::channel;
use {Display, DisplayImpl, GlObject};
use context::{self, CommandContext, GlVersion};
use uniforms::UniformType;
use Handle;

/// Some shader compilers have race-condition issues, so we lock this mutex
/// in the GL thread every time we compile a shader or link a program.
static COMPILER_GLOBAL_LOCK: StaticMutex = MUTEX_INIT;

struct Shader {
    display: Arc<DisplayImpl>,
    id: Handle,
}

impl Drop for Shader {
    fn drop(&mut self) {
        let id = self.id.clone();
        self.display.context.exec(move |: ctxt| {
            unsafe {
                match id {
                    Handle::Id(id) => {
                        assert!(ctxt.version >= &GlVersion(2, 0));
                        ctxt.gl.DeleteShader(id);
                    },
                    Handle::Handle(id) => {
                        assert!(ctxt.extensions.gl_arb_shader_objects);
                        ctxt.gl.DeleteObjectARB(id);
                    }
                }
            }
        });
    }
}

/// Input when creating a program.
pub enum ProgramCreationInput<'a> {
    /// Use GLSL source code.
    SourceCode {
        /// Source code of the vertex shader.
        vertex_shader: &'a str,

        /// Source code of the optional tessellation control shader.
        tessellation_control_shader: Option<&'a str>,

        /// Source code of the optional tessellation evaluation shader.
        tessellation_evaluation_shader: Option<&'a str>,

        /// Source code of the optional geometry shader.
        geometry_shader: Option<&'a str>,

        /// Source code of the fragment shader.
        fragment_shader: &'a str,
    },
}

impl<'a> IntoProgramCreationInput<'a> for ProgramCreationInput<'a> {
    fn into_program_creation_input(self) -> ProgramCreationInput<'a> {
        self
    }
}

/// Traits for objects that can be turned into `ProgramCreationInput`.
pub trait IntoProgramCreationInput<'a> {
    /// Builds the `ProgramCreationInput`.
    fn into_program_creation_input(self) -> ProgramCreationInput<'a>;
}

/// Represents the source code of a program.
pub struct SourceCode<'a> {
    /// Source code of the vertex shader.
    pub vertex_shader: &'a str,

    /// Source code of the optional tessellation control shader.
    pub tessellation_control_shader: Option<&'a str>,

    /// Source code of the optional tessellation evaluation shader.
    pub tessellation_evaluation_shader: Option<&'a str>,

    /// Source code of the optional geometry shader.
    pub geometry_shader: Option<&'a str>,

    /// Source code of the fragment shader.
    pub fragment_shader: &'a str,
}

impl<'a> IntoProgramCreationInput<'a> for SourceCode<'a> {
    fn into_program_creation_input(self) -> ProgramCreationInput<'a> {
        let SourceCode { vertex_shader, fragment_shader, geometry_shader,
                         tessellation_control_shader, tessellation_evaluation_shader } = self;

        ProgramCreationInput::SourceCode {
            vertex_shader: vertex_shader,
            tessellation_control_shader: tessellation_control_shader,
            tessellation_evaluation_shader: tessellation_evaluation_shader,
            geometry_shader: geometry_shader,
            fragment_shader: fragment_shader,
        }
    }
}

/// Represents the compiled binary data of a program.
pub struct Binary {
    /// An implementation-defined format.
    pub format: u32,

    /// The binary data.
    pub content: Vec<u8>,
}

/// A combination of shaders linked together.
pub struct Program {
    display: Arc<DisplayImpl>,
    #[allow(dead_code)]
    shaders: Vec<Shader>,
    id: Handle,
    uniforms: Arc<HashMap<String, Uniform>>,
    uniform_blocks: Arc<HashMap<String, UniformBlock>>,
    attributes: Arc<HashMap<String, Attribute>>,
    frag_data_locations: Mutex<HashMap<String, Option<u32>>>,
    has_tessellation_shaders: bool,
}

/// Information about a uniform (except its name).
#[derive(Debug, Copy)]
#[doc(hidden)]
pub struct Uniform {
    /// The location of the uniform.
    ///
    /// This is internal information, you probably don't need to use it.
    pub location: i32,

    /// Type of the uniform.
    pub ty: UniformType,

    /// If it is an array, the number of elements.
    pub size: Option<usize>,
}

/// Information about a uniform block (except its name).
#[derive(Debug, Clone)]
#[doc(hidden)]
pub struct UniformBlock {
    /// The binding point of the uniform.
    ///
    /// This is internal information, you probably don't need to use it.
    pub binding: i32,

    /// Size in bytes of the data in the block.
    pub size: usize,

    /// List of elements in the block.
    pub members: Vec<UniformBlockMember>,
}

/// Information about a uniform inside a block.
#[derive(Debug, Clone)]
#[doc(hidden)]
pub struct UniformBlockMember {
    /// Name of the member.
    pub name: String,
<commit_msg>Unhide UniformBlock and UniformBlockMember<commit_after>use gl;
use libc;
use std::{ffi, fmt, mem, ptr};
use std::collections::HashMap;
use std::sync::{Arc, Mutex, StaticMutex, MUTEX_INIT};
use std::sync::mpsc::channel;
use {Display, DisplayImpl, GlObject};
use context::{self, CommandContext, GlVersion};
use uniforms::UniformType;
use Handle;

/// Some shader compilers have race-condition issues, so we lock this mutex
/// in the GL thread every time we compile a shader or link a program.
static COMPILER_GLOBAL_LOCK: StaticMutex = MUTEX_INIT;

struct Shader {
    display: Arc<DisplayImpl>,
    id: Handle,
}

impl Drop for Shader {
    fn drop(&mut self) {
        let id = self.id.clone();
        self.display.context.exec(move |: ctxt| {
            unsafe {
                match id {
                    Handle::Id(id) => {
                        assert!(ctxt.version >= &GlVersion(2, 0));
                        ctxt.gl.DeleteShader(id);
                    },
                    Handle::Handle(id) => {
                        assert!(ctxt.extensions.gl_arb_shader_objects);
                        ctxt.gl.DeleteObjectARB(id);
                    }
                }
            }
        });
    }
}

/// Input when creating a program.
pub enum ProgramCreationInput<'a> {
    /// Use GLSL source code.
    SourceCode {
        /// Source code of the vertex shader.
        vertex_shader: &'a str,

        /// Source code of the optional tessellation control shader.
        tessellation_control_shader: Option<&'a str>,

        /// Source code of the optional tessellation evaluation shader.
        tessellation_evaluation_shader: Option<&'a str>,

        /// Source code of the optional geometry shader.
        geometry_shader: Option<&'a str>,

        /// Source code of the fragment shader.
        fragment_shader: &'a str,
    },
}

impl<'a> IntoProgramCreationInput<'a> for ProgramCreationInput<'a> {
    fn into_program_creation_input(self) -> ProgramCreationInput<'a> {
        self
    }
}

/// Traits for objects that can be turned into `ProgramCreationInput`.
pub trait IntoProgramCreationInput<'a> {
    /// Builds the `ProgramCreationInput`.
    fn into_program_creation_input(self) -> ProgramCreationInput<'a>;
}

/// Represents the source code of a program.
pub struct SourceCode<'a> {
    /// Source code of the vertex shader.
    pub vertex_shader: &'a str,

    /// Source code of the optional tessellation control shader.
    pub tessellation_control_shader: Option<&'a str>,

    /// Source code of the optional tessellation evaluation shader.
    pub tessellation_evaluation_shader: Option<&'a str>,

    /// Source code of the optional geometry shader.
    pub geometry_shader: Option<&'a str>,

    /// Source code of the fragment shader.
    pub fragment_shader: &'a str,
}

impl<'a> IntoProgramCreationInput<'a> for SourceCode<'a> {
    fn into_program_creation_input(self) -> ProgramCreationInput<'a> {
        let SourceCode { vertex_shader, fragment_shader, geometry_shader,
                         tessellation_control_shader, tessellation_evaluation_shader } = self;

        ProgramCreationInput::SourceCode {
            vertex_shader: vertex_shader,
            tessellation_control_shader: tessellation_control_shader,
            tessellation_evaluation_shader: tessellation_evaluation_shader,
            geometry_shader: geometry_shader,
            fragment_shader: fragment_shader,
        }
    }
}

/// Represents the compiled binary data of a program.
pub struct Binary {
    /// An implementation-defined format.
    pub format: u32,

    /// The binary data.
    pub content: Vec<u8>,
}

/// A combination of shaders linked together.
pub struct Program {
    display: Arc<DisplayImpl>,
    #[allow(dead_code)]
    shaders: Vec<Shader>,
    id: Handle,
    uniforms: Arc<HashMap<String, Uniform>>,
    uniform_blocks: Arc<HashMap<String, UniformBlock>>,
    attributes: Arc<HashMap<String, Attribute>>,
    frag_data_locations: Mutex<HashMap<String, Option<u32>>>,
    has_tessellation_shaders: bool,
}

/// Information about a uniform (except its name).
#[derive(Debug, Copy)]
#[doc(hidden)]
pub struct Uniform {
    /// The location of the uniform.
    ///
    /// This is internal information, you probably don't need to use it.
    pub location: i32,

    /// Type of the uniform.
    pub ty: UniformType,

    /// If it is an array, the number of elements.
    pub size: Option<usize>,
}

/// Information about a uniform block (except its name).
#[derive(Debug, Clone)]
pub struct UniformBlock {
    /// The binding point of the uniform.
    ///
    /// This is internal information, you probably don't need to use it.
    pub binding: i32,

    /// Size in bytes of the data in the block.
    pub size: usize,

    /// List of elements in the block.
    pub members: Vec<UniformBlockMember>,
}

/// Information about a uniform inside a block.
#[derive(Debug, Clone)]
pub struct UniformBlockMember {
    /// Name of the member.
    pub name: String,

{'fraction_non_alphanumeric': 0.10649945257290734, 'fraction_numerical': 0.002189708370657908, 'mean_word_length': 2.6195965417867435, 'pattern_counts': {'":': 0, '<': 69, '<?xml version=': 0, '>': 81, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7609435', 'n_tokens_mistral': 2924, 'n_tokens_neox': 2897, 'n_words': 895}