mirror of
https://github.com/servo/servo.git
synced 2025-06-19 22:59:03 +01:00
Auto merge of #21523 - servo:webgl, r=avadacatavra,jdm
Some more drive-by WebGL fixes and cleanups <!-- Reviewable:start --> This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/21523) <!-- Reviewable:end -->
This commit is contained in:
commit
6f81ed49f6
164 changed files with 452 additions and 2780 deletions
|
@ -344,12 +344,17 @@ class CGMethodCall(CGThing):
|
|||
|
||||
distinguishingIndex = method.distinguishingIndexForArgCount(argCount)
|
||||
|
||||
# We can't handle unions at the distinguishing index.
|
||||
# We can't handle unions of non-object values at the distinguishing index.
|
||||
for (returnType, args) in possibleSignatures:
|
||||
if args[distinguishingIndex].type.isUnion():
|
||||
raise TypeError("No support for unions as distinguishing "
|
||||
"arguments yet: %s",
|
||||
args[distinguishingIndex].location)
|
||||
type = args[distinguishingIndex].type
|
||||
if type.isUnion():
|
||||
if type.nullable():
|
||||
type = type.inner
|
||||
for type in type.flatMemberTypes:
|
||||
if not (type.isObject() or type.isNonCallbackInterface()):
|
||||
raise TypeError("No support for unions with non-object variants "
|
||||
"as distinguishing arguments yet: %s",
|
||||
args[distinguishingIndex].location)
|
||||
|
||||
# Convert all our arguments up to the distinguishing index.
|
||||
# Doesn't matter which of the possible signatures we use, since
|
||||
|
@ -388,6 +393,7 @@ class CGMethodCall(CGThing):
|
|||
interfacesSigs = [
|
||||
s for s in possibleSignatures
|
||||
if (s[1][distinguishingIndex].type.isObject() or
|
||||
s[1][distinguishingIndex].type.isUnion() or
|
||||
s[1][distinguishingIndex].type.isNonCallbackInterface())]
|
||||
# There might be more than one of these; we need to check
|
||||
# which ones we unwrap to.
|
||||
|
@ -2366,7 +2372,6 @@ def UnionTypes(descriptors, dictionaries, callbacks, typedefs, config):
|
|||
'dom::bindings::conversions::ConversionBehavior',
|
||||
'dom::bindings::conversions::StringificationBehavior',
|
||||
'dom::bindings::conversions::root_from_handlevalue',
|
||||
'dom::bindings::error::throw_not_in_union',
|
||||
'std::ptr::NonNull',
|
||||
'dom::bindings::mozmap::MozMap',
|
||||
'dom::bindings::root::DomRoot',
|
||||
|
@ -4450,8 +4455,8 @@ class CGUnionConversionStruct(CGThing):
|
|||
other.append(booleanConversion[0])
|
||||
conversions.append(CGList(other, "\n\n"))
|
||||
conversions.append(CGGeneric(
|
||||
"throw_not_in_union(cx, \"%s\");\n"
|
||||
"Err(())" % ", ".join(names)))
|
||||
"Ok(ConversionResult::Failure(\"argument could not be converted to any of: %s\".into()))" % ", ".join(names)
|
||||
))
|
||||
method = CGWrapper(
|
||||
CGIndenter(CGList(conversions, "\n\n")),
|
||||
pre="unsafe fn from_jsval(cx: *mut JSContext,\n"
|
||||
|
|
|
@ -255,14 +255,6 @@ pub unsafe fn report_pending_exception(cx: *mut JSContext, dispatch_event: bool)
|
|||
}
|
||||
}
|
||||
|
||||
/// Throw an exception to signal that a `JSVal` can not be converted to any of
|
||||
/// the types in an IDL union type.
|
||||
pub unsafe fn throw_not_in_union(cx: *mut JSContext, names: &'static str) {
|
||||
assert!(!JS_IsExceptionPending(cx));
|
||||
let error = format!("argument could not be converted to any of: {}", names);
|
||||
throw_type_error(cx, &error);
|
||||
}
|
||||
|
||||
/// Throw an exception to signal that a `JSObject` can not be converted to a
|
||||
/// given DOM type.
|
||||
pub unsafe fn throw_invalid_this(cx: *mut JSContext, proto_id: u16) {
|
||||
|
|
|
@ -240,14 +240,18 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext {
|
|||
self.base.GenerateMipmap(target)
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
/// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5
|
||||
unsafe fn BufferData(&self, cx: *mut JSContext, target: u32, data: *mut JSObject, usage: u32) -> Fallible<()> {
|
||||
self.base.BufferData(cx, target, data, usage)
|
||||
fn BufferData(
|
||||
&self,
|
||||
target: u32,
|
||||
data: Option<ArrayBufferViewOrArrayBuffer>,
|
||||
usage: u32,
|
||||
) {
|
||||
self.base.BufferData(target, data, usage)
|
||||
}
|
||||
|
||||
/// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5
|
||||
fn BufferData_(&self, target: u32, size: i64, usage: u32) -> Fallible<()> {
|
||||
fn BufferData_(&self, target: u32, size: i64, usage: u32) {
|
||||
self.base.BufferData_(target, size, usage)
|
||||
}
|
||||
|
||||
|
|
|
@ -154,6 +154,7 @@ impl WebGLBuffer {
|
|||
|
||||
impl Drop for WebGLBuffer {
|
||||
fn drop(&mut self) {
|
||||
self.delete();
|
||||
self.mark_for_deletion();
|
||||
assert!(self.is_deleted());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1165,14 +1165,16 @@ impl WebGLRenderingContext {
|
|||
return
|
||||
);
|
||||
|
||||
let array_buffer = handle_potential_webgl_error!(
|
||||
self,
|
||||
self.current_vao().element_array_buffer().get().ok_or(InvalidOperation),
|
||||
return
|
||||
);
|
||||
|
||||
if count > 0 && primcount > 0 {
|
||||
if let Some(array_buffer) = self.current_vao().element_array_buffer().get() {
|
||||
// This operation cannot overflow in u64 and we know all those values are nonnegative.
|
||||
let val = offset as u64 + (count as u64 * type_size as u64);
|
||||
if val > array_buffer.capacity() as u64 {
|
||||
return self.webgl_error(InvalidOperation);
|
||||
}
|
||||
} else {
|
||||
// This operation cannot overflow in u64 and we know all those values are nonnegative.
|
||||
let val = offset as u64 + (count as u64 * type_size as u64);
|
||||
if val > array_buffer.capacity() as u64 {
|
||||
return self.webgl_error(InvalidOperation);
|
||||
}
|
||||
}
|
||||
|
@ -1324,19 +1326,6 @@ impl Drop for WebGLRenderingContext {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
unsafe fn fallible_array_buffer_view_to_vec(
|
||||
cx: *mut JSContext,
|
||||
abv: *mut JSObject,
|
||||
) -> Result<Vec<u8>, Error> {
|
||||
assert!(!abv.is_null());
|
||||
typedarray!(in(cx) let array_buffer_view: ArrayBufferView = abv);
|
||||
match array_buffer_view {
|
||||
Ok(v) => Ok(v.to_vec()),
|
||||
Err(_) => Err(Error::Type("Not an ArrayBufferView".to_owned())),
|
||||
}
|
||||
}
|
||||
|
||||
impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.1
|
||||
fn Canvas(&self) -> DomRoot<HTMLCanvasElement> {
|
||||
|
@ -1892,52 +1881,44 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
|||
handle_potential_webgl_error!(self, texture.generate_mipmap());
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5
|
||||
unsafe fn BufferData(
|
||||
fn BufferData(
|
||||
&self,
|
||||
cx: *mut JSContext,
|
||||
target: u32,
|
||||
data: *mut JSObject,
|
||||
data: Option<ArrayBufferViewOrArrayBuffer>,
|
||||
usage: u32,
|
||||
) -> ErrorResult {
|
||||
if data.is_null() {
|
||||
return Ok(self.webgl_error(InvalidValue));
|
||||
}
|
||||
|
||||
typedarray!(in(cx) let array_buffer: ArrayBuffer = data);
|
||||
let data_vec = match array_buffer {
|
||||
Ok(data) => data.to_vec(),
|
||||
Err(_) => fallible_array_buffer_view_to_vec(cx, data)?,
|
||||
) {
|
||||
let data = match data {
|
||||
Some(ArrayBufferViewOrArrayBuffer::ArrayBuffer(data)) => data.to_vec(),
|
||||
Some(ArrayBufferViewOrArrayBuffer::ArrayBufferView(data)) => data.to_vec(),
|
||||
None => return self.webgl_error(InvalidValue),
|
||||
};
|
||||
|
||||
let bound_buffer = handle_potential_webgl_error!(self, self.bound_buffer(target), return Ok(()));
|
||||
let bound_buffer = handle_potential_webgl_error!(self, self.bound_buffer(target), return);
|
||||
let bound_buffer = match bound_buffer {
|
||||
Some(bound_buffer) => bound_buffer,
|
||||
None => return Ok(self.webgl_error(InvalidOperation)),
|
||||
None => return self.webgl_error(InvalidOperation),
|
||||
};
|
||||
|
||||
handle_potential_webgl_error!(self, bound_buffer.buffer_data(target, data_vec, usage));
|
||||
Ok(())
|
||||
handle_potential_webgl_error!(self, bound_buffer.buffer_data(target, data, usage));
|
||||
}
|
||||
|
||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5
|
||||
fn BufferData_(&self, target: u32, size: i64, usage: u32) -> ErrorResult {
|
||||
let bound_buffer = handle_potential_webgl_error!(self, self.bound_buffer(target), return Ok(()));
|
||||
fn BufferData_(&self, target: u32, size: i64, usage: u32) {
|
||||
let bound_buffer = handle_potential_webgl_error!(self, self.bound_buffer(target), return);
|
||||
let bound_buffer = match bound_buffer {
|
||||
Some(bound_buffer) => bound_buffer,
|
||||
None => return Ok(self.webgl_error(InvalidOperation)),
|
||||
None => return self.webgl_error(InvalidOperation),
|
||||
};
|
||||
|
||||
if size < 0 {
|
||||
return Ok(self.webgl_error(InvalidValue));
|
||||
return self.webgl_error(InvalidValue);
|
||||
}
|
||||
|
||||
// FIXME: Allocating a buffer based on user-requested size is
|
||||
// not great, but we don't have a fallible allocation to try.
|
||||
let data = vec![0u8; size as usize];
|
||||
handle_potential_webgl_error!(self, bound_buffer.buffer_data(target, data, usage));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5
|
||||
|
@ -2757,7 +2738,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
|||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5
|
||||
fn IsBuffer(&self, buffer: Option<&WebGLBuffer>) -> bool {
|
||||
buffer.map_or(false, |buf| {
|
||||
self.validate_ownership(buf).is_ok() && buf.target().is_some() && !buf.is_marked_for_deletion()
|
||||
self.validate_ownership(buf).is_ok() && buf.target().is_some() && !buf.is_deleted()
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -3643,7 +3624,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
|||
Float32ArrayOrUnrestrictedFloatSequence::UnrestrictedFloatSequence(v) => v,
|
||||
};
|
||||
if values.len() < 1 {
|
||||
return self.webgl_error(InvalidOperation);
|
||||
// https://github.com/KhronosGroup/WebGL/issues/2700
|
||||
return self.webgl_error(InvalidValue);
|
||||
}
|
||||
self.vertex_attrib(indx, values[0], 0f32, 0f32, 1f32);
|
||||
}
|
||||
|
@ -3660,7 +3642,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
|||
Float32ArrayOrUnrestrictedFloatSequence::UnrestrictedFloatSequence(v) => v,
|
||||
};
|
||||
if values.len() < 2 {
|
||||
return self.webgl_error(InvalidOperation);
|
||||
// https://github.com/KhronosGroup/WebGL/issues/2700
|
||||
return self.webgl_error(InvalidValue);
|
||||
}
|
||||
self.vertex_attrib(indx, values[0], values[1], 0f32, 1f32);
|
||||
}
|
||||
|
@ -3677,7 +3660,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
|||
Float32ArrayOrUnrestrictedFloatSequence::UnrestrictedFloatSequence(v) => v,
|
||||
};
|
||||
if values.len() < 3 {
|
||||
return self.webgl_error(InvalidOperation);
|
||||
// https://github.com/KhronosGroup/WebGL/issues/2700
|
||||
return self.webgl_error(InvalidValue);
|
||||
}
|
||||
self.vertex_attrib(indx, values[0], values[1], values[2], 1f32);
|
||||
}
|
||||
|
@ -3694,7 +3678,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
|||
Float32ArrayOrUnrestrictedFloatSequence::UnrestrictedFloatSequence(v) => v,
|
||||
};
|
||||
if values.len() < 4 {
|
||||
return self.webgl_error(InvalidOperation);
|
||||
// https://github.com/KhronosGroup/WebGL/issues/2700
|
||||
return self.webgl_error(InvalidValue);
|
||||
}
|
||||
self.vertex_attrib(indx, values[0], values[1], values[2], values[3]);
|
||||
}
|
||||
|
|
|
@ -124,8 +124,15 @@ impl WebGLVertexArrayObjectOES {
|
|||
}
|
||||
|
||||
let context = self.upcast::<WebGLObject>().context();
|
||||
let buffer = context.array_buffer().ok_or(WebGLError::InvalidOperation)?;
|
||||
buffer.increment_attached_counter();
|
||||
let buffer = context.array_buffer();
|
||||
match buffer {
|
||||
Some(ref buffer) => buffer.increment_attached_counter(),
|
||||
None if offset != 0 => {
|
||||
// https://github.com/KhronosGroup/WebGL/pull/2228
|
||||
return Err(WebGLError::InvalidOperation)
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
context.send_command(WebGLCommand::VertexAttribPointer(
|
||||
index,
|
||||
size,
|
||||
|
@ -146,7 +153,7 @@ impl WebGLVertexArrayObjectOES {
|
|||
normalized,
|
||||
stride: stride as u8,
|
||||
offset: offset as u32,
|
||||
buffer: Some(Dom::from_ref(&*buffer)),
|
||||
buffer: buffer.map(|b| Dom::from_ref(&*b)),
|
||||
divisor: data.divisor,
|
||||
};
|
||||
|
||||
|
|
|
@ -305,10 +305,7 @@ interface WebGL2RenderingContextBase
|
|||
/* Buffer objects */
|
||||
// WebGL1:
|
||||
// BUG: https://github.com/KhronosGroup/WebGL/issues/2216
|
||||
// FIXME(xanewok): https://github.com/servo/servo/issues/20513
|
||||
[Throws]
|
||||
void bufferData(GLenum target, object? data, GLenum usage);
|
||||
[Throws]
|
||||
void bufferData(GLenum target, /*[AllowShared]*/ BufferSource? data, GLenum usage);
|
||||
void bufferData(GLenum target, GLsizeiptr size, GLenum usage);
|
||||
void bufferSubData(GLenum target, GLintptr dstByteOffset, /*[AllowShared]*/ BufferSource srcData);
|
||||
// WebGL2:
|
||||
|
|
|
@ -421,7 +421,8 @@ interface WebGLRenderingContextBase
|
|||
const GLenum RGB5_A1 = 0x8057;
|
||||
const GLenum RGB565 = 0x8D62;
|
||||
const GLenum DEPTH_COMPONENT16 = 0x81A5;
|
||||
const GLenum STENCIL_INDEX = 0x1901;
|
||||
// https://github.com/KhronosGroup/WebGL/pull/2371
|
||||
// const GLenum STENCIL_INDEX = 0x1901;
|
||||
const GLenum STENCIL_INDEX8 = 0x8D48;
|
||||
const GLenum DEPTH_STENCIL = 0x84F9;
|
||||
|
||||
|
@ -687,10 +688,7 @@ interface WebGLRenderingContext
|
|||
{
|
||||
// BUG: https://github.com/KhronosGroup/WebGL/issues/2216
|
||||
|
||||
// FIXME(xanewok): https://github.com/servo/servo/issues/20513
|
||||
[Throws]
|
||||
void bufferData(GLenum target, object? data, GLenum usage);
|
||||
[Throws]
|
||||
void bufferData(GLenum target, /*[AllowShared]*/ BufferSource? data, GLenum usage);
|
||||
void bufferData(GLenum target, GLsizeiptr size, GLenum usage);
|
||||
void bufferSubData(GLenum target, GLintptr offset, /*[AllowShared]*/ BufferSource data);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue