aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock4
-rw-r--r--components/canvas/Cargo.toml2
-rw-r--r--components/canvas/webgl_thread.rs28
-rw-r--r--components/canvas_traits/webgl.rs10
-rw-r--r--components/script/dom/webgl2renderingcontext.rs86
-rw-r--r--components/script/dom/webglrenderingcontext.rs103
-rw-r--r--components/script/dom/webidls/WebGL2RenderingContext.webidl6
-rw-r--r--tests/wpt/webgl/meta/conformance2/transform_feedback/simultaneous_binding.html.ini64
8 files changed, 254 insertions, 49 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 03e2674e91c..bafaad3cabb 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -5345,9 +5345,9 @@ dependencies = [
[[package]]
name = "sparkle"
-version = "0.1.24"
+version = "0.1.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7cd7f292661a533c2a7e239af495ba63891b5723c3a6d48712b2e3823466174"
+checksum = "7184285ed8ddbf106cda8fef17f584207fc64a03125e3694c324b19b708825fa"
dependencies = [
"gl_generator 0.13.1",
]
diff --git a/components/canvas/Cargo.toml b/components/canvas/Cargo.toml
index 7285776ddec..f0374c3df90 100644
--- a/components/canvas/Cargo.toml
+++ b/components/canvas/Cargo.toml
@@ -35,7 +35,7 @@ pixels = { path = "../pixels" }
raqote = { version = "0.8", features = ["text"] }
servo_arc = { path = "../servo_arc" }
servo_config = { path = "../config" }
-sparkle = "0.1.24"
+sparkle = "0.1.25"
style = { path = "../style" }
# NOTE: the sm-angle feature only enables ANGLE on Windows, not other platforms!
surfman = { version = "0.2", features = ["sm-angle", "sm-angle-default"] }
diff --git a/components/canvas/webgl_thread.rs b/components/canvas/webgl_thread.rs
index 0d8bc69cb77..62f979e65e0 100644
--- a/components/canvas/webgl_thread.rs
+++ b/components/canvas/webgl_thread.rs
@@ -919,7 +919,7 @@ impl WebGLThread {
0,
gl::RGBA,
gl::UNSIGNED_BYTE,
- None,
+ gl::TexImageSource::Pixels(None),
);
self.dom_outputs.insert(
pipeline_id,
@@ -1595,7 +1595,31 @@ impl WebGLImpl {
0,
format.as_gl_constant(),
effective_data_type,
- Some(&pixels),
+ gl::TexImageSource::Pixels(Some(&pixels)),
+ );
+ },
+ WebGLCommand::TexImage2DPBO {
+ target,
+ level,
+ internal_format,
+ size,
+ format,
+ effective_data_type,
+ unpacking_alignment,
+ offset,
+ } => {
+ gl.pixel_store_i(gl::UNPACK_ALIGNMENT, unpacking_alignment as i32);
+
+ gl.tex_image_2d(
+ target,
+ level as i32,
+ internal_format.as_gl_constant() as i32,
+ size.width as i32,
+ size.height as i32,
+ 0,
+ format.as_gl_constant(),
+ effective_data_type,
+ gl::TexImageSource::BufferOffset(offset),
);
},
WebGLCommand::TexSubImage2D {
diff --git a/components/canvas_traits/webgl.rs b/components/canvas_traits/webgl.rs
index c95fe603a35..2b4b9dda482 100644
--- a/components/canvas_traits/webgl.rs
+++ b/components/canvas_traits/webgl.rs
@@ -398,6 +398,16 @@ pub enum WebGLCommand {
pixel_format: Option<PixelFormat>,
data: TruncatedDebug<IpcSharedMemory>,
},
+ TexImage2DPBO {
+ target: u32,
+ level: u32,
+ internal_format: TexFormat,
+ size: Size2D<u32>,
+ format: TexFormat,
+ effective_data_type: u32,
+ unpacking_alignment: u32,
+ offset: i64,
+ },
TexSubImage2D {
target: u32,
level: u32,
diff --git a/components/script/dom/webgl2renderingcontext.rs b/components/script/dom/webgl2renderingcontext.rs
index 0ca44ab3d7c..4af734253af 100644
--- a/components/script/dom/webgl2renderingcontext.rs
+++ b/components/script/dom/webgl2renderingcontext.rs
@@ -29,7 +29,8 @@ use crate::dom::webglprogram::WebGLProgram;
use crate::dom::webglquery::WebGLQuery;
use crate::dom::webglrenderbuffer::WebGLRenderbuffer;
use crate::dom::webglrenderingcontext::{
- uniform_get, uniform_typed, Operation, TexPixels, VertexAttrib, WebGLRenderingContext,
+ uniform_get, uniform_typed, Operation, TexPixels, TexSource, VertexAttrib,
+ WebGLRenderingContext,
};
use crate::dom::webglsampler::{WebGLSampler, WebGLSamplerValue};
use crate::dom::webglshader::WebGLShader;
@@ -2926,6 +2927,79 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext {
border: i32,
format: u32,
type_: u32,
+ pbo_offset: i64,
+ ) -> Fallible<()> {
+ let pixel_unpack_buffer = match self.bound_pixel_unpack_buffer.get() {
+ Some(pixel_unpack_buffer) => pixel_unpack_buffer,
+ None => return Ok(self.base.webgl_error(InvalidOperation)),
+ };
+
+ if let Some(tf_buffer) = self.bound_transform_feedback_buffer.get() {
+ if pixel_unpack_buffer == tf_buffer {
+ return Ok(self.base.webgl_error(InvalidOperation));
+ }
+ }
+
+ if pbo_offset < 0 || pbo_offset as usize > pixel_unpack_buffer.capacity() {
+ return Ok(self.base.webgl_error(InvalidValue));
+ }
+
+ let unpacking_alignment = self.base.texture_unpacking_alignment();
+
+ let validator = TexImage2DValidator::new(
+ &self.base,
+ target,
+ level,
+ internalformat as u32,
+ width,
+ height,
+ border,
+ format,
+ type_,
+ );
+
+ let TexImage2DValidatorResult {
+ texture,
+ target,
+ width,
+ height,
+ level,
+ border,
+ internal_format,
+ format,
+ data_type,
+ } = match validator.validate() {
+ Ok(result) => result,
+ Err(_) => return Ok(()),
+ };
+
+ self.base.tex_image_2d(
+ &texture,
+ target,
+ data_type,
+ internal_format,
+ format,
+ level,
+ border,
+ unpacking_alignment,
+ Size2D::new(width, height),
+ TexSource::BufferOffset(pbo_offset),
+ );
+
+ Ok(())
+ }
+
+ /// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.6
+ fn TexImage2D___(
+ &self,
+ target: u32,
+ level: i32,
+ internalformat: i32,
+ width: i32,
+ height: i32,
+ border: i32,
+ format: u32,
+ type_: u32,
source: ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement,
) -> Fallible<()> {
if self.bound_pixel_unpack_buffer.get().is_some() {
@@ -2975,7 +3049,8 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext {
level,
border,
unpacking_alignment,
- pixels,
+ pixels.size(),
+ TexSource::Pixels(pixels),
);
Ok(())
@@ -2983,7 +3058,7 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext {
/// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.6
#[allow(unsafe_code)]
- fn TexImage2D___(
+ fn TexImage2D____(
&self,
target: u32,
level: i32,
@@ -3060,6 +3135,8 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext {
return Ok(self.base.webgl_error(InvalidOperation));
}
+ let size = Size2D::new(width, height);
+
self.base.tex_image_2d(
&texture,
target,
@@ -3069,7 +3146,8 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext {
level,
border,
unpacking_alignment,
- TexPixels::from_array(buff, Size2D::new(width, height)),
+ size,
+ TexSource::Pixels(TexPixels::from_array(buff, size)),
);
Ok(())
diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs
index 4c1adbc58d3..a3f78e64c91 100644
--- a/components/script/dom/webglrenderingcontext.rs
+++ b/components/script/dom/webglrenderingcontext.rs
@@ -613,12 +613,13 @@ impl WebGLRenderingContext {
level,
0,
1,
- TexPixels::new(
+ size,
+ TexSource::Pixels(TexPixels::new(
IpcSharedMemory::from_bytes(&pixels),
size,
PixelFormat::RGBA8,
true,
- ),
+ )),
);
false
@@ -756,15 +757,16 @@ impl WebGLRenderingContext {
level: u32,
_border: u32,
unpacking_alignment: u32,
- pixels: TexPixels,
+ size: Size2D<u32>,
+ source: TexSource,
) {
// TexImage2D depth is always equal to 1.
handle_potential_webgl_error!(
self,
texture.initialize(
target,
- pixels.size.width,
- pixels.size.height,
+ size.width,
+ size.height,
1,
format,
level,
@@ -775,12 +777,6 @@ impl WebGLRenderingContext {
let settings = self.texture_unpacking_settings.get();
let dest_premultiplied = settings.contains(TextureUnpacking::PREMULTIPLY_ALPHA);
- let alpha_treatment = match (pixels.premultiplied, dest_premultiplied) {
- (true, false) => Some(AlphaTreatment::Unmultiply),
- (false, true) => Some(AlphaTreatment::Premultiply),
- _ => None,
- };
-
let y_axis_treatment = if settings.contains(TextureUnpacking::FLIP_Y_AXIS) {
YAxisTreatment::Flipped
} else {
@@ -795,21 +791,43 @@ impl WebGLRenderingContext {
.extension_manager
.effective_type(data_type.as_gl_constant());
- // TODO(emilio): convert colorspace if requested.
- self.send_command(WebGLCommand::TexImage2D {
- target: target.as_gl_constant(),
- level,
- internal_format,
- size: pixels.size,
- format,
- data_type,
- effective_data_type,
- unpacking_alignment,
- alpha_treatment,
- y_axis_treatment,
- pixel_format: pixels.pixel_format,
- data: pixels.data.into(),
- });
+ match source {
+ TexSource::Pixels(pixels) => {
+ let alpha_treatment = match (pixels.premultiplied, dest_premultiplied) {
+ (true, false) => Some(AlphaTreatment::Unmultiply),
+ (false, true) => Some(AlphaTreatment::Premultiply),
+ _ => None,
+ };
+
+ // TODO(emilio): convert colorspace if requested.
+ self.send_command(WebGLCommand::TexImage2D {
+ target: target.as_gl_constant(),
+ level,
+ internal_format,
+ size,
+ format,
+ data_type,
+ effective_data_type,
+ unpacking_alignment,
+ alpha_treatment,
+ y_axis_treatment,
+ pixel_format: pixels.pixel_format,
+ data: pixels.data.into(),
+ });
+ },
+ TexSource::BufferOffset(offset) => {
+ self.send_command(WebGLCommand::TexImage2DPBO {
+ target: target.as_gl_constant(),
+ level,
+ internal_format,
+ size,
+ format,
+ effective_data_type,
+ unpacking_alignment,
+ offset,
+ });
+ },
+ }
if let Some(fb) = self.bound_draw_framebuffer.get() {
fb.invalidate_texture(&*texture);
@@ -839,9 +857,9 @@ impl WebGLRenderingContext {
// - x offset plus the width is greater than the texture width
// - y offset plus the height is greater than the texture height
if xoffset < 0 ||
- (xoffset as u32 + pixels.size.width) > image_info.width() ||
+ (xoffset as u32 + pixels.size().width) > image_info.width() ||
yoffset < 0 ||
- (yoffset as u32 + pixels.size.height) > image_info.height()
+ (yoffset as u32 + pixels.size().height) > image_info.height()
{
return self.webgl_error(InvalidValue);
}
@@ -884,7 +902,7 @@ impl WebGLRenderingContext {
level,
xoffset,
yoffset,
- size: pixels.size,
+ size: pixels.size(),
format,
data_type,
effective_data_type,
@@ -4319,6 +4337,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
return Ok(());
}
+ let size = Size2D::new(width, height);
+
self.tex_image_2d(
&texture,
target,
@@ -4328,7 +4348,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
level,
border,
unpacking_alignment,
- TexPixels::from_array(buff, Size2D::new(width, height)),
+ size,
+ TexSource::Pixels(TexPixels::from_array(buff, size)),
);
Ok(())
@@ -4358,8 +4379,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
target,
level,
internal_format as u32,
- pixels.size.width as i32,
- pixels.size.height as i32,
+ pixels.size().width as i32,
+ pixels.size().height as i32,
0,
format,
data_type,
@@ -4391,7 +4412,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
target,
level,
internal_format,
- pixels.size,
+ pixels.size(),
data_type,
) {
// FIXME(nox): What is the spec for this? No error is emitted ever
@@ -4408,7 +4429,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
level,
border,
1,
- pixels,
+ pixels.size(),
+ TexSource::Pixels(pixels),
);
Ok(())
}
@@ -4568,8 +4590,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
target,
level,
format,
- pixels.size.width as i32,
- pixels.size.height as i32,
+ pixels.size().width as i32,
+ pixels.size().height as i32,
0,
format,
data_type,
@@ -4910,6 +4932,15 @@ impl TexPixels {
premultiplied: false,
}
}
+
+ pub fn size(&self) -> Size2D<u32> {
+ self.size
+ }
+}
+
+pub enum TexSource {
+ Pixels(TexPixels),
+ BufferOffset(i64),
}
#[derive(JSTraceable)]
diff --git a/components/script/dom/webidls/WebGL2RenderingContext.webidl b/components/script/dom/webidls/WebGL2RenderingContext.webidl
index 7595fd951cf..632f1ce5cc6 100644
--- a/components/script/dom/webidls/WebGL2RenderingContext.webidl
+++ b/components/script/dom/webidls/WebGL2RenderingContext.webidl
@@ -505,9 +505,9 @@ interface mixin WebGL2RenderingContextOverloads
GLenum format, GLenum type, TexImageSource source); // May throw DOMException
// WebGL2 entrypoints:
- //[Throws]
- //void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
- // GLint border, GLenum format, GLenum type, GLintptr pboOffset);
+ [Throws]
+ void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
+ GLint border, GLenum format, GLenum type, GLintptr pboOffset);
[Throws]
void texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
GLint border, GLenum format, GLenum type,
diff --git a/tests/wpt/webgl/meta/conformance2/transform_feedback/simultaneous_binding.html.ini b/tests/wpt/webgl/meta/conformance2/transform_feedback/simultaneous_binding.html.ini
index 9eaefa95b43..b4cdc0030c9 100644
--- a/tests/wpt/webgl/meta/conformance2/transform_feedback/simultaneous_binding.html.ini
+++ b/tests/wpt/webgl/meta/conformance2/transform_feedback/simultaneous_binding.html.ini
@@ -1,5 +1,4 @@
[simultaneous_binding.html]
- expected: ERROR
[WebGL test #12: getError expected: INVALID_OPERATION. Was NO_ERROR : drawArrays: buffer used as vertex attrib and tf simultaneously]
expected: FAIL
@@ -75,3 +74,66 @@
[WebGL test #17: getError expected: INVALID_OPERATION. Was NO_ERROR : drawElements: buffer used as uniform buffer and tf simultaneously]
expected: FAIL
+ [WebGL test #110: getError expected: NO_ERROR. Was INVALID_OPERATION : PIXEL_UNPACK_BUFFER is not bound for transform feedback]
+ expected: FAIL
+
+ [WebGL test #101: getError expected: INVALID_OPERATION. Was NO_ERROR : bufferSubData with double bound buffer]
+ expected: FAIL
+
+ [WebGL test #85: getError expected: INVALID_OPERATION. Was NO_ERROR : PIXEL_PACK_BUFFER is bound for transform feedback]
+ expected: FAIL
+
+ [WebGL test #118: getError expected: INVALID_OPERATION. Was NO_ERROR : copyBufferSubData with double bound buffer]
+ expected: FAIL
+
+ [WebGL test #104: getError expected: INVALID_OPERATION. Was NO_ERROR : copyBufferSubData with double bound buffer]
+ expected: FAIL
+
+ [WebGL test #114: getError expected: INVALID_OPERATION. Was NO_ERROR : bufferData with double bound buffer]
+ expected: FAIL
+
+ [WebGL test #103: getError expected: INVALID_OPERATION. Was NO_ERROR : copyBufferSubData with double bound buffer]
+ expected: FAIL
+
+ [WebGL test #116: getError expected: INVALID_OPERATION. Was NO_ERROR : getBufferSubData with double bound buffer]
+ expected: FAIL
+
+ [WebGL test #88: getError expected: INVALID_OPERATION. Was NO_ERROR : getBufferSubData with double bound buffer]
+ expected: FAIL
+
+ [WebGL test #113: getError expected: INVALID_OPERATION. Was NO_ERROR : PIXEL_PACK_BUFFER is bound for transform feedback]
+ expected: FAIL
+
+ [WebGL test #83: getError expected: INVALID_OPERATION. Was NO_ERROR : PIXEL_UNPACK_BUFFER is bound for transform feedback]
+ expected: FAIL
+
+ [WebGL test #117: getError expected: INVALID_OPERATION. Was NO_ERROR : copyBufferSubData with double bound buffer]
+ expected: FAIL
+
+ [WebGL test #100: getError expected: INVALID_OPERATION. Was NO_ERROR : bufferData with double bound buffer]
+ expected: FAIL
+
+ [WebGL test #89: getError expected: INVALID_OPERATION. Was NO_ERROR : copyBufferSubData with double bound buffer]
+ expected: FAIL
+
+ [WebGL test #102: getError expected: INVALID_OPERATION. Was NO_ERROR : getBufferSubData with double bound buffer]
+ expected: FAIL
+
+ [WebGL test #111: getError expected: INVALID_OPERATION. Was NO_ERROR : PIXEL_UNPACK_BUFFER is bound for transform feedback]
+ expected: FAIL
+
+ [WebGL test #87: getError expected: INVALID_OPERATION. Was NO_ERROR : bufferSubData with double bound buffer]
+ expected: FAIL
+
+ [WebGL test #99: getError expected: INVALID_OPERATION. Was NO_ERROR : PIXEL_PACK_BUFFER is bound for transform feedback]
+ expected: FAIL
+
+ [WebGL test #86: getError expected: INVALID_OPERATION. Was NO_ERROR : bufferData with double bound buffer]
+ expected: FAIL
+
+ [WebGL test #90: getError expected: INVALID_OPERATION. Was NO_ERROR : copyBufferSubData with double bound buffer]
+ expected: FAIL
+
+ [WebGL test #115: getError expected: INVALID_OPERATION. Was NO_ERROR : bufferSubData with double bound buffer]
+ expected: FAIL
+