mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
During some new development work that might make transform resets more expensive we realized that the resets were mostly coming from the calls to snap the transform to a pixel translate value and many of those were NOPs since the transform was already on a pixel translate value. This PR will avoid those trivially unnecessary reset operations.
71 lines
2.3 KiB
C++
71 lines
2.3 KiB
C++
// 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
|