Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
853cbd6
get the stack ready
May 16, 2019
72042cf
draft
May 17, 2019
8489c08
Do nothing if the params didn't change when compositing platform views.
May 17, 2019
647e66b
merge
May 17, 2019
f7d7aaa
draft
May 17, 2019
c0741b2
draft
May 18, 2019
6e95d26
draft2
May 24, 2019
a3e1d61
clip rrect
May 28, 2019
4cf9f8a
typo fix
May 28, 2019
1daacb0
Merge branch 'master' into platform_view_transform
May 28, 2019
04d1f40
counting previous clips and only add and remove uiview when number of…
May 29, 2019
5b05eb2
draft
May 30, 2019
9b290cb
draft
May 30, 2019
52a8252
comments and formatting
May 31, 2019
3a899fa
english
May 31, 2019
cabc67a
remove friend from operator==
May 31, 2019
4496b21
merge master
Jun 3, 2019
4bdae98
fix issue caused by merging
Jun 3, 2019
33513b9
review fixes
Jun 3, 2019
e8926a5
remove tranform\cilpping util method into a different file and add th…
Jun 4, 2019
3f4c586
rename after review
Jun 4, 2019
d4f88f2
move stack to paint context
Jun 4, 2019
4eeb64f
draft vector with unique_ptr
Jun 4, 2019
6d78901
more review fixes
Jun 4, 2019
e494853
unittests for mutator stack
Jun 5, 2019
81e5c19
move stack to paint context complete
Jun 5, 2019
ea11fad
formatting
Jun 5, 2019
2c79050
Merge branch 'master' into platform_view_transform
Jun 5, 2019
5deaaeb
draft
Jun 6, 2019
0f70a44
mutator stack compare fixes
Jun 6, 2019
32d2681
mutator stack compare fixes
Jun 6, 2019
021b2ce
merge
Jun 6, 2019
b874420
revert the change that made the vector containing unique_ptr
Jun 6, 2019
95d2834
merge
Jun 6, 2019
a1794de
formatting
Jun 6, 2019
7178add
Merge branch 'platform_view_transform' into platform_view_clip_path
Jun 6, 2019
2f0125c
add TODO
Jun 6, 2019
d22acbd
fix a bug where the reused clip view doesn't reset transform
Jun 10, 2019
2b08642
addition to last fix
Jun 10, 2019
1599067
adding touch transparent view
Jun 10, 2019
f1f36bd
Merge branch 'platform_view_transform' into platform_view_clip_path
Jun 10, 2019
b8e4111
adding approximate for conic and remove debugging logs
Jun 10, 2019
a027fa0
some review fixes
Jun 11, 2019
12ff43a
union done
Jun 11, 2019
a9a660f
draft
Jun 11, 2019
f4b9503
review fixes
Jun 12, 2019
7c0fa63
draft
Jun 12, 2019
2eb40d6
embeded param does not delete stack when destructed
Jun 12, 2019
6d4c82c
Merge branch 'platform_view_transform' into platform_view_transform_u…
Jun 12, 2019
7d1d0e5
copy constructor for Mutator
Jun 12, 2019
46098a4
more tests
Jun 12, 2019
fa1248a
remove the move to
Jun 12, 2019
dd0eed8
merge
Jun 12, 2019
50843a0
share ptr for vector_
Jun 12, 2019
31ec192
Merge branch 'master' into platform_view_transform
Jun 12, 2019
00fb915
merge
Jun 12, 2019
3b6b3b0
formatting
Jun 12, 2019
b4b59ca
fixes unittest
Jun 12, 2019
ee57e42
Update BUILD.gn
iskakaushik Jun 12, 2019
979d251
license file fix
Jun 12, 2019
c4bfea1
Merge branch 'platform_view_transform' into platform_view_clip_path
Jun 12, 2019
a297a9f
remove testing logs
Jun 12, 2019
98f47aa
merge master
Jun 25, 2019
6c7d755
fix
Jun 25, 2019
13f515c
mark
Jun 25, 2019
467ac65
revert mark
Jun 25, 2019
ac72abf
formatting
Jun 25, 2019
e64360c
use constant
Jun 25, 2019
9b2f55f
review fixes
Jul 1, 2019
ad6f400
add todo
Jul 1, 2019
8ef8260
Merge branch 'master' into platform_view_clip_path
Jul 2, 2019
2c9f1aa
Merge branch 'master' into platform_view_clip_path
Jul 2, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions flow/embedded_views.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ void MutatorsStack::pushClipRRect(const SkRRect& rrect) {
vector_.push_back(element);
};

void MutatorsStack::pushClipPath(const SkPath& path) {
std::shared_ptr<Mutator> element = std::make_shared<Mutator>(path);
vector_.push_back(element);
};

void MutatorsStack::pushTransform(const SkMatrix& matrix) {
std::shared_ptr<Mutator> element = std::make_shared<Mutator>(matrix);
vector_.push_back(element);
Expand Down
1 change: 0 additions & 1 deletion flow/embedded_views.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ class MutatorsStack {
void pushClipRect(const SkRect& rect);
void pushClipRRect(const SkRRect& rrect);
void pushClipPath(const SkPath& path);

Copy link
Contributor

Choose a reason for hiding this comment

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

revert

void pushTransform(const SkMatrix& matrix);

// Removes the `Mutator` on the top of the stack
Expand Down
3 changes: 3 additions & 0 deletions flow/layers/clip_path_layer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,16 @@ void ClipPathLayer::Paint(PaintContext& context) const {
SkAutoCanvasRestore save(context.internal_nodes_canvas, true);
context.internal_nodes_canvas->clipPath(clip_path_,
clip_behavior_ != Clip::hardEdge);
context.mutators_stack.pushClipPath(clip_path_);

if (clip_behavior_ == Clip::antiAliasWithSaveLayer) {
context.internal_nodes_canvas->saveLayer(paint_bounds(), nullptr);
}
PaintChildren(context);
if (clip_behavior_ == Clip::antiAliasWithSaveLayer) {
context.internal_nodes_canvas->restore();
}
context.mutators_stack.pop();
}

} // namespace flutter
17 changes: 17 additions & 0 deletions flow/mutators_stack_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,15 @@ TEST(MutatorsStack, PushClipRRect) {
ASSERT_TRUE(iter->get()->rrect() == rrect);
}

TEST(MutatorsStack, PushClipPath) {
flutter::MutatorsStack stack;
SkPath path;
stack.pushClipPath(path);
auto iter = stack.bottom();
ASSERT_TRUE(iter->get()->type() == flutter::MutatorType::clip_path);
ASSERT_TRUE(iter->get()->path() == path);
}

TEST(MutatorsStack, PushTransform) {
MutatorsStack stack;
SkMatrix matrix;
Expand Down Expand Up @@ -102,6 +111,8 @@ TEST(MutatorsStack, Equality) {
stack.pushClipRect(rect);
SkRRect rrect = SkRRect::MakeEmpty();
stack.pushClipRRect(rrect);
SkPath path;
stack.pushClipPath(path);

MutatorsStack stackOther;
SkMatrix matrixOther = SkMatrix::MakeScale(1, 1);
Expand All @@ -110,6 +121,8 @@ TEST(MutatorsStack, Equality) {
stackOther.pushClipRect(rectOther);
SkRRect rrectOther = SkRRect::MakeEmpty();
stackOther.pushClipRRect(rrectOther);
SkPath otherPath;
stackOther.pushClipPath(otherPath);

ASSERT_TRUE(stack == stackOther);
}
Expand Down Expand Up @@ -177,6 +190,10 @@ TEST(Mutator, Equality) {
Mutator otherMutator3 = Mutator(rrect);
ASSERT_TRUE(mutator3 == otherMutator3);

SkPath path;
flutter::Mutator mutator4 = flutter::Mutator(path);
flutter::Mutator otherMutator4 = flutter::Mutator(path);
ASSERT_TRUE(mutator4 == otherMutator4);
ASSERT_FALSE(mutator2 == mutator);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,6 @@
}
++iter;
}

// Reverse scale based on screen scale.
//
// The UIKit frame is set based on the logical resolution instead of physical.
Expand Down Expand Up @@ -363,7 +362,6 @@
UIView* platform_view_root = root_views_[view_id].get();
UIView* overlay = overlays_[view_id]->overlay_view;
FML_CHECK(platform_view_root.superview == overlay.superview);

if (platform_view_root.superview == flutter_view) {
[flutter_view bringSubviewToFront:platform_view_root];
[flutter_view bringSubviewToFront:overlay];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
@end

namespace flutter {

// Converts a SkMatrix to CATransform3D.
// Certain fields are ignored in CATransform3D since SkMatrix is 3x3 and CATransform3D is 4x4.
CATransform3D GetCATransform3DFromSkMatrix(const SkMatrix& matrix);
Expand Down Expand Up @@ -85,8 +84,8 @@ class FlutterPlatformViewsController {
// Returns the `FlutterPlatformView` object associated with the view_id.
//
// If the `FlutterPlatformViewsController` does not contain any `FlutterPlatformView` object or
// a `FlutterPlatformView` object asscociated with the view_id cannot be found, the method returns
// nil.
// a `FlutterPlatformView` object asscociated with the view_id cannot be found, the method
// returns nil.
NSObject<FlutterPlatformView>* GetPlatformViewByID(int view_id);

std::vector<SkCanvas*> GetCurrentCanvases();
Expand All @@ -109,8 +108,8 @@ class FlutterPlatformViewsController {
std::map<std::string, fml::scoped_nsobject<NSObject<FlutterPlatformViewFactory>>> factories_;
std::map<int64_t, fml::scoped_nsobject<NSObject<FlutterPlatformView>>> views_;
std::map<int64_t, fml::scoped_nsobject<FlutterTouchInterceptingView>> touch_interceptors_;
// Mapping a platform view ID to the top most parent view (root_view) who is a direct child to the
// `flutter_view_`.
// Mapping a platform view ID to the top most parent view (root_view) who is a direct child to
// the `flutter_view_`.
//
// The platform view with the view ID is a child of the root view; If the platform view is not
// clipped, and no clipping view is added, the root view will be the intercepting view.
Expand Down Expand Up @@ -152,6 +151,7 @@ class FlutterPlatformViewsController {
void EnsureGLOverlayInitialized(int64_t overlay_id,
std::shared_ptr<IOSGLContext> gl_context,
GrContext* gr_context);

// Traverse the `mutators_stack` and return the number of clip operations.
int CountClips(const MutatorsStack& mutators_stack);

Expand All @@ -172,10 +172,10 @@ class FlutterPlatformViewsController {
// Applies the mutators in the mutators_stack to the UIView chain that was constructed by
// `ReconstructClipViewsChain`
//
// Clips are applied to the super view with a CALayer mask. Transforms are applied to the current
// view that's at the head of the chain. For example the following mutators stack [T_1, C_2, T_3,
// T_4, C_5, T_6] where T denotes a transform and C denotes a clip, will result in the following
// UIView tree:
// Clips are applied to the super view with a CALayer mask. Transforms are applied to the
// current view that's at the head of the chain. For example the following mutators stack [T_1,
// C_2, T_3, T_4, C_5, T_6] where T denotes a transform and C denotes a clip, will result in the
// following UIView tree:
//
// C_2 -> C_5 -> PLATFORM_VIEW
// (PLATFORM_VIEW is a subview of C_5 which is a subview of C_2)
Expand All @@ -184,7 +184,6 @@ class FlutterPlatformViewsController {
//
// After each clip operation, we update the head to the super view of the current head.
void ApplyMutators(const MutatorsStack& mutators_stack, UIView* embedded_view);

void CompositeWithParams(int view_id, const flutter::EmbeddedViewParams& params);

FML_DISALLOW_COPY_AND_ASSIGN(FlutterPlatformViewsController);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

#include "flutter/shell/platform/darwin/ios/ios_surface.h"

static int kMaxPointsInVerb = 4;

namespace flutter {

FlutterPlatformViewLayer::FlutterPlatformViewLayer(fml::scoped_nsobject<UIView> overlay_view,
Expand Down Expand Up @@ -129,6 +131,76 @@ - (void)clipRRect:(const SkRRect&)clipSkRRect {
CGPathRelease(pathRef);
}

- (void)clipPath:(const SkPath&)path {
CGMutablePathRef pathRef = CGPathCreateMutable();
if (!path.isValid()) {
return;
}
if (path.isEmpty()) {
CAShapeLayer* clip = [[CAShapeLayer alloc] init];
clip.path = pathRef;
self.layer.mask = clip;
CGPathRelease(pathRef);
return;
}

// Loop through all verbs and translate them into CGPath
SkPath::Iter iter(path, true);
SkPoint pts[kMaxPointsInVerb];
SkPath::Verb verb = iter.next(pts);
SkPoint last_pt_from_last_verb;
while (verb != SkPath::kDone_Verb) {
if (verb == SkPath::kLine_Verb || verb == SkPath::kQuad_Verb || verb == SkPath::kConic_Verb ||
verb == SkPath::kCubic_Verb) {
FML_DCHECK(last_pt_from_last_verb == pts[0]);
}
switch (verb) {
case SkPath::kMove_Verb: {
CGPathMoveToPoint(pathRef, nil, pts[0].x(), pts[0].y());
last_pt_from_last_verb = pts[0];
break;
}
case SkPath::kLine_Verb: {
CGPathAddLineToPoint(pathRef, nil, pts[1].x(), pts[1].y());
Copy link
Contributor

Choose a reason for hiding this comment

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

are we sure we can assume that pts[0] is the last point of the previous verb?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Offline discussion: We confirmed we can assume the pts[0] is always the last point of the previous verb, but we are going to add a DCHECK for our own sanity.

last_pt_from_last_verb = pts[1];
break;
}
case SkPath::kQuad_Verb: {
CGPathAddQuadCurveToPoint(pathRef, nil, pts[1].x(), pts[1].y(), pts[2].x(), pts[2].y());
last_pt_from_last_verb = pts[2];
break;
}
case SkPath::kConic_Verb: {
// Conic is not available in quartz, we use quad to approximate.
Copy link
Contributor

Choose a reason for hiding this comment

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

Reference a TODO issue here to better approximate this with multiple quads.

// TODO(cyanglaz): Better approximate the conic path.
// https://github.com/flutter/flutter/issues/35062
CGPathAddQuadCurveToPoint(pathRef, nil, pts[1].x(), pts[1].y(), pts[2].x(), pts[2].y());
last_pt_from_last_verb = pts[2];
break;
}
case SkPath::kCubic_Verb: {
CGPathAddCurveToPoint(pathRef, nil, pts[1].x(), pts[1].y(), pts[2].x(), pts[2].y(),
pts[3].x(), pts[3].y());
last_pt_from_last_verb = pts[3];
break;
}
case SkPath::kClose_Verb: {
CGPathCloseSubpath(pathRef);
break;
}
case SkPath::kDone_Verb: {
break;
}
}
verb = iter.next(pts);
}

CAShapeLayer* clip = [[CAShapeLayer alloc] init];
clip.path = pathRef;
self.layer.mask = clip;
CGPathRelease(pathRef);
}

- (void)setClip:(flutter::MutatorType)type
rect:(const SkRect&)rect
rrect:(const SkRRect&)rrect
Expand All @@ -143,7 +215,7 @@ - (void)setClip:(flutter::MutatorType)type
[self clipRRect:rrect];
break;
case flutter::clip_path:
// TODO(cyanglaz): Add clip path
[self clipPath:path];
break;
default:
break;
Expand Down