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#ifndef FLUTTER_DISPLAY_LIST_DISPLAY_LIST_MATRIX_CLIP_TRACKER_H_
6#define FLUTTER_DISPLAY_LIST_DISPLAY_LIST_MATRIX_CLIP_TRACKER_H_
7
8#include <vector>
9
10#include "flutter/display_list/dl_canvas.h"
11#include "flutter/fml/logging.h"
12
13#include "third_party/skia/include/core/SkM44.h"
14#include "third_party/skia/include/core/SkMatrix.h"
15#include "third_party/skia/include/core/SkPath.h"
16#include "third_party/skia/include/core/SkRRect.h"
17#include "third_party/skia/include/core/SkRect.h"
18#include "third_party/skia/include/core/SkScalar.h"
19
20namespace flutter {
21
22class DisplayListMatrixClipTracker {
23 private:
24 using ClipOp = DlCanvas::ClipOp;
25
26 public:
27 DisplayListMatrixClipTracker(const SkRect& cull_rect, const SkMatrix& matrix);
28 DisplayListMatrixClipTracker(const SkRect& cull_rect, const SkM44& matrix);
29
30 // This method should almost never be used as it breaks the encapsulation
31 // of the enclosing clips. However it is needed for practical purposes in
32 // some rare cases - such as when a saveLayer is collecting rendering
33 // operations prior to applying a filter on the entire layer bounds and
34 // some of those operations fall outside the enclosing clip, but their
35 // filtered content will spread out from where they were rendered on the
36 // layer into the enclosing clipped area.
37 // Omitting the |cull_rect| argument, or passing nullptr, will restore the
38 // cull rect to the initial value it had when the tracker was constructed.
39 void resetCullRect(const SkRect* cull_rect = nullptr) {
40 current_->resetBounds(cull_rect: cull_rect ? *cull_rect : original_cull_rect_);
41 }
42
43 static bool is_3x3(const SkM44& m44);
44
45 SkRect base_device_cull_rect() const { return saved_[0]->device_cull_rect(); }
46
47 bool using_4x4_matrix() const { return current_->is_4x4(); }
48
49 SkM44 matrix_4x4() const { return current_->matrix_4x4(); }
50 SkMatrix matrix_3x3() const { return current_->matrix_3x3(); }
51 SkRect local_cull_rect() const { return current_->local_cull_rect(); }
52 SkRect device_cull_rect() const { return current_->device_cull_rect(); }
53 bool content_culled(const SkRect& content_bounds) const {
54 return current_->content_culled(content_bounds);
55 }
56 bool is_cull_rect_empty() const { return current_->is_cull_rect_empty(); }
57
58 void save();
59 void restore();
60 void reset();
61 int getSaveCount() {
62 // saved_[0] is always the untouched initial conditions
63 // saved_[1] is the first editable stack entry
64 return saved_.size() - 1;
65 }
66 void restoreToCount(int restore_count);
67
68 void translate(SkScalar tx, SkScalar ty) { current_->translate(tx, ty); }
69 void scale(SkScalar sx, SkScalar sy) { current_->scale(sx, sy); }
70 void skew(SkScalar skx, SkScalar sky) { current_->skew(skx, sky); }
71 void rotate(SkScalar degrees) { current_->rotate(degrees); }
72 void transform(const SkM44& m44);
73 void transform(const SkMatrix& matrix) { current_->transform(matrix); }
74 // clang-format off
75 void transform2DAffine(
76 SkScalar mxx, SkScalar mxy, SkScalar mxt,
77 SkScalar myx, SkScalar myy, SkScalar myt);
78 void transformFullPerspective(
79 SkScalar mxx, SkScalar mxy, SkScalar mxz, SkScalar mxt,
80 SkScalar myx, SkScalar myy, SkScalar myz, SkScalar myt,
81 SkScalar mzx, SkScalar mzy, SkScalar mzz, SkScalar mzt,
82 SkScalar mwx, SkScalar mwy, SkScalar mwz, SkScalar mwt);
83 // clang-format on
84 void setTransform(const SkMatrix& matrix) { current_->setTransform(matrix); }
85 void setTransform(const SkM44& m44);
86 void setIdentity() { current_->setIdentity(); }
87 bool mapRect(SkRect* rect) const { return current_->mapRect(rect: *rect, mapped: rect); }
88
89 void clipRect(const SkRect& rect, ClipOp op, bool is_aa) {
90 current_->clipBounds(clip: rect, op, is_aa);
91 }
92 void clipRRect(const SkRRect& rrect, ClipOp op, bool is_aa);
93 void clipPath(const SkPath& path, ClipOp op, bool is_aa);
94
95 private:
96 class Data {
97 public:
98 virtual ~Data() = default;
99
100 virtual bool is_4x4() const = 0;
101
102 virtual SkMatrix matrix_3x3() const = 0;
103 virtual SkM44 matrix_4x4() const = 0;
104
105 SkRect device_cull_rect() const { return cull_rect_; }
106 virtual SkRect local_cull_rect() const = 0;
107 virtual bool content_culled(const SkRect& content_bounds) const;
108 bool is_cull_rect_empty() const { return cull_rect_.isEmpty(); }
109
110 virtual void translate(SkScalar tx, SkScalar ty) = 0;
111 virtual void scale(SkScalar sx, SkScalar sy) = 0;
112 virtual void skew(SkScalar skx, SkScalar sky) = 0;
113 virtual void rotate(SkScalar degrees) = 0;
114 virtual void transform(const SkMatrix& matrix) = 0;
115 virtual void transform(const SkM44& m44) = 0;
116 virtual void setTransform(const SkMatrix& matrix) = 0;
117 virtual void setTransform(const SkM44& m44) = 0;
118 virtual void setIdentity() = 0;
119 virtual bool mapRect(const SkRect& rect, SkRect* mapped) const = 0;
120 virtual bool canBeInverted() const = 0;
121
122 virtual void clipBounds(const SkRect& clip, ClipOp op, bool is_aa);
123
124 virtual void resetBounds(const SkRect& cull_rect);
125
126 protected:
127 Data(const SkRect& rect) : cull_rect_(rect) {}
128
129 virtual bool has_perspective() const = 0;
130
131 SkRect cull_rect_;
132 };
133 friend class Data3x3;
134 friend class Data4x4;
135
136 SkRect original_cull_rect_;
137 Data* current_;
138 std::vector<std::unique_ptr<Data>> saved_;
139};
140
141} // namespace flutter
142
143#endif // FLUTTER_DISPLAY_LIST_DISPLAY_LIST_MATRIX_CLIP_TRACKER_H_
144

source code of flutter_engine/flutter/display_list/utils/dl_matrix_clip_tracker.h