--- a/gfx/doc/README.webrender
+++ b/gfx/doc/README.webrender
@@ -74,9 +74,9 @@ there is another crate in m-c called moz
the same folder to store its rust dependencies. If one of the libraries that is
required by both mozjs_sys and webrender is updated without updating the other
project's Cargo.lock file, that results in build bustage.
This means that any time you do this sort of manual update of packages, you need
to make sure that mozjs_sys also has its Cargo.lock file updated if needed, hence
the need to run the cargo update command in js/src as well. Hopefully this will
be resolved soon.
-Latest Commit: 7da345684dc29ca60f29cb79acc8d99c474ec477
+Latest Commit: dab674d09a51ff5253da0797d129bf29b25896e5
--- a/gfx/webrender/Cargo.toml
+++ b/gfx/webrender/Cargo.toml
@@ -13,21 +13,21 @@ profiler = ["thread_profiler/thread_prof
[dependencies]
app_units = "0.4"
bincode = "1.0.0-alpha2"
bit-set = "0.4"
byteorder = "1.0"
euclid = "0.11"
fnv = "1.0"
-gleam = "0.2.30"
+gleam = "0.4.1"
lazy_static = "0.2"
log = "0.3"
num-traits = "0.1.32"
-offscreen_gl_context = {version = "0.6", features = ["serde", "osmesa"]}
+offscreen_gl_context = {version = "0.8.0", features = ["serde", "osmesa"]}
time = "0.1"
threadpool = "1.3.2"
webrender_traits = {path = "../webrender_traits"}
bitflags = "0.7"
gamma-lut = "0.1"
thread_profiler = "0.1.1"
[dev-dependencies]
--- a/gfx/webrender/res/prim_shared.glsl
+++ b/gfx/webrender/res/prim_shared.glsl
@@ -498,62 +498,114 @@ VertexInfo write_vertex(RectWithSize ins
#ifdef WR_FEATURE_TRANSFORM
struct TransformVertexInfo {
vec3 local_pos;
vec2 screen_pos;
vec4 clipped_local_rect;
};
+float cross2(vec2 v0, vec2 v1) {
+ return v0.x * v1.y - v0.y * v1.x;
+}
+
+// Return intersection of line (p0,p1) and line (p2,p3)
+vec2 intersect_lines(vec2 p0, vec2 p1, vec2 p2, vec2 p3) {
+ vec2 d0 = p0 - p1;
+ vec2 d1 = p2 - p3;
+
+ float s0 = cross2(p0, p1);
+ float s1 = cross2(p2, p3);
+
+ float d = cross2(d0, d1);
+ float nx = s0 * d1.x - d0.x * s1;
+ float ny = s0 * d1.y - d0.y * s1;
+
+ return vec2(nx / d, ny / d);
+}
+
TransformVertexInfo write_transform_vertex(RectWithSize instance_rect,
RectWithSize local_clip_rect,
float z,
Layer layer,
AlphaBatchTask task) {
- vec2 lp0_base = instance_rect.p0;
- vec2 lp1_base = instance_rect.p0 + instance_rect.size;
+ RectWithEndpoint local_rect = to_rect_with_endpoint(instance_rect);
+
+ vec2 current_local_pos, prev_local_pos, next_local_pos;
- vec2 lp0 = clamp_rect(clamp_rect(lp0_base, local_clip_rect),
- layer.local_clip_rect);
- vec2 lp1 = clamp_rect(clamp_rect(lp1_base, local_clip_rect),
- layer.local_clip_rect);
+ // Select the current vertex and the previous/next vertices,
+ // based on the vertex ID that is known based on the instance rect.
+ switch (gl_VertexID) {
+ case 0:
+ current_local_pos = vec2(local_rect.p0.x, local_rect.p0.y);
+ next_local_pos = vec2(local_rect.p0.x, local_rect.p1.y);
+ prev_local_pos = vec2(local_rect.p1.x, local_rect.p0.y);
+ break;
+ case 1:
+ current_local_pos = vec2(local_rect.p1.x, local_rect.p0.y);
+ next_local_pos = vec2(local_rect.p0.x, local_rect.p0.y);
+ prev_local_pos = vec2(local_rect.p1.x, local_rect.p1.y);
+ break;
+ case 2:
+ current_local_pos = vec2(local_rect.p0.x, local_rect.p1.y);
+ prev_local_pos = vec2(local_rect.p0.x, local_rect.p0.y);
+ next_local_pos = vec2(local_rect.p1.x, local_rect.p1.y);
+ break;
+ case 3:
+ current_local_pos = vec2(local_rect.p1.x, local_rect.p1.y);
+ prev_local_pos = vec2(local_rect.p0.x, local_rect.p1.y);
+ next_local_pos = vec2(local_rect.p1.x, local_rect.p0.y);
+ break;
+ }
- vec4 clipped_local_rect = vec4(lp0, lp1 - lp0);
-
- vec2 p0 = lp0;
- vec2 p1 = vec2(lp1.x, lp0.y);
- vec2 p2 = vec2(lp0.x, lp1.y);
- vec2 p3 = lp1;
+ // Transform them to world space
+ vec4 current_world_pos = layer.transform * vec4(current_local_pos, 0.0, 1.0);
+ vec4 prev_world_pos = layer.transform * vec4(prev_local_pos, 0.0, 1.0);
+ vec4 next_world_pos = layer.transform * vec4(next_local_pos, 0.0, 1.0);
- vec4 t0 = layer.transform * vec4(p0, 0, 1);
- vec4 t1 = layer.transform * vec4(p1, 0, 1);
- vec4 t2 = layer.transform * vec4(p2, 0, 1);
- vec4 t3 = layer.transform * vec4(p3, 0, 1);
+ // Convert to device space
+ vec2 current_device_pos = uDevicePixelRatio * current_world_pos.xy / current_world_pos.w;
+ vec2 prev_device_pos = uDevicePixelRatio * prev_world_pos.xy / prev_world_pos.w;
+ vec2 next_device_pos = uDevicePixelRatio * next_world_pos.xy / next_world_pos.w;
- vec2 tp0 = t0.xy / t0.w;
- vec2 tp1 = t1.xy / t1.w;
- vec2 tp2 = t2.xy / t2.w;
- vec2 tp3 = t3.xy / t3.w;
+ // Get the normals of each of the vectors between the current and next/prev vertices.
+ const float amount = 2.0;
+ vec2 dir_prev = normalize(current_device_pos - prev_device_pos);
+ vec2 dir_next = normalize(current_device_pos - next_device_pos);
+ vec2 norm_prev = vec2(-dir_prev.y, dir_prev.x);
+ vec2 norm_next = vec2( dir_next.y, -dir_next.x);
- // compute a CSS space aligned bounding box
- vec2 min_pos = uDevicePixelRatio * min(min(tp0.xy, tp1.xy), min(tp2.xy, tp3.xy));
- vec2 max_pos = uDevicePixelRatio * max(max(tp0.xy, tp1.xy), max(tp2.xy, tp3.xy));
+ // Push those lines out along the normal by a specific amount of device pixels.
+ vec2 adjusted_prev_p0 = current_device_pos + norm_prev * amount;
+ vec2 adjusted_prev_p1 = prev_device_pos + norm_prev * amount;
+ vec2 adjusted_next_p0 = current_device_pos + norm_next * amount;
+ vec2 adjusted_next_p1 = next_device_pos + norm_next * amount;
- // compute the device space position of this vertex
- vec2 device_pos = mix(min_pos, max_pos, aPosition.xy);
+ // Intersect those adjusted lines to find the actual vertex position.
+ vec2 device_pos = intersect_lines(adjusted_prev_p0,
+ adjusted_prev_p1,
+ adjusted_next_p0,
+ adjusted_next_p1);
- // compute the point position in side the layer, in CSS space
- vec4 layer_pos = get_layer_pos(device_pos / uDevicePixelRatio, layer);
+ // Calculate the snap amount based on the first vertex as a reference point.
+ vec4 world_p0 = layer.transform * vec4(local_rect.p0, 0.0, 1.0);
+ vec2 device_p0 = uDevicePixelRatio * world_p0.xy / world_p0.w;
+ vec2 snap_delta = device_p0 - floor(device_p0 + 0.5);
- // apply the task offset
- vec2 final_pos = device_pos - task.screen_space_origin + task.render_target_origin;
+ // Apply offsets for the render task to get correct screen location.
+ vec2 final_pos = device_pos -
+ snap_delta -
+ task.screen_space_origin +
+ task.render_target_origin;
gl_Position = uTransform * vec4(final_pos, z, 1.0);
- return TransformVertexInfo(layer_pos.xyw, device_pos, clipped_local_rect);
+ vec4 layer_pos = get_layer_pos(device_pos / uDevicePixelRatio, layer);
+
+ return TransformVertexInfo(layer_pos.xyw, device_pos, vec4(instance_rect.p0, instance_rect.size));
}
#endif //WR_FEATURE_TRANSFORM
struct ResourceRect {
vec4 uv_rect;
};
@@ -658,30 +710,45 @@ void write_clip(vec2 global_pos, ClipAre
vec2 texture_size = vec2(textureSize(sCache, 0).xy);
vec2 uv = global_pos + area.task_bounds.xy - area.screen_origin_target_index.xy;
vClipMaskUvBounds = area.task_bounds / texture_size.xyxy;
vClipMaskUv = vec3(uv / texture_size, area.screen_origin_target_index.z);
}
#endif //WR_VERTEX_SHADER
#ifdef WR_FRAGMENT_SHADER
-float distance_from_rect(vec2 p, vec2 origin, vec2 size) {
- vec2 clamped = clamp(p, origin, origin + size);
- return distance(clamped, p);
+float signed_distance_rect(vec2 pos, vec2 p0, vec2 p1) {
+ vec2 d = max(p0 - pos, pos - p1);
+ return length(max(vec2(0.0), d)) + min(0.0, max(d.x, d.y));
}
vec2 init_transform_fs(vec3 local_pos, vec4 local_rect, out float fragment_alpha) {
fragment_alpha = 1.0;
vec2 pos = local_pos.xy / local_pos.z;
- float border_distance = distance_from_rect(pos, local_rect.xy, local_rect.zw);
- if (border_distance != 0.0) {
- float delta = length(fwidth(local_pos.xy));
- fragment_alpha = 1.0 - smoothstep(0.0, 1.0, border_distance / delta * 2.0);
- }
+ // Because the local rect is placed on whole coordinates, but the interpolation
+ // occurs at pixel centers, we need to offset the signed distance by that amount.
+ // In the simple case of no zoom, and no transform, this is 0.5. However, we
+ // need to scale this by the amount that the local rect is changing by per
+ // fragment, based on the current zoom and transform.
+ vec2 fw = fwidth(pos.xy);
+ vec2 dxdy = 0.5 * fw;
+
+ // Now get the actual signed distance. Inset the local rect by the offset amount
+ // above to get correct distance values. This ensures that we only apply
+ // anti-aliasing when the fragment has partial coverage.
+ float d = signed_distance_rect(pos,
+ local_rect.xy + dxdy,
+ local_rect.xy + local_rect.zw - dxdy);
+
+ // Find the appropriate distance to apply the AA smoothstep over.
+ float afwidth = 0.5 / length(fw);
+
+ // Only apply AA to fragments outside the signed distance field.
+ fragment_alpha = 1.0 - smoothstep(0.0, afwidth, d);
return pos;
}
float do_clip() {
// anything outside of the mask is considered transparent
bvec4 inside = lessThanEqual(
vec4(vClipMaskUvBounds.xy, vClipMaskUv.xy),
--- a/gfx/webrender/res/ps_border.fs.glsl
+++ b/gfx/webrender/res/ps_border.fs.glsl
@@ -239,26 +239,26 @@ vec4 draw_double_edge(float pos,
alpha += alpha_for_solid_border(pos, 0.0, one_third_width, pixels_per_fragment);
return get_fragment_color(distance_from_mix_line, pixels_per_fragment) * vec4(1.0, 1.0, 1.0, alpha);
}
vec4 draw_double_edge_vertical(vec2 local_pos,
float distance_from_mix_line,
float pixels_per_fragment) {
// Get our position within this specific segment
- float position = local_pos.x - vLocalRect.x;
- return draw_double_edge(position, vLocalRect.z, distance_from_mix_line, pixels_per_fragment);
+ float position = abs(local_pos.x - vRefPoint.x);
+ return draw_double_edge(position, abs(vPieceRect.z), distance_from_mix_line, pixels_per_fragment);
}
vec4 draw_double_edge_horizontal(vec2 local_pos,
float distance_from_mix_line,
float pixels_per_fragment) {
// Get our position within this specific segment
- float position = local_pos.y - vLocalRect.y;
- return draw_double_edge(position, vLocalRect.w, distance_from_mix_line, pixels_per_fragment);
+ float position = abs(local_pos.y - vRefPoint.y);
+ return draw_double_edge(position, abs(vPieceRect.w), distance_from_mix_line, pixels_per_fragment);
}
vec4 draw_double_edge_corner_with_radius(vec2 local_pos,
float distance_from_mix_line,
float pixels_per_fragment) {
float total_border_width = vRadii.x - vRadii.z;
float one_third_width = total_border_width / 3.0;
float total_border_height = vRadii.y - vRadii.w;
--- a/gfx/webrender/src/debug_render.rs
+++ b/gfx/webrender/src/debug_render.rs
@@ -156,17 +156,17 @@ impl DebugRenderer {
let color1 = PackedColor::from_color(color1);
self.line_vertices.push(DebugColorVertex::new(x0 as f32, y0 as f32, color0));
self.line_vertices.push(DebugColorVertex::new(x1 as f32, y1 as f32, color1));
}
pub fn render(&mut self,
device: &mut Device,
viewport_size: &DeviceUintSize) {
- let _gm = GpuMarker::new("debug");
+ let _gm = GpuMarker::new(device.rc_gl(), "debug");
device.disable_depth();
device.set_blend(true);
device.set_blend_mode_alpha();
let projection = Matrix4D::ortho(0.0,
viewport_size.width as f32,
viewport_size.height as f32,
0.0,
--- a/gfx/webrender/src/device.rs
+++ b/gfx/webrender/src/device.rs
@@ -12,41 +12,38 @@ use internal_types::{DebugFontVertex, De
use super::shader_source;
use std::collections::HashMap;
use std::fs::File;
use std::hash::BuildHasherDefault;
use std::io::Read;
use std::iter::repeat;
use std::mem;
use std::path::PathBuf;
+use std::rc::Rc;
//use std::sync::mpsc::{channel, Sender};
//use std::thread;
use webrender_traits::{ColorF, ImageFormat};
use webrender_traits::{DeviceIntPoint, DeviceIntRect, DeviceIntSize, DeviceUintSize};
#[derive(Debug, Copy, Clone)]
pub struct FrameId(usize);
#[cfg(not(any(target_arch = "arm", target_arch = "aarch64")))]
const GL_FORMAT_A: gl::GLuint = gl::RED;
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
const GL_FORMAT_A: gl::GLuint = gl::ALPHA;
-#[cfg(any(target_os = "windows", all(unix, not(target_os = "android"))))]
-const GL_FORMAT_BGRA: gl::GLuint = gl::BGRA;
+const GL_FORMAT_BGRA_GL: gl::GLuint = gl::BGRA;
-#[cfg(target_os = "android")]
-const GL_FORMAT_BGRA: gl::GLuint = gl::BGRA_EXT;
+const GL_FORMAT_BGRA_GLES: gl::GLuint = gl::BGRA_EXT;
-#[cfg(not(any(target_arch = "arm", target_arch = "aarch64")))]
-const SHADER_VERSION: &'static str = "#version 150\n";
+const SHADER_VERSION_GL: &'static str = "#version 150\n";
-#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
-const SHADER_VERSION: &'static str = "#version 300 es\n";
+const SHADER_VERSION_GLES: &'static str = "#version 300 es\n";
static SHADER_PREAMBLE: &'static str = "shared";
#[repr(u32)]
pub enum DepthFunction {
Less = gl::LESS,
}
@@ -73,16 +70,38 @@ pub enum VertexFormat {
Clip,
}
enum FBOTarget {
Read,
Draw,
}
+fn get_gl_format_bgra(gl: &gl::Gl) -> gl::GLuint {
+ match gl.get_type() {
+ gl::GlType::Gl => {
+ GL_FORMAT_BGRA_GL
+ }
+ gl::GlType::Gles => {
+ GL_FORMAT_BGRA_GLES
+ }
+ }
+}
+
+fn get_shader_version(gl: &gl::Gl) -> &'static str {
+ match gl.get_type() {
+ gl::GlType::Gl => {
+ SHADER_VERSION_GL
+ }
+ gl::GlType::Gles => {
+ SHADER_VERSION_GLES
+ }
+ }
+}
+
fn get_optional_shader_source(shader_name: &str, base_path: &Option<PathBuf>) -> Option<String> {
if let Some(ref base) = *base_path {
let shader_path = base.join(&format!("{}.glsl", shader_name));
if shader_path.exists() {
let mut source = String::new();
File::open(&shader_path).unwrap().read_to_string(&mut source).unwrap();
return Some(source);
}
@@ -96,198 +115,198 @@ fn get_shader_source(shader_name: &str,
.expect(&format!("Couldn't get required shader: {}", shader_name))
}
pub trait FileWatcherHandler : Send {
fn file_changed(&self, path: PathBuf);
}
impl VertexFormat {
- fn bind(&self, main: VBOId, instance: VBOId, offset: gl::GLuint, instance_stride: gl::GLint) {
- main.bind();
+ fn bind(&self, gl: &gl::Gl, main: VBOId, instance: VBOId, offset: gl::GLuint, instance_stride: gl::GLint) {
+ main.bind(gl);
match *self {
VertexFormat::DebugFont => {
- gl::enable_vertex_attrib_array(VertexAttribute::Position as gl::GLuint);
- gl::enable_vertex_attrib_array(VertexAttribute::Color as gl::GLuint);
- gl::enable_vertex_attrib_array(VertexAttribute::ColorTexCoord as gl::GLuint);
+ gl.enable_vertex_attrib_array(VertexAttribute::Position as gl::GLuint);
+ gl.enable_vertex_attrib_array(VertexAttribute::Color as gl::GLuint);
+ gl.enable_vertex_attrib_array(VertexAttribute::ColorTexCoord as gl::GLuint);
- gl::vertex_attrib_divisor(VertexAttribute::Position as gl::GLuint, 0);
- gl::vertex_attrib_divisor(VertexAttribute::Color as gl::GLuint, 0);
- gl::vertex_attrib_divisor(VertexAttribute::ColorTexCoord as gl::GLuint, 0);
+ gl.vertex_attrib_divisor(VertexAttribute::Position as gl::GLuint, 0);
+ gl.vertex_attrib_divisor(VertexAttribute::Color as gl::GLuint, 0);
+ gl.vertex_attrib_divisor(VertexAttribute::ColorTexCoord as gl::GLuint, 0);
let vertex_stride = mem::size_of::<DebugFontVertex>() as gl::GLuint;
- gl::vertex_attrib_pointer(VertexAttribute::Position as gl::GLuint,
+ gl.vertex_attrib_pointer(VertexAttribute::Position as gl::GLuint,
2,
gl::FLOAT,
false,
vertex_stride as gl::GLint,
0 + vertex_stride * offset);
- gl::vertex_attrib_pointer(VertexAttribute::Color as gl::GLuint,
+ gl.vertex_attrib_pointer(VertexAttribute::Color as gl::GLuint,
4,
gl::UNSIGNED_BYTE,
true,
vertex_stride as gl::GLint,
8 + vertex_stride * offset);
- gl::vertex_attrib_pointer(VertexAttribute::ColorTexCoord as gl::GLuint,
+ gl.vertex_attrib_pointer(VertexAttribute::ColorTexCoord as gl::GLuint,
2,
gl::FLOAT,
false,
vertex_stride as gl::GLint,
12 + vertex_stride * offset);
}
VertexFormat::DebugColor => {
- gl::enable_vertex_attrib_array(VertexAttribute::Position as gl::GLuint);
- gl::enable_vertex_attrib_array(VertexAttribute::Color as gl::GLuint);
+ gl.enable_vertex_attrib_array(VertexAttribute::Position as gl::GLuint);
+ gl.enable_vertex_attrib_array(VertexAttribute::Color as gl::GLuint);
- gl::vertex_attrib_divisor(VertexAttribute::Position as gl::GLuint, 0);
- gl::vertex_attrib_divisor(VertexAttribute::Color as gl::GLuint, 0);
+ gl.vertex_attrib_divisor(VertexAttribute::Position as gl::GLuint, 0);
+ gl.vertex_attrib_divisor(VertexAttribute::Color as gl::GLuint, 0);
let vertex_stride = mem::size_of::<DebugColorVertex>() as gl::GLuint;
- gl::vertex_attrib_pointer(VertexAttribute::Position as gl::GLuint,
+ gl.vertex_attrib_pointer(VertexAttribute::Position as gl::GLuint,
2,
gl::FLOAT,
false,
vertex_stride as gl::GLint,
0 + vertex_stride * offset);
- gl::vertex_attrib_pointer(VertexAttribute::Color as gl::GLuint,
+ gl.vertex_attrib_pointer(VertexAttribute::Color as gl::GLuint,
4,
gl::UNSIGNED_BYTE,
true,
vertex_stride as gl::GLint,
8 + vertex_stride * offset);
}
VertexFormat::Rectangles |
VertexFormat::Triangles => {
let vertex_stride = mem::size_of::<PackedVertex>() as gl::GLuint;
- gl::enable_vertex_attrib_array(VertexAttribute::Position as gl::GLuint);
- gl::vertex_attrib_divisor(VertexAttribute::Position as gl::GLuint, 0);
+ gl.enable_vertex_attrib_array(VertexAttribute::Position as gl::GLuint);
+ gl.vertex_attrib_divisor(VertexAttribute::Position as gl::GLuint, 0);
- gl::vertex_attrib_pointer(VertexAttribute::Position as gl::GLuint,
+ gl.vertex_attrib_pointer(VertexAttribute::Position as gl::GLuint,
2,
gl::FLOAT,
false,
vertex_stride as gl::GLint,
0);
- instance.bind();
+ instance.bind(gl);
let mut offset = 0;
for &attrib in [VertexAttribute::GlobalPrimId,
VertexAttribute::PrimitiveAddress,
VertexAttribute::TaskIndex,
VertexAttribute::ClipTaskIndex,
VertexAttribute::LayerIndex,
VertexAttribute::ElementIndex,
VertexAttribute::ZIndex,
].into_iter() {
- gl::enable_vertex_attrib_array(attrib as gl::GLuint);
- gl::vertex_attrib_divisor(attrib as gl::GLuint, 1);
- gl::vertex_attrib_i_pointer(attrib as gl::GLuint,
+ gl.enable_vertex_attrib_array(attrib as gl::GLuint);
+ gl.vertex_attrib_divisor(attrib as gl::GLuint, 1);
+ gl.vertex_attrib_i_pointer(attrib as gl::GLuint,
1,
gl::INT,
instance_stride,
offset);
offset += 4;
}
- gl::enable_vertex_attrib_array(VertexAttribute::UserData as gl::GLuint);
- gl::vertex_attrib_divisor(VertexAttribute::UserData as gl::GLuint, 1);
- gl::vertex_attrib_i_pointer(VertexAttribute::UserData as gl::GLuint,
+ gl.enable_vertex_attrib_array(VertexAttribute::UserData as gl::GLuint);
+ gl.vertex_attrib_divisor(VertexAttribute::UserData as gl::GLuint, 1);
+ gl.vertex_attrib_i_pointer(VertexAttribute::UserData as gl::GLuint,
2,
gl::INT,
instance_stride,
offset);
}
VertexFormat::Clear => {
let vertex_stride = mem::size_of::<PackedVertex>() as gl::GLuint;
- gl::enable_vertex_attrib_array(ClearAttribute::Position as gl::GLuint);
- gl::vertex_attrib_divisor(ClearAttribute::Position as gl::GLuint, 0);
+ gl.enable_vertex_attrib_array(ClearAttribute::Position as gl::GLuint);
+ gl.vertex_attrib_divisor(ClearAttribute::Position as gl::GLuint, 0);
- gl::vertex_attrib_pointer(ClearAttribute::Position as gl::GLuint,
+ gl.vertex_attrib_pointer(ClearAttribute::Position as gl::GLuint,
2,
gl::FLOAT,
false,
vertex_stride as gl::GLint,
0);
- instance.bind();
+ instance.bind(gl);
- gl::enable_vertex_attrib_array(ClearAttribute::Rectangle as gl::GLuint);
- gl::vertex_attrib_divisor(ClearAttribute::Rectangle as gl::GLuint, 1);
- gl::vertex_attrib_i_pointer(ClearAttribute::Rectangle as gl::GLuint,
+ gl.enable_vertex_attrib_array(ClearAttribute::Rectangle as gl::GLuint);
+ gl.vertex_attrib_divisor(ClearAttribute::Rectangle as gl::GLuint, 1);
+ gl.vertex_attrib_i_pointer(ClearAttribute::Rectangle as gl::GLuint,
4,
gl::INT,
instance_stride,
0);
}
VertexFormat::Blur => {
let vertex_stride = mem::size_of::<PackedVertex>() as gl::GLuint;
- gl::enable_vertex_attrib_array(BlurAttribute::Position as gl::GLuint);
- gl::vertex_attrib_divisor(BlurAttribute::Position as gl::GLuint, 0);
+ gl.enable_vertex_attrib_array(BlurAttribute::Position as gl::GLuint);
+ gl.vertex_attrib_divisor(BlurAttribute::Position as gl::GLuint, 0);
- gl::vertex_attrib_pointer(BlurAttribute::Position as gl::GLuint,
+ gl.vertex_attrib_pointer(BlurAttribute::Position as gl::GLuint,
2,
gl::FLOAT,
false,
vertex_stride as gl::GLint,
0);
- instance.bind();
+ instance.bind(gl);
for (i, &attrib) in [BlurAttribute::RenderTaskIndex,
BlurAttribute::SourceTaskIndex,
BlurAttribute::Direction,
].into_iter().enumerate() {
- gl::enable_vertex_attrib_array(attrib as gl::GLuint);
- gl::vertex_attrib_divisor(attrib as gl::GLuint, 1);
- gl::vertex_attrib_i_pointer(attrib as gl::GLuint,
+ gl.enable_vertex_attrib_array(attrib as gl::GLuint);
+ gl.vertex_attrib_divisor(attrib as gl::GLuint, 1);
+ gl.vertex_attrib_i_pointer(attrib as gl::GLuint,
1,
gl::INT,
instance_stride,
(i * 4) as gl::GLuint);
}
}
VertexFormat::Clip => {
let vertex_stride = mem::size_of::<PackedVertex>() as gl::GLuint;
- gl::enable_vertex_attrib_array(ClipAttribute::Position as gl::GLuint);
- gl::vertex_attrib_divisor(ClipAttribute::Position as gl::GLuint, 0);
+ gl.enable_vertex_attrib_array(ClipAttribute::Position as gl::GLuint);
+ gl.vertex_attrib_divisor(ClipAttribute::Position as gl::GLuint, 0);
- gl::vertex_attrib_pointer(ClipAttribute::Position as gl::GLuint,
+ gl.vertex_attrib_pointer(ClipAttribute::Position as gl::GLuint,
2,
gl::FLOAT,
false,
vertex_stride as gl::GLint,
0);
- instance.bind();
+ instance.bind(gl);
for (i, &attrib) in [ClipAttribute::RenderTaskIndex,
ClipAttribute::LayerIndex,
ClipAttribute::DataIndex,
ClipAttribute::SegmentIndex,
].into_iter().enumerate() {
- gl::enable_vertex_attrib_array(attrib as gl::GLuint);
- gl::vertex_attrib_divisor(attrib as gl::GLuint, 1);
- gl::vertex_attrib_i_pointer(attrib as gl::GLuint,
+ gl.enable_vertex_attrib_array(attrib as gl::GLuint);
+ gl.vertex_attrib_divisor(attrib as gl::GLuint, 1);
+ gl.vertex_attrib_i_pointer(attrib as gl::GLuint,
1,
gl::INT,
instance_stride,
(i * 4) as gl::GLuint);
}
}
}
}
}
impl TextureId {
- pub fn bind(&self) {
- gl::bind_texture(self.target, self.name);
+ pub fn bind(&self, gl: &gl::Gl) {
+ gl.bind_texture(self.target, self.name);
}
pub fn new(name: gl::GLuint) -> TextureId {
TextureId {
name: name,
target: gl::TEXTURE_2D,
}
}
@@ -298,167 +317,170 @@ impl TextureId {
target: gl::TEXTURE_2D,
}
}
pub fn is_valid(&self) -> bool { *self != TextureId::invalid() }
}
impl ProgramId {
- fn bind(&self) {
- gl::use_program(self.0);
+ fn bind(&self, gl: &gl::Gl) {
+ gl.use_program(self.0);
}
}
impl VBOId {
- fn bind(&self) {
- gl::bind_buffer(gl::ARRAY_BUFFER, self.0);
+ fn bind(&self, gl: &gl::Gl) {
+ gl.bind_buffer(gl::ARRAY_BUFFER, self.0);
}
}
impl IBOId {
- fn bind(&self) {
- gl::bind_buffer(gl::ELEMENT_ARRAY_BUFFER, self.0);
+ fn bind(&self, gl: &gl::Gl) {
+ gl.bind_buffer(gl::ELEMENT_ARRAY_BUFFER, self.0);
}
}
impl UBOId {
- fn _bind(&self) {
- gl::bind_buffer(gl::UNIFORM_BUFFER, self.0);
+ fn _bind(&self, gl: &gl::Gl) {
+ gl.bind_buffer(gl::UNIFORM_BUFFER, self.0);
}
}
impl FBOId {
- fn bind(&self, target: FBOTarget) {
+ fn bind(&self, gl: &gl::Gl, target: FBOTarget) {
let target = match target {
FBOTarget::Read => gl::READ_FRAMEBUFFER,
FBOTarget::Draw => gl::DRAW_FRAMEBUFFER,
};
- gl::bind_framebuffer(target, self.0);
+ gl.bind_framebuffer(target, self.0);
}
}
struct Texture {
+ gl: Rc<gl::Gl>,
id: gl::GLuint,
format: ImageFormat,
width: u32,
height: u32,
filter: TextureFilter,
mode: RenderTargetMode,
fbo_ids: Vec<FBOId>,
}
impl Drop for Texture {
fn drop(&mut self) {
if !self.fbo_ids.is_empty() {
let fbo_ids: Vec<_> = self.fbo_ids.iter().map(|&FBOId(fbo_id)| fbo_id).collect();
- gl::delete_framebuffers(&fbo_ids[..]);
+ self.gl.delete_framebuffers(&fbo_ids[..]);
}
- gl::delete_textures(&[self.id]);
+ self.gl.delete_textures(&[self.id]);
}
}
struct Program {
+ gl: Rc<gl::Gl>,
id: gl::GLuint,
u_transform: gl::GLint,
u_device_pixel_ratio: gl::GLint,
name: String,
vs_source: String,
fs_source: String,
prefix: Option<String>,
vs_id: Option<gl::GLuint>,
fs_id: Option<gl::GLuint>,
}
impl Program {
fn attach_and_bind_shaders(&mut self,
vs_id: gl::GLuint,
fs_id: gl::GLuint,
vertex_format: VertexFormat) -> Result<(), ShaderError> {
- gl::attach_shader(self.id, vs_id);
- gl::attach_shader(self.id, fs_id);
+ self.gl.attach_shader(self.id, vs_id);
+ self.gl.attach_shader(self.id, fs_id);
match vertex_format {
VertexFormat::Triangles | VertexFormat::Rectangles |
VertexFormat::DebugFont | VertexFormat::DebugColor => {
- gl::bind_attrib_location(self.id, VertexAttribute::Position as gl::GLuint, "aPosition");
- gl::bind_attrib_location(self.id, VertexAttribute::Color as gl::GLuint, "aColor");
- gl::bind_attrib_location(self.id, VertexAttribute::ColorTexCoord as gl::GLuint, "aColorTexCoord");
+ self.gl.bind_attrib_location(self.id, VertexAttribute::Position as gl::GLuint, "aPosition");
+ self.gl.bind_attrib_location(self.id, VertexAttribute::Color as gl::GLuint, "aColor");
+ self.gl.bind_attrib_location(self.id, VertexAttribute::ColorTexCoord as gl::GLuint, "aColorTexCoord");
- gl::bind_attrib_location(self.id, VertexAttribute::GlobalPrimId as gl::GLuint, "aGlobalPrimId");
- gl::bind_attrib_location(self.id, VertexAttribute::PrimitiveAddress as gl::GLuint, "aPrimitiveAddress");
- gl::bind_attrib_location(self.id, VertexAttribute::TaskIndex as gl::GLuint, "aTaskIndex");
- gl::bind_attrib_location(self.id, VertexAttribute::ClipTaskIndex as gl::GLuint, "aClipTaskIndex");
- gl::bind_attrib_location(self.id, VertexAttribute::LayerIndex as gl::GLuint, "aLayerIndex");
- gl::bind_attrib_location(self.id, VertexAttribute::ElementIndex as gl::GLuint, "aElementIndex");
- gl::bind_attrib_location(self.id, VertexAttribute::UserData as gl::GLuint, "aUserData");
- gl::bind_attrib_location(self.id, VertexAttribute::ZIndex as gl::GLuint, "aZIndex");
+ self.gl.bind_attrib_location(self.id, VertexAttribute::GlobalPrimId as gl::GLuint, "aGlobalPrimId");
+ self.gl.bind_attrib_location(self.id, VertexAttribute::PrimitiveAddress as gl::GLuint, "aPrimitiveAddress");
+ self.gl.bind_attrib_location(self.id, VertexAttribute::TaskIndex as gl::GLuint, "aTaskIndex");
+ self.gl.bind_attrib_location(self.id, VertexAttribute::ClipTaskIndex as gl::GLuint, "aClipTaskIndex");
+ self.gl.bind_attrib_location(self.id, VertexAttribute::LayerIndex as gl::GLuint, "aLayerIndex");
+ self.gl.bind_attrib_location(self.id, VertexAttribute::ElementIndex as gl::GLuint, "aElementIndex");
+ self.gl.bind_attrib_location(self.id, VertexAttribute::UserData as gl::GLuint, "aUserData");
+ self.gl.bind_attrib_location(self.id, VertexAttribute::ZIndex as gl::GLuint, "aZIndex");
}
VertexFormat::Clear => {
- gl::bind_attrib_location(self.id, ClearAttribute::Position as gl::GLuint, "aPosition");
- gl::bind_attrib_location(self.id, ClearAttribute::Rectangle as gl::GLuint, "aClearRectangle");
+ self.gl.bind_attrib_location(self.id, ClearAttribute::Position as gl::GLuint, "aPosition");
+ self.gl.bind_attrib_location(self.id, ClearAttribute::Rectangle as gl::GLuint, "aClearRectangle");
}
VertexFormat::Blur => {
- gl::bind_attrib_location(self.id, BlurAttribute::Position as gl::GLuint, "aPosition");
- gl::bind_attrib_location(self.id, BlurAttribute::RenderTaskIndex as gl::GLuint, "aBlurRenderTaskIndex");
- gl::bind_attrib_location(self.id, BlurAttribute::SourceTaskIndex as gl::GLuint, "aBlurSourceTaskIndex");
- gl::bind_attrib_location(self.id, BlurAttribute::Direction as gl::GLuint, "aBlurDirection");
+ self.gl.bind_attrib_location(self.id, BlurAttribute::Position as gl::GLuint, "aPosition");
+ self.gl.bind_attrib_location(self.id, BlurAttribute::RenderTaskIndex as gl::GLuint, "aBlurRenderTaskIndex");
+ self.gl.bind_attrib_location(self.id, BlurAttribute::SourceTaskIndex as gl::GLuint, "aBlurSourceTaskIndex");
+ self.gl.bind_attrib_location(self.id, BlurAttribute::Direction as gl::GLuint, "aBlurDirection");
}
VertexFormat::Clip => {
- gl::bind_attrib_location(self.id, ClipAttribute::Position as gl::GLuint, "aPosition");
- gl::bind_attrib_location(self.id, ClipAttribute::RenderTaskIndex as gl::GLuint, "aClipRenderTaskIndex");
- gl::bind_attrib_location(self.id, ClipAttribute::LayerIndex as gl::GLuint, "aClipLayerIndex");
- gl::bind_attrib_location(self.id, ClipAttribute::DataIndex as gl::GLuint, "aClipDataIndex");
- gl::bind_attrib_location(self.id, ClipAttribute::SegmentIndex as gl::GLuint, "aClipSegmentIndex");
+ self.gl.bind_attrib_location(self.id, ClipAttribute::Position as gl::GLuint, "aPosition");
+ self.gl.bind_attrib_location(self.id, ClipAttribute::RenderTaskIndex as gl::GLuint, "aClipRenderTaskIndex");
+ self.gl.bind_attrib_location(self.id, ClipAttribute::LayerIndex as gl::GLuint, "aClipLayerIndex");
+ self.gl.bind_attrib_location(self.id, ClipAttribute::DataIndex as gl::GLuint, "aClipDataIndex");
+ self.gl.bind_attrib_location(self.id, ClipAttribute::SegmentIndex as gl::GLuint, "aClipSegmentIndex");
}
}
- gl::link_program(self.id);
- if gl::get_program_iv(self.id, gl::LINK_STATUS) == (0 as gl::GLint) {
- let error_log = gl::get_program_info_log(self.id);
+ self.gl.link_program(self.id);
+ if self.gl.get_program_iv(self.id, gl::LINK_STATUS) == (0 as gl::GLint) {
+ let error_log = self.gl.get_program_info_log(self.id);
println!("Failed to link shader program: {}", error_log);
- gl::detach_shader(self.id, vs_id);
- gl::detach_shader(self.id, fs_id);
+ self.gl.detach_shader(self.id, vs_id);
+ self.gl.detach_shader(self.id, fs_id);
return Err(ShaderError::Link(error_log));
}
Ok(())
}
}
impl Drop for Program {
fn drop(&mut self) {
- gl::delete_program(self.id);
+ self.gl.delete_program(self.id);
}
}
struct VAO {
+ gl: Rc<gl::Gl>,
id: gl::GLuint,
ibo_id: IBOId,
main_vbo_id: VBOId,
instance_vbo_id: VBOId,
instance_stride: gl::GLint,
owns_indices: bool,
owns_vertices: bool,
owns_instances: bool,
}
impl Drop for VAO {
fn drop(&mut self) {
- gl::delete_vertex_arrays(&[self.id]);
+ self.gl.delete_vertex_arrays(&[self.id]);
if self.owns_indices {
// todo(gw): maybe make these their own type with hashmap?
- gl::delete_buffers(&[self.ibo_id.0]);
+ self.gl.delete_buffers(&[self.ibo_id.0]);
}
if self.owns_vertices {
- gl::delete_buffers(&[self.main_vbo_id.0]);
+ self.gl.delete_buffers(&[self.main_vbo_id.0]);
}
if self.owns_instances {
- gl::delete_buffers(&[self.instance_vbo_id.0])
+ self.gl.delete_buffers(&[self.instance_vbo_id.0])
}
}
}
#[derive(PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Copy, Clone)]
pub struct TextureId {
name: gl::GLuint,
target: gl::GLuint,
@@ -491,142 +513,167 @@ pub trait NamedTag {
#[derive(Debug, Clone)]
pub struct GpuSample<T> {
pub tag: T,
pub time_ns: u64,
}
pub struct GpuFrameProfile<T> {
+ gl: Rc<gl::Gl>,
queries: Vec<gl::GLuint>,
samples: Vec<GpuSample<T>>,
next_query: usize,
pending_query: gl::GLuint,
frame_id: FrameId,
}
impl<T> GpuFrameProfile<T> {
- #[cfg(not(target_os = "android"))]
- fn new() -> GpuFrameProfile<T> {
- let queries = gl::gen_queries(MAX_EVENTS_PER_FRAME as gl::GLint);
-
- GpuFrameProfile {
- queries: queries,
- samples: Vec::new(),
- next_query: 0,
- pending_query: 0,
- frame_id: FrameId(0),
- }
- }
-
- #[cfg(target_os = "android")]
- fn new() -> GpuFrameProfile<T> {
- GpuFrameProfile {
- queries: Vec::new(),
- samples: Vec::new(),
- next_query: 0,
- pending_query: 0,
- frame_id: FrameId(0),
+ fn new(gl: Rc<gl::Gl>) -> GpuFrameProfile<T> {
+ match gl.get_type() {
+ gl::GlType::Gl => {
+ let queries = gl.gen_queries(MAX_EVENTS_PER_FRAME as gl::GLint);
+ GpuFrameProfile {
+ gl: gl,
+ queries: queries,
+ samples: Vec::new(),
+ next_query: 0,
+ pending_query: 0,
+ frame_id: FrameId(0),
+ }
+ }
+ gl::GlType::Gles => {
+ GpuFrameProfile {
+ gl: gl,
+ queries: Vec::new(),
+ samples: Vec::new(),
+ next_query: 0,
+ pending_query: 0,
+ frame_id: FrameId(0),
+ }
+ }
}
}
fn begin_frame(&mut self, frame_id: FrameId) {
self.frame_id = frame_id;
self.next_query = 0;
self.pending_query = 0;
self.samples.clear();
}
- #[cfg(not(target_os = "android"))]
fn end_frame(&mut self) {
- if self.pending_query != 0 {
- gl::end_query(gl::TIME_ELAPSED);
+ match self.gl.get_type() {
+ gl::GlType::Gl => {
+ if self.pending_query != 0 {
+ self.gl.end_query(gl::TIME_ELAPSED);
+ }
+ }
+ gl::GlType::Gles => {},
}
}
- #[cfg(target_os = "android")]
- fn end_frame(&mut self) {
+ fn add_marker(&mut self, tag: T) -> GpuMarker
+ where T: NamedTag {
+ match self.gl.get_type() {
+ gl::GlType::Gl => {
+ self.add_marker_gl(tag)
+ }
+ gl::GlType::Gles => {
+ self.add_marker_gles(tag)
+ }
+ }
}
- #[cfg(not(target_os = "android"))]
- fn add_marker(&mut self, tag: T) -> GpuMarker
+ fn add_marker_gl(&mut self, tag: T) -> GpuMarker
where T: NamedTag {
if self.pending_query != 0 {
- gl::end_query(gl::TIME_ELAPSED);
+ self.gl.end_query(gl::TIME_ELAPSED);
}
- let marker = GpuMarker::new(tag.get_label());
+ let marker = GpuMarker::new(&self.gl, tag.get_label());
if self.next_query < MAX_EVENTS_PER_FRAME {
self.pending_query = self.queries[self.next_query];
- gl::begin_query(gl::TIME_ELAPSED, self.pending_query);
+ self.gl.begin_query(gl::TIME_ELAPSED, self.pending_query);
self.samples.push(GpuSample {
tag: tag,
time_ns: 0,
});
} else {
self.pending_query = 0;
}
self.next_query += 1;
marker
}
- #[cfg(target_os = "android")]
- fn add_marker(&mut self, tag: T) {
+ fn add_marker_gles(&mut self, tag: T) -> GpuMarker
+ where T: NamedTag {
+ let marker = GpuMarker::new(&self.gl, tag.get_label());
self.samples.push(GpuSample {
tag: tag,
time_ns: 0,
});
+ marker
}
fn is_valid(&self) -> bool {
self.next_query > 0 && self.next_query <= MAX_EVENTS_PER_FRAME
}
- #[cfg(not(target_os = "android"))]
fn build_samples(&mut self) -> Vec<GpuSample<T>> {
+ match self.gl.get_type() {
+ gl::GlType::Gl => {
+ self.build_samples_gl()
+ }
+ gl::GlType::Gles => {
+ self.build_samples_gles()
+ }
+ }
+ }
+
+ fn build_samples_gl(&mut self) -> Vec<GpuSample<T>> {
for (index, sample) in self.samples.iter_mut().enumerate() {
- sample.time_ns = gl::get_query_object_ui64v(self.queries[index], gl::QUERY_RESULT)
+ sample.time_ns = self.gl.get_query_object_ui64v(self.queries[index], gl::QUERY_RESULT)
}
mem::replace(&mut self.samples, Vec::new())
}
- #[cfg(target_os = "android")]
- fn build_samples(&mut self) -> Vec<GpuSample<T>> {
+ fn build_samples_gles(&mut self) -> Vec<GpuSample<T>> {
mem::replace(&mut self.samples, Vec::new())
}
}
impl<T> Drop for GpuFrameProfile<T> {
- #[cfg(not(target_os = "android"))]
fn drop(&mut self) {
- gl::delete_queries(&self.queries);
- }
-
- #[cfg(target_os = "android")]
- fn drop(&mut self) {
+ match self.gl.get_type() {
+ gl::GlType::Gl => {
+ self.gl.delete_queries(&self.queries);
+ }
+ gl::GlType::Gles => {},
+ }
}
}
pub struct GpuProfiler<T> {
frames: [GpuFrameProfile<T>; MAX_PROFILE_FRAMES],
next_frame: usize,
}
impl<T> GpuProfiler<T> {
- pub fn new() -> GpuProfiler<T> {
+ pub fn new(gl: &Rc<gl::Gl>) -> GpuProfiler<T> {
GpuProfiler {
next_frame: 0,
frames: [
- GpuFrameProfile::new(),
- GpuFrameProfile::new(),
- GpuFrameProfile::new(),
- GpuFrameProfile::new(),
+ GpuFrameProfile::new(gl.clone()),
+ GpuFrameProfile::new(gl.clone()),
+ GpuFrameProfile::new(gl.clone()),
+ GpuFrameProfile::new(gl.clone()),
],
}
}
pub fn build_samples(&mut self) -> Option<(FrameId, Vec<GpuSample<T>>)> {
let frame = &mut self.frames[self.next_frame];
if frame.is_valid() {
Some((frame.frame_id, frame.build_samples()))
@@ -641,57 +688,63 @@ impl<T> GpuProfiler<T> {
}
pub fn end_frame(&mut self) {
let frame = &mut self.frames[self.next_frame];
frame.end_frame();
self.next_frame = (self.next_frame + 1) % MAX_PROFILE_FRAMES;
}
- #[cfg(not(target_os = "android"))]
pub fn add_marker(&mut self, tag: T) -> GpuMarker
where T: NamedTag {
self.frames[self.next_frame].add_marker(tag)
}
-
- #[cfg(target_os = "android")]
- pub fn add_marker(&mut self, tag: T) {
- self.frames[self.next_frame].add_marker(tag)
- }
}
#[must_use]
-pub struct GpuMarker(());
-
-#[cfg(any(target_arch="arm", target_arch="aarch64"))]
-impl GpuMarker {
- pub fn new(_: &str) -> GpuMarker {
- GpuMarker(())
- }
-
- pub fn fire(_: &str) {}
+pub struct GpuMarker{
+ gl: Rc<gl::Gl>,
}
-
-#[cfg(not(any(target_arch="arm", target_arch="aarch64")))]
impl GpuMarker {
- pub fn new(message: &str) -> GpuMarker {
- gl::push_group_marker_ext(message);
- GpuMarker(())
+ pub fn new(gl: &Rc<gl::Gl>, message: &str) -> GpuMarker {
+ match gl.get_type() {
+ gl::GlType::Gl => {
+ gl.push_group_marker_ext(message);
+ GpuMarker{
+ gl: gl.clone(),
+ }
+ }
+ gl::GlType::Gles => {
+ GpuMarker{
+ gl: gl.clone(),
+ }
+ }
+ }
}
- pub fn fire(message: &str) {
- gl::insert_event_marker_ext(message);
+ pub fn fire(gl: &gl::Gl, message: &str) {
+ match gl.get_type() {
+ gl::GlType::Gl => {
+ gl.insert_event_marker_ext(message);
+ }
+ gl::GlType::Gles => {},
+ }
}
}
#[cfg(not(any(target_arch="arm", target_arch="aarch64")))]
impl Drop for GpuMarker {
fn drop(&mut self) {
- gl::pop_group_marker_ext();
+ match self.gl.get_type() {
+ gl::GlType::Gl => {
+ self.gl.pop_group_marker_ext();
+ }
+ gl::GlType::Gles => {},
+ }
}
}
#[derive(Debug, Copy, Clone)]
pub enum VertexUsageHint {
Static,
Dynamic,
Stream,
@@ -792,16 +845,17 @@ pub struct Capabilities {
#[derive(Clone, Debug)]
pub enum ShaderError {
Compilation(String, String), // name, error mssage
Link(String), // error message
}
pub struct Device {
+ gl: Rc<gl::Gl>,
// device state
bound_textures: [TextureId; 16],
bound_program: ProgramId,
bound_vao: VAOId,
bound_read_fbo: FBOId,
bound_draw_fbo: FBOId,
default_read_fbo: gl::GLuint,
default_draw_fbo: gl::GLuint,
@@ -830,32 +884,37 @@ pub struct Device {
max_texture_size: u32,
// Frame counter. This is used to map between CPU
// frames and GPU frames.
frame_id: FrameId,
}
impl Device {
- pub fn new(resource_override_path: Option<PathBuf>,
+ pub fn new(gl: Rc<gl::Gl>,
+ resource_override_path: Option<PathBuf>,
_file_changed_handler: Box<FileWatcherHandler>) -> Device {
//let file_watcher = FileWatcherThread::new(file_changed_handler);
let shader_preamble = get_shader_source(SHADER_PREAMBLE, &resource_override_path);
//file_watcher.add_watch(resource_path);
+ let max_ubo_size = gl.get_integer_v(gl::MAX_UNIFORM_BLOCK_SIZE) as usize;
+ let max_texture_size = gl.get_integer_v(gl::MAX_TEXTURE_SIZE) as u32;
+
Device {
+ gl: gl,
resource_override_path: resource_override_path,
// This is initialized to 1 by default, but it is set
// every frame by the call to begin_frame().
device_pixel_ratio: 1.0,
inside_frame: false,
capabilities: Capabilities {
- max_ubo_size: gl::get_integer_v(gl::MAX_UNIFORM_BLOCK_SIZE) as usize,
+ max_ubo_size: max_ubo_size,
supports_multisampling: false, //TODO
},
bound_textures: [ TextureId::invalid(); 16 ],
bound_program: ProgramId(0),
bound_vao: VAOId(0),
bound_read_fbo: FBOId(0),
bound_draw_fbo: FBOId(0),
@@ -866,179 +925,189 @@ impl Device {
programs: HashMap::with_hasher(Default::default()),
vaos: HashMap::with_hasher(Default::default()),
shader_preamble: shader_preamble,
next_vao_id: 1,
//file_watcher: file_watcher,
- max_texture_size: gl::get_integer_v(gl::MAX_TEXTURE_SIZE) as u32,
+ max_texture_size: max_texture_size,
frame_id: FrameId(0),
}
}
+ pub fn gl(&self) -> &gl::Gl {
+ &*self.gl
+ }
+
+ pub fn rc_gl(&self) -> &Rc<gl::Gl> {
+ &self.gl
+ }
+
pub fn max_texture_size(&self) -> u32 {
self.max_texture_size
}
pub fn get_capabilities(&self) -> &Capabilities {
&self.capabilities
}
- pub fn compile_shader(name: &str,
+ pub fn compile_shader(gl: &gl::Gl,
+ name: &str,
source_str: &str,
shader_type: gl::GLenum,
shader_preamble: &[String])
-> Result<gl::GLuint, ShaderError> {
debug!("compile {:?}", name);
let mut s = String::new();
- s.push_str(SHADER_VERSION);
+ s.push_str(get_shader_version(gl));
for prefix in shader_preamble {
s.push_str(&prefix);
}
s.push_str(source_str);
- let id = gl::create_shader(shader_type);
+ let id = gl.create_shader(shader_type);
let mut source = Vec::new();
source.extend_from_slice(s.as_bytes());
- gl::shader_source(id, &[&source[..]]);
- gl::compile_shader(id);
- let log = gl::get_shader_info_log(id);
- if gl::get_shader_iv(id, gl::COMPILE_STATUS) == (0 as gl::GLint) {
+ gl.shader_source(id, &[&source[..]]);
+ gl.compile_shader(id);
+ let log = gl.get_shader_info_log(id);
+ if gl.get_shader_iv(id, gl::COMPILE_STATUS) == (0 as gl::GLint) {
println!("Failed to compile shader: {:?}\n{}", name, log);
Err(ShaderError::Compilation(name.to_string(), log))
} else {
if !log.is_empty() {
println!("Warnings detected on shader: {:?}\n{}", name, log);
}
Ok(id)
}
}
pub fn begin_frame(&mut self, device_pixel_ratio: f32) -> FrameId {
debug_assert!(!self.inside_frame);
self.inside_frame = true;
self.device_pixel_ratio = device_pixel_ratio;
// Retrive the currently set FBO.
- let default_read_fbo = gl::get_integer_v(gl::READ_FRAMEBUFFER_BINDING);
+ let default_read_fbo = self.gl.get_integer_v(gl::READ_FRAMEBUFFER_BINDING);
self.default_read_fbo = default_read_fbo as gl::GLuint;
- let default_draw_fbo = gl::get_integer_v(gl::DRAW_FRAMEBUFFER_BINDING);
+ let default_draw_fbo = self.gl.get_integer_v(gl::DRAW_FRAMEBUFFER_BINDING);
self.default_draw_fbo = default_draw_fbo as gl::GLuint;
// Texture state
for i in 0..self.bound_textures.len() {
self.bound_textures[i] = TextureId::invalid();
- gl::active_texture(gl::TEXTURE0 + i as gl::GLuint);
- gl::bind_texture(gl::TEXTURE_2D, 0);
+ self.gl.active_texture(gl::TEXTURE0 + i as gl::GLuint);
+ self.gl.bind_texture(gl::TEXTURE_2D, 0);
}
// Shader state
self.bound_program = ProgramId(0);
- gl::use_program(0);
+ self.gl.use_program(0);
// Vertex state
self.bound_vao = VAOId(0);
self.clear_vertex_array();
// FBO state
self.bound_read_fbo = FBOId(self.default_read_fbo);
self.bound_draw_fbo = FBOId(self.default_draw_fbo);
// Pixel op state
- gl::pixel_store_i(gl::UNPACK_ALIGNMENT, 1);
+ self.gl.pixel_store_i(gl::UNPACK_ALIGNMENT, 1);
// Default is sampler 0, always
- gl::active_texture(gl::TEXTURE0);
+ self.gl.active_texture(gl::TEXTURE0);
self.frame_id
}
pub fn bind_texture(&mut self,
sampler: TextureSampler,
texture_id: TextureId) {
debug_assert!(self.inside_frame);
let sampler_index = sampler as usize;
if self.bound_textures[sampler_index] != texture_id {
self.bound_textures[sampler_index] = texture_id;
- gl::active_texture(gl::TEXTURE0 + sampler_index as gl::GLuint);
- texture_id.bind();
- gl::active_texture(gl::TEXTURE0);
+ self.gl.active_texture(gl::TEXTURE0 + sampler_index as gl::GLuint);
+ texture_id.bind(self.gl());
+ self.gl.active_texture(gl::TEXTURE0);
}
}
pub fn bind_read_target(&mut self, texture_id: Option<(TextureId, i32)>) {
debug_assert!(self.inside_frame);
let fbo_id = texture_id.map_or(FBOId(self.default_read_fbo), |texture_id| {
self.textures.get(&texture_id.0).unwrap().fbo_ids[texture_id.1 as usize]
});
if self.bound_read_fbo != fbo_id {
self.bound_read_fbo = fbo_id;
- fbo_id.bind(FBOTarget::Read);
+ fbo_id.bind(self.gl(), FBOTarget::Read);
}
}
pub fn bind_draw_target(&mut self,
texture_id: Option<(TextureId, i32)>,
dimensions: Option<DeviceUintSize>) {
debug_assert!(self.inside_frame);
let fbo_id = texture_id.map_or(FBOId(self.default_draw_fbo), |texture_id| {
self.textures.get(&texture_id.0).unwrap().fbo_ids[texture_id.1 as usize]
});
if self.bound_draw_fbo != fbo_id {
self.bound_draw_fbo = fbo_id;
- fbo_id.bind(FBOTarget::Draw);
+ fbo_id.bind(self.gl(), FBOTarget::Draw);
}
if let Some(dimensions) = dimensions {
- gl::viewport(0, 0, dimensions.width as gl::GLint, dimensions.height as gl::GLint);
+ self.gl.viewport(0, 0, dimensions.width as gl::GLint, dimensions.height as gl::GLint);
}
}
pub fn bind_program(&mut self,
program_id: ProgramId,
projection: &Matrix4D<f32>) {
debug_assert!(self.inside_frame);
if self.bound_program != program_id {
self.bound_program = program_id;
- program_id.bind();
+ program_id.bind(&*self.gl);
}
let program = self.programs.get(&program_id).unwrap();
self.set_uniforms(program,
projection,
self.device_pixel_ratio);
}
pub fn create_texture_ids(&mut self,
count: i32,
target: TextureTarget) -> Vec<TextureId> {
- let id_list = gl::gen_textures(count);
+ let id_list = self.gl.gen_textures(count);
let mut texture_ids = Vec::new();
let target = match target {
TextureTarget::Default => gl::TEXTURE_2D,
TextureTarget::Array => gl::TEXTURE_2D_ARRAY,
};
for id in id_list {
let texture_id = TextureId {
name: id,
target: target,
};
let texture = Texture {
+ gl: self.gl.clone(),
id: id,
width: 0,
height: 0,
format: ImageFormat::Invalid,
filter: TextureFilter::Nearest,
mode: RenderTargetMode::None,
fbo_ids: vec![],
};
@@ -1062,39 +1131,39 @@ impl Device {
TextureFilter::Nearest => {
gl::NEAREST
}
TextureFilter::Linear => {
gl::LINEAR
}
};
- gl::tex_parameter_i(target, gl::TEXTURE_MAG_FILTER, filter as gl::GLint);
- gl::tex_parameter_i(target, gl::TEXTURE_MIN_FILTER, filter as gl::GLint);
+ self.gl.tex_parameter_i(target, gl::TEXTURE_MAG_FILTER, filter as gl::GLint);
+ self.gl.tex_parameter_i(target, gl::TEXTURE_MIN_FILTER, filter as gl::GLint);
- gl::tex_parameter_i(target, gl::TEXTURE_WRAP_S, gl::CLAMP_TO_EDGE as gl::GLint);
- gl::tex_parameter_i(target, gl::TEXTURE_WRAP_T, gl::CLAMP_TO_EDGE as gl::GLint);
+ self.gl.tex_parameter_i(target, gl::TEXTURE_WRAP_S, gl::CLAMP_TO_EDGE as gl::GLint);
+ self.gl.tex_parameter_i(target, gl::TEXTURE_WRAP_T, gl::CLAMP_TO_EDGE as gl::GLint);
}
fn upload_texture_image(&mut self,
target: gl::GLuint,
width: u32,
height: u32,
internal_format: u32,
format: u32,
type_: u32,
pixels: Option<&[u8]>) {
- gl::tex_image_2d(target,
- 0,
- internal_format as gl::GLint,
- width as gl::GLint, height as gl::GLint,
- 0,
- format,
- type_,
- pixels);
+ self.gl.tex_image_2d(target,
+ 0,
+ internal_format as gl::GLint,
+ width as gl::GLint, height as gl::GLint,
+ 0,
+ format,
+ type_,
+ pixels);
}
pub fn init_texture(&mut self,
texture_id: TextureId,
width: u32,
height: u32,
format: ImageFormat,
filter: TextureFilter,
@@ -1106,17 +1175,17 @@ impl Device {
let texture = self.textures.get_mut(&texture_id).expect("Didn't find texture!");
texture.format = format;
texture.width = width;
texture.height = height;
texture.filter = filter;
texture.mode = mode;
}
- let (internal_format, gl_format) = gl_texture_formats_for_image_format(format);
+ let (internal_format, gl_format) = gl_texture_formats_for_image_format(self.gl(), format);
let type_ = gl_type_for_texture_format(format);
match mode {
RenderTargetMode::SimpleRenderTarget => {
self.bind_texture(DEFAULT_TEXTURE, texture_id);
self.set_texture_parameters(texture_id.target, filter);
self.upload_texture_image(texture_id.target,
width,
@@ -1171,79 +1240,79 @@ impl Device {
// If we have enough layers allocated already, just use them.
// TODO(gw): Probably worth removing some after a while if
// there is a surplus?
let current_layer_count = texture.fbo_ids.len() as i32;
if current_layer_count >= layer_count {
return;
}
- let (internal_format, gl_format) = gl_texture_formats_for_image_format(texture.format);
+ let (internal_format, gl_format) = gl_texture_formats_for_image_format(&*self.gl, texture.format);
let type_ = gl_type_for_texture_format(texture.format);
- gl::tex_image_3d(texture_id.target,
- 0,
- internal_format as gl::GLint,
- texture.width as gl::GLint,
- texture.height as gl::GLint,
- layer_count,
- 0,
- gl_format,
- type_,
- None);
+ self.gl.tex_image_3d(texture_id.target,
+ 0,
+ internal_format as gl::GLint,
+ texture.width as gl::GLint,
+ texture.height as gl::GLint,
+ layer_count,
+ 0,
+ gl_format,
+ type_,
+ None);
let needed_layer_count = layer_count - current_layer_count;
- let new_fbos = gl::gen_framebuffers(needed_layer_count);
+ let new_fbos = self.gl.gen_framebuffers(needed_layer_count);
texture.fbo_ids.extend(new_fbos.into_iter().map(|id| FBOId(id)));
for (fbo_index, fbo_id) in texture.fbo_ids.iter().enumerate() {
- gl::bind_framebuffer(gl::FRAMEBUFFER, fbo_id.0);
- gl::framebuffer_texture_layer(gl::FRAMEBUFFER,
- gl::COLOR_ATTACHMENT0,
- texture_id.name,
- 0,
- fbo_index as gl::GLint);
+ self.gl.bind_framebuffer(gl::FRAMEBUFFER, fbo_id.0);
+ self.gl.framebuffer_texture_layer(gl::FRAMEBUFFER,
+ gl::COLOR_ATTACHMENT0,
+ texture_id.name,
+ 0,
+ fbo_index as gl::GLint);
// TODO(gw): Share depth render buffer between FBOs to
// save memory!
// TODO(gw): Free these renderbuffers on exit!
- let renderbuffer_ids = gl::gen_renderbuffers(1);
+ let renderbuffer_ids = self.gl.gen_renderbuffers(1);
let depth_rb = renderbuffer_ids[0];
- gl::bind_renderbuffer(gl::RENDERBUFFER, depth_rb);
- gl::renderbuffer_storage(gl::RENDERBUFFER,
- gl::DEPTH_COMPONENT24,
- texture.width as gl::GLsizei,
- texture.height as gl::GLsizei);
- gl::framebuffer_renderbuffer(gl::FRAMEBUFFER,
- gl::DEPTH_ATTACHMENT,
- gl::RENDERBUFFER,
- depth_rb);
+ self.gl.bind_renderbuffer(gl::RENDERBUFFER, depth_rb);
+ self.gl.renderbuffer_storage(gl::RENDERBUFFER,
+ gl::DEPTH_COMPONENT24,
+ texture.width as gl::GLsizei,
+ texture.height as gl::GLsizei);
+ self.gl.framebuffer_renderbuffer(gl::FRAMEBUFFER,
+ gl::DEPTH_ATTACHMENT,
+ gl::RENDERBUFFER,
+ depth_rb);
}
}
None => {
debug_assert!(texture.fbo_ids.len() == 0 || texture.fbo_ids.len() == 1);
if texture.fbo_ids.is_empty() {
- let new_fbo = gl::gen_framebuffers(1)[0];
+ let new_fbo = self.gl.gen_framebuffers(1)[0];
- gl::bind_framebuffer(gl::FRAMEBUFFER, new_fbo);
+ self.gl.bind_framebuffer(gl::FRAMEBUFFER, new_fbo);
- gl::framebuffer_texture_2d(gl::FRAMEBUFFER,
- gl::COLOR_ATTACHMENT0,
- texture_id.target,
- texture_id.name,
- 0);
+ self.gl.framebuffer_texture_2d(gl::FRAMEBUFFER,
+ gl::COLOR_ATTACHMENT0,
+ texture_id.target,
+ texture_id.name,
+ 0);
texture.fbo_ids.push(FBOId(new_fbo));
}
}
}
// TODO(gw): Hack! Modify the code above to use the normal binding interfaces the device exposes.
- gl::bind_framebuffer(gl::READ_FRAMEBUFFER, self.bound_read_fbo.0);
- gl::bind_framebuffer(gl::DRAW_FRAMEBUFFER, self.bound_draw_fbo.0);
+ self.gl.bind_framebuffer(gl::READ_FRAMEBUFFER, self.bound_read_fbo.0);
+ self.gl.bind_framebuffer(gl::DRAW_FRAMEBUFFER, self.bound_draw_fbo.0);
}
pub fn blit_render_target(&mut self,
src_texture: Option<(TextureId, i32)>,
src_rect: Option<DeviceIntRect>,
dest_rect: DeviceIntRect) {
debug_assert!(self.inside_frame);
@@ -1251,26 +1320,26 @@ impl Device {
let texture = self.textures.get(&src_texture.unwrap().0).expect("unknown texture id!");
DeviceIntRect::new(DeviceIntPoint::zero(),
DeviceIntSize::new(texture.width as gl::GLint,
texture.height as gl::GLint))
});
self.bind_read_target(src_texture);
- gl::blit_framebuffer(src_rect.origin.x,
- src_rect.origin.y,
- src_rect.origin.x + src_rect.size.width,
- src_rect.origin.y + src_rect.size.height,
- dest_rect.origin.x,
- dest_rect.origin.y,
- dest_rect.origin.x + dest_rect.size.width,
- dest_rect.origin.y + dest_rect.size.height,
- gl::COLOR_BUFFER_BIT,
- gl::LINEAR);
+ self.gl.blit_framebuffer(src_rect.origin.x,
+ src_rect.origin.y,
+ src_rect.origin.x + src_rect.size.width,
+ src_rect.origin.y + src_rect.size.height,
+ dest_rect.origin.x,
+ dest_rect.origin.y,
+ dest_rect.origin.x + dest_rect.size.width,
+ dest_rect.origin.y + dest_rect.size.height,
+ gl::COLOR_BUFFER_BIT,
+ gl::LINEAR);
}
pub fn resize_texture(&mut self,
texture_id: TextureId,
new_width: u32,
new_height: u32,
format: ImageFormat,
filter: TextureFilter,
@@ -1281,66 +1350,66 @@ impl Device {
let temp_texture_id = self.create_texture_ids(1, TextureTarget::Default)[0];
self.init_texture(temp_texture_id, old_size.width, old_size.height, format, filter, mode, None);
self.create_fbo_for_texture_if_necessary(temp_texture_id, None);
self.bind_read_target(Some((texture_id, 0)));
self.bind_texture(DEFAULT_TEXTURE, temp_texture_id);
- gl::copy_tex_sub_image_2d(temp_texture_id.target,
- 0,
- 0,
- 0,
- 0,
- 0,
- old_size.width as i32,
- old_size.height as i32);
+ self.gl.copy_tex_sub_image_2d(temp_texture_id.target,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ old_size.width as i32,
+ old_size.height as i32);
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_read_target(Some((temp_texture_id, 0)));
self.bind_texture(DEFAULT_TEXTURE, texture_id);
- gl::copy_tex_sub_image_2d(texture_id.target,
- 0,
- 0,
- 0,
- 0,
- 0,
- old_size.width as i32,
- old_size.height as i32);
+ self.gl.copy_tex_sub_image_2d(texture_id.target,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ old_size.width as i32,
+ old_size.height as i32);
self.bind_read_target(None);
self.deinit_texture(temp_texture_id);
}
pub fn deinit_texture(&mut self, texture_id: TextureId) {
debug_assert!(self.inside_frame);
self.bind_texture(DEFAULT_TEXTURE, texture_id);
let texture = self.textures.get_mut(&texture_id).unwrap();
- let (internal_format, gl_format) = gl_texture_formats_for_image_format(texture.format);
+ let (internal_format, gl_format) = gl_texture_formats_for_image_format(&*self.gl, texture.format);
let type_ = gl_type_for_texture_format(texture.format);
- gl::tex_image_2d(texture_id.target,
- 0,
- internal_format,
- 0,
- 0,
- 0,
- gl_format,
- type_,
- None);
+ self.gl.tex_image_2d(texture_id.target,
+ 0,
+ internal_format,
+ 0,
+ 0,
+ 0,
+ gl_format,
+ type_,
+ None);
if !texture.fbo_ids.is_empty() {
let fbo_ids: Vec<_> = texture.fbo_ids.iter().map(|&FBOId(fbo_id)| fbo_id).collect();
- gl::delete_framebuffers(&fbo_ids[..]);
+ self.gl.delete_framebuffers(&fbo_ids[..]);
}
texture.format = ImageFormat::Invalid;
texture.width = 0;
texture.height = 0;
texture.fbo_ids.clear();
}
@@ -1353,17 +1422,17 @@ impl Device {
pub fn create_program_with_prefix(&mut self,
base_filename: &str,
include_filenames: &[&str],
prefix: Option<String>,
vertex_format: VertexFormat) -> Result<ProgramId, ShaderError> {
debug_assert!(self.inside_frame);
- let pid = gl::create_program();
+ let pid = self.gl.create_program();
let mut vs_name = String::from(base_filename);
vs_name.push_str(".vs");
let mut fs_name = String::from(base_filename);
fs_name.push_str(".fs");
let mut include = format!("// Base shader: {}\n", base_filename);
for inc_filename in include_filenames {
@@ -1371,16 +1440,17 @@ impl Device {
include.push_str(&src);
}
if let Some(shared_src) = get_optional_shader_source(base_filename, &self.resource_override_path) {
include.push_str(&shared_src);
}
let program = Program {
+ gl: self.gl.clone(),
name: base_filename.to_owned(),
id: pid,
u_transform: -1,
u_device_pixel_ratio: -1,
vs_source: get_shader_source(&vs_name, &self.resource_override_path),
fs_source: get_shader_source(&fs_name, &self.resource_override_path),
prefix: prefix,
vs_id: None,
@@ -1418,121 +1488,123 @@ impl Device {
vs_preamble.push(self.shader_preamble.to_owned());
fs_preamble.push(self.shader_preamble.to_owned());
vs_preamble.push(include.clone());
fs_preamble.push(include);
// todo(gw): store shader ids so they can be freed!
- let vs_id = try!{ Device::compile_shader(&program.name,
+ let vs_id = try!{ Device::compile_shader(&*self.gl,
+ &program.name,
&program.vs_source,
gl::VERTEX_SHADER,
&vs_preamble) };
- let fs_id = try!{ Device::compile_shader(&program.name,
+ let fs_id = try!{ Device::compile_shader(&*self.gl,
+ &program.name,
&program.fs_source,
gl::FRAGMENT_SHADER,
&fs_preamble) };
if let Some(vs_id) = program.vs_id {
- gl::detach_shader(program.id, vs_id);
+ self.gl.detach_shader(program.id, vs_id);
}
if let Some(fs_id) = program.fs_id {
- gl::detach_shader(program.id, fs_id);
+ self.gl.detach_shader(program.id, fs_id);
}
if let Err(bind_error) = program.attach_and_bind_shaders(vs_id, fs_id, vertex_format) {
if let (Some(vs_id), Some(fs_id)) = (program.vs_id, program.fs_id) {
try! { program.attach_and_bind_shaders(vs_id, fs_id, vertex_format) };
} else {
return Err(bind_error);
}
} else {
if let Some(vs_id) = program.vs_id {
- gl::delete_shader(vs_id);
+ self.gl.delete_shader(vs_id);
}
if let Some(fs_id) = program.fs_id {
- gl::delete_shader(fs_id);
+ self.gl.delete_shader(fs_id);
}
program.vs_id = Some(vs_id);
program.fs_id = Some(fs_id);
}
- program.u_transform = gl::get_uniform_location(program.id, "uTransform");
- program.u_device_pixel_ratio = gl::get_uniform_location(program.id, "uDevicePixelRatio");
+ program.u_transform = self.gl.get_uniform_location(program.id, "uTransform");
+ program.u_device_pixel_ratio = self.gl.get_uniform_location(program.id, "uDevicePixelRatio");
- program_id.bind();
- let u_color_0 = gl::get_uniform_location(program.id, "sColor0");
+ program_id.bind(&*self.gl);
+ let u_color_0 = self.gl.get_uniform_location(program.id, "sColor0");
if u_color_0 != -1 {
- gl::uniform_1i(u_color_0, TextureSampler::Color0 as i32);
+ self.gl.uniform_1i(u_color_0, TextureSampler::Color0 as i32);
}
- let u_color1 = gl::get_uniform_location(program.id, "sColor1");
+ let u_color1 = self.gl.get_uniform_location(program.id, "sColor1");
if u_color1 != -1 {
- gl::uniform_1i(u_color1, TextureSampler::Color1 as i32);
+ self.gl.uniform_1i(u_color1, TextureSampler::Color1 as i32);
}
- let u_color_2 = gl::get_uniform_location(program.id, "sColor2");
+ let u_color_2 = self.gl.get_uniform_location(program.id, "sColor2");
if u_color_2 != -1 {
- gl::uniform_1i(u_color_2, TextureSampler::Color2 as i32);
+ self.gl.uniform_1i(u_color_2, TextureSampler::Color2 as i32);
}
- let u_mask = gl::get_uniform_location(program.id, "sMask");
+ let u_mask = self.gl.get_uniform_location(program.id, "sMask");
if u_mask != -1 {
- gl::uniform_1i(u_mask, TextureSampler::Mask as i32);
+ self.gl.uniform_1i(u_mask, TextureSampler::Mask as i32);
}
- let u_cache = gl::get_uniform_location(program.id, "sCache");
+ let u_cache = self.gl.get_uniform_location(program.id, "sCache");
if u_cache != -1 {
- gl::uniform_1i(u_cache, TextureSampler::Cache as i32);
+ self.gl.uniform_1i(u_cache, TextureSampler::Cache as i32);
}
- let u_layers = gl::get_uniform_location(program.id, "sLayers");
+ let u_layers = self.gl.get_uniform_location(program.id, "sLayers");
if u_layers != -1 {
- gl::uniform_1i(u_layers, TextureSampler::Layers as i32);
+ self.gl.uniform_1i(u_layers, TextureSampler::Layers as i32);
}
- let u_tasks = gl::get_uniform_location(program.id, "sRenderTasks");
+ let u_tasks = self.gl.get_uniform_location(program.id, "sRenderTasks");
if u_tasks != -1 {
- gl::uniform_1i(u_tasks, TextureSampler::RenderTasks as i32);
+ self.gl.uniform_1i(u_tasks, TextureSampler::RenderTasks as i32);
}
- let u_prim_geom = gl::get_uniform_location(program.id, "sPrimGeometry");
+ let u_prim_geom = self.gl.get_uniform_location(program.id, "sPrimGeometry");
if u_prim_geom != -1 {
- gl::uniform_1i(u_prim_geom, TextureSampler::Geometry as i32);
+ self.gl.uniform_1i(u_prim_geom, TextureSampler::Geometry as i32);
}
- let u_data16 = gl::get_uniform_location(program.id, "sData16");
+ let u_data16 = self.gl.get_uniform_location(program.id, "sData16");
if u_data16 != -1 {
- gl::uniform_1i(u_data16, TextureSampler::Data16 as i32);
+ self.gl.uniform_1i(u_data16, TextureSampler::Data16 as i32);
}
- let u_data32 = gl::get_uniform_location(program.id, "sData32");
+ let u_data32 = self.gl.get_uniform_location(program.id, "sData32");
if u_data32 != -1 {
- gl::uniform_1i(u_data32, TextureSampler::Data32 as i32);
+ self.gl.uniform_1i(u_data32, TextureSampler::Data32 as i32);
}
- let u_data64 = gl::get_uniform_location(program.id, "sData64");
+ let u_data64 = self.gl.get_uniform_location(program.id, "sData64");
if u_data64 != -1 {
- gl::uniform_1i(u_data64, TextureSampler::Data64 as i32);
+ self.gl.uniform_1i(u_data64, TextureSampler::Data64 as i32);
}
- let u_data128 = gl::get_uniform_location(program.id, "sData128");
+ let u_data128 = self.gl.get_uniform_location(program.id, "sData128");
if u_data128 != -1 {
- gl::uniform_1i(u_data128, TextureSampler::Data128 as i32);
+ self.gl.uniform_1i(u_data128, TextureSampler::Data128 as i32);
}
- let u_resource_rects = gl::get_uniform_location(program.id, "sResourceRects");
+ let u_resource_rects = self.gl.get_uniform_location(program.id, "sResourceRects");
if u_resource_rects != -1 {
- gl::uniform_1i(u_resource_rects, TextureSampler::ResourceRects as i32);
+ self.gl.uniform_1i(u_resource_rects, TextureSampler::ResourceRects as i32);
}
- let u_gradients = gl::get_uniform_location(program.id, "sGradients");
+ let u_gradients = self.gl.get_uniform_location(program.id, "sGradients");
if u_gradients != -1 {
- gl::uniform_1i(u_gradients, TextureSampler::Gradients as i32);
+ self.gl.uniform_1i(u_gradients, TextureSampler::Gradients as i32);
}
Ok(())
}
/*
pub fn refresh_shader(&mut self, path: PathBuf) {
let mut vs_preamble_path = self.resource_path.clone();
@@ -1567,51 +1639,51 @@ impl Device {
for program_id in programs_to_update {
self.load_program(program_id, false);
}
}*/
pub fn get_uniform_location(&self, program_id: ProgramId, name: &str) -> UniformLocation {
let ProgramId(program_id) = program_id;
- UniformLocation(gl::get_uniform_location(program_id, name))
+ UniformLocation(self.gl.get_uniform_location(program_id, name))
}
pub fn set_uniform_2f(&self, uniform: UniformLocation, x: f32, y: f32) {
debug_assert!(self.inside_frame);
let UniformLocation(location) = uniform;
- gl::uniform_2f(location, x, y);
+ self.gl.uniform_2f(location, x, y);
}
fn set_uniforms(&self,
program: &Program,
transform: &Matrix4D<f32>,
device_pixel_ratio: f32) {
debug_assert!(self.inside_frame);
- gl::uniform_matrix_4fv(program.u_transform,
+ self.gl.uniform_matrix_4fv(program.u_transform,
false,
&transform.to_row_major_array());
- gl::uniform_1f(program.u_device_pixel_ratio, device_pixel_ratio);
+ self.gl.uniform_1f(program.u_device_pixel_ratio, device_pixel_ratio);
}
fn update_image_for_2d_texture(&mut self,
target: gl::GLuint,
x0: gl::GLint,
y0: gl::GLint,
width: gl::GLint,
height: gl::GLint,
format: gl::GLuint,
data: &[u8]) {
- gl::tex_sub_image_2d(target,
- 0,
- x0, y0,
- width, height,
- format,
- gl::UNSIGNED_BYTE,
- data);
+ self.gl.tex_sub_image_2d(target,
+ 0,
+ x0, y0,
+ width, height,
+ format,
+ gl::UNSIGNED_BYTE,
+ data);
}
pub fn update_texture(&mut self,
texture_id: TextureId,
x0: u32,
y0: u32,
width: u32,
height: u32,
@@ -1625,131 +1697,132 @@ impl Device {
ImageFormat::A8 => {
if cfg!(any(target_arch="arm", target_arch="aarch64")) {
for byte in data {
expanded_data.push(*byte);
expanded_data.push(*byte);
expanded_data.push(*byte);
expanded_data.push(*byte);
}
- (GL_FORMAT_BGRA, 4, expanded_data.as_slice())
+ (get_gl_format_bgra(self.gl()), 4, expanded_data.as_slice())
} else {
(GL_FORMAT_A, 1, data)
}
}
ImageFormat::RGB8 => (gl::RGB, 3, data),
- ImageFormat::RGBA8 => (GL_FORMAT_BGRA, 4, data),
+ ImageFormat::RGBA8 => (get_gl_format_bgra(self.gl()), 4, data),
ImageFormat::Invalid | ImageFormat::RGBAF32 => unreachable!(),
};
let row_length = match stride {
Some(value) => value / bpp,
None => width,
};
// Take the stride into account for all rows, except the last one.
let len = bpp * row_length * (height - 1)
+ width * bpp;
assert!(data.len() as u32 >= len);
let data = &data[0..len as usize];
if let Some(..) = stride {
- gl::pixel_store_i(gl::UNPACK_ROW_LENGTH, row_length as gl::GLint);
+ self.gl.pixel_store_i(gl::UNPACK_ROW_LENGTH, row_length as gl::GLint);
}
self.bind_texture(DEFAULT_TEXTURE, texture_id);
self.update_image_for_2d_texture(texture_id.target,
x0 as gl::GLint,
y0 as gl::GLint,
width as gl::GLint,
height as gl::GLint,
gl_format,
data);
// Reset row length to 0, otherwise the stride would apply to all texture uploads.
if let Some(..) = stride {
- gl::pixel_store_i(gl::UNPACK_ROW_LENGTH, 0 as gl::GLint);
+ self.gl.pixel_store_i(gl::UNPACK_ROW_LENGTH, 0 as gl::GLint);
}
}
fn clear_vertex_array(&mut self) {
debug_assert!(self.inside_frame);
- gl::bind_vertex_array(0);
+ self.gl.bind_vertex_array(0);
}
pub fn bind_vao(&mut self, vao_id: VAOId) {
debug_assert!(self.inside_frame);
if self.bound_vao != vao_id {
self.bound_vao = vao_id;
let VAOId(id) = vao_id;
- gl::bind_vertex_array(id);
+ self.gl.bind_vertex_array(id);
}
}
fn create_vao_with_vbos(&mut self,
format: VertexFormat,
main_vbo_id: VBOId,
instance_vbo_id: VBOId,
ibo_id: IBOId,
vertex_offset: gl::GLuint,
instance_stride: gl::GLint,
owns_vertices: bool,
owns_instances: bool,
owns_indices: bool)
-> VAOId {
debug_assert!(self.inside_frame);
- let vao_ids = gl::gen_vertex_arrays(1);
+ let vao_ids = self.gl.gen_vertex_arrays(1);
let vao_id = vao_ids[0];
- gl::bind_vertex_array(vao_id);
+ self.gl.bind_vertex_array(vao_id);
- format.bind(main_vbo_id, instance_vbo_id, vertex_offset, instance_stride);
- ibo_id.bind(); // force it to be a part of VAO
+ format.bind(self.gl(), main_vbo_id, instance_vbo_id, vertex_offset, instance_stride);
+ ibo_id.bind(self.gl()); // force it to be a part of VAO
let vao = VAO {
+ gl: self.gl.clone(),
id: vao_id,
ibo_id: ibo_id,
main_vbo_id: main_vbo_id,
instance_vbo_id: instance_vbo_id,
instance_stride: instance_stride,
owns_indices: owns_indices,
owns_vertices: owns_vertices,
owns_instances: owns_instances,
};
- gl::bind_vertex_array(0);
+ self.gl.bind_vertex_array(0);
let vao_id = VAOId(vao_id);
debug_assert!(!self.vaos.contains_key(&vao_id));
self.vaos.insert(vao_id, vao);
vao_id
}
pub fn create_vao(&mut self, format: VertexFormat, inst_stride: gl::GLint) -> VAOId {
debug_assert!(self.inside_frame);
- let buffer_ids = gl::gen_buffers(3);
+ let buffer_ids = self.gl.gen_buffers(3);
let ibo_id = IBOId(buffer_ids[0]);
let main_vbo_id = VBOId(buffer_ids[1]);
let intance_vbo_id = VBOId(buffer_ids[2]);
self.create_vao_with_vbos(format, main_vbo_id, intance_vbo_id, ibo_id, 0, inst_stride, true, true, true)
}
pub fn create_vao_with_new_instances(&mut self, format: VertexFormat, inst_stride: gl::GLint,
base_vao: VAOId) -> VAOId {
debug_assert!(self.inside_frame);
- let buffer_ids = gl::gen_buffers(1);
+ let buffer_ids = self.gl.gen_buffers(1);
let intance_vbo_id = VBOId(buffer_ids[0]);
let (main_vbo_id, ibo_id) = {
let vao = self.vaos.get(&base_vao).unwrap();
(vao.main_vbo_id, vao.ibo_id)
};
self.create_vao_with_vbos(format, main_vbo_id, intance_vbo_id, ibo_id, 0, inst_stride, false, true, false)
}
@@ -1758,270 +1831,273 @@ impl Device {
vao_id: VAOId,
vertices: &[V],
usage_hint: VertexUsageHint) {
debug_assert!(self.inside_frame);
let vao = self.vaos.get(&vao_id).unwrap();
debug_assert_eq!(self.bound_vao, vao_id);
- vao.main_vbo_id.bind();
- gl::buffer_data(gl::ARRAY_BUFFER, &vertices, usage_hint.to_gl());
+ vao.main_vbo_id.bind(self.gl());
+ gl::buffer_data(self.gl(), gl::ARRAY_BUFFER, &vertices, usage_hint.to_gl());
}
pub fn update_vao_instances<V>(&mut self,
vao_id: VAOId,
instances: &[V],
usage_hint: VertexUsageHint) {
debug_assert!(self.inside_frame);
let vao = self.vaos.get(&vao_id).unwrap();
debug_assert_eq!(self.bound_vao, vao_id);
debug_assert_eq!(vao.instance_stride as usize, mem::size_of::<V>());
- vao.instance_vbo_id.bind();
- gl::buffer_data(gl::ARRAY_BUFFER, &instances, usage_hint.to_gl());
+ vao.instance_vbo_id.bind(self.gl());
+ gl::buffer_data(self.gl(), gl::ARRAY_BUFFER, &instances, usage_hint.to_gl());
}
pub fn update_vao_indices<I>(&mut self,
vao_id: VAOId,
indices: &[I],
usage_hint: VertexUsageHint) {
debug_assert!(self.inside_frame);
let vao = self.vaos.get(&vao_id).unwrap();
debug_assert_eq!(self.bound_vao, vao_id);
- vao.ibo_id.bind();
- gl::buffer_data(gl::ELEMENT_ARRAY_BUFFER, &indices, usage_hint.to_gl());
+ vao.ibo_id.bind(self.gl());
+ gl::buffer_data(self.gl(), gl::ELEMENT_ARRAY_BUFFER, &indices, usage_hint.to_gl());
}
pub fn draw_triangles_u16(&mut self, first_vertex: i32, index_count: i32) {
debug_assert!(self.inside_frame);
- gl::draw_elements(gl::TRIANGLES,
- index_count,
- gl::UNSIGNED_SHORT,
- first_vertex as u32 * 2);
+ self.gl.draw_elements(gl::TRIANGLES,
+ index_count,
+ gl::UNSIGNED_SHORT,
+ first_vertex as u32 * 2);
}
pub fn draw_triangles_u32(&mut self, first_vertex: i32, index_count: i32) {
debug_assert!(self.inside_frame);
- gl::draw_elements(gl::TRIANGLES,
- index_count,
- gl::UNSIGNED_INT,
- first_vertex as u32 * 4);
+ self.gl.draw_elements(gl::TRIANGLES,
+ index_count,
+ gl::UNSIGNED_INT,
+ first_vertex as u32 * 4);
}
pub fn draw_nonindexed_lines(&mut self, first_vertex: i32, vertex_count: i32) {
debug_assert!(self.inside_frame);
- gl::draw_arrays(gl::LINES,
- first_vertex,
- vertex_count);
+ self.gl.draw_arrays(gl::LINES,
+ first_vertex,
+ vertex_count);
}
pub fn draw_indexed_triangles_instanced_u16(&mut self,
index_count: i32,
instance_count: i32) {
debug_assert!(self.inside_frame);
- gl::draw_elements_instanced(gl::TRIANGLES, index_count, gl::UNSIGNED_SHORT, 0, instance_count);
+ self.gl.draw_elements_instanced(gl::TRIANGLES, index_count, gl::UNSIGNED_SHORT, 0, instance_count);
}
pub fn end_frame(&mut self) {
self.bind_draw_target(None, None);
self.bind_read_target(None);
debug_assert!(self.inside_frame);
self.inside_frame = false;
- gl::bind_texture(gl::TEXTURE_2D, 0);
- gl::use_program(0);
+ self.gl.bind_texture(gl::TEXTURE_2D, 0);
+ self.gl.use_program(0);
for i in 0..self.bound_textures.len() {
- gl::active_texture(gl::TEXTURE0 + i as gl::GLuint);
- gl::bind_texture(gl::TEXTURE_2D, 0);
+ self.gl.active_texture(gl::TEXTURE0 + i as gl::GLuint);
+ self.gl.bind_texture(gl::TEXTURE_2D, 0);
}
- gl::active_texture(gl::TEXTURE0);
+ self.gl.active_texture(gl::TEXTURE0);
self.frame_id.0 += 1;
}
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);
+ let index = self.gl.get_uniform_block_index(program_id.0, name);
+ self.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);
+ let ubo = self.gl.gen_buffers(1)[0];
+ self.gl.bind_buffer(gl::UNIFORM_BUFFER, ubo);
+ gl::buffer_data(self.gl(), gl::UNIFORM_BUFFER, data, gl::STATIC_DRAW);
+ self.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);
+ self.gl.bind_buffer(gl::UNIFORM_BUFFER, 0);
+ self.gl.bind_buffer_base(gl::UNIFORM_BUFFER, binding, 0);
}
pub fn delete_buffer(&self, buffer: UBOId) {
- gl::delete_buffers(&[buffer.0]);
+ self.gl.delete_buffers(&[buffer.0]);
}
#[cfg(target_os = "android")]
pub fn set_multisample(&self, enable: bool) {
}
#[cfg(not(target_os = "android"))]
pub fn set_multisample(&self, enable: bool) {
if self.capabilities.supports_multisampling {
if enable {
- gl::enable(gl::MULTISAMPLE);
+ self.gl.enable(gl::MULTISAMPLE);
} else {
- gl::disable(gl::MULTISAMPLE);
+ self.gl.disable(gl::MULTISAMPLE);
}
}
}
pub fn clear_target(&self,
color: Option<[f32; 4]>,
depth: Option<f32>) {
let mut clear_bits = 0;
if let Some(color) = color {
- gl::clear_color(color[0], color[1], color[2], color[3]);
+ self.gl.clear_color(color[0], color[1], color[2], color[3]);
clear_bits |= gl::COLOR_BUFFER_BIT;
}
if let Some(depth) = depth {
- gl::clear_depth(depth as f64);
+ self.gl.clear_depth(depth as f64);
clear_bits |= gl::DEPTH_BUFFER_BIT;
}
if clear_bits != 0 {
- gl::clear(clear_bits);
+ self.gl.clear(clear_bits);
}
}
pub fn clear_target_rect(&self,
color: Option<[f32; 4]>,
depth: Option<f32>,
rect: DeviceIntRect) {
let mut clear_bits = 0;
if let Some(color) = color {
- gl::clear_color(color[0], color[1], color[2], color[3]);
+ self.gl.clear_color(color[0], color[1], color[2], color[3]);
clear_bits |= gl::COLOR_BUFFER_BIT;
}
if let Some(depth) = depth {
- gl::clear_depth(depth as f64);
+ self.gl.clear_depth(depth as f64);
clear_bits |= gl::DEPTH_BUFFER_BIT;
}
if clear_bits != 0 {
- gl::enable(gl::SCISSOR_TEST);
- gl::scissor(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
- gl::clear(clear_bits);
- gl::disable(gl::SCISSOR_TEST);
+ self.gl.enable(gl::SCISSOR_TEST);
+ self.gl.scissor(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
+ self.gl.clear(clear_bits);
+ self.gl.disable(gl::SCISSOR_TEST);
}
}
pub fn enable_depth(&self) {
- gl::enable(gl::DEPTH_TEST);
+ self.gl.enable(gl::DEPTH_TEST);
}
pub fn disable_depth(&self) {
- gl::disable(gl::DEPTH_TEST);
+ self.gl.disable(gl::DEPTH_TEST);
}
pub fn set_depth_func(&self, depth_func: DepthFunction) {
- gl::depth_func(depth_func as gl::GLuint);
+ self.gl.depth_func(depth_func as gl::GLuint);
}
pub fn enable_depth_write(&self) {
- gl::depth_mask(true);
+ self.gl.depth_mask(true);
}
pub fn disable_depth_write(&self) {
- gl::depth_mask(false);
+ self.gl.depth_mask(false);
}
pub fn disable_stencil(&self) {
- gl::disable(gl::STENCIL_TEST);
+ self.gl.disable(gl::STENCIL_TEST);
}
pub fn disable_scissor(&self) {
- gl::disable(gl::SCISSOR_TEST);
+ self.gl.disable(gl::SCISSOR_TEST);
}
pub fn set_blend(&self, enable: bool) {
if enable {
- gl::enable(gl::BLEND);
+ self.gl.enable(gl::BLEND);
} else {
- gl::disable(gl::BLEND);
+ self.gl.disable(gl::BLEND);
}
}
pub fn set_blend_mode_premultiplied_alpha(&self) {
- gl::blend_func(gl::ONE, gl::ONE_MINUS_SRC_ALPHA);
- gl::blend_equation(gl::FUNC_ADD);
+ self.gl.blend_func(gl::ONE, gl::ONE_MINUS_SRC_ALPHA);
+ self.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);
+ //self.gl.blend_func(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA);
+ self.gl.blend_func_separate(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA,
+ gl::ONE, gl::ONE);
+ self.gl.blend_equation(gl::FUNC_ADD);
}
pub fn set_blend_mode_subpixel(&self, color: ColorF) {
- gl::blend_color(color.r, color.g, color.b, color.a);
- gl::blend_func(gl::CONSTANT_COLOR, gl::ONE_MINUS_SRC_COLOR);
+ self.gl.blend_color(color.r, color.g, color.b, color.a);
+ self.gl.blend_func(gl::CONSTANT_COLOR, gl::ONE_MINUS_SRC_COLOR);
}
pub fn set_blend_mode_multiply(&self) {
- gl::blend_func_separate(gl::ZERO, gl::SRC_COLOR,
- gl::ZERO, gl::SRC_ALPHA);
- gl::blend_equation(gl::FUNC_ADD);
+ self.gl.blend_func_separate(gl::ZERO, gl::SRC_COLOR,
+ gl::ZERO, gl::SRC_ALPHA);
+ self.gl.blend_equation(gl::FUNC_ADD);
}
pub fn set_blend_mode_max(&self) {
- gl::blend_func_separate(gl::ONE, gl::ONE,
- gl::ONE, gl::ONE);
- gl::blend_equation_separate(gl::MAX, gl::FUNC_ADD);
+ self.gl.blend_func_separate(gl::ONE, gl::ONE,
+ gl::ONE, gl::ONE);
+ self.gl.blend_equation_separate(gl::MAX, gl::FUNC_ADD);
}
pub fn set_blend_mode_min(&self) {
- gl::blend_func_separate(gl::ONE, gl::ONE,
- gl::ONE, gl::ONE);
- gl::blend_equation_separate(gl::MIN, gl::FUNC_ADD);
+ self.gl.blend_func_separate(gl::ONE, gl::ONE,
+ gl::ONE, gl::ONE);
+ self.gl.blend_equation_separate(gl::MIN, gl::FUNC_ADD);
}
}
impl Drop for Device {
fn drop(&mut self) {
//self.file_watcher.exit();
}
}
-fn gl_texture_formats_for_image_format(format: ImageFormat) -> (gl::GLint, gl::GLuint) {
+fn gl_texture_formats_for_image_format(gl: &gl::Gl, format: ImageFormat) -> (gl::GLint, gl::GLuint) {
match format {
ImageFormat::A8 => {
if cfg!(any(target_arch="arm", target_arch="aarch64")) {
- (GL_FORMAT_BGRA as gl::GLint, GL_FORMAT_BGRA)
+ (get_gl_format_bgra(gl) as gl::GLint, get_gl_format_bgra(gl))
} else {
(GL_FORMAT_A as gl::GLint, GL_FORMAT_A)
}
},
ImageFormat::RGB8 => (gl::RGB as gl::GLint, gl::RGB),
ImageFormat::RGBA8 => {
- if cfg!(any(target_arch="arm", target_arch="aarch64")) {
- (GL_FORMAT_BGRA as gl::GLint, GL_FORMAT_BGRA)
- } else {
- (gl::RGBA as gl::GLint, GL_FORMAT_BGRA)
+ match gl.get_type() {
+ gl::GlType::Gl => {
+ (gl::RGBA as gl::GLint, get_gl_format_bgra(gl))
+ }
+ gl::GlType::Gles => {
+ (get_gl_format_bgra(gl) as gl::GLint, get_gl_format_bgra(gl))
+ }
}
}
ImageFormat::RGBAF32 => (gl::RGBA32F as gl::GLint, gl::RGBA),
ImageFormat::Invalid => unreachable!(),
}
}
fn gl_type_for_texture_format(format: ImageFormat) -> gl::GLuint {
--- a/gfx/webrender/src/internal_types.rs
+++ b/gfx/webrender/src/internal_types.rs
@@ -1,16 +1,17 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use app_units::Au;
use device::TextureFilter;
use euclid::{TypedPoint2D, UnknownUnit};
use fnv::FnvHasher;
+use gleam::gl;
use offscreen_gl_context::{NativeGLContext, NativeGLContextHandle};
use offscreen_gl_context::{GLContext, NativeGLContextMethods, GLContextDispatcher};
use offscreen_gl_context::{OSMesaContext, OSMesaContextHandle};
use offscreen_gl_context::{ColorAttachmentType, GLContextAttributes, GLLimits};
use profiler::BackendProfileCounters;
use std::collections::{HashMap, HashSet};
use std::f32;
use std::hash::BuildHasherDefault;
@@ -69,24 +70,26 @@ impl GLContextHandleWrapper {
size: DeviceIntSize,
attributes: GLContextAttributes,
dispatcher: Option<Box<GLContextDispatcher>>) -> Result<GLContextWrapper, &'static str> {
match *self {
GLContextHandleWrapper::Native(ref handle) => {
let ctx = GLContext::<NativeGLContext>::new_shared_with_dispatcher(size.to_untyped(),
attributes,
ColorAttachmentType::Texture,
+ gl::GlType::default(),
Some(handle),
dispatcher);
ctx.map(GLContextWrapper::Native)
}
GLContextHandleWrapper::OSMesa(ref handle) => {
let ctx = GLContext::<OSMesaContext>::new_shared_with_dispatcher(size.to_untyped(),
attributes,
ColorAttachmentType::Texture,
+ gl::GlType::default(),
Some(handle),
dispatcher);
ctx.map(GLContextWrapper::OSMesa)
}
}
}
}
--- a/gfx/webrender/src/profiler.rs
+++ b/gfx/webrender/src/profiler.rs
@@ -1,14 +1,14 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use debug_render::DebugRenderer;
-use device::{GpuMarker, GpuSample, NamedTag};
+use device::{Device, GpuMarker, GpuSample, NamedTag};
use euclid::{Point2D, Size2D, Rect};
use std::collections::vec_deque::VecDeque;
use std::f32;
use std::mem;
use webrender_traits::ColorF;
use time::precise_time_ns;
const GRAPH_WIDTH: f32 = 1024.0;
@@ -634,23 +634,24 @@ impl Profiler {
if left {
self.y_left = new_y;
} else {
self.y_right = new_y;
}
}
pub fn draw_profile(&mut self,
+ device: &mut Device,
frame_profile: &FrameProfileCounters,
backend_profile: &BackendProfileCounters,
renderer_profile: &RendererProfileCounters,
renderer_timers: &mut RendererProfileTimers,
debug_renderer: &mut DebugRenderer) {
- let _gm = GpuMarker::new("profile");
+ let _gm = GpuMarker::new(device.rc_gl(), "profile");
self.x_left = 20.0;
self.y_left = 40.0;
self.x_right = 400.0;
self.y_right = 40.0;
self.draw_counters(&[
&renderer_profile.frame_counter,
&renderer_profile.frame_time,
--- a/gfx/webrender/src/renderer.rs
+++ b/gfx/webrender/src/renderer.rs
@@ -11,16 +11,17 @@
use debug_colors;
use debug_render::DebugRenderer;
use device::{DepthFunction, Device, FrameId, ProgramId, TextureId, VertexFormat, GpuMarker, GpuProfiler};
use device::{GpuSample, TextureFilter, VAOId, VertexUsageHint, FileWatcherHandler, TextureTarget, ShaderError};
use euclid::Matrix4D;
use fnv::FnvHasher;
use frame_builder::FrameBuilderConfig;
+use gleam::gl;
use gpu_store::{GpuStore, GpuStoreLayout};
use internal_types::{CacheTextureId, RendererFrame, ResultMsg, TextureUpdateOp};
use internal_types::{ExternalImageUpdateList, TextureUpdateList, PackedVertex, RenderTargetMode};
use internal_types::{ORTHO_NEAR_PLANE, ORTHO_FAR_PLANE, SourceTexture};
use internal_types::{BatchTextures, TextureSampler, GLContextHandleWrapper};
use prim_store::GradientData;
use profiler::{Profiler, BackendProfileCounters};
use profiler::{GpuProfileTag, RendererProfileTimers, RendererProfileCounters};
@@ -30,16 +31,17 @@ use render_task::RenderTaskData;
use std;
use std::cmp;
use std::collections::{HashMap, VecDeque};
use std::f32;
use std::hash::BuildHasherDefault;
use std::marker::PhantomData;
use std::mem;
use std::path::PathBuf;
+use std::rc::Rc;
use std::sync::{Arc, Mutex};
use std::sync::mpsc::{channel, Receiver, Sender};
use std::thread;
use texture_cache::TextureCache;
use threadpool::ThreadPool;
use tiling::{AlphaBatchKind, BlurCommand, Frame, PrimitiveBatch, PrimitiveBatchData};
use tiling::{CacheClipInstance, PrimitiveInstance, RenderTarget};
use time::precise_time_ns;
@@ -555,32 +557,34 @@ impl Renderer {
/// let opts = webrender::RendererOptions {
/// device_pixel_ratio: 1.0,
/// resource_override_path: None,
/// enable_aa: false,
/// enable_profiler: false,
/// };
/// let (renderer, sender) = Renderer::new(opts);
/// ```
- pub fn new(mut options: RendererOptions,
+ pub fn new(gl: Rc<gl::Gl>,
+ mut options: RendererOptions,
initial_window_size: DeviceUintSize) -> Result<(Renderer, RenderApiSender), InitError> {
let (api_tx, api_rx) = try!{ channel::msg_channel() };
let (payload_tx, payload_rx) = try!{ channel::payload_channel() };
let (result_tx, result_rx) = channel();
register_thread_with_profiler("Compositor".to_owned());
let notifier = Arc::new(Mutex::new(None));
let file_watch_handler = FileWatcher {
result_tx: result_tx.clone(),
notifier: notifier.clone(),
};
- let mut device = Device::new(options.resource_override_path.clone(),
+ let mut device = Device::new(gl,
+ options.resource_override_path.clone(),
Box::new(file_watch_handler));
// device-pixel ratio doesn't matter here - we are just creating resources.
device.begin_frame(1.0);
let cs_box_shadow = try!{
LazilyCompiledShader::new(ShaderKind::Cache(VertexFormat::Triangles),
"cs_box_shadow",
&[],
@@ -853,16 +857,18 @@ impl Renderer {
recorder,
backend_main_thread_dispatcher,
blob_image_renderer,
backend_vr_compositor,
initial_window_size);
backend.run(backend_profile_counters);
})};
+ let gpu_profile = GpuProfiler::new(device.rc_gl());
+
let renderer = Renderer {
result_rx: result_rx,
device: device,
current_frame: None,
pending_texture_updates: Vec::new(),
pending_shader_updates: Vec::new(),
cs_box_shadow: cs_box_shadow,
cs_text_run: cs_text_run,
@@ -891,17 +897,17 @@ impl Renderer {
profile_counters: RendererProfileCounters::new(),
profiler: Profiler::new(),
enable_profiler: options.enable_profiler,
max_recorded_profiles: options.max_recorded_profiles,
clear_framebuffer: options.clear_framebuffer,
clear_color: options.clear_color,
last_time: 0,
render_targets: Vec::new(),
- gpu_profile: GpuProfiler::new(),
+ gpu_profile: gpu_profile,
prim_vao_id: prim_vao_id,
blur_vao_id: blur_vao_id,
clip_vao_id: clip_vao_id,
gdt_index: 0,
gpu_data_textures: gpu_data_textures,
pipeline_epoch_map: HashMap::with_hasher(Default::default()),
main_thread_dispatcher: main_thread_dispatcher,
cache_texture_id_map: Vec::new(),
@@ -912,16 +918,20 @@ impl Renderer {
cpu_profiles: VecDeque::new(),
gpu_profiles: VecDeque::new(),
};
let sender = RenderApiSender::new(api_tx, payload_tx);
Ok((renderer, sender))
}
+ pub fn gl(&self) -> &gl::Gl {
+ self.device.gl()
+ }
+
/// Sets the new RenderNotifier.
///
/// The RenderNotifier will be called when processing e.g. of a (scrolling) frame is done,
/// and therefore the screen should be updated.
pub fn set_render_notifier(&self, notifier: Box<RenderNotifier>) {
let mut notifier_arc = self.notifier.lock().unwrap();
*notifier_arc = Some(notifier);
}
@@ -1072,17 +1082,18 @@ impl Renderer {
}
let cpu_profile = CpuProfile::new(cpu_frame_id,
profile_timers.cpu_time.get(),
self.profile_counters.draw_calls.get());
self.cpu_profiles.push_back(cpu_profile);
}
if self.enable_profiler {
- self.profiler.draw_profile(&frame.profile_counters,
+ self.profiler.draw_profile(&mut self.device,
+ &frame.profile_counters,
&self.backend_profile_counters,
&self.profile_counters,
&mut profile_timers,
&mut self.debug);
}
self.profile_counters.reset();
self.profile_counters.frame_counter.inc();
@@ -1117,17 +1128,17 @@ impl Renderer {
if update_uniforms {
self.update_uniform_locations();
}
}
*/
fn update_texture_cache(&mut self) {
- let _gm = GpuMarker::new("texture cache update");
+ let _gm = GpuMarker::new(self.device.rc_gl(), "texture cache update");
let mut pending_texture_updates = mem::replace(&mut self.pending_texture_updates, vec![]);
for update_list in pending_texture_updates.drain(..) {
for update in update_list.updates {
match update.op {
TextureUpdateOp::Create { width, height, format, filter, mode, data } => {
let CacheTextureId(cache_texture_index) = update.id;
if self.cache_texture_id_map.len() == cache_texture_index {
// Create a new native texture, as requested by the texture cache.
@@ -1508,27 +1519,27 @@ impl Renderer {
{
let _gm = self.gpu_profile.add_marker(GPU_TAG_CACHE_CLIP);
let vao = self.clip_vao_id;
// switch to multiplicative blending
self.device.set_blend(true);
self.device.set_blend_mode_multiply();
// draw rounded cornered rectangles
if !target.clip_batcher.rectangles.is_empty() {
- let _gm2 = GpuMarker::new("clip rectangles");
+ let _gm2 = GpuMarker::new(self.device.rc_gl(), "clip rectangles");
let shader = self.cs_clip_rectangle.get(&mut self.device).unwrap();
self.draw_instanced_batch(&target.clip_batcher.rectangles,
vao,
shader,
&BatchTextures::no_texture(),
&projection);
}
// draw image masks
for (mask_texture_id, items) in target.clip_batcher.images.iter() {
- let _gm2 = GpuMarker::new("clip images");
+ let _gm2 = GpuMarker::new(self.device.rc_gl(), "clip images");
let texture_id = self.resolve_source_texture(mask_texture_id);
self.device.bind_texture(TextureSampler::Mask, texture_id);
let shader = self.cs_clip_image.get(&mut self.device).unwrap();
self.draw_instanced_batch(items,
vao,
shader,
&BatchTextures::no_texture(),
&projection);
@@ -1551,17 +1562,17 @@ impl Renderer {
self.draw_instanced_batch(&target.text_run_cache_prims,
vao,
shader,
&target.text_run_textures,
&projection);
}
- let _gm2 = GpuMarker::new("alpha batches");
+ let _gm2 = GpuMarker::new(self.device.rc_gl(), "alpha batches");
self.device.set_blend(false);
let mut prev_blend_mode = BlendMode::None;
self.device.set_depth_func(DepthFunction::Less);
self.device.enable_depth();
self.device.enable_depth_write();
for batch in &target.alpha_batcher.opaque_batches {
@@ -1615,17 +1626,17 @@ impl Renderer {
// custom item. Then we patch the resource_rects structure
// here before it's uploaded to the GPU.
if !frame.deferred_resolves.is_empty() {
let handler = self.external_image_handler
.as_mut()
.expect("Found external image, but no handler set!");
for deferred_resolve in &frame.deferred_resolves {
- GpuMarker::fire("deferred resolve");
+ GpuMarker::fire(self.device.gl(), "deferred resolve");
let props = &deferred_resolve.image_properties;
let external_id = props.external_id
.expect("BUG: Deferred resolves must be external images!");
let image = handler.lock(external_id);
let texture_id = match image.source {
ExternalImageSource::NativeTexture(texture_id) => TextureId::new(texture_id),
_ => panic!("No native texture found."),
@@ -1662,17 +1673,17 @@ impl Renderer {
handler.release(external_id);
}
}
}
fn draw_tile_frame(&mut self,
frame: &mut Frame,
framebuffer_size: &DeviceUintSize) {
- let _gm = GpuMarker::new("tile frame draw");
+ let _gm = GpuMarker::new(self.device.rc_gl(), "tile frame draw");
self.update_deferred_resolves(frame);
// Some tests use a restricted viewport smaller than the main screen size.
// Ensure we clear the framebuffer in these tests.
// TODO(gw): Find a better solution for this?
let needs_clear = frame.window_size.width < framebuffer_size.width ||
frame.window_size.height < framebuffer_size.height;
--- a/gfx/webrender_traits/Cargo.toml
+++ b/gfx/webrender_traits/Cargo.toml
@@ -8,20 +8,20 @@ repository = "https://github.com/servo/w
[features]
nightly = ["euclid/unstable", "serde/unstable"]
ipc = ["ipc-channel"]
[dependencies]
app_units = "0.4"
byteorder = "1.0"
euclid = "0.11"
-gleam = "0.2"
+gleam = "0.4"
heapsize = "0.3.6"
ipc-channel = {version = "0.7", optional = true}
-offscreen_gl_context = {version = "0.6", features = ["serde"]}
+offscreen_gl_context = {version = "0.8", features = ["serde"]}
serde = "0.9"
serde_derive = "0.9"
[target.'cfg(target_os = "macos")'.dependencies]
core-graphics = "0.7"
[target.'cfg(target_os = "windows")'.dependencies]
dwrote = "0.3"
--- a/gfx/webrender_traits/src/display_item.rs
+++ b/gfx/webrender_traits/src/display_item.rs
@@ -81,16 +81,17 @@ pub struct WebGLDisplayItem {
pub struct NormalBorder {
pub left: BorderSide,
pub right: BorderSide,
pub top: BorderSide,
pub bottom: BorderSide,
pub radius: BorderRadius,
}
+#[repr(u32)]
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
pub enum RepeatMode {
Stretch,
Repeat,
Round,
Space,
}
@@ -188,16 +189,17 @@ pub struct BoxShadowDisplayItem {
pub offset: LayoutPoint,
pub color: ColorF,
pub blur_radius: f32,
pub spread_radius: f32,
pub border_radius: f32,
pub clip_mode: BoxShadowClipMode,
}
+#[repr(u32)]
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, Ord, PartialOrd)]
pub enum ExtendMode {
Clamp,
Repeat,
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct Gradient {
@@ -246,17 +248,16 @@ pub struct StackingContext {
pub bounds: LayoutRect,
pub z_index: i32,
pub transform: Option<PropertyBinding<LayoutTransform>>,
pub perspective: Option<LayoutTransform>,
pub mix_blend_mode: MixBlendMode,
pub filters: ItemRange,
}
-#[repr(C)]
#[repr(u32)]
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub enum ScrollPolicy {
Scrollable = 0,
Fixed = 1,
}
known_heap_size!(0, ScrollPolicy);
--- a/gfx/webrender_traits/src/image.rs
+++ b/gfx/webrender_traits/src/image.rs
@@ -15,17 +15,16 @@ impl ImageKey {
}
/// An arbitrary identifier for an external image provided by the
/// application. It must be a unique identifier for each external
/// image.
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
pub struct ExternalImageId(pub u64);
-#[repr(C)]
#[repr(u32)]
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub enum ImageFormat {
Invalid = 0,
A8 = 1,
RGB8 = 2,
RGBA8 = 3,
RGBAF32 = 4,
@@ -103,16 +102,17 @@ pub trait BlobImageRenderer: Send {
descriptor: &BlobImageDescriptor);
fn resolve_blob_image(&mut self, key: ImageKey) -> BlobImageResult;
}
pub type BlobImageData = Vec<u8>;
pub type BlobImageResult = Result<RasterizedBlobImage, BlobImageError>;
+#[repr(C)]
#[derive(Copy, Clone, Debug)]
pub struct BlobImageDescriptor {
pub width: u32,
pub height: u32,
pub format: ImageFormat,
pub scale_factor: f32,
}
--- a/gfx/webrender_traits/src/webgl.rs
+++ b/gfx/webrender_traits/src/webgl.rs
@@ -380,283 +380,287 @@ impl fmt::Debug for WebGLCommand {
impl WebGLCommand {
/// NOTE: This method consumes the command
pub fn apply<Native: NativeGLContextMethods>(self, ctx: &GLContext<Native>) {
match self {
WebGLCommand::GetContextAttributes(sender) =>
sender.send(*ctx.borrow_attributes()).unwrap(),
WebGLCommand::ActiveTexture(target) =>
- gl::active_texture(target),
+ ctx.gl().active_texture(target),
WebGLCommand::AttachShader(program_id, shader_id) =>
- gl::attach_shader(program_id.get(), shader_id.get()),
+ ctx.gl().attach_shader(program_id.get(), shader_id.get()),
WebGLCommand::DetachShader(program_id, shader_id) =>
- gl::detach_shader(program_id.get(), shader_id.get()),
+ ctx.gl().detach_shader(program_id.get(), shader_id.get()),
WebGLCommand::BindAttribLocation(program_id, index, name) =>
- gl::bind_attrib_location(program_id.get(), index, &name),
+ ctx.gl().bind_attrib_location(program_id.get(), index, &name),
WebGLCommand::BlendColor(r, g, b, a) =>
- gl::blend_color(r, g, b, a),
+ ctx.gl().blend_color(r, g, b, a),
WebGLCommand::BlendEquation(mode) =>
- gl::blend_equation(mode),
+ ctx.gl().blend_equation(mode),
WebGLCommand::BlendEquationSeparate(mode_rgb, mode_alpha) =>
- gl::blend_equation_separate(mode_rgb, mode_alpha),
+ ctx.gl().blend_equation_separate(mode_rgb, mode_alpha),
WebGLCommand::BlendFunc(src, dest) =>
- gl::blend_func(src, dest),
+ ctx.gl().blend_func(src, dest),
WebGLCommand::BlendFuncSeparate(src_rgb, dest_rgb, src_alpha, dest_alpha) =>
- gl::blend_func_separate(src_rgb, dest_rgb, src_alpha, dest_alpha),
+ ctx.gl().blend_func_separate(src_rgb, dest_rgb, src_alpha, dest_alpha),
WebGLCommand::BufferData(buffer_type, data, usage) =>
- gl::buffer_data(buffer_type, &data, usage),
+ gl::buffer_data(ctx.gl(), buffer_type, &data, usage),
WebGLCommand::BufferSubData(buffer_type, offset, data) =>
- gl::buffer_sub_data(buffer_type, offset, &data),
+ gl::buffer_sub_data(ctx.gl(), buffer_type, offset, &data),
WebGLCommand::Clear(mask) =>
- gl::clear(mask),
+ ctx.gl().clear(mask),
WebGLCommand::ClearColor(r, g, b, a) =>
- gl::clear_color(r, g, b, a),
+ ctx.gl().clear_color(r, g, b, a),
WebGLCommand::ClearDepth(depth) =>
- gl::clear_depth(depth),
+ ctx.gl().clear_depth(depth),
WebGLCommand::ClearStencil(stencil) =>
- gl::clear_stencil(stencil),
+ ctx.gl().clear_stencil(stencil),
WebGLCommand::ColorMask(r, g, b, a) =>
- gl::color_mask(r, g, b, a),
+ ctx.gl().color_mask(r, g, b, a),
WebGLCommand::CopyTexImage2D(target, level, internal_format, x, y, width, height, border) =>
- gl::copy_tex_image_2d(target, level, internal_format, x, y, width, height, border),
+ ctx.gl().copy_tex_image_2d(target, level, internal_format, x, y, width, height, border),
WebGLCommand::CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height) =>
- gl::copy_tex_sub_image_2d(target, level, xoffset, yoffset, x, y, width, height),
+ ctx.gl().copy_tex_sub_image_2d(target, level, xoffset, yoffset, x, y, width, height),
WebGLCommand::CullFace(mode) =>
- gl::cull_face(mode),
+ ctx.gl().cull_face(mode),
WebGLCommand::DepthFunc(func) =>
- gl::depth_func(func),
+ ctx.gl().depth_func(func),
WebGLCommand::DepthMask(flag) =>
- gl::depth_mask(flag),
+ ctx.gl().depth_mask(flag),
WebGLCommand::DepthRange(near, far) =>
- gl::depth_range(near, far),
+ ctx.gl().depth_range(near, far),
WebGLCommand::Disable(cap) =>
- gl::disable(cap),
+ ctx.gl().disable(cap),
WebGLCommand::Enable(cap) =>
- gl::enable(cap),
+ ctx.gl().enable(cap),
WebGLCommand::FramebufferRenderbuffer(target, attachment, renderbuffertarget, rb) =>
- gl::framebuffer_renderbuffer(target, attachment, renderbuffertarget, rb.map_or(0, WebGLRenderbufferId::get)),
+ ctx.gl().framebuffer_renderbuffer(target, attachment, renderbuffertarget, rb.map_or(0, WebGLRenderbufferId::get)),
WebGLCommand::FramebufferTexture2D(target, attachment, textarget, texture, level) =>
- gl::framebuffer_texture_2d(target, attachment, textarget, texture.map_or(0, WebGLTextureId::get), level),
+ ctx.gl().framebuffer_texture_2d(target, attachment, textarget, texture.map_or(0, WebGLTextureId::get), level),
WebGLCommand::FrontFace(mode) =>
- gl::front_face(mode),
+ ctx.gl().front_face(mode),
WebGLCommand::DisableVertexAttribArray(attrib_id) =>
- gl::disable_vertex_attrib_array(attrib_id),
+ ctx.gl().disable_vertex_attrib_array(attrib_id),
WebGLCommand::DrawArrays(mode, first, count) =>
- gl::draw_arrays(mode, first, count),
+ ctx.gl().draw_arrays(mode, first, count),
WebGLCommand::DrawElements(mode, count, type_, offset) =>
- gl::draw_elements(mode, count, type_, offset as u32),
+ ctx.gl().draw_elements(mode, count, type_, offset as u32),
WebGLCommand::EnableVertexAttribArray(attrib_id) =>
- gl::enable_vertex_attrib_array(attrib_id),
+ ctx.gl().enable_vertex_attrib_array(attrib_id),
WebGLCommand::Hint(name, val) =>
- gl::hint(name, val),
+ ctx.gl().hint(name, val),
WebGLCommand::IsEnabled(cap, chan) =>
- chan.send(gl::is_enabled(cap) != 0).unwrap(),
+ chan.send(ctx.gl().is_enabled(cap) != 0).unwrap(),
WebGLCommand::LineWidth(width) =>
- gl::line_width(width),
+ ctx.gl().line_width(width),
WebGLCommand::PixelStorei(name, val) =>
- gl::pixel_store_i(name, val),
+ ctx.gl().pixel_store_i(name, val),
WebGLCommand::PolygonOffset(factor, units) =>
- gl::polygon_offset(factor, units),
+ ctx.gl().polygon_offset(factor, units),
WebGLCommand::ReadPixels(x, y, width, height, format, pixel_type, chan) =>
- Self::read_pixels(x, y, width, height, format, pixel_type, chan),
+ Self::read_pixels(ctx.gl(), x, y, width, height, format, pixel_type, chan),
WebGLCommand::RenderbufferStorage(target, format, width, height) =>
- gl::renderbuffer_storage(target, format, width, height),
+ ctx.gl().renderbuffer_storage(target, format, width, height),
WebGLCommand::SampleCoverage(value, invert) =>
- gl::sample_coverage(value, invert),
+ ctx.gl().sample_coverage(value, invert),
WebGLCommand::Scissor(x, y, width, height) =>
- gl::scissor(x, y, width, height),
+ ctx.gl().scissor(x, y, width, height),
WebGLCommand::StencilFunc(func, ref_, mask) =>
- gl::stencil_func(func, ref_, mask),
+ ctx.gl().stencil_func(func, ref_, mask),
WebGLCommand::StencilFuncSeparate(face, func, ref_, mask) =>
- gl::stencil_func_separate(face, func, ref_, mask),
+ ctx.gl().stencil_func_separate(face, func, ref_, mask),
WebGLCommand::StencilMask(mask) =>
- gl::stencil_mask(mask),
+ ctx.gl().stencil_mask(mask),
WebGLCommand::StencilMaskSeparate(face, mask) =>
- gl::stencil_mask_separate(face, mask),
+ ctx.gl().stencil_mask_separate(face, mask),
WebGLCommand::StencilOp(fail, zfail, zpass) =>
- gl::stencil_op(fail, zfail, zpass),
+ ctx.gl().stencil_op(fail, zfail, zpass),
WebGLCommand::StencilOpSeparate(face, fail, zfail, zpass) =>
- gl::stencil_op_separate(face, fail, zfail, zpass),
+ ctx.gl().stencil_op_separate(face, fail, zfail, zpass),
WebGLCommand::GetActiveAttrib(program_id, index, chan) =>
- Self::active_attrib(program_id, index, chan),
+ Self::active_attrib(ctx.gl(), program_id, index, chan),
WebGLCommand::GetActiveUniform(program_id, index, chan) =>
- Self::active_uniform(program_id, index, chan),
+ Self::active_uniform(ctx.gl(), program_id, index, chan),
WebGLCommand::GetAttribLocation(program_id, name, chan) =>
- Self::attrib_location(program_id, name, chan),
+ Self::attrib_location(ctx.gl(), program_id, name, chan),
WebGLCommand::GetVertexAttrib(index, pname, chan) =>
- Self::vertex_attrib(index, pname, chan),
+ Self::vertex_attrib(ctx.gl(), index, pname, chan),
WebGLCommand::GetBufferParameter(target, param_id, chan) =>
- Self::buffer_parameter(target, param_id, chan),
+ Self::buffer_parameter(ctx.gl(), target, param_id, chan),
WebGLCommand::GetParameter(param_id, chan) =>
- Self::parameter(param_id, chan),
+ Self::parameter(ctx.gl(), param_id, chan),
WebGLCommand::GetProgramParameter(program_id, param_id, chan) =>
- Self::program_parameter(program_id, param_id, chan),
+ Self::program_parameter(ctx.gl(), program_id, param_id, chan),
WebGLCommand::GetShaderParameter(shader_id, param_id, chan) =>
- Self::shader_parameter(shader_id, param_id, chan),
+ Self::shader_parameter(ctx.gl(), shader_id, param_id, chan),
WebGLCommand::GetUniformLocation(program_id, name, chan) =>
- Self::uniform_location(program_id, name, chan),
+ Self::uniform_location(ctx.gl(), program_id, name, chan),
WebGLCommand::GetShaderInfoLog(shader_id, chan) =>
- Self::shader_info_log(shader_id, chan),
+ Self::shader_info_log(ctx.gl(), shader_id, chan),
WebGLCommand::GetProgramInfoLog(program_id, chan) =>
- Self::program_info_log(program_id, chan),
+ Self::program_info_log(ctx.gl(), program_id, chan),
WebGLCommand::CompileShader(shader_id, source) =>
- Self::compile_shader(shader_id, source),
+ Self::compile_shader(ctx.gl(), shader_id, source),
WebGLCommand::CreateBuffer(chan) =>
- Self::create_buffer(chan),
+ Self::create_buffer(ctx.gl(), chan),
WebGLCommand::CreateFramebuffer(chan) =>
- Self::create_framebuffer(chan),
+ Self::create_framebuffer(ctx.gl(), chan),
WebGLCommand::CreateRenderbuffer(chan) =>
- Self::create_renderbuffer(chan),
+ Self::create_renderbuffer(ctx.gl(), chan),
WebGLCommand::CreateTexture(chan) =>
- Self::create_texture(chan),
+ Self::create_texture(ctx.gl(), chan),
WebGLCommand::CreateProgram(chan) =>
- Self::create_program(chan),
+ Self::create_program(ctx.gl(), chan),
WebGLCommand::CreateShader(shader_type, chan) =>
- Self::create_shader(shader_type, chan),
+ Self::create_shader(ctx.gl(), shader_type, chan),
WebGLCommand::DeleteBuffer(id) =>
- gl::delete_buffers(&[id.get()]),
+ ctx.gl().delete_buffers(&[id.get()]),
WebGLCommand::DeleteFramebuffer(id) =>
- gl::delete_framebuffers(&[id.get()]),
+ ctx.gl().delete_framebuffers(&[id.get()]),
WebGLCommand::DeleteRenderbuffer(id) =>
- gl::delete_renderbuffers(&[id.get()]),
+ ctx.gl().delete_renderbuffers(&[id.get()]),
WebGLCommand::DeleteTexture(id) =>
- gl::delete_textures(&[id.get()]),
+ ctx.gl().delete_textures(&[id.get()]),
WebGLCommand::DeleteProgram(id) =>
- gl::delete_program(id.get()),
+ ctx.gl().delete_program(id.get()),
WebGLCommand::DeleteShader(id) =>
- gl::delete_shader(id.get()),
+ ctx.gl().delete_shader(id.get()),
WebGLCommand::BindBuffer(target, id) =>
- gl::bind_buffer(target, id.map_or(0, WebGLBufferId::get)),
+ ctx.gl().bind_buffer(target, id.map_or(0, WebGLBufferId::get)),
WebGLCommand::BindFramebuffer(target, request) =>
- Self::bind_framebuffer(target, request, ctx),
+ Self::bind_framebuffer(ctx.gl(), target, request, ctx),
WebGLCommand::BindRenderbuffer(target, id) =>
- gl::bind_renderbuffer(target, id.map_or(0, WebGLRenderbufferId::get)),
+ ctx.gl().bind_renderbuffer(target, id.map_or(0, WebGLRenderbufferId::get)),
WebGLCommand::BindTexture(target, id) =>
- gl::bind_texture(target, id.map_or(0, WebGLTextureId::get)),
+ ctx.gl().bind_texture(target, id.map_or(0, WebGLTextureId::get)),
WebGLCommand::LinkProgram(program_id) =>
- gl::link_program(program_id.get()),
+ ctx.gl().link_program(program_id.get()),
WebGLCommand::Uniform1f(uniform_id, v) =>
- gl::uniform_1f(uniform_id, v),
+ ctx.gl().uniform_1f(uniform_id, v),
WebGLCommand::Uniform1fv(uniform_id, v) =>
- gl::uniform_1fv(uniform_id, &v),
+ ctx.gl().uniform_1fv(uniform_id, &v),
WebGLCommand::Uniform1i(uniform_id, v) =>
- gl::uniform_1i(uniform_id, v),
+ ctx.gl().uniform_1i(uniform_id, v),
WebGLCommand::Uniform1iv(uniform_id, v) =>
- gl::uniform_1iv(uniform_id, &v),
+ ctx.gl().uniform_1iv(uniform_id, &v),
WebGLCommand::Uniform2f(uniform_id, x, y) =>
- gl::uniform_2f(uniform_id, x, y),
+ ctx.gl().uniform_2f(uniform_id, x, y),
WebGLCommand::Uniform2fv(uniform_id, v) =>
- gl::uniform_2fv(uniform_id, &v),
+ ctx.gl().uniform_2fv(uniform_id, &v),
WebGLCommand::Uniform2i(uniform_id, x, y) =>
- gl::uniform_2i(uniform_id, x, y),
+ ctx.gl().uniform_2i(uniform_id, x, y),
WebGLCommand::Uniform2iv(uniform_id, v) =>
- gl::uniform_2iv(uniform_id, &v),
+ ctx.gl().uniform_2iv(uniform_id, &v),
WebGLCommand::Uniform3f(uniform_id, x, y, z) =>
- gl::uniform_3f(uniform_id, x, y, z),
+ ctx.gl().uniform_3f(uniform_id, x, y, z),
WebGLCommand::Uniform3fv(uniform_id, v) =>
- gl::uniform_3fv(uniform_id, &v),
+ ctx.gl().uniform_3fv(uniform_id, &v),
WebGLCommand::Uniform3i(uniform_id, x, y, z) =>
- gl::uniform_3i(uniform_id, x, y, z),
+ ctx.gl().uniform_3i(uniform_id, x, y, z),
WebGLCommand::Uniform3iv(uniform_id, v) =>
- gl::uniform_3iv(uniform_id, &v),
+ ctx.gl().uniform_3iv(uniform_id, &v),
WebGLCommand::Uniform4f(uniform_id, x, y, z, w) =>
- gl::uniform_4f(uniform_id, x, y, z, w),
+ ctx.gl().uniform_4f(uniform_id, x, y, z, w),
WebGLCommand::Uniform4fv(uniform_id, v) =>
- gl::uniform_4fv(uniform_id, &v),
+ ctx.gl().uniform_4fv(uniform_id, &v),
WebGLCommand::Uniform4i(uniform_id, x, y, z, w) =>
- gl::uniform_4i(uniform_id, x, y, z, w),
+ ctx.gl().uniform_4i(uniform_id, x, y, z, w),
WebGLCommand::Uniform4iv(uniform_id, v) =>
- gl::uniform_4iv(uniform_id, &v),
+ ctx.gl().uniform_4iv(uniform_id, &v),
WebGLCommand::UniformMatrix2fv(uniform_id, transpose, v) =>
- gl::uniform_matrix_2fv(uniform_id, transpose, &v),
+ ctx.gl().uniform_matrix_2fv(uniform_id, transpose, &v),
WebGLCommand::UniformMatrix3fv(uniform_id, transpose, v) =>
- gl::uniform_matrix_3fv(uniform_id, transpose, &v),
+ ctx.gl().uniform_matrix_3fv(uniform_id, transpose, &v),
WebGLCommand::UniformMatrix4fv(uniform_id, transpose, v) =>
- gl::uniform_matrix_4fv(uniform_id, transpose, &v),
+ ctx.gl().uniform_matrix_4fv(uniform_id, transpose, &v),
WebGLCommand::UseProgram(program_id) =>
- gl::use_program(program_id.get()),
+ ctx.gl().use_program(program_id.get()),
WebGLCommand::ValidateProgram(program_id) =>
- gl::validate_program(program_id.get()),
+ ctx.gl().validate_program(program_id.get()),
WebGLCommand::VertexAttrib(attrib_id, x, y, z, w) =>
- gl::vertex_attrib_4f(attrib_id, x, y, z, w),
+ ctx.gl().vertex_attrib_4f(attrib_id, x, y, z, w),
WebGLCommand::VertexAttribPointer2f(attrib_id, size, normalized, stride, offset) =>
- gl::vertex_attrib_pointer_f32(attrib_id, size, normalized, stride, offset),
+ ctx.gl().vertex_attrib_pointer_f32(attrib_id, size, normalized, stride, offset),
WebGLCommand::VertexAttribPointer(attrib_id, size, data_type, normalized, stride, offset) =>
- gl::vertex_attrib_pointer(attrib_id, size, data_type, normalized, stride, offset),
+ ctx.gl().vertex_attrib_pointer(attrib_id, size, data_type, normalized, stride, offset),
WebGLCommand::Viewport(x, y, width, height) =>
- gl::viewport(x, y, width, height),
+ ctx.gl().viewport(x, y, width, height),
WebGLCommand::TexImage2D(target, level, internal, width, height, format, data_type, data) =>
- gl::tex_image_2d(target, level, internal, width, height, /*border*/0, format, data_type, Some(&data)),
+ ctx.gl().tex_image_2d(target, level, internal, width, height, /*border*/0, format, data_type, Some(&data)),
WebGLCommand::TexParameteri(target, name, value) =>
- gl::tex_parameter_i(target, name, value),
+ ctx.gl().tex_parameter_i(target, name, value),
WebGLCommand::TexParameterf(target, name, value) =>
- gl::tex_parameter_f(target, name, value),
+ ctx.gl().tex_parameter_f(target, name, value),
WebGLCommand::TexSubImage2D(target, level, xoffset, yoffset, x, y, width, height, data) =>
- gl::tex_sub_image_2d(target, level, xoffset, yoffset, x, y, width, height, &data),
+ ctx.gl().tex_sub_image_2d(target, level, xoffset, yoffset, x, y, width, height, &data),
WebGLCommand::DrawingBufferWidth(sender) =>
sender.send(ctx.borrow_draw_buffer().unwrap().size().width).unwrap(),
WebGLCommand::DrawingBufferHeight(sender) =>
sender.send(ctx.borrow_draw_buffer().unwrap().size().height).unwrap(),
WebGLCommand::Finish(sender) =>
- Self::finish(sender),
+ Self::finish(ctx.gl(), sender),
WebGLCommand::Flush =>
- gl::flush(),
+ ctx.gl().flush(),
WebGLCommand::GenerateMipmap(target) =>
- gl::generate_mipmap(target),
+ ctx.gl().generate_mipmap(target),
}
// FIXME: Use debug_assertions once tests are run with them
- let error = gl::get_error();
+ let error = ctx.gl().get_error();
assert!(error == gl::NO_ERROR, "Unexpected WebGL error: 0x{:x} ({})", error, error);
}
- fn read_pixels(x: i32, y: i32, width: i32, height: i32, format: u32, pixel_type: u32,
+ fn read_pixels(gl: &gl::Gl, x: i32, y: i32, width: i32, height: i32, format: u32, pixel_type: u32,
chan: MsgSender<Vec<u8>>) {
- let result = gl::read_pixels(x, y, width, height, format, pixel_type);
+ let result = gl.read_pixels(x, y, width, height, format, pixel_type);
chan.send(result).unwrap()
}
- fn active_attrib(program_id: WebGLProgramId,
+ fn active_attrib(gl: &gl::Gl,
+ program_id: WebGLProgramId,
index: u32,
chan: MsgSender<WebGLResult<(i32, u32, String)>>) {
- let result = if index >= gl::get_program_iv(program_id.get(), gl::ACTIVE_ATTRIBUTES) as u32 {
+ let result = if index >= gl.get_program_iv(program_id.get(), gl::ACTIVE_ATTRIBUTES) as u32 {
Err(WebGLError::InvalidValue)
} else {
- Ok(gl::get_active_attrib(program_id.get(), index))
+ Ok(gl.get_active_attrib(program_id.get(), index))
};
chan.send(result).unwrap();
}
- fn active_uniform(program_id: WebGLProgramId,
+ fn active_uniform(gl: &gl::Gl,
+ program_id: WebGLProgramId,
index: u32,
chan: MsgSender<WebGLResult<(i32, u32, String)>>) {
- let result = if index >= gl::get_program_iv(program_id.get(), gl::ACTIVE_UNIFORMS) as u32 {
+ let result = if index >= gl.get_program_iv(program_id.get(), gl::ACTIVE_UNIFORMS) as u32 {
Err(WebGLError::InvalidValue)
} else {
- Ok(gl::get_active_uniform(program_id.get(), index))
+ Ok(gl.get_active_uniform(program_id.get(), index))
};
chan.send(result).unwrap();
}
- fn attrib_location(program_id: WebGLProgramId,
+ fn attrib_location(gl: &gl::Gl,
+ program_id: WebGLProgramId,
name: String,
chan: MsgSender<Option<i32>> ) {
- let attrib_location = gl::get_attrib_location(program_id.get(), &name);
+ let attrib_location = gl.get_attrib_location(program_id.get(), &name);
let attrib_location = if attrib_location == -1 {
None
} else {
Some(attrib_location)
};
chan.send(attrib_location).unwrap();
}
- fn parameter(param_id: u32,
+ fn parameter(gl: &gl::Gl,
+ param_id: u32,
chan: MsgSender<WebGLResult<WebGLParameter>>) {
let result = match param_id {
gl::ACTIVE_TEXTURE |
//gl::ALPHA_BITS |
gl::BLEND_DST_ALPHA |
gl::BLEND_DST_RGB |
gl::BLEND_EQUATION_ALPHA |
gl::BLEND_EQUATION_RGB |
@@ -699,36 +703,36 @@ impl WebGLCommand {
gl::STENCIL_PASS_DEPTH_FAIL |
gl::STENCIL_PASS_DEPTH_PASS |
gl::STENCIL_REF |
gl::STENCIL_VALUE_MASK |
gl::STENCIL_WRITEMASK |
gl::SUBPIXEL_BITS |
gl::UNPACK_ALIGNMENT =>
//gl::UNPACK_COLORSPACE_CONVERSION_WEBGL =>
- Ok(WebGLParameter::Int(gl::get_integer_v(param_id))),
+ Ok(WebGLParameter::Int(gl.get_integer_v(param_id))),
gl::BLEND |
gl::CULL_FACE |
gl::DEPTH_TEST |
gl::DEPTH_WRITEMASK |
gl::DITHER |
gl::POLYGON_OFFSET_FILL |
gl::SAMPLE_COVERAGE_INVERT |
gl::STENCIL_TEST =>
//gl::UNPACK_FLIP_Y_WEBGL |
//gl::UNPACK_PREMULTIPLY_ALPHA_WEBGL =>
- Ok(WebGLParameter::Bool(gl::get_boolean_v(param_id) != 0)),
+ Ok(WebGLParameter::Bool(gl.get_boolean_v(param_id) != 0)),
gl::DEPTH_CLEAR_VALUE |
gl::LINE_WIDTH |
gl::POLYGON_OFFSET_FACTOR |
gl::POLYGON_OFFSET_UNITS |
gl::SAMPLE_COVERAGE_VALUE =>
- Ok(WebGLParameter::Float(gl::get_float_v(param_id))),
+ Ok(WebGLParameter::Float(gl.get_float_v(param_id))),
gl::VERSION => Ok(WebGLParameter::String("WebGL 1.0".to_owned())),
gl::RENDERER |
gl::VENDOR => Ok(WebGLParameter::String("Mozilla/Servo".to_owned())),
gl::SHADING_LANGUAGE_VERSION => Ok(WebGLParameter::String("WebGL GLSL ES 1.0".to_owned())),
// TODO(zbarsky, emilio): Implement support for the following valid parameters
// Float32Array
@@ -768,189 +772,195 @@ impl WebGLCommand {
// Invalid parameters
_ => Err(WebGLError::InvalidEnum)
};
chan.send(result).unwrap();
}
- fn finish(chan: MsgSender<()>) {
- gl::finish();
+ fn finish(gl: &gl::Gl, chan: MsgSender<()>) {
+ gl.finish();
chan.send(()).unwrap();
}
- fn vertex_attrib(index: u32,
+ fn vertex_attrib(gl: &gl::Gl,
+ index: u32,
pname: u32,
chan: MsgSender<WebGLResult<WebGLParameter>>) {
- let result = if index >= gl::get_integer_v(gl::MAX_VERTEX_ATTRIBS) as u32 {
+ let result = if index >= gl.get_integer_v(gl::MAX_VERTEX_ATTRIBS) as u32 {
Err(WebGLError::InvalidValue)
} else {
match pname {
gl::VERTEX_ATTRIB_ARRAY_ENABLED |
gl::VERTEX_ATTRIB_ARRAY_NORMALIZED =>
- Ok(WebGLParameter::Bool(gl::get_vertex_attrib_iv(index, pname) != 0)),
+ Ok(WebGLParameter::Bool(gl.get_vertex_attrib_iv(index, pname) != 0)),
gl::VERTEX_ATTRIB_ARRAY_SIZE |
gl::VERTEX_ATTRIB_ARRAY_STRIDE |
gl::VERTEX_ATTRIB_ARRAY_TYPE =>
- Ok(WebGLParameter::Int(gl::get_vertex_attrib_iv(index, pname))),
+ Ok(WebGLParameter::Int(gl.get_vertex_attrib_iv(index, pname))),
gl::CURRENT_VERTEX_ATTRIB =>
- Ok(WebGLParameter::FloatArray(gl::get_vertex_attrib_fv(index, pname))),
+ Ok(WebGLParameter::FloatArray(gl.get_vertex_attrib_fv(index, pname))),
// gl::VERTEX_ATTRIB_ARRAY_BUFFER_BINDING should return WebGLBuffer
_ => Err(WebGLError::InvalidEnum),
}
};
chan.send(result).unwrap();
}
- fn buffer_parameter(target: u32,
+ fn buffer_parameter(gl: &gl::Gl,
+ target: u32,
param_id: u32,
chan: MsgSender<WebGLResult<WebGLParameter>>) {
let result = match param_id {
gl::BUFFER_SIZE |
gl::BUFFER_USAGE =>
- Ok(WebGLParameter::Int(gl::get_buffer_parameter_iv(target, param_id))),
+ Ok(WebGLParameter::Int(gl.get_buffer_parameter_iv(target, param_id))),
_ => Err(WebGLError::InvalidEnum),
};
chan.send(result).unwrap();
}
- fn program_parameter(program_id: WebGLProgramId,
+ fn program_parameter(gl: &gl::Gl,
+ program_id: WebGLProgramId,
param_id: u32,
chan: MsgSender<WebGLResult<WebGLParameter>>) {
let result = match param_id {
gl::DELETE_STATUS |
gl::LINK_STATUS |
gl::VALIDATE_STATUS =>
- Ok(WebGLParameter::Bool(gl::get_program_iv(program_id.get(), param_id) != 0)),
+ Ok(WebGLParameter::Bool(gl.get_program_iv(program_id.get(), param_id) != 0)),
gl::ATTACHED_SHADERS |
gl::ACTIVE_ATTRIBUTES |
gl::ACTIVE_UNIFORMS =>
- Ok(WebGLParameter::Int(gl::get_program_iv(program_id.get(), param_id))),
+ Ok(WebGLParameter::Int(gl.get_program_iv(program_id.get(), param_id))),
_ => Err(WebGLError::InvalidEnum),
};
chan.send(result).unwrap();
}
- fn shader_parameter(shader_id: WebGLShaderId,
+ fn shader_parameter(gl: &gl::Gl,
+ shader_id: WebGLShaderId,
param_id: u32,
chan: MsgSender<WebGLResult<WebGLParameter>>) {
let result = match param_id {
gl::SHADER_TYPE =>
- Ok(WebGLParameter::Int(gl::get_shader_iv(shader_id.get(), param_id))),
+ Ok(WebGLParameter::Int(gl.get_shader_iv(shader_id.get(), param_id))),
gl::DELETE_STATUS |
gl::COMPILE_STATUS =>
- Ok(WebGLParameter::Bool(gl::get_shader_iv(shader_id.get(), param_id) != 0)),
+ Ok(WebGLParameter::Bool(gl.get_shader_iv(shader_id.get(), param_id) != 0)),
_ => Err(WebGLError::InvalidEnum),
};
chan.send(result).unwrap();
}
- fn uniform_location(program_id: WebGLProgramId,
+ fn uniform_location(gl: &gl::Gl,
+ program_id: WebGLProgramId,
name: String,
chan: MsgSender<Option<i32>>) {
- let location = gl::get_uniform_location(program_id.get(), &name);
+ let location = gl.get_uniform_location(program_id.get(), &name);
let location = if location == -1 {
None
} else {
Some(location)
};
chan.send(location).unwrap();
}
- fn shader_info_log(shader_id: WebGLShaderId, chan: MsgSender<String>) {
- let log = gl::get_shader_info_log(shader_id.get());
+ fn shader_info_log(gl: &gl::Gl, shader_id: WebGLShaderId, chan: MsgSender<String>) {
+ let log = gl.get_shader_info_log(shader_id.get());
chan.send(log).unwrap();
}
- fn program_info_log(program_id: WebGLProgramId, chan: MsgSender<String>) {
- let log = gl::get_program_info_log(program_id.get());
+ fn program_info_log(gl: &gl::Gl, program_id: WebGLProgramId, chan: MsgSender<String>) {
+ let log = gl.get_program_info_log(program_id.get());
chan.send(log).unwrap();
}
- fn create_buffer(chan: MsgSender<Option<WebGLBufferId>>) {
- let buffer = gl::gen_buffers(1)[0];
+ fn create_buffer(gl: &gl::Gl, chan: MsgSender<Option<WebGLBufferId>>) {
+ let buffer = gl.gen_buffers(1)[0];
let buffer = if buffer == 0 {
None
} else {
Some(unsafe { WebGLBufferId::new(buffer) })
};
chan.send(buffer).unwrap();
}
- fn create_framebuffer(chan: MsgSender<Option<WebGLFramebufferId>>) {
- let framebuffer = gl::gen_framebuffers(1)[0];
+ fn create_framebuffer(gl: &gl::Gl, chan: MsgSender<Option<WebGLFramebufferId>>) {
+ let framebuffer = gl.gen_framebuffers(1)[0];
let framebuffer = if framebuffer == 0 {
None
} else {
Some(unsafe { WebGLFramebufferId::new(framebuffer) })
};
chan.send(framebuffer).unwrap();
}
- fn create_renderbuffer(chan: MsgSender<Option<WebGLRenderbufferId>>) {
- let renderbuffer = gl::gen_renderbuffers(1)[0];
+ fn create_renderbuffer(gl: &gl::Gl, chan: MsgSender<Option<WebGLRenderbufferId>>) {
+ let renderbuffer = gl.gen_renderbuffers(1)[0];
let renderbuffer = if renderbuffer == 0 {
None
} else {
Some(unsafe { WebGLRenderbufferId::new(renderbuffer) })
};
chan.send(renderbuffer).unwrap();
}
- fn create_texture(chan: MsgSender<Option<WebGLTextureId>>) {
- let texture = gl::gen_textures(1)[0];
+ fn create_texture(gl: &gl::Gl, chan: MsgSender<Option<WebGLTextureId>>) {
+ let texture = gl.gen_textures(1)[0];
let texture = if texture == 0 {
None
} else {
Some(unsafe { WebGLTextureId::new(texture) })
};
chan.send(texture).unwrap();
}
- fn create_program(chan: MsgSender<Option<WebGLProgramId>>) {
- let program = gl::create_program();
+ fn create_program(gl: &gl::Gl, chan: MsgSender<Option<WebGLProgramId>>) {
+ let program = gl.create_program();
let program = if program == 0 {
None
} else {
Some(unsafe { WebGLProgramId::new(program) })
};
chan.send(program).unwrap();
}
- fn create_shader(shader_type: u32, chan: MsgSender<Option<WebGLShaderId>>) {
- let shader = gl::create_shader(shader_type);
+ fn create_shader(gl: &gl::Gl, shader_type: u32, chan: MsgSender<Option<WebGLShaderId>>) {
+ let shader = gl.create_shader(shader_type);
let shader = if shader == 0 {
None
} else {
Some(unsafe { WebGLShaderId::new(shader) })
};
chan.send(shader).unwrap();
}
#[inline]
- fn bind_framebuffer<Native: NativeGLContextMethods>(target: u32,
+ fn bind_framebuffer<Native: NativeGLContextMethods>(gl: &gl::Gl,
+ target: u32,
request: WebGLFramebufferBindingRequest,
ctx: &GLContext<Native>) {
let id = match request {
WebGLFramebufferBindingRequest::Explicit(id) => id.get(),
WebGLFramebufferBindingRequest::Default =>
ctx.borrow_draw_buffer().unwrap().get_framebuffer(),
};
- gl::bind_framebuffer(target, id);
+ gl.bind_framebuffer(target, id);
}
#[inline]
- fn compile_shader(shader_id: WebGLShaderId, source: String) {
- gl::shader_source(shader_id.get(), &[source.as_bytes()]);
- gl::compile_shader(shader_id.get());
+ fn compile_shader(gl: &gl::Gl, shader_id: WebGLShaderId, source: String) {
+ gl.shader_source(shader_id.get(), &[source.as_bytes()]);
+ gl.compile_shader(shader_id.get());
}
}