Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Send an IpcSharedMemory in tex_image_2d and tex_sub_image_2d #22225

Merged
merged 9 commits into from Nov 21, 2018

Move prepare_pixels to canvas_traits::webgl

  • Loading branch information
nox committed Nov 20, 2018
commit 5f9e3d8bb999b29f7b9092a31552e47ceed7da02
@@ -773,9 +773,53 @@ pub enum TexSource {
FromArray,
}

pub fn prepare_pixels(
internal_format: TexFormat,
data_type: TexDataType,
size: Size2D<u32>,
unpacking_alignment: u32,
alpha_treatment: Option<AlphaTreatment>,
y_axis_treatment: YAxisTreatment,
tex_source: TexSource,
mut pixels: Vec<u8>,
) -> Vec<u8> {
match alpha_treatment {
Some(AlphaTreatment::Premultiply) => {
if tex_source == TexSource::FromHtmlElement {
premultiply_inplace(TexFormat::RGBA, TexDataType::UnsignedByte, &mut pixels);
} else {
premultiply_inplace(internal_format, data_type, &mut pixels);
}
},
Some(AlphaTreatment::Unmultiply) => {
assert_eq!(tex_source, TexSource::FromHtmlElement);
unmultiply_inplace(&mut pixels);
},
None => {},
}

if tex_source == TexSource::FromHtmlElement {
pixels = rgba8_image_to_tex_image_data(internal_format, data_type, pixels);
}

if y_axis_treatment == YAxisTreatment::Flipped {
// FINISHME: Consider doing premultiply and flip in a single mutable Vec.
pixels = flip_pixels_y(
internal_format,
data_type,
size.width as usize,
size.height as usize,
unpacking_alignment as usize,
pixels,
);
}

pixels
}

/// Translates an image in rgba8 (red in the first byte) format to
/// the format that was requested of TexImage.
pub fn rgba8_image_to_tex_image_data(
fn rgba8_image_to_tex_image_data(
format: TexFormat,
data_type: TexDataType,
mut pixels: Vec<u8>,
@@ -978,7 +1022,7 @@ pub fn rgba8_image_to_tex_image_data(
}
}

pub fn premultiply_inplace(format: TexFormat, data_type: TexDataType, pixels: &mut [u8]) {
fn premultiply_inplace(format: TexFormat, data_type: TexDataType, pixels: &mut [u8]) {
match (format, data_type) {
(TexFormat::RGBA, TexDataType::UnsignedByte) => {
pixels::rgba8_premultiply_inplace(pixels);
@@ -1017,7 +1061,7 @@ pub fn premultiply_inplace(format: TexFormat, data_type: TexDataType, pixels: &m
}
}

pub fn unmultiply_inplace(pixels: &mut [u8]) {
fn unmultiply_inplace(pixels: &mut [u8]) {
for rgba in pixels.chunks_mut(4) {
let a = (rgba[3] as f32) / 255.0;
rgba[0] = (rgba[0] as f32 / a) as u8;
@@ -1027,7 +1071,7 @@ pub fn unmultiply_inplace(pixels: &mut [u8]) {
}

/// Flips the pixels in the Vec on the Y axis.
pub fn flip_pixels_y(
fn flip_pixels_y(
internal_format: TexFormat,
data_type: TexDataType,
width: usize,
@@ -638,55 +638,6 @@ impl WebGLRenderingContext {
}
}

fn prepare_pixels(
&self,
internal_format: TexFormat,
data_type: TexDataType,
size: Size2D<u32>,
unpacking_alignment: u32,
alpha_treatment: Option<AlphaTreatment>,
y_axis_treatment: YAxisTreatment,
tex_source: TexSource,
mut pixels: Vec<u8>,
) -> Vec<u8> {
match alpha_treatment {
Some(AlphaTreatment::Premultiply) => {
if tex_source == TexSource::FromHtmlElement {
webgl::premultiply_inplace(
TexFormat::RGBA,
TexDataType::UnsignedByte,
&mut pixels,
);
} else {
webgl::premultiply_inplace(internal_format, data_type, &mut pixels);
}
},
Some(AlphaTreatment::Unmultiply) => {
assert_eq!(tex_source, TexSource::FromHtmlElement);
webgl::unmultiply_inplace(&mut pixels);
},
None => {},
}

if tex_source == TexSource::FromHtmlElement {
pixels = webgl::rgba8_image_to_tex_image_data(internal_format, data_type, pixels);
}

if y_axis_treatment == YAxisTreatment::Flipped {
// FINISHME: Consider doing premultiply and flip in a single mutable Vec.
pixels = webgl::flip_pixels_y(
internal_format,
data_type,
size.width as usize,
size.height as usize,
unpacking_alignment as usize,
pixels,
);
}

pixels
}

fn tex_image_2d(
&self,
texture: &WebGLTexture,
@@ -699,6 +650,20 @@ impl WebGLRenderingContext {
tex_source: TexSource,
pixels: TexPixels,
) {
// TexImage2D depth is always equal to 1.
handle_potential_webgl_error!(
self,
texture.initialize(
target,
pixels.size.width,
pixels.size.height,
1,
internal_format,
level,
Some(data_type)
)
);

let settings = self.texture_unpacking_settings.get();
let dest_premultiplied = settings.contains(TextureUnpacking::PREMULTIPLY_ALPHA);

@@ -714,7 +679,7 @@ impl WebGLRenderingContext {
YAxisTreatment::AsIs
};

let buff = self.prepare_pixels(
let buff = webgl::prepare_pixels(
internal_format,
data_type,
pixels.size,
@@ -725,20 +690,6 @@ impl WebGLRenderingContext {
pixels.data,
);

// TexImage2D depth is always equal to 1
handle_potential_webgl_error!(
self,
texture.initialize(
target,
pixels.size.width,
pixels.size.height,
1,
internal_format,
level,
Some(data_type)
)
);

let format = internal_format.as_gl_constant();
let data_type = data_type.as_gl_constant();
let internal_format = self
@@ -777,12 +728,32 @@ impl WebGLRenderingContext {
tex_source: TexSource,
pixels: TexPixels,
) {
// We have already validated level
let image_info = texture.image_info_for_target(&target, level);

// GL_INVALID_VALUE is generated if:
// - xoffset or yoffset is less than 0
// - 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() ||
yoffset < 0 ||
(yoffset as u32 + pixels.size.height) > image_info.height()
{
return self.webgl_error(InvalidValue);
}

// NB: format and internal_format must match.
if format != image_info.internal_format().unwrap() ||
data_type != image_info.data_type().unwrap()
{
return self.webgl_error(InvalidOperation);
}

let settings = self.texture_unpacking_settings.get();
let dest_premultiplied = settings.contains(TextureUnpacking::PREMULTIPLY_ALPHA);

let alpha_treatment = match (
pixels.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,
@@ -794,7 +765,7 @@ impl WebGLRenderingContext {
YAxisTreatment::AsIs
};

let buff = self.prepare_pixels(
let buff = webgl::prepare_pixels(
format,
data_type,
pixels.size,
@@ -805,28 +776,6 @@ impl WebGLRenderingContext {
pixels.data,
);

// We have already validated level
let image_info = texture.image_info_for_target(&target, level);

// GL_INVALID_VALUE is generated if:
// - xoffset or yoffset is less than 0
// - 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() ||
yoffset < 0 ||
(yoffset as u32 + pixels.size.height) > image_info.height()
{
return self.webgl_error(InvalidValue);
}

// NB: format and internal_format must match.
if format != image_info.internal_format().unwrap() ||
data_type != image_info.data_type().unwrap()
{
return self.webgl_error(InvalidOperation);
}

// TODO(emilio): convert colorspace if requested
let (sender, receiver) = ipc::bytes_channel().unwrap();
self.send_command(WebGLCommand::TexSubImage2D {
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.