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 | |
20 | namespace flutter { |
21 | |
22 | class 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 | |