Introduce TexPixels

This commit is contained in:
Anthony Ramine 2018-11-09 11:01:15 +01:00
parent 1e2a72abfe
commit 86987ed75d

View file

@ -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,
}
}
}