Flutter Engine
 
Loading...
Searching...
No Matches
raster_cache_util.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
6
7namespace flutter {
8
10 SkMatrix* out) {
11 // Avoid integral snapping if the matrix has complex transformation to avoid
12 // the artifact observed in https://github.com/flutter/flutter/issues/41654.
13 if (!in.isScaleTranslate()) {
14 return false;
15 }
16
17 SkScalar in_tx = in.getTranslateX();
18 SkScalar in_ty = in.getTranslateY();
19 SkScalar out_tx = SkScalarRoundToScalar(in_tx);
20 SkScalar out_ty = SkScalarRoundToScalar(in_ty);
21 if (out_tx != in_tx || out_ty != in_ty) {
22 // As a side effect of those tests we also know that neither translation
23 // component was a NaN
24 *out = in;
25 (*out)[SkMatrix::kMTransX] = out_tx;
26 (*out)[SkMatrix::kMTransY] = out_ty;
27 return true;
28 }
29
30 return false;
31}
32
33bool RasterCacheUtil::ComputeIntegralTransCTM(const SkM44& in, SkM44* out) {
34 // Avoid integral snapping if the matrix has complex transformation to avoid
35 // the artifact observed in https://github.com/flutter/flutter/issues/41654.
36 if (in.rc(0, 1) != 0 || in.rc(0, 2) != 0) {
37 // X multiplied by either Y or Z
38 return false;
39 }
40 if (in.rc(1, 0) != 0 || in.rc(1, 2) != 0) {
41 // Y multiplied by either X or Z
42 return false;
43 }
44 if (in.rc(3, 0) != 0 || in.rc(3, 1) != 0 || in.rc(3, 2) != 0 ||
45 in.rc(3, 3) != 1) {
46 // W not identity row, therefore perspective is applied
47 return false;
48 }
49 // We do not need to worry about the Z row unless the W row
50 // has perspective entries, which we've just eliminated...
51
52 SkScalar in_tx = in.rc(0, 3);
53 SkScalar in_ty = in.rc(1, 3);
54 SkScalar out_tx = SkScalarRoundToScalar(in_tx);
55 SkScalar out_ty = SkScalarRoundToScalar(in_ty);
56 if (out_tx != in_tx || out_ty != in_ty) {
57 // As a side effect of those tests we also know that neither translation
58 // component was a NaN
59 *out = in;
60 out->setRC(0, 3, out_tx);
61 out->setRC(1, 3, out_ty);
62 // No need to worry about Z translation because it has no effect
63 // without perspective entries...
64 return true;
65 }
66
67 return false;
68}
69
71 DlMatrix* out) {
72 // Avoid integral snapping if the matrix has complex transformation to avoid
73 // the artifact observed in https://github.com/flutter/flutter/issues/41654.
74 if (!in.IsTranslationScaleOnly()) {
75 return false;
76 }
77
78 DlScalar in_tx = in.m[12];
79 DlScalar in_ty = in.m[13];
80 DlScalar out_tx = std::round(in_tx);
81 DlScalar out_ty = std::round(in_ty);
82 if (out_tx != in_tx || out_ty != in_ty) {
83 // As a side effect of those tests we also know that neither translation
84 // component was a NaN
85 *out = in;
86 out->m[12] = out_tx;
87 out->m[13] = out_ty;
88 // No need to worry about Z translation because it has no effect
89 // without perspective entries...
90 return true;
91 }
92
93 return false;
94}
95
96} // namespace flutter
impeller::Scalar DlScalar
static bool ComputeIntegralTransCTM(const SkMatrix &in, SkMatrix *out)
Snap the translation components of the |in| matrix to integers and store the snapped matrix in |out|.
A 4x4 matrix using column-major storage.
Definition matrix.h:37
constexpr bool IsTranslationScaleOnly() const
Returns true if the matrix has a scale-only basis and is non-projective. Note that an identity matrix...
Definition matrix.h:493
Scalar m[16]
Definition matrix.h:39