mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Auto merge of #8086 - froydnj:premultiply-tables, r=jdm
add (un)premultiply tables for canvas {Get,Put}ImageData operations Pretty straightforward use of lookup tables to replace a bunch of expensive float operations. <!-- Reviewable:start --> [<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/8086) <!-- Reviewable:end -->
This commit is contained in:
commit
9a34decec2
8 changed files with 8216 additions and 21 deletions
|
@ -17,6 +17,7 @@ use ipc_channel::ipc::{self, IpcSender};
|
||||||
use ipc_channel::router::ROUTER;
|
use ipc_channel::router::ROUTER;
|
||||||
use layers::platform::surface::NativeSurface;
|
use layers::platform::surface::NativeSurface;
|
||||||
use num::ToPrimitive;
|
use num::ToPrimitive;
|
||||||
|
use premultiplytable::PREMULTIPLY_TABLE;
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::sync::mpsc::{Sender, channel};
|
use std::sync::mpsc::{Sender, channel};
|
||||||
|
@ -597,11 +598,10 @@ impl<'a> CanvasPaintTask<'a> {
|
||||||
let mut src_offset = src_line;
|
let mut src_offset = src_line;
|
||||||
for _ in 0 .. dest_rect.size.width {
|
for _ in 0 .. dest_rect.size.width {
|
||||||
// Premultiply alpha and swap RGBA -> BGRA.
|
// Premultiply alpha and swap RGBA -> BGRA.
|
||||||
// TODO: may want a precomputed premultiply table to make this fast. (#6969)
|
let alpha = imagedata[src_offset + 3] as usize;
|
||||||
let alpha = imagedata[src_offset + 3] as f32 / 255.;
|
dest.push(PREMULTIPLY_TABLE[256 * alpha + imagedata[src_offset + 2] as usize]);
|
||||||
dest.push((imagedata[src_offset + 2] as f32 * alpha) as u8);
|
dest.push(PREMULTIPLY_TABLE[256 * alpha + imagedata[src_offset + 1] as usize]);
|
||||||
dest.push((imagedata[src_offset + 1] as f32 * alpha) as u8);
|
dest.push(PREMULTIPLY_TABLE[256 * alpha + imagedata[src_offset + 0] as usize]);
|
||||||
dest.push((imagedata[src_offset + 0] as f32 * alpha) as u8);
|
|
||||||
dest.push(imagedata[src_offset + 3]);
|
dest.push(imagedata[src_offset + 3]);
|
||||||
src_offset += 4;
|
src_offset += 4;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,4 +25,5 @@ extern crate offscreen_gl_context;
|
||||||
extern crate util;
|
extern crate util;
|
||||||
|
|
||||||
pub mod canvas_paint_task;
|
pub mod canvas_paint_task;
|
||||||
|
mod premultiplytable;
|
||||||
pub mod webgl_paint_task;
|
pub mod webgl_paint_task;
|
||||||
|
|
4102
components/canvas/premultiplytable.rs
Normal file
4102
components/canvas/premultiplytable.rs
Normal file
File diff suppressed because it is too large
Load diff
|
@ -41,6 +41,7 @@ use std::cell::RefCell;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::mpsc::channel;
|
use std::sync::mpsc::channel;
|
||||||
use std::{cmp, fmt};
|
use std::{cmp, fmt};
|
||||||
|
use unpremultiplytable::UNPREMULTIPLY_TABLE;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use util::str::DOMString;
|
use util::str::DOMString;
|
||||||
use util::vec::byte_swap;
|
use util::vec::byte_swap;
|
||||||
|
@ -887,13 +888,11 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D {
|
||||||
let mut data = receiver.recv().unwrap();
|
let mut data = receiver.recv().unwrap();
|
||||||
|
|
||||||
// Un-premultiply alpha
|
// Un-premultiply alpha
|
||||||
// TODO: may want a precomputed un-premultiply table to make this fast.
|
|
||||||
// https://github.com/servo/servo/issues/6969
|
|
||||||
for chunk in data.chunks_mut(4) {
|
for chunk in data.chunks_mut(4) {
|
||||||
let alpha = chunk[3] as f32 / 255.;
|
let alpha = chunk[3] as usize;
|
||||||
chunk[0] = (chunk[0] as f32 / alpha) as u8;
|
chunk[0] = UNPREMULTIPLY_TABLE[256 * alpha + chunk[0] as usize];
|
||||||
chunk[1] = (chunk[1] as f32 / alpha) as u8;
|
chunk[1] = UNPREMULTIPLY_TABLE[256 * alpha + chunk[1] as usize];
|
||||||
chunk[2] = (chunk[2] as f32 / alpha) as u8;
|
chunk[2] = UNPREMULTIPLY_TABLE[256 * alpha + chunk[2] as usize];
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(ImageData::new(self.global.root().r(), sw, sh, Some(data)))
|
Ok(ImageData::new(self.global.root().r(), sw, sh, Some(data)))
|
||||||
|
|
|
@ -95,6 +95,7 @@ pub mod parse;
|
||||||
pub mod script_task;
|
pub mod script_task;
|
||||||
pub mod textinput;
|
pub mod textinput;
|
||||||
mod timers;
|
mod timers;
|
||||||
|
mod unpremultiplytable;
|
||||||
mod webdriver_handlers;
|
mod webdriver_handlers;
|
||||||
|
|
||||||
use dom::bindings::codegen::RegisterBindings;
|
use dom::bindings::codegen::RegisterBindings;
|
||||||
|
|
4102
components/script/unpremultiplytable.rs
Normal file
4102
components/script/unpremultiplytable.rs
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,5 +0,0 @@
|
||||||
[2d.imageData.put.alpha.html]
|
|
||||||
type: testharness
|
|
||||||
[putImageData() puts non-solid image data correctly]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
[2d.imageData.put.unchanged.html]
|
|
||||||
type: testharness
|
|
||||||
[putImageData(getImageData(...), ...) has no effect]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue