mirror of
https://github.com/servo/servo.git
synced 2025-07-24 15:50:21 +01:00
Merge code from Draw* and Draw*Instanced methods
This made me realise we weren't supporting OES_element_index_uint in the ANGLE_instanced_arrays extension.
This commit is contained in:
parent
c5aaae7333
commit
04c81c5cc3
3 changed files with 30 additions and 128 deletions
|
@ -701,10 +701,6 @@ impl WebGLImpl {
|
||||||
ctx.gl().front_face(mode),
|
ctx.gl().front_face(mode),
|
||||||
WebGLCommand::DisableVertexAttribArray(attrib_id) =>
|
WebGLCommand::DisableVertexAttribArray(attrib_id) =>
|
||||||
ctx.gl().disable_vertex_attrib_array(attrib_id),
|
ctx.gl().disable_vertex_attrib_array(attrib_id),
|
||||||
WebGLCommand::DrawArrays(mode, first, count) =>
|
|
||||||
ctx.gl().draw_arrays(mode, first, count),
|
|
||||||
WebGLCommand::DrawElements(mode, count, type_, offset) =>
|
|
||||||
ctx.gl().draw_elements(mode, count, type_, offset as u32),
|
|
||||||
WebGLCommand::EnableVertexAttribArray(attrib_id) =>
|
WebGLCommand::EnableVertexAttribArray(attrib_id) =>
|
||||||
ctx.gl().enable_vertex_attrib_array(attrib_id),
|
ctx.gl().enable_vertex_attrib_array(attrib_id),
|
||||||
WebGLCommand::Hint(name, val) =>
|
WebGLCommand::Hint(name, val) =>
|
||||||
|
@ -957,9 +953,15 @@ impl WebGLImpl {
|
||||||
WebGLCommand::UseProgram(program_id) => {
|
WebGLCommand::UseProgram(program_id) => {
|
||||||
ctx.gl().use_program(program_id.map_or(0, |p| p.get()))
|
ctx.gl().use_program(program_id.map_or(0, |p| p.get()))
|
||||||
}
|
}
|
||||||
|
WebGLCommand::DrawArrays { mode, first, count } => {
|
||||||
|
ctx.gl().draw_arrays(mode, first, count)
|
||||||
|
}
|
||||||
WebGLCommand::DrawArraysInstanced { mode, first, count, primcount } => {
|
WebGLCommand::DrawArraysInstanced { mode, first, count, primcount } => {
|
||||||
ctx.gl().draw_arrays_instanced(mode, first, count, primcount)
|
ctx.gl().draw_arrays_instanced(mode, first, count, primcount)
|
||||||
}
|
}
|
||||||
|
WebGLCommand::DrawElements { mode, count, type_, offset } => {
|
||||||
|
ctx.gl().draw_elements(mode, count, type_, offset)
|
||||||
|
}
|
||||||
WebGLCommand::DrawElementsInstanced { mode, count, type_, offset, primcount } => {
|
WebGLCommand::DrawElementsInstanced { mode, count, type_, offset, primcount } => {
|
||||||
ctx.gl().draw_elements_instanced(mode, count, type_, offset, primcount)
|
ctx.gl().draw_elements_instanced(mode, count, type_, offset, primcount)
|
||||||
}
|
}
|
||||||
|
|
|
@ -201,8 +201,6 @@ pub enum WebGLCommand {
|
||||||
BindRenderbuffer(u32, Option<WebGLRenderbufferId>),
|
BindRenderbuffer(u32, Option<WebGLRenderbufferId>),
|
||||||
BindTexture(u32, Option<WebGLTextureId>),
|
BindTexture(u32, Option<WebGLTextureId>),
|
||||||
DisableVertexAttribArray(u32),
|
DisableVertexAttribArray(u32),
|
||||||
DrawArrays(u32, i32, i32),
|
|
||||||
DrawElements(u32, i32, u32, i64),
|
|
||||||
EnableVertexAttribArray(u32),
|
EnableVertexAttribArray(u32),
|
||||||
FramebufferRenderbuffer(u32, u32, u32, Option<WebGLRenderbufferId>),
|
FramebufferRenderbuffer(u32, u32, u32, Option<WebGLRenderbufferId>),
|
||||||
FramebufferTexture2D(u32, u32, u32, Option<WebGLTextureId>, i32),
|
FramebufferTexture2D(u32, u32, u32, Option<WebGLTextureId>, i32),
|
||||||
|
@ -278,7 +276,9 @@ pub enum WebGLCommand {
|
||||||
GetTexParameterInt(u32, TexParameterInt, WebGLSender<i32>),
|
GetTexParameterInt(u32, TexParameterInt, WebGLSender<i32>),
|
||||||
TexParameteri(u32, u32, i32),
|
TexParameteri(u32, u32, i32),
|
||||||
TexParameterf(u32, u32, f32),
|
TexParameterf(u32, u32, f32),
|
||||||
|
DrawArrays { mode: u32, first: i32, count: i32 },
|
||||||
DrawArraysInstanced { mode: u32, first: i32, count: i32, primcount: i32 },
|
DrawArraysInstanced { mode: u32, first: i32, count: i32, primcount: i32 },
|
||||||
|
DrawElements { mode: u32, count: i32, type_: u32, offset: u32 },
|
||||||
DrawElementsInstanced { mode: u32, count: i32, type_: u32, offset: u32, primcount: i32 },
|
DrawElementsInstanced { mode: u32, count: i32, type_: u32, offset: u32, primcount: i32 },
|
||||||
VertexAttribDivisor { index: u32, divisor: u32 },
|
VertexAttribDivisor { index: u32, divisor: u32 },
|
||||||
GetUniformBool(WebGLProgramId, i32, WebGLSender<bool>),
|
GetUniformBool(WebGLProgramId, i32, WebGLSender<bool>),
|
||||||
|
|
|
@ -1180,9 +1180,15 @@ impl WebGLRenderingContext {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.send_command(
|
if count == 0 || primcount == 0 {
|
||||||
WebGLCommand::DrawArraysInstanced { mode, first, count, primcount },
|
return;
|
||||||
);
|
}
|
||||||
|
|
||||||
|
self.send_command(if primcount == 1 {
|
||||||
|
WebGLCommand::DrawArrays { mode, first, count }
|
||||||
|
} else {
|
||||||
|
WebGLCommand::DrawArraysInstanced { mode, first, count, primcount }
|
||||||
|
});
|
||||||
self.mark_as_dirty();
|
self.mark_as_dirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1210,6 +1216,7 @@ impl WebGLRenderingContext {
|
||||||
let type_size = match type_ {
|
let type_size = match type_ {
|
||||||
constants::UNSIGNED_BYTE => 1,
|
constants::UNSIGNED_BYTE => 1,
|
||||||
constants::UNSIGNED_SHORT => 2,
|
constants::UNSIGNED_SHORT => 2,
|
||||||
|
constants::UNSIGNED_INT if self.extension_manager.is_element_index_uint_enabled() => 4,
|
||||||
_ => return self.webgl_error(InvalidEnum),
|
_ => return self.webgl_error(InvalidEnum),
|
||||||
};
|
};
|
||||||
if offset % type_size != 0 {
|
if offset % type_size != 0 {
|
||||||
|
@ -1224,17 +1231,12 @@ impl WebGLRenderingContext {
|
||||||
|
|
||||||
if count > 0 && primcount > 0 {
|
if count > 0 && primcount > 0 {
|
||||||
if let Some(array_buffer) = self.current_vao().element_array_buffer().get() {
|
if let Some(array_buffer) = self.current_vao().element_array_buffer().get() {
|
||||||
// WebGL Spec: check buffer overflows, must be a valid multiple of the size.
|
// 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);
|
let val = offset as u64 + (count as u64 * type_size as u64);
|
||||||
if val > array_buffer.capacity() as u64 {
|
if val > array_buffer.capacity() as u64 {
|
||||||
return self.webgl_error(InvalidOperation);
|
return self.webgl_error(InvalidOperation);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// From the WebGL spec
|
|
||||||
//
|
|
||||||
// a non-null WebGLBuffer must be bound to the ELEMENT_ARRAY_BUFFER binding point
|
|
||||||
// or an INVALID_OPERATION error will be generated.
|
|
||||||
//
|
|
||||||
return self.webgl_error(InvalidOperation);
|
return self.webgl_error(InvalidOperation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1250,12 +1252,15 @@ impl WebGLRenderingContext {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.send_command(WebGLCommand::DrawElementsInstanced {
|
if count == 0 || primcount == 0 {
|
||||||
mode,
|
return;
|
||||||
count,
|
}
|
||||||
type_,
|
|
||||||
offset: offset as u32,
|
let offset = offset as u32;
|
||||||
primcount,
|
self.send_command(if primcount == 1 {
|
||||||
|
WebGLCommand::DrawElements { mode, count, type_, offset }
|
||||||
|
} else {
|
||||||
|
WebGLCommand::DrawElementsInstanced { mode, count, type_, offset, primcount }
|
||||||
});
|
});
|
||||||
self.mark_as_dirty();
|
self.mark_as_dirty();
|
||||||
}
|
}
|
||||||
|
@ -2411,117 +2416,12 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
|
|
||||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.11
|
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.11
|
||||||
fn DrawArrays(&self, mode: u32, first: i32, count: i32) {
|
fn DrawArrays(&self, mode: u32, first: i32, count: i32) {
|
||||||
match mode {
|
self.draw_arrays_instanced(mode, first, count, 1);
|
||||||
constants::POINTS | constants::LINE_STRIP |
|
|
||||||
constants::LINE_LOOP | constants::LINES |
|
|
||||||
constants::TRIANGLE_STRIP | constants::TRIANGLE_FAN |
|
|
||||||
constants::TRIANGLES => {},
|
|
||||||
_ => {
|
|
||||||
return self.webgl_error(InvalidEnum);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if first < 0 || count < 0 {
|
|
||||||
return self.webgl_error(InvalidValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
let current_program = handle_potential_webgl_error!(
|
|
||||||
self,
|
|
||||||
self.current_program.get().ok_or(InvalidOperation),
|
|
||||||
return
|
|
||||||
);
|
|
||||||
|
|
||||||
let required_len = if count > 0 {
|
|
||||||
handle_potential_webgl_error!(
|
|
||||||
self,
|
|
||||||
first.checked_add(count).map(|len| len as u32).ok_or(InvalidOperation),
|
|
||||||
return
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
};
|
|
||||||
|
|
||||||
handle_potential_webgl_error!(
|
|
||||||
self,
|
|
||||||
self.current_vao().validate_for_draw(required_len, 1, ¤t_program.active_attribs()),
|
|
||||||
return
|
|
||||||
);
|
|
||||||
|
|
||||||
if !self.validate_framebuffer_complete() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.send_command(WebGLCommand::DrawArrays(mode, first, count));
|
|
||||||
self.mark_as_dirty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.11
|
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.11
|
||||||
fn DrawElements(&self, mode: u32, count: i32, type_: u32, offset: i64) {
|
fn DrawElements(&self, mode: u32, count: i32, type_: u32, offset: i64) {
|
||||||
match mode {
|
self.draw_elements_instanced(mode, count, type_, offset, 1);
|
||||||
constants::POINTS | constants::LINE_STRIP |
|
|
||||||
constants::LINE_LOOP | constants::LINES |
|
|
||||||
constants::TRIANGLE_STRIP | constants::TRIANGLE_FAN |
|
|
||||||
constants::TRIANGLES => {},
|
|
||||||
_ => return self.webgl_error(InvalidEnum),
|
|
||||||
}
|
|
||||||
|
|
||||||
// From the GLES 2.0.25 spec, page 21:
|
|
||||||
//
|
|
||||||
// "type must be one of UNSIGNED_BYTE or UNSIGNED_SHORT"
|
|
||||||
let type_size = match type_ {
|
|
||||||
constants::UNSIGNED_BYTE => 1,
|
|
||||||
constants::UNSIGNED_SHORT => 2,
|
|
||||||
constants::UNSIGNED_INT if self.extension_manager.is_element_index_uint_enabled() => 4,
|
|
||||||
_ => return self.webgl_error(InvalidEnum),
|
|
||||||
};
|
|
||||||
|
|
||||||
if offset % type_size != 0 {
|
|
||||||
return self.webgl_error(InvalidOperation);
|
|
||||||
}
|
|
||||||
|
|
||||||
if count < 0 {
|
|
||||||
return self.webgl_error(InvalidValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
if offset < 0 {
|
|
||||||
return self.webgl_error(InvalidValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
let current_program = handle_potential_webgl_error!(
|
|
||||||
self,
|
|
||||||
self.current_program.get().ok_or(InvalidOperation),
|
|
||||||
return
|
|
||||||
);
|
|
||||||
|
|
||||||
if count > 0 {
|
|
||||||
if let Some(array_buffer) = self.current_vao().element_array_buffer().get() {
|
|
||||||
// WebGL Spec: check buffer overflows, must be a valid multiple of the size.
|
|
||||||
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 {
|
|
||||||
// From the WebGL spec
|
|
||||||
//
|
|
||||||
// a non-null WebGLBuffer must be bound to the ELEMENT_ARRAY_BUFFER binding point
|
|
||||||
// or an INVALID_OPERATION error will be generated.
|
|
||||||
//
|
|
||||||
return self.webgl_error(InvalidOperation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(nox): Pass the correct number of vertices required.
|
|
||||||
handle_potential_webgl_error!(
|
|
||||||
self,
|
|
||||||
self.current_vao().validate_for_draw(0, 1, ¤t_program.active_attribs()),
|
|
||||||
return
|
|
||||||
);
|
|
||||||
|
|
||||||
if !self.validate_framebuffer_complete() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.send_command(WebGLCommand::DrawElements(mode, count, type_, offset));
|
|
||||||
self.mark_as_dirty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
|
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue