1 | // Copyright 2013 The Flutter Authors. All rights reserved. |
2 | // Use of this source code is governed by a BSD-style license that can be |
3 | // found in the LICENSE file. |
4 | |
5 | #include "flutter/flow/layers/clip_path_layer.h" |
6 | |
7 | #if defined(LEGACY_FUCHSIA_EMBEDDER) |
8 | |
9 | #include "lib/ui/scenic/cpp/commands.h" |
10 | |
11 | #endif |
12 | |
13 | namespace flutter { |
14 | |
15 | ClipPathLayer::ClipPathLayer(const SkPath& clip_path, Clip clip_behavior) |
16 | : clip_path_(clip_path), clip_behavior_(clip_behavior) { |
17 | FML_DCHECK(clip_behavior != Clip::none); |
18 | } |
19 | |
20 | void ClipPathLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { |
21 | TRACE_EVENT0("flutter" , "ClipPathLayer::Preroll" ); |
22 | |
23 | SkRect previous_cull_rect = context->cull_rect; |
24 | SkRect clip_path_bounds = clip_path_.getBounds(); |
25 | children_inside_clip_ = context->cull_rect.intersect(clip_path_bounds); |
26 | if (children_inside_clip_) { |
27 | TRACE_EVENT_INSTANT0("flutter" , "children inside clip rect" ); |
28 | |
29 | Layer::AutoPrerollSaveLayerState save = |
30 | Layer::AutoPrerollSaveLayerState::Create(context, UsesSaveLayer()); |
31 | context->mutators_stack.PushClipPath(clip_path_); |
32 | SkRect child_paint_bounds = SkRect::MakeEmpty(); |
33 | PrerollChildren(context, matrix, &child_paint_bounds); |
34 | |
35 | if (child_paint_bounds.intersect(clip_path_bounds)) { |
36 | set_paint_bounds(child_paint_bounds); |
37 | } |
38 | context->mutators_stack.Pop(); |
39 | } |
40 | context->cull_rect = previous_cull_rect; |
41 | } |
42 | |
43 | #if defined(LEGACY_FUCHSIA_EMBEDDER) |
44 | |
45 | void ClipPathLayer::UpdateScene(SceneUpdateContext& context) { |
46 | TRACE_EVENT0("flutter" , "ClipPathLayer::UpdateScene" ); |
47 | FML_DCHECK(needs_system_composite()); |
48 | |
49 | // TODO(liyuqian): respect clip_behavior_ |
50 | SceneUpdateContext::Clip clip(context, clip_path_.getBounds()); |
51 | UpdateSceneChildren(context); |
52 | } |
53 | |
54 | #endif |
55 | |
56 | void ClipPathLayer::Paint(PaintContext& context) const { |
57 | TRACE_EVENT0("flutter" , "ClipPathLayer::Paint" ); |
58 | FML_DCHECK(needs_painting()); |
59 | |
60 | if (!children_inside_clip_) { |
61 | TRACE_EVENT_INSTANT0("flutter" , "children not inside clip rect, skipping" ); |
62 | return; |
63 | } |
64 | |
65 | SkAutoCanvasRestore save(context.internal_nodes_canvas, true); |
66 | context.internal_nodes_canvas->clipPath(clip_path_, |
67 | clip_behavior_ != Clip::hardEdge); |
68 | |
69 | if (UsesSaveLayer()) { |
70 | context.internal_nodes_canvas->saveLayer(paint_bounds(), nullptr); |
71 | } |
72 | PaintChildren(context); |
73 | if (UsesSaveLayer()) { |
74 | context.internal_nodes_canvas->restore(); |
75 | } |
76 | } |
77 | |
78 | } // namespace flutter |
79 | |