-
Notifications
You must be signed in to change notification settings - Fork 6k
Add ClipMode to ClipPath/ClipRRect and PhysicalShape layers #5647
Conversation
728e080 to
1fed878
Compare
flow/layers/layer.h
Outdated
| namespace flow { | ||
|
|
||
| // This should be an exact copy of the Clip enum in | ||
| // flutter/package/flutter/lib/src/paining/basic_types.dart |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: should be packages/flutter/lib/src/painting/basic_types.dart
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We now moves the Clip enum to painting.dart.
flow/layers/layer.h
Outdated
| // This should be an exact copy of the Clip enum in | ||
| // flutter/package/flutter/lib/src/paining/basic_types.dart | ||
| // | ||
| // We call it Clip in public dart API to provide our developers the shortest |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
capitalize "Dart"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
lib/ui/compositing.dart
Outdated
| void _pushClipRRect(Float32List rrect) native 'SceneBuilder_pushClipRRect'; | ||
| /// See [pop] for details about the operation stack, and [Clip] for different clip modes. | ||
| /// By default, the clip will be anti-aliased (clipMode = 1 = Clip::antiAlias). | ||
| void pushClipRRect(RRect rrect, [int clipMode = 1]) => _pushClipRRect(rrect._value, clipMode); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can clipMode be an enum defined in the engine Dart code instead of an int?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah the public Dart API should definitely not be using an int for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also, prefer named arguments please
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I thought that only painting.dart is public and compositing.dart is private. If it's also public, then I shall definitely move the enum Clip definition from flutter/flutter's basic_types.dart into flutter/engine's painting.dart.
lib/ui/painting.dart
Outdated
| /// | ||
| /// TODO(liyuqian): Set it to Clip.none. (https://github.com/flutter/flutter/issues/18057) | ||
| /// We currently have Clip.antiAlias to preserve our old behaviors. | ||
| const Clip defaultClipBehavior = Clip.none; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should mark this deprecated so that people don't rely on it (we presumably will remove this in the near future, right?).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I'll remove it once the default behavior switches to Clip.none. Marking as deprecated.
lib/ui/painting.dart
Outdated
|
|
||
| /// The global default value of whether and how to clip a widget. | ||
| /// | ||
| /// TODO(liyuqian): Set it to Clip.none. (https://github.com/flutter/flutter/issues/18057) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODOs shouldn't be in documentation (make this // not ///)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
lib/ui/painting.dart
Outdated
| /// See also: | ||
| /// | ||
| /// * [antiAlias], which is much faster, and has similar clipping results. | ||
| antiAliasWithSaveLayer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
trivial nit: missing trailing comma
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
lib/ui/compositing.dart
Outdated
| void pushClipPath(Path path) native 'SceneBuilder_pushClipPath'; | ||
| /// See [pop] for details about the operation stack. See [Clip] for different clip modes. | ||
| /// By default, the clip will be anti-aliased (clip = [Clip.antiAlias]). | ||
| void pushClipPath(Path path, {Clip clip = Clip.antiAlias}) => _pushClipPath(path, clip.index); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what happens if you push a clip path with Clip.none?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and does Clip.antiAliasWithSaveLayer do anything interesting here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Push a clip layer (e.g., ClipPath, ClipRRect) with Clip.none will trigger assert: https://github.com/flutter/engine/pull/5647/files#diff-9930584db1fb28d6064ad30841935ac1R51
Clip.antiAliasWithSaveLayer will add a Canvas.saveLayer call: https://github.com/flutter/engine/pull/5647/files#diff-9930584db1fb28d6064ad30841935ac1R55
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when you say "assert" do you mean "throw an AssertionError in Dart" or do you mean "crash the engine"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a FXL_DCHECK(clip_mode_ != ClipMode::none) just like FXL_DCHECK(needs_painting()). I think that it'll crash the engine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I implement correctly, the developer should never see this crash. The dart code check whether it's Clip.none, and if it is, drop the ClipPath layer so the C++ side should never receive any ClipPath/ClipRRect layer with ClipMode::none. If the engine somehow receives it, it's probably a much bigger issue that can't be easily bypassed by hot-reload.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm confused. What stops someone from calling SceneBuilder.pushClipPath(path, clip = Clip.none) ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ClipPathLayer in Dart (https://github.com/flutter/flutter/pull/18576/files#diff-58600d3d2645a66835eb03f3c41b447bR725) prevents C++ engine to have Clip.none ClipPath.
But now I see that if someone is pushing a ClipPathLayer without using the Dart class ClipPathLayer, then it could be a problem. I'll print a warning and drop the layer instead of crashing then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would just assert here, just like we do in other methods in this file.
assert(clip != null);
assert(clip != Clip.none);
_pushClipPath(path, clip.index);There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
lib/ui/compositing.dart
Outdated
| /// [elevation] is greater than 0.0, then a shadow is drawn around the layer. | ||
| /// [shadowColor] defines the color of the shadow if present and [color] defines the | ||
| /// By default, the layer's content will not be clipped (clip = [Clip.none]). | ||
| /// If clipMode is nonzero (Clip.hardEdge, Clip.antiAlias, or Clip.antiAliasWithSaveLayer), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please put those values in square brackets
also, rather than "is nonzero" consider "has another value" since the enum values aren't zero.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I clearly forgot to update the comment here when I changed int clipMode to Clip clip. Updating now.
|
@Hixie please let me know if the new changes look good. |
lib/ui/painting.dart
Outdated
| // TODO(liyuqian): Set it to Clip.none. (https://github.com/flutter/flutter/issues/18057) | ||
| // We currently have Clip.antiAlias to preserve our old behaviors. | ||
| @deprecated // we'll eventually remove this and just use Clip.none. | ||
| const Clip defaultClipBehavior = Clip.none; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the comment doesn't match the value? i'm not sure what the purpose of this is.
Consider using @Deprecated() so you can provide a custom message explaining what this is for.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to @Deprecated() and Clip.antiAlias. Thanks for catching the mistake!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i'm worried that that didn't cause any tests to fail! is there no way to test this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My impression is that the flutter/engine is really under-tested. The flutter/flutter CI should definitely catch this failure once we tried to merge the engine change into flutter. Maybe we should have a engine->flutter auto-roller that does the check? It would not only save this change, but many other changes that make engine roll difficult.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it'll be less undertested if you add tests. :-)
An autoroller would be very useful. You should definitely feel empowered to work on that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Hixie : I'm going to work on the autoroller and I'll rely on the golden tests in flutter/flutter to guard this kind of engine changes. Does that sound good to you? Other than that, any more comments on this CL?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would definitely be happy to trade some unit tests here in order to get an autoroller plus relying on framework tests. :-)
So we can roll engine before the flutter/flutter change
5d0ccc4 to
44aadcf
Compare
For flutter/flutter#18057