diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2020-03-10 10:37:53 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-10 10:37:53 -0400 |
commit | 30fafdca19fd1eeb624c661b4c90c68482a43c05 (patch) | |
tree | 31b0755a1f935800039c2fe24c1388c7919ad5b6 /components | |
parent | 70101786915ffbe0ec8141f125af855613b1a00c (diff) | |
parent | 215dd0a1d8a1790c503424a4789fe7a664f896eb (diff) | |
download | servo-30fafdca19fd1eeb624c661b4c90c68482a43c05.tar.gz servo-30fafdca19fd1eeb624c661b4c90c68482a43c05.zip |
Auto merge of #25930 - mmatyas:webgl_fns_indexed_unibuf, r=jdm
Add support for WebGL2 GetIndexedParameter
Adds support for the `GetIndexedParameter` WebGL2 call.
See: https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.2
<!-- Please describe your changes on the following line: -->
Depends on #25915.
cc @jdm @zakorgy
---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] There are tests for these changes
<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->
<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
Diffstat (limited to 'components')
-rw-r--r-- | components/script/dom/webgl2renderingcontext.rs | 135 | ||||
-rw-r--r-- | components/script/dom/webidls/WebGL2RenderingContext.webidl | 2 |
2 files changed, 116 insertions, 21 deletions
diff --git a/components/script/dom/webgl2renderingcontext.rs b/components/script/dom/webgl2renderingcontext.rs index d6452a88043..1c458778a1c 100644 --- a/components/script/dom/webgl2renderingcontext.rs +++ b/components/script/dom/webgl2renderingcontext.rs @@ -56,6 +56,24 @@ use std::cell::Cell; use std::cmp; use std::ptr::{self, NonNull}; +#[unrooted_must_root_lint::must_root] +#[derive(JSTraceable, MallocSizeOf)] +struct IndexedBinding { + buffer: MutNullableDom<WebGLBuffer>, + start: Cell<i64>, + size: Cell<i64>, +} + +impl IndexedBinding { + fn new() -> IndexedBinding { + IndexedBinding { + buffer: MutNullableDom::new(None), + start: Cell::new(0), + size: Cell::new(0), + } + } +} + #[dom_struct] pub struct WebGL2RenderingContext { reflector_: Reflector, @@ -69,6 +87,8 @@ pub struct WebGL2RenderingContext { bound_pixel_unpack_buffer: MutNullableDom<WebGLBuffer>, bound_transform_feedback_buffer: MutNullableDom<WebGLBuffer>, bound_uniform_buffer: MutNullableDom<WebGLBuffer>, + indexed_uniform_buffer_bindings: Box<[IndexedBinding]>, + indexed_transform_feedback_buffer_bindings: Box<[IndexedBinding]>, current_transform_feedback: MutNullableDom<WebGLTransformFeedback>, texture_pack_row_length: Cell<usize>, texture_pack_skip_pixels: Cell<usize>, @@ -111,6 +131,15 @@ impl WebGL2RenderingContext { .map(|_| Default::default()) .collect::<Vec<_>>() .into(); + let indexed_uniform_buffer_bindings = (0..base.limits().max_uniform_buffer_bindings) + .map(|_| IndexedBinding::new()) + .collect::<Vec<_>>() + .into(); + let indexed_transform_feedback_buffer_bindings = + (0..base.limits().max_transform_feedback_separate_attribs) + .map(|_| IndexedBinding::new()) + .collect::<Vec<_>>() + .into(); Some(WebGL2RenderingContext { reflector_: Reflector::new(), @@ -124,6 +153,8 @@ impl WebGL2RenderingContext { bound_pixel_unpack_buffer: MutNullableDom::new(None), bound_transform_feedback_buffer: MutNullableDom::new(None), bound_uniform_buffer: MutNullableDom::new(None), + indexed_uniform_buffer_bindings, + indexed_transform_feedback_buffer_bindings, current_transform_feedback: MutNullableDom::new(None), texture_pack_row_length: Cell::new(0), texture_pack_skip_pixels: Cell::new(0), @@ -1396,6 +1427,14 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { self.unbind_from(&self.bound_pixel_unpack_buffer, &buffer); self.unbind_from(&self.bound_transform_feedback_buffer, &buffer); self.unbind_from(&self.bound_uniform_buffer, &buffer); + + for binding in self.indexed_uniform_buffer_bindings.iter() { + self.unbind_from(&binding.buffer, &buffer); + } + for binding in self.indexed_transform_feedback_buffer_bindings.iter() { + self.unbind_from(&binding.buffer, &buffer); + } + buffer.mark_for_deletion(false); } @@ -1520,6 +1559,46 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { .GetShaderPrecisionFormat(shader_type, precision_type) } + /// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.2 + #[allow(unsafe_code)] + fn GetIndexedParameter(&self, cx: JSContext, target: u32, index: u32) -> JSVal { + let bindings = match target { + constants::TRANSFORM_FEEDBACK_BUFFER_BINDING | + constants::TRANSFORM_FEEDBACK_BUFFER_SIZE | + constants::TRANSFORM_FEEDBACK_BUFFER_START => { + &self.indexed_transform_feedback_buffer_bindings + }, + constants::UNIFORM_BUFFER_BINDING | + constants::UNIFORM_BUFFER_SIZE | + constants::UNIFORM_BUFFER_START => &self.indexed_uniform_buffer_bindings, + _ => { + self.base.webgl_error(InvalidEnum); + return NullValue(); + }, + }; + + let binding = match bindings.get(index as usize) { + Some(binding) => binding, + None => { + self.base.webgl_error(InvalidValue); + return NullValue(); + }, + }; + + match target { + constants::TRANSFORM_FEEDBACK_BUFFER_BINDING | constants::UNIFORM_BUFFER_BINDING => unsafe { + optional_root_object_to_js_or_null!(*cx, binding.buffer.get()) + }, + constants::TRANSFORM_FEEDBACK_BUFFER_START | constants::UNIFORM_BUFFER_START => { + Int32Value(binding.start.get() as _) + }, + constants::TRANSFORM_FEEDBACK_BUFFER_SIZE | constants::UNIFORM_BUFFER_SIZE => { + Int32Value(binding.size.get() as _) + }, + _ => unreachable!(), + } + } + /// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 fn GetUniformLocation( &self, @@ -3212,20 +3291,21 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { /// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.16 fn BindBufferBase(&self, target: u32, index: u32, buffer: Option<&WebGLBuffer>) { - let (bind_limit, slot) = match target { + let (generic_slot, indexed_bindings) = match target { constants::TRANSFORM_FEEDBACK_BUFFER => ( - self.base.limits().max_transform_feedback_separate_attribs, &self.bound_transform_feedback_buffer, + &self.indexed_transform_feedback_buffer_bindings, ), constants::UNIFORM_BUFFER => ( - self.base.limits().max_uniform_buffer_bindings, &self.bound_uniform_buffer, + &self.indexed_uniform_buffer_bindings, ), _ => return self.base.webgl_error(InvalidEnum), }; - if index >= bind_limit { - return self.base.webgl_error(InvalidValue); - } + let indexed_binding = match indexed_bindings.get(index as usize) { + Some(slot) => slot, + None => return self.base.webgl_error(InvalidValue), + }; if let Some(buffer) = buffer { handle_potential_webgl_error!(self.base, self.base.validate_ownership(buffer), return); @@ -3234,6 +3314,9 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { return self.base.webgl_error(InvalidOperation); } handle_potential_webgl_error!(self.base, buffer.set_target_maybe(target), return); + + // for both the generic and the indexed bindings + buffer.increment_attached_counter(); buffer.increment_attached_counter(); } @@ -3242,11 +3325,15 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { index, buffer.map(|b| b.id()), )); - if let Some(old) = slot.get() { - old.decrement_attached_counter(); - } - slot.set(buffer); + for slot in &[&generic_slot, &indexed_binding.buffer] { + if let Some(old) = slot.get() { + old.decrement_attached_counter(); + } + slot.set(buffer); + } + indexed_binding.start.set(0); + indexed_binding.size.set(0); } /// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.16 @@ -3258,20 +3345,21 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { offset: i64, size: i64, ) { - let (bind_limit, slot) = match target { + let (generic_slot, indexed_bindings) = match target { constants::TRANSFORM_FEEDBACK_BUFFER => ( - self.base.limits().max_transform_feedback_separate_attribs, &self.bound_transform_feedback_buffer, + &self.indexed_transform_feedback_buffer_bindings, ), constants::UNIFORM_BUFFER => ( - self.base.limits().max_uniform_buffer_bindings, &self.bound_uniform_buffer, + &self.indexed_uniform_buffer_bindings, ), _ => return self.base.webgl_error(InvalidEnum), }; - if index >= bind_limit { - return self.base.webgl_error(InvalidValue); - } + let indexed_binding = match indexed_bindings.get(index as usize) { + Some(slot) => slot, + None => return self.base.webgl_error(InvalidValue), + }; if offset < 0 || size < 0 { return self.base.webgl_error(InvalidValue); @@ -3302,6 +3390,9 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { return self.base.webgl_error(InvalidOperation); } handle_potential_webgl_error!(self.base, buffer.set_target_maybe(target), return); + + // for both the generic and the indexed bindings + buffer.increment_attached_counter(); buffer.increment_attached_counter(); } @@ -3312,11 +3403,15 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { offset, size, )); - if let Some(old) = slot.get() { - old.decrement_attached_counter(); - } - slot.set(buffer); + for slot in &[&generic_slot, &indexed_binding.buffer] { + if let Some(old) = slot.get() { + old.decrement_attached_counter(); + } + slot.set(buffer); + } + indexed_binding.start.set(offset); + indexed_binding.size.set(size); } /// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.16 diff --git a/components/script/dom/webidls/WebGL2RenderingContext.webidl b/components/script/dom/webidls/WebGL2RenderingContext.webidl index 157fe38f892..e25174b858d 100644 --- a/components/script/dom/webidls/WebGL2RenderingContext.webidl +++ b/components/script/dom/webidls/WebGL2RenderingContext.webidl @@ -531,7 +531,7 @@ interface mixin WebGL2RenderingContextBase /* Uniform Buffer Objects and Transform Feedback Buffers */ void bindBufferBase(GLenum target, GLuint index, WebGLBuffer? buffer); void bindBufferRange(GLenum target, GLuint index, WebGLBuffer? buffer, GLintptr offset, GLsizeiptr size); - // any getIndexedParameter(GLenum target, GLuint index); + any getIndexedParameter(GLenum target, GLuint index); sequence<GLuint>? getUniformIndices(WebGLProgram program, sequence<DOMString> uniformNames); any getActiveUniforms(WebGLProgram program, sequence<GLuint> uniformIndices, GLenum pname); GLuint getUniformBlockIndex(WebGLProgram program, DOMString uniformBlockName); |