Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
dl_matrix_clip_tracker.h
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#ifndef FLUTTER_DISPLAY_LIST_UTILS_DL_MATRIX_CLIP_TRACKER_H_
6#define FLUTTER_DISPLAY_LIST_UTILS_DL_MATRIX_CLIP_TRACKER_H_
7
8#include <vector>
9
10#include "flutter/display_list/dl_canvas.h"
11#include "flutter/fml/logging.h"
12#include "flutter/impeller/geometry/matrix.h"
13#include "flutter/impeller/geometry/rect.h"
14
21
22namespace flutter {
23
25 private:
27 using DlRect = impeller::Rect;
30
31 static_assert(sizeof(SkRect) == sizeof(DlRect));
32
33 static const DlRect& ToDlRect(const SkRect& rect) {
34 return *reinterpret_cast<const DlRect*>(&rect);
35 }
36
37 static constexpr DlMatrix ToDlMatrix(const SkMatrix& matrix) {
38 // clang-format off
42 0.0f, 0.0f, 1.0f, 0.0f,
44 );
45 // clang-format on
46 }
47
48 static constexpr DlMatrix ToDlMatrix(const SkM44& matrix) {
49 DlMatrix dl_matrix;
50 matrix.getColMajor(dl_matrix.m);
51 return dl_matrix;
52 }
53
54 static const SkRect& ToSkRect(const DlRect& rect) {
55 return *reinterpret_cast<const SkRect*>(&rect);
56 }
57
58 static constexpr SkMatrix ToSkMatrix(const DlMatrix& matrix) {
59 return SkMatrix::MakeAll(matrix.m[0], matrix.m[4], matrix.m[12],
60 matrix.m[1], matrix.m[5], matrix.m[13],
61 matrix.m[3], matrix.m[7], matrix.m[15]);
62 }
63
64 static constexpr SkM44 ToSkM44(const DlMatrix& matrix) {
65 return SkM44::ColMajor(matrix.m);
66 }
67
68 public:
69 DisplayListMatrixClipState(const DlRect& cull_rect, const DlMatrix& matrix);
70 DisplayListMatrixClipState(const SkRect& cull_rect, const SkMatrix& matrix);
71 DisplayListMatrixClipState(const SkRect& cull_rect, const SkM44& matrix);
73
74 // This method should almost never be used as it breaks the encapsulation
75 // of the enclosing clips. However it is needed for practical purposes in
76 // some rare cases - such as when a saveLayer is collecting rendering
77 // operations prior to applying a filter on the entire layer bounds and
78 // some of those operations fall outside the enclosing clip, but their
79 // filtered content will spread out from where they were rendered on the
80 // layer into the enclosing clipped area.
81 // Omitting the |cull_rect| argument, or passing nullptr, will restore the
82 // cull rect to the initial value it had when the tracker was constructed.
83 void resetDeviceCullRect(const DlRect& cull_rect);
84 void resetDeviceCullRect(const SkRect& cull_rect) {
85 resetDeviceCullRect(ToDlRect(cull_rect));
86 }
87 void resetLocalCullRect(const DlRect& cull_rect);
88 void resetLocalCullRect(const SkRect& cull_rect) {
89 resetLocalCullRect(ToDlRect(cull_rect));
90 }
91
92 bool using_4x4_matrix() const { return !matrix_.IsAffine(); }
93 bool is_matrix_invertable() const { return matrix_.GetDeterminant() != 0.0f; }
94 bool has_perspective() const { return matrix_.HasPerspective(); }
95
96 const DlMatrix& matrix() const { return matrix_; }
97 SkM44 matrix_4x4() const { return SkM44::ColMajor(matrix_.m); }
98 SkMatrix matrix_3x3() const { return ToSkMatrix(matrix_); }
99
100 SkRect local_cull_rect() const;
101 SkRect device_cull_rect() const { return ToSkRect(cull_rect_); }
102
103 bool content_culled(const DlRect& content_bounds) const;
104 bool content_culled(const SkRect& content_bounds) const {
105 return content_culled(ToDlRect(content_bounds));
106 }
107 bool is_cull_rect_empty() const { return cull_rect_.IsEmpty(); }
108
110 matrix_ = matrix_.Translate({tx, ty});
111 }
112 void scale(SkScalar sx, SkScalar sy) {
113 matrix_ = matrix_.Scale({sx, sy, 1.0f});
114 }
115 void skew(SkScalar skx, SkScalar sky) {
116 matrix_ = matrix_ * DlMatrix::MakeSkew(skx, sky);
117 }
118 void rotate(SkScalar degrees) {
119 matrix_ = matrix_ * DlMatrix::MakeRotationZ(DlDegrees(degrees));
120 }
121 void transform(const DlMatrix& matrix) { matrix_ = matrix_ * matrix; }
122 void transform(const SkM44& m44) { transform(ToDlMatrix(m44)); }
123 void transform(const SkMatrix& matrix) { transform(ToDlMatrix(matrix)); }
124 // clang-format off
126 SkScalar mxx, SkScalar mxy, SkScalar mxt,
127 SkScalar myx, SkScalar myy, SkScalar myt) {
128 matrix_ = matrix_ * DlMatrix::MakeColumn(
129 mxx, myx, 0.0f, 0.0f,
130 mxy, myy, 0.0f, 0.0f,
131 0.0f, 0.0f, 1.0f, 0.0f,
132 mxt, myt, 0.0f, 1.0f
133 );
134 }
136 SkScalar mxx, SkScalar mxy, SkScalar mxz, SkScalar mxt,
137 SkScalar myx, SkScalar myy, SkScalar myz, SkScalar myt,
138 SkScalar mzx, SkScalar mzy, SkScalar mzz, SkScalar mzt,
139 SkScalar mwx, SkScalar mwy, SkScalar mwz, SkScalar mwt) {
140 matrix_ = matrix_ * DlMatrix::MakeColumn(
141 mxx, myx, mzx, mwx,
142 mxy, myy, mzy, mwy,
143 mxz, myz, mzz, mwz,
144 mxt, myt, mzt, mwt
145 );
146 }
147 // clang-format on
148 void setTransform(const DlMatrix& matrix) { matrix_ = matrix; }
149 void setTransform(const SkMatrix& matrix) { matrix_ = ToDlMatrix(matrix); }
150 void setTransform(const SkM44& m44) { matrix_ = ToDlMatrix(m44); }
151 void setIdentity() { matrix_ = DlMatrix(); }
152 // If the matrix in |other_tracker| is invertible then transform this
153 // tracker by the inverse of its matrix and return true. Otherwise,
154 // return false and leave this tracker unmodified.
155 bool inverseTransform(const DisplayListMatrixClipState& other_tracker);
156
157 bool mapRect(DlRect* rect) const { return mapRect(*rect, rect); }
158 bool mapRect(const DlRect& src, DlRect* mapped) const {
159 *mapped = src.TransformAndClipBounds(matrix_);
160 return matrix_.IsAligned2D();
161 }
162 bool mapRect(SkRect* rect) const { return mapRect(*rect, rect); }
163 bool mapRect(const SkRect& src, SkRect* mapped) const {
164 *mapped = ToSkRect(ToDlRect(src).TransformAndClipBounds(matrix_));
165 return matrix_.IsAligned2D();
166 }
167
168 void clipRect(const DlRect& rect, ClipOp op, bool is_aa);
169 void clipRect(const SkRect& rect, ClipOp op, bool is_aa) {
170 clipRect(ToDlRect(rect), op, is_aa);
171 }
172 void clipRRect(const SkRRect& rrect, ClipOp op, bool is_aa);
173 void clipPath(const SkPath& path, ClipOp op, bool is_aa);
174
175 private:
176 DlRect cull_rect_;
177 DlMatrix matrix_;
178
179 void adjustCullRect(const DlRect& clip, ClipOp op, bool is_aa);
180
182};
183
185 private:
186 using ClipOp = DlCanvas::ClipOp;
187 using DlRect = impeller::Rect;
189
190 public:
191 DisplayListMatrixClipTracker(const DlRect& cull_rect, const DlMatrix& matrix);
192 DisplayListMatrixClipTracker(const SkRect& cull_rect, const SkMatrix& matrix);
193 DisplayListMatrixClipTracker(const SkRect& cull_rect, const SkM44& matrix);
194
195 // These methods should almost never be used as they breaks the encapsulation
196 // of the enclosing clips. However they are needed for practical purposes in
197 // some rare cases - such as when a saveLayer is collecting rendering
198 // operations prior to applying a filter on the entire layer bounds and
199 // some of those operations fall outside the enclosing clip, but their
200 // filtered content will spread out from where they were rendered on the
201 // layer into the enclosing clipped area.
202 // Omitting the |cull_rect| argument, or passing nullptr, will restore the
203 // cull rect to the initial value it had when the tracker was constructed.
204 void resetDeviceCullRect(const DlRect* cull_rect = nullptr) {
205 if (cull_rect) {
206 current_->resetDeviceCullRect(*cull_rect);
207 } else {
208 current_->resetDeviceCullRect(saved_[0].cull_rect_);
209 }
210 }
211 void resetDeviceCullRect(const SkRect* cull_rect = nullptr) {
212 if (cull_rect) {
213 current_->resetDeviceCullRect(*cull_rect);
214 } else {
215 current_->resetDeviceCullRect(saved_[0].cull_rect_);
216 }
217 }
218 void resetLocalCullRect(const DlRect* cull_rect = nullptr) {
219 if (cull_rect) {
220 current_->resetLocalCullRect(*cull_rect);
221 } else {
222 current_->resetDeviceCullRect(saved_[0].cull_rect_);
223 }
224 }
225 void resetLocalCullRect(const SkRect* cull_rect = nullptr) {
226 if (cull_rect) {
227 current_->resetLocalCullRect(*cull_rect);
228 } else {
229 current_->resetDeviceCullRect(saved_[0].cull_rect_);
230 }
231 }
232
233 static bool is_3x3(const SkM44& m44);
234
235 SkRect base_device_cull_rect() const { return saved_[0].device_cull_rect(); }
236
237 bool using_4x4_matrix() const { return current_->using_4x4_matrix(); }
238
239 DlMatrix matrix() const { return current_->matrix(); }
240 SkM44 matrix_4x4() const { return current_->matrix_4x4(); }
241 SkMatrix matrix_3x3() const { return current_->matrix_3x3(); }
242 SkRect local_cull_rect() const { return current_->local_cull_rect(); }
243 SkRect device_cull_rect() const { return current_->device_cull_rect(); }
244 bool content_culled(const SkRect& content_bounds) const {
245 return current_->content_culled(content_bounds);
246 }
247 bool is_cull_rect_empty() const { return current_->is_cull_rect_empty(); }
248
249 void save();
250 void restore();
251 void reset();
253 // saved_[0] is always the untouched initial conditions
254 // saved_[1] is the first editable stack entry
255 return saved_.size() - 1;
256 }
257 void restoreToCount(int restore_count);
258
259 void translate(SkScalar tx, SkScalar ty) { current_->translate(tx, ty); }
260 void scale(SkScalar sx, SkScalar sy) { current_->scale(sx, sy); }
261 void skew(SkScalar skx, SkScalar sky) { current_->skew(skx, sky); }
262 void rotate(SkScalar degrees) { current_->rotate(degrees); }
263 void transform(const DlMatrix& matrix) { current_->transform(matrix); }
264 void transform(const SkM44& m44) { current_->transform(m44); }
265 void transform(const SkMatrix& matrix) { current_->transform(matrix); }
266 // clang-format off
268 SkScalar mxx, SkScalar mxy, SkScalar mxt,
269 SkScalar myx, SkScalar myy, SkScalar myt) {
270 current_->transform2DAffine(mxx, mxy, mxt, myx, myy, myt);
271 }
273 SkScalar mxx, SkScalar mxy, SkScalar mxz, SkScalar mxt,
274 SkScalar myx, SkScalar myy, SkScalar myz, SkScalar myt,
275 SkScalar mzx, SkScalar mzy, SkScalar mzz, SkScalar mzt,
276 SkScalar mwx, SkScalar mwy, SkScalar mwz, SkScalar mwt) {
277 current_->transformFullPerspective(
278 mxx, mxy, mxz, mxt,
279 myx, myy, myz, myt,
280 mzx, mzy, mzz, mzt,
281 mwx, mwy, mwz, mwt
282 );
283 }
284 // clang-format on
285 void setTransform(const DlMatrix& matrix) { current_->setTransform(matrix); }
286 void setTransform(const SkMatrix& matrix) { current_->setTransform(matrix); }
287 void setTransform(const SkM44& m44) { current_->setTransform(m44); }
288 void setIdentity() { current_->setIdentity(); }
289 // If the matrix in |other_tracker| is invertible then transform this
290 // tracker by the inverse of its matrix and return true. Otherwise,
291 // return false and leave this tracker unmodified.
293 return current_->inverseTransform(*other_tracker.current_);
294 }
295
296 bool mapRect(DlRect* rect) const { return current_->mapRect(*rect, rect); }
297 bool mapRect(const DlRect& src, DlRect* mapped) {
298 return current_->mapRect(src, mapped);
299 }
300 bool mapRect(SkRect* rect) const { return current_->mapRect(*rect, rect); }
301 bool mapRect(const SkRect& src, SkRect* mapped) {
302 return current_->mapRect(src, mapped);
303 }
304
305 void clipRect(const DlRect& rect, ClipOp op, bool is_aa) {
306 current_->clipRect(rect, op, is_aa);
307 }
308 void clipRect(const SkRect& rect, ClipOp op, bool is_aa) {
309 current_->clipRect(rect, op, is_aa);
310 }
311 void clipRRect(const SkRRect& rrect, ClipOp op, bool is_aa) {
312 current_->clipRRect(rrect, op, is_aa);
313 }
314 void clipPath(const SkPath& path, ClipOp op, bool is_aa) {
315 current_->clipPath(path, op, is_aa);
316 }
317
318 private:
320 std::vector<DisplayListMatrixClipState> saved_;
321};
322
323} // namespace flutter
324
325#endif // FLUTTER_DISPLAY_LIST_UTILS_DL_MATRIX_CLIP_TRACKER_H_
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
Definition SkPath.cpp:3824
Definition SkM44.h:150
static SkM44 ColMajor(const SkScalar c[16])
Definition SkM44.h:218
static constexpr int kMScaleX
horizontal scale factor
Definition SkMatrix.h:353
static constexpr int kMTransY
vertical translation
Definition SkMatrix.h:358
static constexpr int kMPersp1
input y perspective factor
Definition SkMatrix.h:360
static SkMatrix MakeAll(SkScalar scaleX, SkScalar skewX, SkScalar transX, SkScalar skewY, SkScalar scaleY, SkScalar transY, SkScalar pers0, SkScalar pers1, SkScalar pers2)
Definition SkMatrix.h:179
static constexpr int kMPersp0
input x perspective factor
Definition SkMatrix.h:359
static constexpr int kMPersp2
perspective bias
Definition SkMatrix.h:361
static constexpr int kMTransX
horizontal translation
Definition SkMatrix.h:355
static constexpr int kMSkewY
vertical skew factor
Definition SkMatrix.h:356
static constexpr int kMScaleY
vertical scale factor
Definition SkMatrix.h:357
static constexpr int kMSkewX
horizontal skew factor
Definition SkMatrix.h:354
bool inverseTransform(const DisplayListMatrixClipState &other_tracker)
void resetLocalCullRect(const SkRect &cull_rect)
bool mapRect(const DlRect &src, DlRect *mapped) const
void scale(SkScalar sx, SkScalar sy)
void clipRRect(const SkRRect &rrect, ClipOp op, bool is_aa)
void clipRect(const DlRect &rect, ClipOp op, bool is_aa)
DisplayListMatrixClipState(const DisplayListMatrixClipState &other)=default
bool content_culled(const SkRect &content_bounds) const
void transform2DAffine(SkScalar mxx, SkScalar mxy, SkScalar mxt, SkScalar myx, SkScalar myy, SkScalar myt)
bool mapRect(const SkRect &src, SkRect *mapped) const
void setTransform(const DlMatrix &matrix)
void clipPath(const SkPath &path, ClipOp op, bool is_aa)
void resetLocalCullRect(const DlRect &cull_rect)
void transformFullPerspective(SkScalar mxx, SkScalar mxy, SkScalar mxz, SkScalar mxt, SkScalar myx, SkScalar myy, SkScalar myz, SkScalar myt, SkScalar mzx, SkScalar mzy, SkScalar mzz, SkScalar mzt, SkScalar mwx, SkScalar mwy, SkScalar mwz, SkScalar mwt)
void clipRect(const SkRect &rect, ClipOp op, bool is_aa)
void skew(SkScalar skx, SkScalar sky)
bool content_culled(const DlRect &content_bounds) const
void resetDeviceCullRect(const DlRect &cull_rect)
void setTransform(const SkMatrix &matrix)
void resetDeviceCullRect(const SkRect &cull_rect)
void translate(SkScalar tx, SkScalar ty)
void clipRect(const DlRect &rect, ClipOp op, bool is_aa)
bool inverseTransform(const DisplayListMatrixClipTracker &other_tracker)
void clipPath(const SkPath &path, ClipOp op, bool is_aa)
void resetLocalCullRect(const SkRect *cull_rect=nullptr)
void resetDeviceCullRect(const DlRect *cull_rect=nullptr)
void transform2DAffine(SkScalar mxx, SkScalar mxy, SkScalar mxt, SkScalar myx, SkScalar myy, SkScalar myt)
void clipRect(const SkRect &rect, ClipOp op, bool is_aa)
void resetLocalCullRect(const DlRect *cull_rect=nullptr)
void translate(SkScalar tx, SkScalar ty)
void clipRRect(const SkRRect &rrect, ClipOp op, bool is_aa)
void transformFullPerspective(SkScalar mxx, SkScalar mxy, SkScalar mxz, SkScalar mxt, SkScalar myx, SkScalar myy, SkScalar myz, SkScalar myt, SkScalar mzx, SkScalar mzy, SkScalar mzz, SkScalar mzt, SkScalar mwx, SkScalar mwy, SkScalar mwz, SkScalar mwt)
void resetDeviceCullRect(const SkRect *cull_rect=nullptr)
bool mapRect(const DlRect &src, DlRect *mapped)
void skew(SkScalar skx, SkScalar sky)
bool content_culled(const SkRect &content_bounds) const
bool mapRect(const SkRect &src, SkRect *mapped)
float SkScalar
Definition extension.cpp:12
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition switches.h:57
TRect< Scalar > Rect
Definition rect.h:746
A 4x4 matrix using column-major storage.
Definition matrix.h:37
constexpr bool IsAffine() const
Definition matrix.h:321
Scalar m[16]
Definition matrix.h:39
constexpr Matrix Translate(const Vector3 &t) const
Definition matrix.h:240
static constexpr Matrix MakeColumn(Scalar m0, Scalar m1, Scalar m2, Scalar m3, Scalar m4, Scalar m5, Scalar m6, Scalar m7, Scalar m8, Scalar m9, Scalar m10, Scalar m11, Scalar m12, Scalar m13, Scalar m14, Scalar m15)
Definition matrix.h:69
static constexpr Matrix MakeSkew(Scalar sx, Scalar sy)
Definition matrix.h:117
constexpr Matrix Scale(const Vector3 &s) const
Definition matrix.h:252
static Matrix MakeRotationZ(Radians r)
Definition matrix.h:213
Scalar GetDeterminant() const
Definition matrix.cc:162
constexpr bool HasPerspective() const
Definition matrix.h:330
constexpr bool IsAligned2D(Scalar tolerance=0) const
Definition matrix.h:334
constexpr bool IsEmpty() const
Returns true if either of the width or height are 0, negative, or NaN.
Definition rect.h:264