aboutsummaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
Diffstat (limited to 'components')
-rw-r--r--components/canvas/Cargo.toml1
-rw-r--r--components/canvas/canvas_paint_thread.rs3
-rw-r--r--components/canvas/lib.rs1
-rw-r--r--components/canvas/webgl_thread.rs4
-rw-r--r--components/canvas_traits/canvas.rs35
-rw-r--r--components/net/Cargo.toml1
-rw-r--r--components/net/image_cache.rs27
-rw-r--r--components/net/lib.rs1
-rw-r--r--components/net_traits/Cargo.toml1
-rw-r--r--components/net_traits/image/base.rs21
-rw-r--r--components/net_traits/lib.rs1
-rw-r--r--components/pixels/Cargo.toml10
-rw-r--r--components/pixels/lib.rs40
-rw-r--r--components/script/Cargo.toml1
-rw-r--r--components/script/dom/canvasrenderingcontext2d.rs5
-rw-r--r--components/script/dom/webglrenderingcontext.rs20
-rw-r--r--components/script/lib.rs1
17 files changed, 77 insertions, 96 deletions
diff --git a/components/canvas/Cargo.toml b/components/canvas/Cargo.toml
index 4006947acf6..de2073a1e28 100644
--- a/components/canvas/Cargo.toml
+++ b/components/canvas/Cargo.toml
@@ -24,6 +24,7 @@ ipc-channel = "0.11"
log = "0.4"
num-traits = "0.2"
offscreen_gl_context = {version = "0.21", features = ["serde", "osmesa"]}
+pixels = {path = "../pixels"}
serde_bytes = "0.10"
servo_config = {path = "../config"}
webrender = {git = "https://github.com/servo/webrender"}
diff --git a/components/canvas/canvas_paint_thread.rs b/components/canvas/canvas_paint_thread.rs
index 90d338e9a4e..91164a47cf0 100644
--- a/components/canvas/canvas_paint_thread.rs
+++ b/components/canvas/canvas_paint_thread.rs
@@ -7,6 +7,7 @@ use canvas_data::*;
use canvas_traits::canvas::*;
use euclid::Size2D;
use ipc_channel::ipc::{self, IpcSender};
+use pixels;
use std::borrow::ToOwned;
use std::collections::HashMap;
use std::thread;
@@ -141,7 +142,7 @@ impl<'a> CanvasPaintThread <'a> {
let data = match imagedata {
None => vec![0; image_size.width as usize * image_size.height as usize * 4],
Some(mut data) => {
- byte_swap(&mut data);
+ pixels::byte_swap_colors_inplace(&mut data);
data.into()
},
};
diff --git a/components/canvas/lib.rs b/components/canvas/lib.rs
index 8da9544de6e..554f598403c 100644
--- a/components/canvas/lib.rs
+++ b/components/canvas/lib.rs
@@ -15,6 +15,7 @@ extern crate ipc_channel;
#[macro_use] extern crate log;
extern crate num_traits;
extern crate offscreen_gl_context;
+extern crate pixels;
extern crate serde_bytes;
extern crate servo_config;
extern crate webrender;
diff --git a/components/canvas/webgl_thread.rs b/components/canvas/webgl_thread.rs
index 413566e7817..cd8dbde18d2 100644
--- a/components/canvas/webgl_thread.rs
+++ b/components/canvas/webgl_thread.rs
@@ -2,13 +2,13 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-use canvas_traits::canvas::byte_swap;
use canvas_traits::webgl::*;
use euclid::Size2D;
use fnv::FnvHashMap;
use gleam::gl;
use ipc_channel::ipc::IpcBytesSender;
use offscreen_gl_context::{GLContext, GLContextAttributes, GLLimits, NativeGLContextMethods};
+use pixels;
use std::thread;
use super::gl_context::{GLContextFactory, GLContextWrapper};
use webrender;
@@ -562,7 +562,7 @@ impl<VR: WebVRRenderHandler + 'static> WebGLThread<VR> {
let src_slice = &orig_pixels[src_start .. src_start + stride];
(&mut pixels[dst_start .. dst_start + stride]).clone_from_slice(&src_slice[..stride]);
}
- byte_swap(&mut pixels);
+ pixels::byte_swap_colors_inplace(&mut pixels);
pixels
}
diff --git a/components/canvas_traits/canvas.rs b/components/canvas_traits/canvas.rs
index 1fcf1a89a4a..6c7022c62a8 100644
--- a/components/canvas_traits/canvas.rs
+++ b/components/canvas_traits/canvas.rs
@@ -382,38 +382,3 @@ impl FromStr for CompositionOrBlending {
Err(())
}
}
-
-// TODO(pcwalton): Speed up with SIMD, or better yet, find some way to not do this.
-pub fn byte_swap(data: &mut [u8]) {
- let length = data.len();
- // FIXME(rust #27741): Range::step_by is not stable yet as of this writing.
- let mut i = 0;
- while i < length {
- let r = data[i + 2];
- data[i + 2] = data[i + 0];
- data[i + 0] = r;
- i += 4;
- }
-}
-
-pub fn multiply_u8_pixel(a: u8, b: u8) -> u8 {
- return (a as u32 * b as u32 / 255) as u8;
-}
-
-pub fn byte_swap_and_premultiply(data: &mut [u8]) {
- let length = data.len();
-
- let mut i = 0;
- while i < length {
- let r = data[i + 2];
- let g = data[i + 1];
- let b = data[i + 0];
- let a = data[i + 3];
-
- data[i + 0] = multiply_u8_pixel(r, a);
- data[i + 1] = multiply_u8_pixel(g, a);
- data[i + 2] = multiply_u8_pixel(b, a);
-
- i += 4;
- }
-}
diff --git a/components/net/Cargo.toml b/components/net/Cargo.toml
index aca08703bae..4c0b2aa4e9b 100644
--- a/components/net/Cargo.toml
+++ b/components/net/Cargo.toml
@@ -34,6 +34,7 @@ mime_guess = "1.8.0"
msg = {path = "../msg"}
net_traits = {path = "../net_traits"}
openssl = "0.9"
+pixels = {path = "../pixels"}
profile_traits = {path = "../profile_traits"}
serde = "1.0"
serde_json = "1.0"
diff --git a/components/net/image_cache.rs b/components/net/image_cache.rs
index 40ef8041ef7..ba0d679b0e3 100644
--- a/components/net/image_cache.rs
+++ b/components/net/image_cache.rs
@@ -9,6 +9,7 @@ use net_traits::image::base::{Image, ImageMetadata, PixelFormat, load_from_memor
use net_traits::image_cache::{CanRequestImages, ImageCache, ImageResponder};
use net_traits::image_cache::{ImageOrMetadataAvailable, ImageResponse, ImageState};
use net_traits::image_cache::{PendingImageId, UsePlaceholder};
+use pixels;
use servo_url::ServoUrl;
use std::collections::HashMap;
use std::collections::hash_map::Entry::{Occupied, Vacant};
@@ -52,7 +53,7 @@ fn set_webrender_image_key(webrender_api: &webrender_api::RenderApi, image: &mut
let is_opaque = match image.format {
PixelFormat::BGRA8 => {
bytes.extend_from_slice(&*image.bytes);
- premultiply(bytes.as_mut_slice())
+ pixels::premultiply_inplace(bytes.as_mut_slice())
}
PixelFormat::RGB8 => {
for bgr in image.bytes.chunks(3) {
@@ -86,30 +87,6 @@ fn set_webrender_image_key(webrender_api: &webrender_api::RenderApi, image: &mut
image.id = Some(image_key);
}
-// Returns true if the image was found to be
-// completely opaque.
-fn premultiply(data: &mut [u8]) -> bool {
- let mut is_opaque = true;
- let length = data.len();
-
- let mut i = 0;
- while i < length {
- let b = data[i + 0] as u32;
- let g = data[i + 1] as u32;
- let r = data[i + 2] as u32;
- let a = data[i + 3] as u32;
-
- data[i + 0] = (b * a / 255) as u8;
- data[i + 1] = (g * a / 255) as u8;
- data[i + 2] = (r * a / 255) as u8;
-
- i += 4;
- is_opaque = is_opaque && a == 255;
- }
-
- is_opaque
-}
-
// ======================================================================
// Aux structs and enums.
// ======================================================================
diff --git a/components/net/lib.rs b/components/net/lib.rs
index ab5c3bc74a2..285a755a9e9 100644
--- a/components/net/lib.rs
+++ b/components/net/lib.rs
@@ -27,6 +27,7 @@ extern crate mime_guess;
extern crate msg;
extern crate net_traits;
extern crate openssl;
+extern crate pixels;
#[macro_use]
extern crate profile_traits;
#[macro_use] extern crate serde;
diff --git a/components/net_traits/Cargo.toml b/components/net_traits/Cargo.toml
index 9ae5042be69..641d77d8d0c 100644
--- a/components/net_traits/Cargo.toml
+++ b/components/net_traits/Cargo.toml
@@ -24,6 +24,7 @@ malloc_size_of = { path = "../malloc_size_of" }
malloc_size_of_derive = { path = "../malloc_size_of_derive" }
msg = {path = "../msg"}
num-traits = "0.2"
+pixels = {path = "../pixels"}
serde = "1.0"
servo_arc = {path = "../servo_arc"}
servo_config = {path = "../config"}
diff --git a/components/net_traits/image/base.rs b/components/net_traits/image/base.rs
index 35b52e559fe..40d79b9ea74 100644
--- a/components/net_traits/image/base.rs
+++ b/components/net_traits/image/base.rs
@@ -4,6 +4,7 @@
use ipc_channel::ipc::IpcSharedMemory;
use piston_image::{self, DynamicImage, ImageFormat};
+use pixels;
use std::fmt;
use webrender_api;
@@ -46,24 +47,6 @@ pub struct ImageMetadata {
// FIXME: Images must not be copied every frame. Instead we should atomically
// reference count them.
-// TODO(pcwalton): Speed up with SIMD, or better yet, find some way to not do this.
-fn byte_swap_colors_inplace(data: &mut [u8]) {
- let length = data.len();
-
- let mut i = 0;
- while i < length {
- let r = data[i + 2];
- let g = data[i + 1];
- let b = data[i + 0];
-
- data[i + 0] = r;
- data[i + 1] = g;
- data[i + 2] = b;
-
- i += 4;
- }
-}
-
pub fn load_from_memory(buffer: &[u8]) -> Option<Image> {
if buffer.is_empty() {
return None;
@@ -82,7 +65,7 @@ pub fn load_from_memory(buffer: &[u8]) -> Option<Image> {
DynamicImage::ImageRgba8(rgba) => rgba,
image => image.to_rgba(),
};
- byte_swap_colors_inplace(&mut *rgba);
+ pixels::byte_swap_colors_inplace(&mut *rgba);
Some(Image {
width: rgba.width(),
height: rgba.height(),
diff --git a/components/net_traits/lib.rs b/components/net_traits/lib.rs
index 87dcf034caa..7066a3f1f28 100644
--- a/components/net_traits/lib.rs
+++ b/components/net_traits/lib.rs
@@ -17,6 +17,7 @@ extern crate ipc_channel;
#[macro_use] extern crate malloc_size_of_derive;
extern crate msg;
extern crate num_traits;
+extern crate pixels;
#[macro_use] extern crate serde;
extern crate servo_arc;
extern crate servo_url;
diff --git a/components/pixels/Cargo.toml b/components/pixels/Cargo.toml
new file mode 100644
index 00000000000..49dcc3833cf
--- /dev/null
+++ b/components/pixels/Cargo.toml
@@ -0,0 +1,10 @@
+[package]
+name = "pixels"
+version = "0.0.1"
+authors = ["The Servo Project Developers"]
+license = "MPL-2.0"
+publish = false
+
+[lib]
+name = "pixels"
+path = "lib.rs"
diff --git a/components/pixels/lib.rs b/components/pixels/lib.rs
new file mode 100644
index 00000000000..d91b14cb650
--- /dev/null
+++ b/components/pixels/lib.rs
@@ -0,0 +1,40 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// TODO(pcwalton): Speed up with SIMD, or better yet, find some way to not do this.
+pub fn byte_swap_colors_inplace(pixels: &mut [u8]) {
+ assert!(pixels.len() % 4 == 0);
+ for rgba in pixels.chunks_mut(4) {
+ let b = rgba[0];
+ rgba[0] = rgba[2];
+ rgba[2] = b;
+ }
+}
+
+pub fn byte_swap_and_premultiply_inplace(pixels: &mut [u8]) {
+ assert!(pixels.len() % 4 == 0);
+ for rgba in pixels.chunks_mut(4) {
+ let b = rgba[0];
+ rgba[0] = multiply_u8_color(rgba[2], rgba[3]);
+ rgba[1] = multiply_u8_color(rgba[1], rgba[3]);
+ rgba[2] = multiply_u8_color(b, rgba[3]);
+ }
+}
+
+/// Returns true if the pixels were found to be completely opaque.
+pub fn premultiply_inplace(pixels: &mut [u8]) -> bool {
+ assert!(pixels.len() % 4 == 0);
+ let mut is_opaque = true;
+ for rgba in pixels.chunks_mut(4) {
+ rgba[0] = multiply_u8_color(rgba[0], rgba[3]);
+ rgba[1] = multiply_u8_color(rgba[1], rgba[3]);
+ rgba[2] = multiply_u8_color(rgba[2], rgba[3]);
+ is_opaque = is_opaque && rgba[3] == 255;
+ }
+ is_opaque
+}
+
+pub fn multiply_u8_color(a: u8, b: u8) -> u8 {
+ return (a as u32 * b as u32 / 255) as u8;
+}
diff --git a/components/script/Cargo.toml b/components/script/Cargo.toml
index ca859bb472a..078218d624b 100644
--- a/components/script/Cargo.toml
+++ b/components/script/Cargo.toml
@@ -75,6 +75,7 @@ num-traits = "0.2"
offscreen_gl_context = {version = "0.21", features = ["serde"]}
parking_lot = "0.6"
phf = "0.7.18"
+pixels = {path = "../pixels"}
profile_traits = {path = "../profile_traits"}
ref_filter_map = "1.0.1"
ref_slice = "1.0"
diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs
index 9adbaa3a734..15b6eb9560f 100644
--- a/components/script/dom/canvasrenderingcontext2d.rs
+++ b/components/script/dom/canvasrenderingcontext2d.rs
@@ -5,7 +5,7 @@
use canvas_traits::canvas::{Canvas2dMsg, CanvasMsg, CanvasId};
use canvas_traits::canvas::{CompositionOrBlending, FillOrStrokeStyle, FillRule};
use canvas_traits::canvas::{LineCapStyle, LineJoinStyle, LinearGradientStyle};
-use canvas_traits::canvas::{RadialGradientStyle, RepetitionStyle, byte_swap_and_premultiply};
+use canvas_traits::canvas::{RadialGradientStyle, RepetitionStyle};
use cssparser::{Parser, ParserInput, RGBA};
use cssparser::Color as CSSColor;
use dom::bindings::cell::DomRefCell;
@@ -41,6 +41,7 @@ use net_traits::image_cache::ImageResponse;
use net_traits::image_cache::ImageState;
use net_traits::image_cache::UsePlaceholder;
use num_traits::ToPrimitive;
+use pixels;
use profile_traits::ipc as profiled_ipc;
use script_traits::ScriptMsg;
use servo_url::ServoUrl;
@@ -410,7 +411,7 @@ impl CanvasRenderingContext2D {
Some((mut data, size)) => {
// Pixels come from cache in BGRA order and drawImage expects RGBA so we
// have to swap the color values
- byte_swap_and_premultiply(&mut data);
+ pixels::byte_swap_and_premultiply_inplace(&mut data);
let size = Size2D::new(size.width as f64, size.height as f64);
(data, size)
},
diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs
index 7972201b9ce..a2862831f73 100644
--- a/components/script/dom/webglrenderingcontext.rs
+++ b/components/script/dom/webglrenderingcontext.rs
@@ -5,7 +5,6 @@
#[cfg(feature = "webgl_backtrace")]
use backtrace::Backtrace;
use byteorder::{ByteOrder, NativeEndian, WriteBytesExt};
-use canvas_traits::canvas::{byte_swap, multiply_u8_pixel};
use canvas_traits::webgl::{DOMToTextureCommand, Parameter, WebGLCommandBacktrace};
use canvas_traits::webgl::{TexParameter, WebGLCommand, WebGLContextShareMode, WebGLError};
use canvas_traits::webgl::{WebGLFramebufferBindingRequest, WebGLMsg, WebGLMsgSender};
@@ -65,6 +64,7 @@ use js::typedarray::{TypedArray, TypedArrayElementCreator};
use net_traits::image::base::PixelFormat;
use net_traits::image_cache::ImageResponse;
use offscreen_gl_context::{GLContextAttributes, GLLimits};
+use pixels;
use script_layout_interface::HTMLCanvasDataSource;
use serde::{Deserialize, Serialize};
use servo_config::prefs::PREFS;
@@ -550,7 +550,7 @@ impl WebGLRenderingContext {
_ => unimplemented!(),
};
- byte_swap(&mut data);
+ pixels::byte_swap_colors_inplace(&mut data);
(data, size, false)
},
@@ -563,7 +563,7 @@ impl WebGLRenderingContext {
}
if let Some((mut data, size)) = canvas.fetch_all_data() {
// Pixels got from Canvas have already alpha premultiplied
- byte_swap(&mut data);
+ pixels::byte_swap_colors_inplace(&mut data);
(data, size, true)
} else {
return Ok(None);
@@ -679,15 +679,11 @@ impl WebGLRenderingContext {
match (format, data_type) {
(TexFormat::RGBA, TexDataType::UnsignedByte) => {
- for rgba in pixels.chunks_mut(4) {
- rgba[0] = multiply_u8_pixel(rgba[0], rgba[3]);
- rgba[1] = multiply_u8_pixel(rgba[1], rgba[3]);
- rgba[2] = multiply_u8_pixel(rgba[2], rgba[3]);
- }
+ pixels::premultiply_inplace(pixels);
},
(TexFormat::LuminanceAlpha, TexDataType::UnsignedByte) => {
for la in pixels.chunks_mut(2) {
- la[0] = multiply_u8_pixel(la[0], la[1]);
+ la[0] = pixels::multiply_u8_color(la[0], la[1]);
}
},
(TexFormat::RGBA, TexDataType::UnsignedShort5551) => {
@@ -707,9 +703,9 @@ impl WebGLRenderingContext {
let a = extend_to_8_bits(pix & 0x0f);
NativeEndian::write_u16(
rgba,
- ((multiply_u8_pixel(r, a) & 0xf0) as u16) << 8 |
- ((multiply_u8_pixel(g, a) & 0xf0) as u16) << 4 |
- ((multiply_u8_pixel(b, a) & 0xf0) as u16) |
+ ((pixels::multiply_u8_color(r, a) & 0xf0) as u16) << 8 |
+ ((pixels::multiply_u8_color(g, a) & 0xf0) as u16) << 4 |
+ ((pixels::multiply_u8_color(b, a) & 0xf0) as u16) |
((a & 0x0f) as u16),
);
}
diff --git a/components/script/lib.rs b/components/script/lib.rs
index 097f69d7808..a2ece5ce32c 100644
--- a/components/script/lib.rs
+++ b/components/script/lib.rs
@@ -78,6 +78,7 @@ extern crate num_traits;
extern crate offscreen_gl_context;
extern crate parking_lot;
extern crate phf;
+extern crate pixels;
#[macro_use]
extern crate profile_traits;
extern crate ref_filter_map;