mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
Split webgl into separate crate (#36718)
canvas crate was home for both webgl and 2dcanvas impl, but it makes more sense to separate these two, by splitting webgl into standalone crate (like we already have for webgpu). Testing: Rust for fearless refactoring (but there are WPT tests just in case) Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
This commit is contained in:
parent
0c0ee04b8e
commit
955149b194
12 changed files with 79 additions and 33 deletions
259
components/webgl/webgl_limits.rs
Normal file
259
components/webgl/webgl_limits.rs
Normal file
|
@ -0,0 +1,259 @@
|
|||
/* 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, WebGLVersion};
|
||||
use glow::{self as gl, Context as Gl, HasContext};
|
||||
type GLenum = u32;
|
||||
|
||||
pub trait GLLimitsDetect {
|
||||
fn detect(gl: &Gl, webgl_version: WebGLVersion) -> Self;
|
||||
}
|
||||
|
||||
impl GLLimitsDetect for GLLimits {
|
||||
fn detect(gl: &Gl, webgl_version: WebGLVersion) -> 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,
|
||||
max_vertex_output_vectors,
|
||||
max_fragment_input_vectors,
|
||||
);
|
||||
if gl.version().is_embedded {
|
||||
max_fragment_uniform_vectors = gl.get_integer(gl::MAX_FRAGMENT_UNIFORM_VECTORS);
|
||||
max_varying_vectors = gl.get_integer(gl::MAX_VARYING_VECTORS);
|
||||
max_vertex_uniform_vectors = gl.get_integer(gl::MAX_VERTEX_UNIFORM_VECTORS);
|
||||
max_vertex_output_vectors = gl
|
||||
.try_get_integer(gl::MAX_VERTEX_OUTPUT_COMPONENTS)
|
||||
.map(|c| c / 4)
|
||||
.unwrap_or(max_varying_vectors);
|
||||
max_fragment_input_vectors = gl
|
||||
.try_get_integer(gl::MAX_FRAGMENT_INPUT_COMPONENTS)
|
||||
.map(|c| c / 4)
|
||||
.unwrap_or(max_vertex_output_vectors);
|
||||
} else {
|
||||
max_fragment_uniform_vectors = gl.get_integer(gl::MAX_FRAGMENT_UNIFORM_COMPONENTS) / 4;
|
||||
max_vertex_uniform_vectors = gl.get_integer(gl::MAX_VERTEX_UNIFORM_COMPONENTS) / 4;
|
||||
|
||||
max_fragment_input_vectors = gl
|
||||
.try_get_integer(gl::MAX_FRAGMENT_INPUT_COMPONENTS)
|
||||
.or_else(|| gl.try_get_integer(gl::MAX_VARYING_COMPONENTS))
|
||||
.map(|c| c / 4)
|
||||
.unwrap_or_else(|| gl.get_integer(gl::MAX_VARYING_VECTORS));
|
||||
max_vertex_output_vectors = gl
|
||||
.try_get_integer(gl::MAX_VERTEX_OUTPUT_COMPONENTS)
|
||||
.map(|c| c / 4)
|
||||
.unwrap_or(max_fragment_input_vectors);
|
||||
max_varying_vectors = max_vertex_output_vectors
|
||||
.min(max_fragment_input_vectors)
|
||||
.max(4);
|
||||
};
|
||||
|
||||
let (
|
||||
max_uniform_block_size,
|
||||
max_uniform_buffer_bindings,
|
||||
min_program_texel_offset,
|
||||
max_program_texel_offset,
|
||||
max_transform_feedback_separate_attribs,
|
||||
max_draw_buffers,
|
||||
max_color_attachments,
|
||||
max_combined_uniform_blocks,
|
||||
max_combined_vertex_uniform_components,
|
||||
max_combined_fragment_uniform_components,
|
||||
max_vertex_uniform_blocks,
|
||||
max_vertex_uniform_components,
|
||||
max_fragment_uniform_blocks,
|
||||
max_fragment_uniform_components,
|
||||
max_3d_texture_size,
|
||||
max_array_texture_layers,
|
||||
uniform_buffer_offset_alignment,
|
||||
max_element_index,
|
||||
max_elements_indices,
|
||||
max_elements_vertices,
|
||||
max_fragment_input_components,
|
||||
max_samples,
|
||||
max_server_wait_timeout,
|
||||
max_texture_lod_bias,
|
||||
max_varying_components,
|
||||
max_vertex_output_components,
|
||||
);
|
||||
if webgl_version == WebGLVersion::WebGL2 {
|
||||
max_uniform_block_size = gl.get_integer64(gl::MAX_UNIFORM_BLOCK_SIZE);
|
||||
max_uniform_buffer_bindings = gl.get_integer(gl::MAX_UNIFORM_BUFFER_BINDINGS);
|
||||
min_program_texel_offset = gl.get_signed_integer(gl::MIN_PROGRAM_TEXEL_OFFSET);
|
||||
max_program_texel_offset = gl.get_integer(gl::MAX_PROGRAM_TEXEL_OFFSET);
|
||||
max_transform_feedback_separate_attribs =
|
||||
gl.get_integer(gl::MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS);
|
||||
max_color_attachments = gl.get_integer(gl::MAX_COLOR_ATTACHMENTS);
|
||||
max_draw_buffers = gl
|
||||
.get_integer(gl::MAX_DRAW_BUFFERS)
|
||||
.min(max_color_attachments);
|
||||
max_combined_uniform_blocks = gl.get_integer(gl::MAX_COMBINED_UNIFORM_BLOCKS);
|
||||
max_combined_vertex_uniform_components =
|
||||
gl.get_integer64(gl::MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS);
|
||||
max_combined_fragment_uniform_components =
|
||||
gl.get_integer64(gl::MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS);
|
||||
max_vertex_uniform_blocks = gl.get_integer(gl::MAX_VERTEX_UNIFORM_BLOCKS);
|
||||
max_vertex_uniform_components = gl.get_integer(gl::MAX_VERTEX_UNIFORM_COMPONENTS);
|
||||
max_fragment_uniform_blocks = gl.get_integer(gl::MAX_FRAGMENT_UNIFORM_BLOCKS);
|
||||
max_fragment_uniform_components = gl.get_integer(gl::MAX_FRAGMENT_UNIFORM_COMPONENTS);
|
||||
uniform_buffer_offset_alignment = gl.get_integer(gl::UNIFORM_BUFFER_OFFSET_ALIGNMENT);
|
||||
max_3d_texture_size = gl.get_integer(gl::MAX_3D_TEXTURE_SIZE);
|
||||
max_array_texture_layers = gl.get_integer(gl::MAX_ARRAY_TEXTURE_LAYERS);
|
||||
max_element_index = gl
|
||||
.try_get_integer64(gl::MAX_ELEMENT_INDEX)
|
||||
.unwrap_or(u32::MAX as u64); // requires GL 4.3
|
||||
max_elements_indices = gl.get_integer(gl::MAX_ELEMENTS_INDICES);
|
||||
max_elements_vertices = gl.get_integer(gl::MAX_ELEMENTS_VERTICES);
|
||||
max_fragment_input_components = gl.get_integer(gl::MAX_FRAGMENT_INPUT_COMPONENTS);
|
||||
max_samples = gl.get_integer(gl::MAX_SAMPLES);
|
||||
max_server_wait_timeout =
|
||||
std::time::Duration::from_nanos(gl.get_integer64(gl::MAX_SERVER_WAIT_TIMEOUT));
|
||||
max_texture_lod_bias = gl.get_float(gl::MAX_TEXTURE_LOD_BIAS);
|
||||
max_varying_components = gl.try_get_integer(gl::MAX_VARYING_COMPONENTS).unwrap_or(
|
||||
// macOS Core Profile is buggy. The spec says this value is 4 * MAX_VARYING_VECTORS.
|
||||
max_varying_vectors * 4,
|
||||
);
|
||||
max_vertex_output_components = gl.get_integer(gl::MAX_VERTEX_OUTPUT_COMPONENTS);
|
||||
} else {
|
||||
max_uniform_block_size = 0;
|
||||
max_uniform_buffer_bindings = 0;
|
||||
min_program_texel_offset = 0;
|
||||
max_program_texel_offset = 0;
|
||||
max_transform_feedback_separate_attribs = 0;
|
||||
max_color_attachments = 1;
|
||||
max_draw_buffers = 1;
|
||||
max_combined_uniform_blocks = 0;
|
||||
max_combined_vertex_uniform_components = 0;
|
||||
max_combined_fragment_uniform_components = 0;
|
||||
max_vertex_uniform_blocks = 0;
|
||||
max_vertex_uniform_components = 0;
|
||||
max_fragment_uniform_blocks = 0;
|
||||
max_fragment_uniform_components = 0;
|
||||
uniform_buffer_offset_alignment = 0;
|
||||
max_3d_texture_size = 0;
|
||||
max_array_texture_layers = 0;
|
||||
max_element_index = 0;
|
||||
max_elements_indices = 0;
|
||||
max_elements_vertices = 0;
|
||||
max_fragment_input_components = 0;
|
||||
max_samples = 0;
|
||||
max_server_wait_timeout = std::time::Duration::default();
|
||||
max_texture_lod_bias = 0.0;
|
||||
max_varying_components = 0;
|
||||
max_vertex_output_components = 0;
|
||||
}
|
||||
|
||||
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,
|
||||
max_transform_feedback_separate_attribs,
|
||||
max_vertex_output_vectors,
|
||||
max_fragment_input_vectors,
|
||||
max_uniform_buffer_bindings,
|
||||
min_program_texel_offset,
|
||||
max_program_texel_offset,
|
||||
max_color_attachments,
|
||||
max_draw_buffers,
|
||||
max_uniform_block_size,
|
||||
max_combined_uniform_blocks,
|
||||
max_combined_vertex_uniform_components,
|
||||
max_combined_fragment_uniform_components,
|
||||
max_vertex_uniform_blocks,
|
||||
max_vertex_uniform_components,
|
||||
max_fragment_uniform_blocks,
|
||||
max_fragment_uniform_components,
|
||||
max_3d_texture_size,
|
||||
max_array_texture_layers,
|
||||
uniform_buffer_offset_alignment,
|
||||
max_element_index,
|
||||
max_elements_indices,
|
||||
max_elements_vertices,
|
||||
max_fragment_input_components,
|
||||
max_samples,
|
||||
max_server_wait_timeout,
|
||||
max_texture_lod_bias,
|
||||
max_varying_components,
|
||||
max_vertex_output_components,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trait GLExt {
|
||||
fn try_get_integer(self, parameter: GLenum) -> Option<u32>;
|
||||
fn try_get_integer64(self, parameter: GLenum) -> Option<u64>;
|
||||
fn try_get_signed_integer(self, parameter: GLenum) -> Option<i32>;
|
||||
fn try_get_float(self, parameter: GLenum) -> Option<f32>;
|
||||
fn get_integer(self, parameter: GLenum) -> u32;
|
||||
fn get_integer64(self, parameter: GLenum) -> u64;
|
||||
fn get_signed_integer(self, parameter: GLenum) -> i32;
|
||||
fn get_float(self, parameter: GLenum) -> f32;
|
||||
}
|
||||
|
||||
macro_rules! create_fun {
|
||||
($tryer:ident, $getter:ident, $gltype:ty, $glcall:ident, $rstype:ty) => {
|
||||
#[allow(unsafe_code)]
|
||||
fn $tryer(self, parameter: GLenum) -> Option<$rstype> {
|
||||
let mut value = [<$gltype>::default()];
|
||||
unsafe {
|
||||
self.$glcall(parameter, &mut value);
|
||||
}
|
||||
if unsafe { self.get_error() } != gl::NO_ERROR {
|
||||
None
|
||||
} else {
|
||||
Some(value[0] as $rstype)
|
||||
}
|
||||
}
|
||||
|
||||
fn $getter(self, parameter: GLenum) -> $rstype {
|
||||
self.$tryer(parameter).unwrap()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl GLExt for &Gl {
|
||||
create_fun!(
|
||||
try_get_integer,
|
||||
get_integer,
|
||||
i32,
|
||||
get_parameter_i32_slice,
|
||||
u32
|
||||
);
|
||||
create_fun!(
|
||||
try_get_integer64,
|
||||
get_integer64,
|
||||
i64,
|
||||
get_parameter_i64_slice,
|
||||
u64
|
||||
);
|
||||
create_fun!(
|
||||
try_get_signed_integer,
|
||||
get_signed_integer,
|
||||
i32,
|
||||
get_parameter_i32_slice,
|
||||
i32
|
||||
);
|
||||
create_fun!(try_get_float, get_float, f32, get_parameter_f32_slice, f32);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue