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_rrect_layer.h" |
6 | |
7 | namespace flutter { |
8 | |
9 | ClipRRectLayer::ClipRRectLayer(const SkRRect& clip_rrect, Clip clip_behavior) |
10 | : clip_rrect_(clip_rrect), clip_behavior_(clip_behavior) { |
11 | FML_DCHECK(clip_behavior != Clip::none); |
12 | } |
13 | |
14 | void ClipRRectLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { |
15 | TRACE_EVENT0("flutter" , "ClipRRectLayer::Preroll" ); |
16 | |
17 | SkRect previous_cull_rect = context->cull_rect; |
18 | SkRect clip_rrect_bounds = clip_rrect_.getBounds(); |
19 | children_inside_clip_ = context->cull_rect.intersect(clip_rrect_bounds); |
20 | if (children_inside_clip_) { |
21 | TRACE_EVENT_INSTANT0("flutter" , "children inside clip rect" ); |
22 | |
23 | Layer::AutoPrerollSaveLayerState save = |
24 | Layer::AutoPrerollSaveLayerState::Create(context, UsesSaveLayer()); |
25 | context->mutators_stack.PushClipRRect(clip_rrect_); |
26 | SkRect child_paint_bounds = SkRect::MakeEmpty(); |
27 | PrerollChildren(context, matrix, &child_paint_bounds); |
28 | |
29 | if (child_paint_bounds.intersect(clip_rrect_bounds)) { |
30 | set_paint_bounds(child_paint_bounds); |
31 | } |
32 | context->mutators_stack.Pop(); |
33 | } |
34 | context->cull_rect = previous_cull_rect; |
35 | } |
36 | |
37 | #if defined(LEGACY_FUCHSIA_EMBEDDER) |
38 | |
39 | void ClipRRectLayer::UpdateScene(SceneUpdateContext& context) { |
40 | TRACE_EVENT0("flutter" , "ClipRRectLayer::UpdateScene" ); |
41 | FML_DCHECK(needs_system_composite()); |
42 | |
43 | // TODO(liyuqian): respect clip_behavior_ |
44 | SceneUpdateContext::Clip clip(context, clip_rrect_.getBounds()); |
45 | UpdateSceneChildren(context); |
46 | } |
47 | |
48 | #endif |
49 | |
50 | void ClipRRectLayer::Paint(PaintContext& context) const { |
51 | TRACE_EVENT0("flutter" , "ClipRRectLayer::Paint" ); |
52 | FML_DCHECK(needs_painting()); |
53 | |
54 | if (!children_inside_clip_) { |
55 | TRACE_EVENT_INSTANT0("flutter" , "children not inside clip rect, skipping" ); |
56 | return; |
57 | } |
58 | |
59 | SkAutoCanvasRestore save(context.internal_nodes_canvas, true); |
60 | context.internal_nodes_canvas->clipRRect(clip_rrect_, |
61 | clip_behavior_ != Clip::hardEdge); |
62 | |
63 | if (UsesSaveLayer()) { |
64 | context.internal_nodes_canvas->saveLayer(paint_bounds(), nullptr); |
65 | } |
66 | PaintChildren(context); |
67 | if (UsesSaveLayer()) { |
68 | context.internal_nodes_canvas->restore(); |
69 | } |
70 | } |
71 | |
72 | } // namespace flutter |
73 | |