mirror of
https://github.com/servo/servo.git
synced 2025-08-04 21:20:23 +01:00
Introduce TexPixels
This commit is contained in:
parent
1e2a72abfe
commit
86987ed75d
1 changed files with 69 additions and 41 deletions
|
@ -429,8 +429,7 @@ impl WebGLRenderingContext {
|
||||||
target,
|
target,
|
||||||
0,
|
0,
|
||||||
info.internal_format().unwrap_or(TexFormat::RGBA),
|
info.internal_format().unwrap_or(TexFormat::RGBA),
|
||||||
info.width(),
|
Size2D::new(info.width(), info.height()),
|
||||||
info.height(),
|
|
||||||
info.data_type().unwrap_or(TexDataType::UnsignedByte),
|
info.data_type().unwrap_or(TexDataType::UnsignedByte),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -475,8 +474,7 @@ impl WebGLRenderingContext {
|
||||||
target: TexImageTarget,
|
target: TexImageTarget,
|
||||||
level: u32,
|
level: u32,
|
||||||
format: TexFormat,
|
format: TexFormat,
|
||||||
width: u32,
|
size: Size2D<u32>,
|
||||||
height: u32,
|
|
||||||
data_type: TexDataType,
|
data_type: TexDataType,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if self
|
if self
|
||||||
|
@ -490,14 +488,25 @@ impl WebGLRenderingContext {
|
||||||
// Handle validation failed: LINEAR filtering not valid for this texture
|
// Handle validation failed: LINEAR filtering not valid for this texture
|
||||||
// WebGL Conformance tests expect to fallback to [0, 0, 0, 255] RGBA UNSIGNED_BYTE
|
// WebGL Conformance tests expect to fallback to [0, 0, 0, 255] RGBA UNSIGNED_BYTE
|
||||||
let data_type = TexDataType::UnsignedByte;
|
let data_type = TexDataType::UnsignedByte;
|
||||||
let expected_byte_length = width * height * 4;
|
let expected_byte_length = size.area() * 4;
|
||||||
let mut pixels = vec![0u8; expected_byte_length as usize];
|
let mut pixels = vec![0u8; expected_byte_length as usize];
|
||||||
for rgba8 in pixels.chunks_mut(4) {
|
for rgba8 in pixels.chunks_mut(4) {
|
||||||
rgba8[3] = 255u8;
|
rgba8[3] = 255u8;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.tex_image_2d(
|
self.tex_image_2d(
|
||||||
texture, target, data_type, format, level, width, height, 0, 1, true, true, pixels,
|
texture,
|
||||||
|
target,
|
||||||
|
data_type,
|
||||||
|
format,
|
||||||
|
level,
|
||||||
|
size.width,
|
||||||
|
size.height,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
pixels,
|
||||||
);
|
);
|
||||||
|
|
||||||
false
|
false
|
||||||
|
@ -517,13 +526,10 @@ impl WebGLRenderingContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_image_pixels(
|
fn get_image_pixels(&self, source: TexImageSource) -> Fallible<Option<TexPixels>> {
|
||||||
&self,
|
|
||||||
source: TexImageSource,
|
|
||||||
) -> Fallible<Option<(Vec<u8>, Size2D<u32>, bool)>> {
|
|
||||||
Ok(Some(match source {
|
Ok(Some(match source {
|
||||||
TexImageSource::ImageData(image_data) => {
|
TexImageSource::ImageData(image_data) => {
|
||||||
(image_data.to_vec(), image_data.get_size(), false)
|
TexPixels::new(image_data.to_vec(), image_data.get_size(), false)
|
||||||
},
|
},
|
||||||
TexImageSource::HTMLImageElement(image) => {
|
TexImageSource::HTMLImageElement(image) => {
|
||||||
let document = document_from_node(&*self.canvas);
|
let document = document_from_node(&*self.canvas);
|
||||||
|
@ -555,7 +561,7 @@ impl WebGLRenderingContext {
|
||||||
|
|
||||||
pixels::byte_swap_colors_inplace(&mut data);
|
pixels::byte_swap_colors_inplace(&mut data);
|
||||||
|
|
||||||
(data, size, false)
|
TexPixels::new(data, size, false)
|
||||||
},
|
},
|
||||||
// TODO(emilio): Getting canvas data is implemented in CanvasRenderingContext2D,
|
// TODO(emilio): Getting canvas data is implemented in CanvasRenderingContext2D,
|
||||||
// but we need to refactor it moving it to `HTMLCanvasElement` and support
|
// but we need to refactor it moving it to `HTMLCanvasElement` and support
|
||||||
|
@ -567,7 +573,7 @@ impl WebGLRenderingContext {
|
||||||
if let Some((mut data, size)) = canvas.fetch_all_data() {
|
if let Some((mut data, size)) = canvas.fetch_all_data() {
|
||||||
// Pixels got from Canvas have already alpha premultiplied
|
// Pixels got from Canvas have already alpha premultiplied
|
||||||
pixels::byte_swap_colors_inplace(&mut data);
|
pixels::byte_swap_colors_inplace(&mut data);
|
||||||
(data, size, true)
|
TexPixels::new(data, size, true)
|
||||||
} else {
|
} else {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
@ -3752,10 +3758,12 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
return Ok(self.webgl_error(InvalidOperation));
|
return Ok(self.webgl_error(InvalidOperation));
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self
|
let size = Size2D::new(width, height);
|
||||||
.validate_filterable_texture(&texture, target, level, format, width, height, data_type)
|
|
||||||
{
|
if !self.validate_filterable_texture(&texture, target, level, format, size, data_type) {
|
||||||
return Ok(()); // The validator sets the correct error for use
|
// FIXME(nox): What is the spec for this? No error is emitted ever
|
||||||
|
// by validate_filterable_texture.
|
||||||
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.tex_image_2d(
|
self.tex_image_2d(
|
||||||
|
@ -3790,8 +3798,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
return Ok(self.webgl_error(InvalidEnum));
|
return Ok(self.webgl_error(InvalidEnum));
|
||||||
}
|
}
|
||||||
|
|
||||||
let (pixels, size, premultiplied) = match self.get_image_pixels(source)? {
|
let pixels = match self.get_image_pixels(source)? {
|
||||||
Some(triple) => triple,
|
Some(pixels) => pixels,
|
||||||
None => return Ok(()),
|
None => return Ok(()),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3800,8 +3808,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
target,
|
target,
|
||||||
level,
|
level,
|
||||||
internal_format,
|
internal_format,
|
||||||
size.width as i32,
|
pixels.size.width as i32,
|
||||||
size.height as i32,
|
pixels.size.height as i32,
|
||||||
0,
|
0,
|
||||||
format,
|
format,
|
||||||
data_type,
|
data_type,
|
||||||
|
@ -3810,21 +3818,27 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
let TexImage2DValidatorResult {
|
let TexImage2DValidatorResult {
|
||||||
texture,
|
texture,
|
||||||
target,
|
target,
|
||||||
width,
|
|
||||||
height,
|
|
||||||
level,
|
level,
|
||||||
border,
|
border,
|
||||||
format,
|
format,
|
||||||
data_type,
|
data_type,
|
||||||
|
..
|
||||||
} = match validator.validate() {
|
} = match validator.validate() {
|
||||||
Ok(result) => result,
|
Ok(result) => result,
|
||||||
Err(_) => return Ok(()), // NB: The validator sets the correct error for us.
|
Err(_) => return Ok(()), // NB: The validator sets the correct error for us.
|
||||||
};
|
};
|
||||||
|
|
||||||
if !self
|
if !self.validate_filterable_texture(
|
||||||
.validate_filterable_texture(&texture, target, level, format, width, height, data_type)
|
&texture,
|
||||||
{
|
target,
|
||||||
return Ok(()); // The validator sets the correct error for use
|
level,
|
||||||
|
format,
|
||||||
|
pixels.size,
|
||||||
|
data_type,
|
||||||
|
) {
|
||||||
|
// FIXME(nox): What is the spec for this? No error is emitted ever
|
||||||
|
// by validate_filterable_texture.
|
||||||
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.tex_image_2d(
|
self.tex_image_2d(
|
||||||
|
@ -3833,13 +3847,13 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
data_type,
|
data_type,
|
||||||
format,
|
format,
|
||||||
level,
|
level,
|
||||||
width,
|
pixels.size.width,
|
||||||
height,
|
pixels.size.height,
|
||||||
border,
|
border,
|
||||||
1,
|
1,
|
||||||
premultiplied,
|
pixels.premultiplied,
|
||||||
true,
|
true,
|
||||||
pixels,
|
pixels.data,
|
||||||
);
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -3991,8 +4005,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
data_type: u32,
|
data_type: u32,
|
||||||
source: TexImageSource,
|
source: TexImageSource,
|
||||||
) -> ErrorResult {
|
) -> ErrorResult {
|
||||||
let (pixels, size, premultiplied) = match self.get_image_pixels(source)? {
|
let pixels = match self.get_image_pixels(source)? {
|
||||||
Some(triple) => triple,
|
Some(pixels) => pixels,
|
||||||
None => return Ok(()),
|
None => return Ok(()),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4001,8 +4015,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
target,
|
target,
|
||||||
level,
|
level,
|
||||||
format,
|
format,
|
||||||
size.width as i32,
|
pixels.size.width as i32,
|
||||||
size.height as i32,
|
pixels.size.height as i32,
|
||||||
0,
|
0,
|
||||||
format,
|
format,
|
||||||
data_type,
|
data_type,
|
||||||
|
@ -4010,8 +4024,6 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
let TexImage2DValidatorResult {
|
let TexImage2DValidatorResult {
|
||||||
texture,
|
texture,
|
||||||
target,
|
target,
|
||||||
width,
|
|
||||||
height,
|
|
||||||
level,
|
level,
|
||||||
format,
|
format,
|
||||||
data_type,
|
data_type,
|
||||||
|
@ -4027,14 +4039,14 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
level,
|
level,
|
||||||
xoffset,
|
xoffset,
|
||||||
yoffset,
|
yoffset,
|
||||||
width,
|
pixels.size.width,
|
||||||
height,
|
pixels.size.height,
|
||||||
format,
|
format,
|
||||||
data_type,
|
data_type,
|
||||||
1,
|
1,
|
||||||
premultiplied,
|
pixels.premultiplied,
|
||||||
true,
|
true,
|
||||||
pixels,
|
pixels.data,
|
||||||
);
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -4543,3 +4555,19 @@ fn rgba8_image_to_tex_image_data(
|
||||||
_ => unreachable!("Unsupported formats {:?} {:?}", format, data_type),
|
_ => unreachable!("Unsupported formats {:?} {:?}", format, data_type),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct TexPixels {
|
||||||
|
data: Vec<u8>,
|
||||||
|
size: Size2D<u32>,
|
||||||
|
premultiplied: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TexPixels {
|
||||||
|
fn new(data: Vec<u8>, size: Size2D<u32>, premultiplied: bool) -> Self {
|
||||||
|
Self {
|
||||||
|
data,
|
||||||
|
size,
|
||||||
|
premultiplied,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue