aboutsummaryrefslogtreecommitdiffstats
path: root/components/canvas/webgl_limits.rs
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2019-10-15 12:57:00 -0500
committerAlan Jeffrey <ajeffrey@mozilla.com>2019-11-01 08:47:11 -0500
commita358bca7667a2da42024aca4ef619dad6d812862 (patch)
treeacf2cc228afdf6875931d546cc08ec29dfb05362 /components/canvas/webgl_limits.rs
parent48d918dcdead5fcf38dbda1dfc0d0ca8284108c2 (diff)
downloadservo-a358bca7667a2da42024aca4ef619dad6d812862.tar.gz
servo-a358bca7667a2da42024aca4ef619dad6d812862.zip
Use surfman for managing GL surfaces
Co-authored-by: Alan Jeffrey <ajeffrey@mozilla.com> Co-authored-by: Zakor Gyula <gyula.zakor@h-lab.eu> Co-authored-by: Josh Matthews <josh@joshmatthews.net>
Diffstat (limited to 'components/canvas/webgl_limits.rs')
-rw-r--r--components/canvas/webgl_limits.rs96
1 files changed, 96 insertions, 0 deletions
diff --git a/components/canvas/webgl_limits.rs b/components/canvas/webgl_limits.rs
new file mode 100644
index 00000000000..23630117515
--- /dev/null
+++ b/components/canvas/webgl_limits.rs
@@ -0,0 +1,96 @@
+/* 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 https://mozilla.org/MPL/2.0/. */
+
+use canvas_traits::webgl::GLLimits;
+use sparkle::gl;
+use sparkle::gl::GLenum;
+use sparkle::gl::Gl;
+
+pub trait GLLimitsDetect {
+ fn detect(gl: &Gl) -> Self;
+}
+
+impl GLLimitsDetect for GLLimits {
+ fn detect(gl: &Gl) -> GLLimits {
+ let max_vertex_attribs = gl.get_integer(gl::MAX_VERTEX_ATTRIBS);
+ let max_tex_size = gl.get_integer(gl::MAX_TEXTURE_SIZE);
+ let max_cube_map_tex_size = gl.get_integer(gl::MAX_CUBE_MAP_TEXTURE_SIZE);
+ let max_combined_texture_image_units = gl.get_integer(gl::MAX_COMBINED_TEXTURE_IMAGE_UNITS);
+ let max_renderbuffer_size = gl.get_integer(gl::MAX_RENDERBUFFER_SIZE);
+ let max_texture_image_units = gl.get_integer(gl::MAX_TEXTURE_IMAGE_UNITS);
+ let max_vertex_texture_image_units = gl.get_integer(gl::MAX_VERTEX_TEXTURE_IMAGE_UNITS);
+
+ // TODO: better value for this?
+ let max_client_wait_timeout_webgl = std::time::Duration::new(1, 0);
+
+ // Based on:
+ // https://searchfox.org/mozilla-central/rev/5a744713370ec47969595e369fd5125f123e6d24/dom/canvas/WebGLContextValidate.cpp#523-558
+ let (max_fragment_uniform_vectors, max_varying_vectors, max_vertex_uniform_vectors);
+ match gl.try_get_integer(gl::MAX_FRAGMENT_UNIFORM_VECTORS) {
+ Some(max_vectors) => {
+ max_fragment_uniform_vectors = max_vectors;
+ max_varying_vectors = gl.get_integer(gl::MAX_VARYING_VECTORS);
+ max_vertex_uniform_vectors = gl.get_integer(gl::MAX_VERTEX_UNIFORM_VECTORS);
+ },
+ None => {
+ let max_fragment_uniform_components =
+ gl.get_integer(gl::MAX_FRAGMENT_UNIFORM_COMPONENTS);
+ let max_vertex_uniform_components =
+ gl.get_integer(gl::MAX_VERTEX_UNIFORM_COMPONENTS);
+
+ let max_vertex_output_components = gl
+ .try_get_integer(gl::MAX_VERTEX_OUTPUT_COMPONENTS)
+ .unwrap_or(0);
+ let max_fragment_input_components = gl
+ .try_get_integer(gl::MAX_FRAGMENT_INPUT_COMPONENTS)
+ .unwrap_or(0);
+ let max_varying_components = max_vertex_output_components
+ .min(max_fragment_input_components)
+ .max(16);
+
+ max_fragment_uniform_vectors = max_fragment_uniform_components / 4;
+ max_varying_vectors = max_varying_components / 4;
+ max_vertex_uniform_vectors = max_vertex_uniform_components / 4;
+ },
+ }
+
+ GLLimits {
+ max_vertex_attribs,
+ max_tex_size,
+ max_cube_map_tex_size,
+ max_combined_texture_image_units,
+ max_fragment_uniform_vectors,
+ max_renderbuffer_size,
+ max_texture_image_units,
+ max_varying_vectors,
+ max_vertex_texture_image_units,
+ max_vertex_uniform_vectors,
+ max_client_wait_timeout_webgl,
+ }
+ }
+}
+
+trait GLExt {
+ fn try_get_integer(self, parameter: GLenum) -> Option<u32>;
+ fn get_integer(self, parameter: GLenum) -> u32;
+}
+
+impl<'a> GLExt for &'a Gl {
+ #[allow(unsafe_code)]
+ fn try_get_integer(self, parameter: GLenum) -> Option<u32> {
+ let mut value = [0];
+ unsafe {
+ self.get_integer_v(parameter, &mut value);
+ }
+ if self.get_error() != gl::NO_ERROR {
+ None
+ } else {
+ Some(value[0] as u32)
+ }
+ }
+
+ fn get_integer(self, parameter: GLenum) -> u32 {
+ self.try_get_integer(parameter).unwrap()
+ }
+}