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

Remove Cell/DomRefCell member wrappers from CanvasState struct #23436

Closed
jdm opened this issue May 21, 2019 · 13 comments
Closed

Remove Cell/DomRefCell member wrappers from CanvasState struct #23436

jdm opened this issue May 21, 2019 · 13 comments
Labels

Comments

@jdm
Copy link
Member

@jdm jdm commented May 21, 2019

CanvasState was introduced as part of a big refactor in #23381 that extracted common aspects of the offscreen canvas rendering context and the 2d canvas rendering context. Since the CanvasState struct is stored inside of a DomRefCell itself, that means that we can modify the methods for CanvasState to accept &self or &mut self directly, so the Cell and DomRefCell members inside of CanvasState are redundant and can be removed.

Code: components/script/dom/canvasrenderingcontext2d.rs

To verify that everything behaves the same after changing the code, run ./mach test-wpt tests/wpt/web-platform-tests/2dcontext/ tests/wpt/web-platform-tests/offscreen-canvas.

@highfive
Copy link

@highfive highfive commented May 21, 2019

Hi! If you have any questions regarding this issue, feel free to make a comment here, or ask it in the #servo channel in IRC.

If you intend to work on this issue, then add @highfive: assign me to your comment, and I'll assign this to you. 😄

@jdm jdm mentioned this issue May 21, 2019
3 of 5 tasks complete
@chansuke
Copy link
Contributor

@chansuke chansuke commented May 23, 2019

@highfive: assign me

@highfive highfive added the C-assigned label May 23, 2019
@highfive
Copy link

@highfive highfive commented May 23, 2019

Hey @chansuke! Thanks for your interest in working on this issue. It's now assigned to you!

@jdm
Copy link
Member Author

@jdm jdm commented May 23, 2019

#23381 has not actually been able to merge yet, so this will have to wait.

@jdm
Copy link
Member Author

@jdm jdm commented Jun 3, 2019

#23381 has merged, so this can be worked on now.

@chansuke
Copy link
Contributor

@chansuke chansuke commented Jun 11, 2019

@jdm Thanks! I will be going to start wokring on this:)

@chansuke
Copy link
Contributor

@chansuke chansuke commented Jun 23, 2019

@jdm Hi, I've removed the wrapper in CanvasState struct(to state: CanvasContextState) at first and updating like below
let transform = self.state.borrow().transform;let transform = self.state.transform;
but I'm stucking with this line(L:1467),
*self.canvas_state.borrow().state.borrow_mut() = CanvasContextState::new();.
Could you give me a suggestion to how to handle this? Thanks.

@jdm
Copy link
Member Author

@jdm jdm commented Jun 23, 2019

self.canvas_state.borrow_mut().state = CanvasContextState::new() should do what you want.

bors-servo added a commit that referenced this issue Jul 9, 2019
Remove redundant RefCell from CanvasState struct

<!-- Please describe your changes on the following line: -->
Removed DomRefCell member wrappers from CanvasState.

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes fix #23436 (GitHub issue number if applicable)

<!-- Either: -->
- [ ] There are tests for these changes OR
- [x] These changes do not require tests because it only fixed redundancy.

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/23730)
<!-- Reviewable:end -->
@jdm jdm added the C-has open PR label Jul 12, 2019
bors-servo added a commit that referenced this issue Aug 26, 2019
Remove redundant RefCell from CanvasState struct

<!-- Please describe your changes on the following line: -->
Removed DomRefCell member wrappers from CanvasState.

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes fix #23436 (GitHub issue number if applicable)

<!-- Either: -->
- [ ] There are tests for these changes OR
- [x] These changes do not require tests because it only fixed redundancy.

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/23730)
<!-- Reviewable:end -->
@utsavoza
Copy link
Contributor

@utsavoza utsavoza commented Apr 8, 2020

Hey @jdm, I see that code concerning the issue has changed quite a bit since this both the issue and its PR (#23730) was created. Based on the current implementation of CanvasState, I believe we should rather remove the DomRefCell wrapper for CanvasState since we are currently borrowing it immutably in both CanvasRenderingContext2D and OffscreenCanvasRenderingContext2D (unless we intend to borrow it mutably in the future?). Is there any specific reason I am missing why we should instead opt to remove Cell/DomRefCell member wrappers from CanvasState?

@jdm
Copy link
Member Author

@jdm jdm commented Apr 8, 2020

@utsavoza In general I find methods that are &self or &mut self as needed on a struct are easier to read than those same methods performing lots of borrow/borrow_mut calls on their members. If we keep the DomRefCell wrapper around CanvasState and remove the per-member wrappers, that will yield easier to read code in my opinion.

@utsavoza
Copy link
Contributor

@utsavoza utsavoza commented Apr 8, 2020

I agree. I did actually try to remove the Cell/DomRefCell member wrappers from CanvasState struct. The issue I saw with that is there will be some public methods in CanvasState that will now accept &mut self instead of &self.

For example: draw_image method will now cause canvas_state to be borrowed mutably in CanvasRenderingContext2D. This is a specific example where a wpt test failed with:

  │    9: script::dom::canvasrenderingcontext2d::CanvasRenderingContext2D::send_canvas_2d_msg
  │   10: script::canvas_state::CanvasState::draw_image_internal
  │   11: script::canvas_state::CanvasState::draw_image
  │   12: <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
  │   13: script::dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding::CanvasRenderingContext2DBinding::drawImage

From the stacktrace, I am assuming that while mutably borrowing canvas_state in CanvasRenderingContext2D::DrawImage, we are trying to borrow canvas_state again via:

  • CanvasState::draw_image
  • CanvasState::draw_image_internal
  • CanvasRenderingContext2D::context.send_canvas_2d_msg

which then causes the wpt to fail.

There are few other similar scenarios that are resulting in failing wpt tests, which is why I considered removing DomRefCell wrapper for CanvasState itself.

@jdm
Copy link
Member Author

@jdm jdm commented Apr 8, 2020

From reading the code (since draw_image_internal does not directly invoke send_canvas_2d_msg), it looks like that either comes from CanvasState::draw_html_canvas_element or CanvasState::draw_offscreen_canvas. I think we should only end up with a borrow problem in the case where we try to draw an html canvas inside of itself. One option to avoid that would be to pass the source canvas's CanvasId as an argument to draw_html_canvas_element and call this code with the source canvasid instead. That would avoid having to go through CanvasRenderingContext2D::send_canvas_2d_message.

@jdm
Copy link
Member Author

@jdm jdm commented Apr 8, 2020

That being said, if the resulting code is just working around a couple edge cases, you might be right that it will be easier to read and write if we keep the member wrappers instead of the overall CanvasState wrapper. Use your best judgement!

@utsavoza utsavoza mentioned this issue Apr 10, 2020
4 of 4 tasks complete
bors-servo added a commit that referenced this issue Apr 15, 2020
Remove DomRefCell wrapper for CanvasState

<!-- Please describe your changes on the following line: -->

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes fix #23436
- [x] There are tests for these changes

The PR removes the DomRefCell wrapper for CanvasState from `CanvasRenderingContext2D` and `OffscreenCanvasRenderingContext2D`. The reason for keeping member wrappers in CanvasState instead of overall CanvasState wrapper itself is because I believe that removing member wrappers would make it rather difficult to refactor the internal CanvasState methods in order to cover certain edge cases.

[For example](#23436 (comment)): Drawing a canvas inside of itself would require getting and providing certain parameters for source canvas such as `canvas_id` and `is_origin_clean` that are currently accessed through source canvas context. Also, we might run into similar issue when creating patterns using canvas.

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

4 participants
You can’t perform that action at this time.