Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Isolate GL calls to the device only #480

Merged
merged 3 commits into from Oct 27, 2016
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -6,7 +6,6 @@ use debug_font_data;
use device::{Device, ProgramId, VAOId, TextureId, VertexFormat};
use device::{TextureFilter, VertexUsageHint, TextureTarget};
use euclid::{Matrix4D, Point2D, Size2D, Rect};
use gleam::gl;
use internal_types::{ORTHO_NEAR_PLANE, ORTHO_FAR_PLANE, TextureSampler};
use internal_types::{DebugFontVertex, DebugColorVertex, RenderTargetMode, PackedColor};
use std::f32;
@@ -165,11 +164,10 @@ impl DebugRenderer {
if !self.font_indices.is_empty() ||
!self.line_vertices.is_empty() ||
!self.tri_vertices.is_empty() {
gl::disable(gl::DEPTH_TEST);
gl::enable(gl::BLEND);
gl::blend_equation(gl::FUNC_ADD);
gl::blend_func_separate(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA,
gl::ONE, gl::ONE);

device.disable_depth();
device.set_blend(true);
device.set_blend_mode_alpha();

let projection = Matrix4D::ortho(0.0,
viewport_size.width as f32,
@@ -187,14 +185,14 @@ impl DebugRenderer {
device.update_vao_main_vertices(self.tri_vao,
&self.tri_vertices,
VertexUsageHint::Dynamic);
device.draw_triangles_u32(0, self.tri_indices.len() as gl::GLint);
device.draw_triangles_u32(0, self.tri_indices.len() as i32);

// Lines
device.bind_vao(self.line_vao);
device.update_vao_main_vertices(self.line_vao,
&self.line_vertices,
VertexUsageHint::Dynamic);
device.draw_nonindexed_lines(0, self.line_vertices.len() as gl::GLint);
device.draw_nonindexed_lines(0, self.line_vertices.len() as i32);

// Glyphs
device.bind_program(self.font_program_id, &projection);
@@ -206,7 +204,7 @@ impl DebugRenderer {
device.update_vao_main_vertices(self.font_vao,
&self.font_vertices,
VertexUsageHint::Dynamic);
device.draw_triangles_u32(0, self.font_indices.len() as gl::GLint);
device.draw_triangles_u32(0, self.font_indices.len() as i32);
}

self.font_indices.clear();
@@ -39,6 +39,8 @@ const SHADER_VERSION: &'static str = "#version 300 es\n";

static SHADER_PREAMBLE: &'static str = "shared.glsl";

pub type ViewportDimensions = [u32; 2];

lazy_static! {
pub static ref MAX_TEXTURE_SIZE: gl::GLint = {
gl::get_integer_v(gl::MAX_TEXTURE_SIZE)
@@ -343,29 +345,31 @@ impl TextureId {

impl ProgramId {
fn bind(&self) {
let ProgramId(id) = *self;
gl::use_program(id);
gl::use_program(self.0);
}
}

impl VBOId {
fn bind(&self) {
let VBOId(id) = *self;
gl::bind_buffer(gl::ARRAY_BUFFER, id);
gl::bind_buffer(gl::ARRAY_BUFFER, self.0);
}
}

impl IBOId {
fn bind(&self) {
let IBOId(id) = *self;
gl::bind_buffer(gl::ELEMENT_ARRAY_BUFFER, id);
gl::bind_buffer(gl::ELEMENT_ARRAY_BUFFER, self.0);
}
}

impl UBOId {
fn _bind(&self) {
gl::bind_buffer(gl::UNIFORM_BUFFER, self.0);
}
}

impl FBOId {
fn bind(&self) {
let FBOId(id) = *self;
gl::bind_framebuffer(gl::FRAMEBUFFER, id);
gl::bind_framebuffer(gl::FRAMEBUFFER, self.0);
}
}

@@ -525,6 +529,9 @@ pub struct VBOId(gl::GLuint);
#[derive(PartialEq, Eq, Hash, Debug, Copy, Clone)]
struct IBOId(gl::GLuint);

#[derive(PartialEq, Eq, Hash, Debug, Copy, Clone)]
pub struct UBOId(gl::GLuint);

const MAX_EVENTS_PER_FRAME: usize = 256;
const MAX_PROFILE_FRAMES: usize = 4;

@@ -776,6 +783,11 @@ impl FileWatcherThread {
}
*/

pub struct Capabilities {
pub max_ubo_size: usize,
pub supports_multisampling: bool,
}

pub struct Device {
// device state
bound_textures: [TextureId; 16],
@@ -785,6 +797,9 @@ pub struct Device {
default_fbo: gl::GLuint,
device_pixel_ratio: f32,

// HW or API capabilties
capabilities: Capabilities,

// debug
inside_frame: bool,

@@ -822,6 +837,11 @@ impl Device {
device_pixel_ratio: device_pixel_ratio,
inside_frame: false,

capabilities: Capabilities {
max_ubo_size: gl::get_integer_v(gl::MAX_UNIFORM_BLOCK_SIZE) as usize,
supports_multisampling: false, //TODO
},

bound_textures: [ TextureId::invalid(); 16 ],
bound_program: ProgramId(0),
bound_vao: VAOId(0),
@@ -840,6 +860,10 @@ impl Device {
}
}

pub fn get_capabilities(&self) -> &Capabilities {
&self.capabilities
}

pub fn compile_shader(path: &PathBuf,
shader_type: gl::GLenum,
shader_preamble: &[String],
@@ -921,7 +945,7 @@ impl Device {
}
}

pub fn bind_render_target(&mut self, texture_id: Option<(TextureId, i32)>) {
pub fn bind_render_target(&mut self, texture_id: Option<(TextureId, i32, ViewportDimensions)>) {
debug_assert!(self.inside_frame);

let fbo_id = texture_id.map_or(FBOId(self.default_fbo), |texture_id| {
@@ -932,6 +956,10 @@ impl Device {
self.bound_fbo = fbo_id;
fbo_id.bind();
}

if let Some((_, _, dim)) = texture_id {
gl::viewport(0, 0, dim[0] as gl::GLint, dim[1] as gl::GLint);
}
}

pub fn bind_program(&mut self,
@@ -1179,7 +1207,7 @@ impl Device {
self.init_texture(temp_texture_id, old_width, old_height, format, filter, mode, None);
self.create_fbo_for_texture_if_necessary(temp_texture_id, None);

self.bind_render_target(Some((texture_id, 0)));
self.bind_render_target(Some((texture_id, 0, [1, 1]))); // the viewport doesn't matter here
self.bind_texture(TextureSampler::Color, temp_texture_id);

gl::copy_tex_sub_image_2d(temp_texture_id.target,
@@ -1194,7 +1222,7 @@ impl Device {
self.deinit_texture(texture_id);
self.init_texture(texture_id, new_width, new_height, format, filter, mode, None);
self.create_fbo_for_texture_if_necessary(texture_id, None);
self.bind_render_target(Some((temp_texture_id, 0)));
self.bind_render_target(Some((temp_texture_id, 0, [1, 1]))); // the viewport doesn't matter here
self.bind_texture(TextureSampler::Color, texture_id);

gl::copy_tex_sub_image_2d(texture_id.target,
@@ -1698,6 +1726,80 @@ impl Device {

gl::active_texture(gl::TEXTURE0);
}

pub fn assign_ubo_binding(&self, program_id: ProgramId, name: &str, value: u32) -> u32 {
let index = gl::get_uniform_block_index(program_id.0, name);
gl::uniform_block_binding(program_id.0, index, value);
index
}

pub fn create_ubo<T>(&self, data: &[T], binding: u32) -> UBOId {
let ubo = gl::gen_buffers(1)[0];
gl::bind_buffer(gl::UNIFORM_BUFFER, ubo);
gl::buffer_data(gl::UNIFORM_BUFFER, data, gl::STATIC_DRAW);
gl::bind_buffer_base(gl::UNIFORM_BUFFER, binding, ubo);
UBOId(ubo)
}

pub fn reset_ubo(&self, binding: u32) {
gl::bind_buffer(gl::UNIFORM_BUFFER, 0);
gl::bind_buffer_base(gl::UNIFORM_BUFFER, binding, 0);
}

pub fn delete_buffer(&self, buffer: UBOId) {
gl::delete_buffers(&[buffer.0]);
}

pub fn set_multisample(&self, enable: bool) {
if self.capabilities.supports_multisampling {
if enable {
gl::enable(gl::MULTISAMPLE);
} else {
gl::disable(gl::MULTISAMPLE);
}
}
}

pub fn clear_color(&self, c: [f32; 4]) {
gl::clear_color(c[0], c[1], c[2], c[3]);
gl::clear(gl::COLOR_BUFFER_BIT);
}

pub fn disable_depth(&self) {
gl::disable(gl::DEPTH_TEST);
}

pub fn disable_depth_write(&self) {
gl::depth_mask(false);
}

pub fn disable_stencil(&self) {
gl::disable(gl::STENCIL);
}

pub fn disable_scissor(&self) {
gl::disable(gl::SCISSOR_TEST);
}

pub fn set_blend(&self, enable: bool) {
if enable {
gl::enable(gl::BLEND);
} else {
gl::disable(gl::BLEND);
}
}

pub fn set_blend_mode_premultiplied_alpha(&self) {
gl::blend_func(gl::SRC_ALPHA, gl::ZERO);
gl::blend_equation(gl::FUNC_ADD);
}

pub fn set_blend_mode_alpha(&self) {
//gl::blend_func(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA);
gl::blend_func_separate(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA,
gl::ONE, gl::ONE);
gl::blend_equation(gl::FUNC_ADD);
}
}

impl Drop for Device {
@@ -16,14 +16,14 @@ use std::sync::{Arc, Mutex};
use std::sync::mpsc::Sender;
use texture_cache::TextureCache;
use webrender_traits::{ApiMsg, AuxiliaryLists, BuiltDisplayList, IdNamespace};
use webrender_traits::{RenderNotifier, WebGLContextId, RenderDispatcher};
use webrender_traits::{RenderNotifier, RenderDispatcher, WebGLCommand, WebGLContextId};
use batch::new_id;
use device::TextureId;
use record;
use tiling::FrameBuilderConfig;
use gleam::gl;
use offscreen_gl_context::GLContextDispatcher;


pub struct RenderBackend {
api_rx: IpcReceiver<ApiMsg>,
payload_rx: IpcBytesReceiver,
@@ -335,7 +335,7 @@ impl RenderBackend {
// incur minimal cost.
for (_, webgl_context) in &self.webgl_contexts {
webgl_context.make_current();
gl::flush();
webgl_context.apply_command(WebGLCommand::Flush);
webgl_context.unbind();
}

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.