| // Copyright 2013 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "flutter/flow/raster_cache_util.h" |
| |
| namespace flutter { |
| |
| bool RasterCacheUtil::ComputeIntegralTransCTM(const SkMatrix& in, |
| SkMatrix* out) { |
| // Avoid integral snapping if the matrix has complex transformation to avoid |
| // the artifact observed in https://github.com/flutter/flutter/issues/41654. |
| if (!in.isScaleTranslate()) { |
| return false; |
| } |
| |
| SkScalar in_tx = in.getTranslateX(); |
| SkScalar in_ty = in.getTranslateY(); |
| SkScalar out_tx = SkScalarRoundToScalar(in_tx); |
| SkScalar out_ty = SkScalarRoundToScalar(in_ty); |
| if (out_tx != in_tx || out_ty != in_ty) { |
| // As a side effect of those tests we also know that neither translation |
| // component was a NaN |
| *out = in; |
| (*out)[SkMatrix::kMTransX] = out_tx; |
| (*out)[SkMatrix::kMTransY] = out_ty; |
| return true; |
| } |
| |
| return false; |
| } |
| |
| bool RasterCacheUtil::ComputeIntegralTransCTM(const SkM44& in, SkM44* out) { |
| // Avoid integral snapping if the matrix has complex transformation to avoid |
| // the artifact observed in https://github.com/flutter/flutter/issues/41654. |
| if (in.rc(0, 1) != 0 || in.rc(0, 2) != 0) { |
| // X multiplied by either Y or Z |
| return false; |
| } |
| if (in.rc(1, 0) != 0 || in.rc(1, 2) != 0) { |
| // Y multiplied by either X or Z |
| return false; |
| } |
| if (in.rc(3, 0) != 0 || in.rc(3, 1) != 0 || in.rc(3, 2) != 0 || |
| in.rc(3, 3) != 1) { |
| // W not identity row, therefore perspective is applied |
| return false; |
| } |
| // We do not need to worry about the Z row unless the W row |
| // has perspective entries, which we've just eliminated... |
| |
| SkScalar in_tx = in.rc(0, 3); |
| SkScalar in_ty = in.rc(1, 3); |
| SkScalar out_tx = SkScalarRoundToScalar(in_tx); |
| SkScalar out_ty = SkScalarRoundToScalar(in_ty); |
| if (out_tx != in_tx || out_ty != in_ty) { |
| // As a side effect of those tests we also know that neither translation |
| // component was a NaN |
| *out = in; |
| out->setRC(0, 3, out_tx); |
| out->setRC(1, 3, out_ty); |
| // No need to worry about Z translation because it has no effect |
| // without perspective entries... |
| return true; |
| } |
| |
| return false; |
| } |
| |
| } // namespace flutter |