Chromium Code Reviews| Index: cc/layer_tree_host_common.cc |
| diff --git a/cc/layer_tree_host_common.cc b/cc/layer_tree_host_common.cc |
| index c28db4087d3f31f8d5c671f1042c957d8e43b441..f7eee5b7ed30fa196558f00a12e8b5d81964dec1 100644 |
| --- a/cc/layer_tree_host_common.cc |
| +++ b/cc/layer_tree_host_common.cc |
| @@ -546,6 +546,30 @@ static void roundTranslationComponents(gfx::Transform* transform) |
| transform->matrix().setDouble(1, 3, MathUtil::Round(transform->matrix().getDouble(1, 3))); |
| } |
| +static void roundAlmostIntegerComponent(SkMatrix44* matrix, int i, int j) |
| +{ |
| + const double kErrorThreshold = 0.0001; |
| + double d = matrix->getDouble(i, j); |
| + double rounded = MathUtil::Round(d); |
| + double error = std::abs(rounded - d); |
| + if (error > 0 && error < kErrorThreshold) |
| + matrix->setDouble(i, j, rounded); |
| +} |
| + |
| +// Tiny errors caused by multiple multiplications and divisions on mixed double |
| +// and float operands may result almost-integer scales and translations like |
| +// 1.00001. Round them so that some transform can be identity as expected. |
| +static void roundAlmostIntegerScalesAndTranslationComponents(gfx::Transform* transform) |
| +{ |
| + if (transform->IsScaleOrTranslation() && !transform->IsIdentityOrTranslation()) { |
|
Ian Vollick
2013/03/07 21:18:36
Unless I'm reading this wrong, it looks like we'll
|
| + SkMatrix44* matrix = &transform->matrix(); |
| + roundAlmostIntegerComponent(matrix, 0, 0); |
| + roundAlmostIntegerComponent(matrix, 1, 1); |
| + roundAlmostIntegerComponent(matrix, 0, 3); |
| + roundAlmostIntegerComponent(matrix, 1, 3); |
| + } |
| +} |
| + |
| // Recursively walks the layer tree starting at the given node and computes all the |
| // necessary transformations, clipRects, render surfaces, etc. |
| template<typename LayerType, typename LayerList, typename RenderSurfaceType> |
| @@ -719,6 +743,9 @@ static void calculateDrawPropertiesInternal(LayerType* layer, const gfx::Transfo |
| layerDrawProperties.target_space_transform = combinedTransform; |
| // M[draw] = M[parent] * LT * S[layer2content] |
| layerDrawProperties.target_space_transform.Scale(1.0 / layer->contentsScaleX(), 1.0 / layer->contentsScaleY()); |
| + // Eliminate the tiny errors in scales and translations to prevent the errors from propagating, |
| + // to prevent bluriness and ensures LCDText working as expected. |
| + roundAlmostIntegerScalesAndTranslationComponents(&layerDrawProperties.target_space_transform); |
|
enne (OOO)
2013/03/07 19:05:34
Is it ok to round the draw transform but not the s
Xianzhu
2013/03/07 19:38:17
I think the rounding will reflect in screen_space_
shawnsingh
2013/03/07 20:13:36
I agree with Xianzhu, it should be OK with respect
Ian Vollick
2013/03/07 21:18:36
I'd considered tackling this sort of rounding, too
|
| // layerScreenSpaceTransform represents the transform between root layer's "screen space" and local content space. |
| layerDrawProperties.screen_space_transform = fullHierarchyMatrix; |
| @@ -764,6 +791,9 @@ static void calculateDrawPropertiesInternal(LayerType* layer, const gfx::Transfo |
| // only needs to scale the layer to surface space. |
| layerDrawProperties.target_space_transform.MakeIdentity(); |
| layerDrawProperties.target_space_transform.Scale(renderSurfaceSublayerScale.x() / layer->contentsScaleX(), renderSurfaceSublayerScale.y() / layer->contentsScaleY()); |
| + // Eliminate the tiny errors in scales and translations to prevent the errors from propagating, |
| + // to prevent bluriness and to ensure LCDText working as expected. |
| + roundAlmostIntegerScalesAndTranslationComponents(&layerDrawProperties.target_space_transform); |
|
enne (OOO)
2013/03/07 19:05:34
I don't understand what this change does. The LCD
Xianzhu
2013/03/07 19:38:17
Based on the exisiting code, we enable LCD text on
enne (OOO)
2013/03/07 20:19:36
What you say is correct. However, we enable LCD t
|
| // Inside the surface's subtree, we scale everything to the owning layer's scale. |
| // The sublayer matrix transforms layer rects into target |