Flutter Engine
transform_layer.cc
Go to the documentation of this file.
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/transform_layer.h"
6 
7 #include <optional>
8 
9 namespace flutter {
10 
12  : transform_(transform) {
13  // Checks (in some degree) that SkMatrix transform_ is valid and initialized.
14  //
15  // If transform_ is uninitialized, this assert may look flaky as it doesn't
16  // fail all the time, and some rerun may make it pass. But don't ignore it and
17  // just rerun the test if this is triggered, since even a flaky failure here
18  // may signify a potentially big problem in the code.
19  //
20  // We have to write this flaky test because there is no reliable way to test
21  // whether a variable is initialized or not in C++.
22  FML_DCHECK(transform_.isFinite());
23  if (!transform_.isFinite()) {
24  FML_LOG(ERROR) << "TransformLayer is constructed with an invalid matrix.";
25  transform_.setIdentity();
26  }
27 }
28 
29 void TransformLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
30  TRACE_EVENT0("flutter", "TransformLayer::Preroll");
31 
32  SkMatrix child_matrix;
33  child_matrix.setConcat(matrix, transform_);
34  context->mutators_stack.PushTransform(transform_);
35  SkRect previous_cull_rect = context->cull_rect;
36  SkMatrix inverse_transform_;
37  // Perspective projections don't produce rectangles that are useful for
38  // culling for some reason.
39  if (!transform_.hasPerspective() && transform_.invert(&inverse_transform_)) {
40  inverse_transform_.mapRect(&context->cull_rect);
41  } else {
42  context->cull_rect = kGiantRect;
43  }
44 
45  SkRect child_paint_bounds = SkRect::MakeEmpty();
46  PrerollChildren(context, child_matrix, &child_paint_bounds);
47 
48  transform_.mapRect(&child_paint_bounds);
49  set_paint_bounds(child_paint_bounds);
50 
51  context->cull_rect = previous_cull_rect;
52  context->mutators_stack.Pop();
53 }
54 
55 #if defined(LEGACY_FUCHSIA_EMBEDDER)
56 
57 void TransformLayer::UpdateScene(std::shared_ptr<SceneUpdateContext> context) {
58  TRACE_EVENT0("flutter", "TransformLayer::UpdateScene");
60 
61  std::optional<SceneUpdateContext::Transform> transform;
62  if (!transform_.isIdentity()) {
63  transform.emplace(context, transform_);
64  }
65 
66  UpdateSceneChildren(context);
67 }
68 
69 #endif
70 
71 void TransformLayer::Paint(PaintContext& context) const {
72  TRACE_EVENT0("flutter", "TransformLayer::Paint");
74 
75  SkAutoCanvasRestore save(context.internal_nodes_canvas, true);
76  context.internal_nodes_canvas->concat(transform_);
77 
78  PaintChildren(context);
79 }
80 
81 } // namespace flutter
void Paint(PaintContext &context) const override
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:75
#define FML_DCHECK(condition)
Definition: logging.h:86
TransformLayer(const SkMatrix &transform)
void PushTransform(const SkMatrix &matrix)
void Preroll(PrerollContext *context, const SkMatrix &matrix) override
#define FML_LOG(severity)
Definition: logging.h:65
void PrerollChildren(PrerollContext *context, const SkMatrix &child_matrix, SkRect *child_paint_bounds)
static constexpr SkRect kGiantRect
Definition: layer.h:38
bool needs_system_composite() const
Definition: layer.h:161
bool needs_painting() const
Definition: layer.h:174
void set_paint_bounds(const SkRect &paint_bounds)
Definition: layer.h:170
SkCanvas * internal_nodes_canvas
Definition: layer.h:115
MutatorsStack & mutators_stack
Definition: layer.h:47
void PaintChildren(PaintContext &context) const