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

isTargetTransparent() now samples the cache directly. #4955

Merged

Conversation

AndrewJDR
Copy link
Contributor

@AndrewJDR AndrewJDR commented May 7, 2018

This is a work in progress. It seems to work for the limited things I've tried it with -- mostly hit-testing paths. I know that it doesn't work on apple platforms where retina scaling is enabled, so I'd like some advice on how to get that working properly, and any other feedback/notes.

For example, I check for cache validity with the following:

if (target.shouldCache && target._cacheCanvas && !target.isCacheDirty())

Is there a better way to be doing this, or other things to consider checking about the state of the cache?

And finally, does the math here correct?

Thank you!


Previously, isTargetTransparent would do a paint from the cache to the contextCache which has more overhead and is slower. With this commit, fabricjs will test the cache canvas directly using x/y coordinates calculated with respect to the target object center. This is more performant since it avoids an extra render
on every call to isTargetTransparent.

@AndrewJDR AndrewJDR force-pushed the isTargetTransparent_direct_from_cache branch 2 times, most recently from 48323cf to 1047898 Compare May 7, 2018 13:37
@@ -492,6 +492,20 @@
* @return {Boolean}
*/
isTargetTransparent: function (target, x, y) {
if (target.shouldCache && target._cacheCanvas && !target.isCacheDirty()) {
Copy link
Member

Choose a reason for hiding this comment

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

the logic that tells us if the target is on its own cache canvas is a little bit more complex ( i have to verify )

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah ok. I've now noticed a canvas/path that this code doesn't properly handle, so I'm wondering if it's due to not checking its cache canvas properly or something.

curRelTargetY = y - center.y;

curRelTargetX = (target._cacheCanvas.width / 2) + (curRelTargetX / target.zoomX);
curRelTargetY = (target._cacheCanvas.height / 2) + (curRelTargetY / target.zoomY);
Copy link
Member

Choose a reason for hiding this comment

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

for blurriness reasons more than width/2 there is another property where we can see the center of the obect on the canvas, i think is called cacheTranslateX/Y or something like that, you find it in UpdateCacheCanvas function.

Also the translation respect the center should take care of the object rotation using the matrices directly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay, I tried using cacheTranslateX/Y in various ways, but I was getting weird results. I'll give it another try though.

@AndrewJDR AndrewJDR force-pushed the isTargetTransparent_direct_from_cache branch 2 times, most recently from e2ccc43 to f89a9b6 Compare May 8, 2018 06:43
Previously, isTargetTransparent would do a paint from the cache
to the contextCache which has more overhead and is slower.
With this commit, fabricjs will test the cache canvas directly
using x/y coordinates calculated with respect to the target object
center. This is more performant since it avoids an extra render
on every call to isTargetTransparent.
@AndrewJDR AndrewJDR force-pushed the isTargetTransparent_direct_from_cache branch from f89a9b6 to 3665449 Compare May 8, 2018 06:50
@@ -492,6 +492,17 @@
* @return {Boolean}
*/
isTargetTransparent: function (target, x, y) {
if (target.shouldCache() && target._cacheCanvas && !target.isCacheDirty()) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

shouldCache() returns the result of this.objectCaching && (!this.group || this.needsItsOwnCache() || !this.group.isOnACache()). Does this seem sufficient?

@@ -492,6 +492,17 @@
* @return {Boolean}
*/
isTargetTransparent: function (target, x, y) {
if (target.shouldCache() && target._cacheCanvas && !target.isCacheDirty()) {
var normalizedPointer = this._normalizePointer(target, {x: x, y: y}),
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed to use _normalizePointer() here, which uses the xform matrix so it handles rotation etc.

@AndrewJDR
Copy link
Contributor Author

Updated, accounted for rotations and it also seems to work with retina scaling enabled, now.

@asturur
Copy link
Member

asturur commented May 8, 2018

I m a little bit busy and i have to wrap up 2 things and release 2.2.4, but i l check this next.

@asturur
Copy link
Member

asturur commented May 8, 2018

it looks good anyway

@asturur
Copy link
Member

asturur commented May 19, 2018

i think is good, i m gonna merge it.
Writing a test is not straight forward, let's keep it as it is.

@asturur asturur merged commit c3b6e65 into fabricjs:master May 19, 2018
@asturur asturur mentioned this pull request May 19, 2018
thiagocunha pushed a commit to thiagocunha/fabric.js that referenced this pull request Nov 18, 2019
* isTargetTransparent() now samples the cache directly.

Previously, isTargetTransparent would do a paint from the cache
to the contextCache which has more overhead and is slower.
With this commit, fabricjs will test the cache canvas directly
using x/y coordinates calculated with respect to the target object
center. This is more performant since it avoids an extra render
on every call to isTargetTransparent.

* remove cacheDirty that should not be needed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants