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

Do not use lookup tables for put_image_data #9911

Merged
merged 3 commits into from
Apr 1, 2016

Conversation

magni-
Copy link
Contributor

@magni- magni- commented Mar 8, 2016

Fixes #9599

"This is the first Rust code I have ever written" (and also my first time writing real browser code, it's been quite the learning experience).

Some questions:

For really fast CPU results, use integer SIMD instructions to handle more than one pixel at a time.

This was out of the scope of #9599, right? I started looking into doing that, but it seems to be a lot more work than the E-easy label would suggest. std::simd is marked as "unstable", is that a blocker?

128 can be added before dividing to round more accurately.

@michaelwu, what did you mean by that?
#9599 mentions #8086, but this isn't just a revert of that PR, correct? I didn't touch script/ at all. Do I need to re-add the tests here: https://github.com/servo/servo/pull/8086/files#diff-d6e07693f6e7f8f93e2113a102d1d405L1 ?

Also, the #9599 is Do not use lookup tables for {Get,Put}ImageData operations, but we only use lookup tables for the Put, not the Get, right?

Sorry for all the noobish questions.

Review on Reviewable

@highfive highfive added the S-awaiting-review There is new code that needs to be reviewed. label Mar 8, 2016
@magni- magni- changed the title Dont use lookup tables for put_image_data Don't use lookup tables for put_image_data Mar 8, 2016
@wafflespeanut
Copy link
Contributor

r? @michaelwu

@highfive highfive assigned michaelwu and unassigned wafflespeanut Mar 8, 2016
@michaelwu
Copy link
Contributor

Thanks for the PR!

128 can be added before dividing to round more accurately.

@michaelwu, what did you mean by that?

The math rounds down by default, so if the result was something like 5.75 in floating point, the final result would be 5 rather than 6. Adding 128 before dividing allows us to round up in these cases. From a floating point POV, it looks like you're adding .5 before rounding down.

#9599 mentions #8086, but this isn't just a revert of that PR, correct? I didn't touch script/ at all. Do I need to re-add the tests here: https://github.com/servo/servo/pull/8086/files#diff-d6e07693f6e7f8f93e2113a102d1d405L1 ?

Correct. You shouldn't need to put those tests back on the failing list if the math here is correct. However, you might need to do the rounding thing I suggested to get the results accurate enough to not fail tests.

Also, the #9599 is Do not use lookup tables for {Get,Put}ImageData operations, but we only use lookup tables for the Put, not the Get, right?

It looks like we only use the table for the Get. Either way - your PR is on the right track.

@jdm
Copy link
Member

jdm commented Mar 8, 2016

See also components/script/unpremultiplytable.rs.

@michaelwu
Copy link
Contributor

For really fast CPU results, use integer SIMD instructions to handle more than one pixel at a time.

This was out of the scope of #9599, right? I started looking into doing that, but it seems to be a lot more work than the E-easy label would suggest. std::simd is marked as "unstable", is that a blocker?

Yeah don't worry about it. It's tricky since you have to worry about alignment too.

@magni-
Copy link
Contributor Author

magni- commented Mar 9, 2016

Out of curiosity, why is the premultiplication for put_image_data implemented in components/canvas but the unpremultiplication (postdivision?) for GetImageData implemented in components/script?

The math rounds down by default, so if the result was something like 5.75 in floating point, the final result would be 5 rather than 6. Adding 128 before dividing allows us to round up in these cases. From a floating point POV, it looks like you're adding .5 before rounding down.

Ahh gotcha, makes a lot more sense now.

@@ -795,6 +790,11 @@ fn is_zero_size_gradient(pattern: &Pattern) -> bool {
false
}

fn premultiply_channel_by_alpha(channel: u8, alpha: u16) -> u8 {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I felt like this could be spun out into a helper, not least because those ((((s looked potentially confusing, but happy to put it back in put_image_data.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you put this function in the block where it's used?

@magni- magni- changed the title Don't use lookup tables for put_image_data Don't use lookup tables for put_image_data and GetImageData Mar 9, 2016
@jdm
Copy link
Member

jdm commented Mar 9, 2016

@bors-servo: try

@bors-servo
Copy link
Contributor

⌛ Trying commit b1e087f with merge b01dd4a...

bors-servo pushed a commit that referenced this pull request Mar 9, 2016
Don't use lookup tables for put_image_data and GetImageData

Fixes #9599

"This is the first Rust code I have ever written" (and also my first time writing real browser code, it's been quite the learning experience).

Some questions:

> For really fast CPU results, use integer SIMD instructions to handle more than one pixel at a time.

This was out of the scope of #9599, right? I started looking into doing that, but it seems to be a lot more work than the `E-easy` label would suggest. [`std::simd`](https://doc.rust-lang.org/1.0.0/std/simd/index.html) is marked as "unstable", is that a blocker?

> 128 can be added before dividing to round more accurately.

@michaelwu, what did you mean by that?

Also, the #9599 is `Do not use lookup tables for {Get,Put}ImageData operations`, but we only use lookup tables for the `Put`, not the `Get`, right?

Sorry for all the noobish questions.

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.svg" height="40" alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/9911)
<!-- Reviewable:end -->
@bors-servo
Copy link
Contributor

💔 Test failed - mac-rel-wpt

@highfive highfive added the S-tests-failed The changes caused existing tests to fail. label Mar 9, 2016
@jdm
Copy link
Member

jdm commented Mar 9, 2016

 ▶ Unexpected subtest result in /2dcontext/pixel-manipulation/2d.imageData.put.dirty.rect2.html:
  │ FAIL [expected PASS] putImageData() only modifies areas inside the dirty rectangle, using x and y
  │   → assert_approx_equals: Red channel of the pixel at (50, 25) expected 0 +/- 2 but got 255
  │ 
  │ _assertPixelApprox@http://web-platform.test:8000/common/canvas-tests.js:46:5
  │ @http://web-platform.test:8000/2dcontext/pixel-manipulation/2d.imageData.put.dirty.rect2.html:17:1
  │ Test.prototype.step@http://web-platform.test:8000/resources/testharness.js:1381:20
  │ _addTest/</<@http://web-platform.test:8000/common/canvas-tests.js:61:13
  │ Test.prototype.step@http://web-platform.test:8000/resources/testharness.js:1381:20
  └ _addTest/<@http://web-platform.test:8000/common/canvas-tests.js:58:9

  ▶ Unexpected subtest result in /2dcontext/pixel-manipulation/2d.imageData.put.unchanged.html:
  │ FAIL [expected PASS] putImageData(getImageData(...), ...) has no effect
  │   → assert_equals: olddata["14"] === imgdata2.data["14"] (got 85[number], expected 0[number]) expected 0 but got 85
  │ 
  │ _assertSame@http://web-platform.test:8000/common/canvas-tests.js:16:5
  │ @http://web-platform.test:8000/2dcontext/pixel-manipulation/2d.imageData.put.unchanged.html:20:5
  │ Test.prototype.step@http://web-platform.test:8000/resources/testharness.js:1381:20
  │ _addTest/</<@http://web-platform.test:8000/common/canvas-tests.js:61:13
  │ Test.prototype.step@http://web-platform.test:8000/resources/testharness.js:1381:20
  └ _addTest/<@http://web-platform.test:8000/common/canvas-tests.js:58:9

@highfive highfive removed the S-tests-failed The changes caused existing tests to fail. label Mar 10, 2016
chunk[2] = UNPREMULTIPLY_TABLE[256 * alpha + chunk[2] as usize];
let alpha = chunk[3] as u16;
if alpha != 0 {
chunk[0] = ((chunk[0] as u16 * 255 + (alpha / 2)) / alpha) as u8;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After lots of Googling, I took this from https://bugzilla.mozilla.org/show_bug.cgi?id=659725#c31. Not sure what the best solution here is though.

@michaelwu
Copy link
Contributor

@bors-servo: try

@bors-servo
Copy link
Contributor

⌛ Trying commit 33f67b0 with merge 9c328d6...

bors-servo pushed a commit that referenced this pull request Mar 12, 2016
Don't use lookup tables for put_image_data and GetImageData

Fixes #9599

"This is the first Rust code I have ever written" (and also my first time writing real browser code, it's been quite the learning experience).

Some questions:

> For really fast CPU results, use integer SIMD instructions to handle more than one pixel at a time.

This was out of the scope of #9599, right? I started looking into doing that, but it seems to be a lot more work than the `E-easy` label would suggest. [`std::simd`](https://doc.rust-lang.org/1.0.0/std/simd/index.html) is marked as "unstable", is that a blocker?

> 128 can be added before dividing to round more accurately.

@michaelwu, what did you mean by that?

Also, the #9599 is `Do not use lookup tables for {Get,Put}ImageData operations`, but we only use lookup tables for the `Put`, not the `Get`, right?

Sorry for all the noobish questions.

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.svg" height="40" alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/9911)
<!-- Reviewable:end -->
@bors-servo
Copy link
Contributor

💔 Test failed - mac-rel-wpt

@highfive highfive added the S-tests-failed The changes caused existing tests to fail. label Mar 12, 2016
@bors-servo
Copy link
Contributor

💔 Test failed - linux-rel

@highfive highfive added the S-tests-failed The changes caused existing tests to fail. label Mar 25, 2016
@magni-
Copy link
Contributor Author

magni- commented Mar 25, 2016

Hmm, three timeouts that I don't think have anything to do with my PR?

  ▶ TIMEOUT [expected OK] /websockets/opening-handshake/003-sets-origin.worker

  ▶ Unexpected subtest result in /websockets/opening-handshake/003-sets-origin.worker:
  │ TIMEOUT [expected PASS] W3C WebSocket API - origin set in a Worker
  └   → Test timed out

  ▶ TIMEOUT [expected FAIL] /css21_dev/html4/border-color-applies-to-013.htm
  │ 
  │ Shutting down the Constellation after generating an output file or exit flag specified
  │ thread 'Constellation' panicked at 'called `Result::unwrap()` on an `Err` value: IoError(Error { repr: Os { code: 104, message: "Connection reset by peer" } })', ../src/libcore/result.rs:746
  │ stack backtrace:
  │    1:     0x7f0edc6d1930 - sys::backtrace::tracing::imp::write::h495bc662e480d01f2cv
  │    2:     0x7f0edc6d678f - panicking::default_handler::_$u7b$$u7b$closure$u7d$$u7d$::closure.44522
  │    3:     0x7f0edc6d6408 - panicking::default_handler::h4e73712d1e927dfeH0z
  │    4:     0x7f0edc6c06cc - sys_common::unwind::begin_unwind_inner::h0e1be209f5e9e87dg2t
  │    5:     0x7f0edc6c1678 - sys_common::unwind::begin_unwind_fmt::h45dc2fac9b5e0d23m1t
  │    6:     0x7f0edc6d0c31 - rust_begin_unwind
  │    7:     0x7f0edc70e1af - panicking::panic_fmt::h40f5ec0cdc3fc429FRL
  │    8:     0x7f0edba1f84e - result::unwrap_failed::h18184822212557296049
  │    9:     0x7f0edba48999 - font_cache_thread::FontCacheThread::exit::h2850cfb8b5add96auMn
  │   10:     0x7f0edad396f5 - constellation::Constellation<LTF, STF>::handle_exit::h15804920269366392541
  │   11:     0x7f0edad16916 - constellation::Constellation<LTF, STF>::handle_request::h11164905505392349147
  │   12:     0x7f0edad0b2f7 - sys_common::unwind::try::try_fn::h1825336841370962927
  │   13:     0x7f0edc6d0bbb - __rust_try
  │   14:     0x7f0edc6d0b4d - sys_common::unwind::inner_try::he9b0b11c6b5b4e7fiZt
  │   15:     0x7f0edad0c1fa - boxed::F.FnBox<A>::call_box::h17027304325024401966
  │   16:     0x7f0edc6d4d59 - sys::thread::Thread::new::thread_start::hf1ffcc04a41608eb9Xy
  │   17:     0x7f0ed8968181 - start_thread
  │   18:     0x7f0ed847f47c - __clone
  └   19:                0x0 - <unknown>

@jdm
Copy link
Member

jdm commented Mar 25, 2016

Yes, those are known intermittent failures.

@highfive highfive removed the S-tests-failed The changes caused existing tests to fail. label Mar 31, 2016
@magni-
Copy link
Contributor Author

magni- commented Apr 1, 2016

@bors-servo: try

bors-servo pushed a commit that referenced this pull request Apr 1, 2016
Do not use lookup tables for put_image_data

Fixes #9599

"This is the first Rust code I have ever written" (and also my first time writing real browser code, it's been quite the learning experience).

Some questions:

> For really fast CPU results, use integer SIMD instructions to handle more than one pixel at a time.

This was out of the scope of #9599, right? I started looking into doing that, but it seems to be a lot more work than the `E-easy` label would suggest. [`std::simd`](https://doc.rust-lang.org/1.0.0/std/simd/index.html) is marked as "unstable", is that a blocker?

> 128 can be added before dividing to round more accurately.

@michaelwu, what did you mean by that?

Also, the #9599 is `Do not use lookup tables for {Get,Put}ImageData operations`, but we only use lookup tables for the `Put`, not the `Get`, right?

Sorry for all the noobish questions.

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.svg" height="40" alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/9911)
<!-- Reviewable:end -->
@bors-servo
Copy link
Contributor

⌛ Trying commit 3055581 with merge cb2cb9a...

@bors-servo
Copy link
Contributor

☀️ Test successful - android, arm32, linux-dev, linux-rel, mac-dev-unit, mac-rel-css, mac-rel-wpt, status-appveyor

@magni-
Copy link
Contributor Author

magni- commented Apr 1, 2016

@michaelwu Despite the S-needs-rebase label, this PR is ready for 👀 now 😄

@jdm jdm removed the S-needs-rebase There are merge conflict errors. label Apr 1, 2016
@michaelwu
Copy link
Contributor

@bors-servo: r=michaelwu

@bors-servo
Copy link
Contributor

📌 Commit 3055581 has been approved by michaelwu

@highfive highfive added S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. and removed S-awaiting-review There is new code that needs to be reviewed. labels Apr 1, 2016
@bors-servo
Copy link
Contributor

⌛ Testing commit 3055581 with merge 983956a...

bors-servo pushed a commit that referenced this pull request Apr 1, 2016
Do not use lookup tables for put_image_data

Fixes #9599

"This is the first Rust code I have ever written" (and also my first time writing real browser code, it's been quite the learning experience).

Some questions:

> For really fast CPU results, use integer SIMD instructions to handle more than one pixel at a time.

This was out of the scope of #9599, right? I started looking into doing that, but it seems to be a lot more work than the `E-easy` label would suggest. [`std::simd`](https://doc.rust-lang.org/1.0.0/std/simd/index.html) is marked as "unstable", is that a blocker?

> 128 can be added before dividing to round more accurately.

@michaelwu, what did you mean by that?

Also, the #9599 is `Do not use lookup tables for {Get,Put}ImageData operations`, but we only use lookup tables for the `Put`, not the `Get`, right?

Sorry for all the noobish questions.

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.svg" height="40" alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/9911)
<!-- Reviewable:end -->
@bors-servo
Copy link
Contributor

☀️ Test successful - android, arm32, linux-dev, linux-rel, mac-dev-unit, mac-rel-css, mac-rel-wpt, status-appveyor

@bors-servo
Copy link
Contributor

👀 Test was successful, but fast-forwarding failed: 422 Update is not a fast forward

@bors-servo
Copy link
Contributor

⌛ Testing commit 3055581 with merge 4e4a213...

bors-servo pushed a commit that referenced this pull request Apr 1, 2016
Do not use lookup tables for put_image_data

Fixes #9599

"This is the first Rust code I have ever written" (and also my first time writing real browser code, it's been quite the learning experience).

Some questions:

> For really fast CPU results, use integer SIMD instructions to handle more than one pixel at a time.

This was out of the scope of #9599, right? I started looking into doing that, but it seems to be a lot more work than the `E-easy` label would suggest. [`std::simd`](https://doc.rust-lang.org/1.0.0/std/simd/index.html) is marked as "unstable", is that a blocker?

> 128 can be added before dividing to round more accurately.

@michaelwu, what did you mean by that?

Also, the #9599 is `Do not use lookup tables for {Get,Put}ImageData operations`, but we only use lookup tables for the `Put`, not the `Get`, right?

Sorry for all the noobish questions.

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.svg" height="40" alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/9911)
<!-- Reviewable:end -->
@bors-servo
Copy link
Contributor

☀️ Test successful - android, arm32, linux-dev, linux-rel, mac-dev-unit, mac-rel-css, mac-rel-wpt, status-appveyor

@bors-servo bors-servo merged commit 3055581 into servo:master Apr 1, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants