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 3d06aa4a12b98233ed420ff14677606e16c3c93e..1796511a48444ef2237c6246d070c4bb4212b56e 100644 |
| --- a/cc/layer_tree_host_common.cc |
| +++ b/cc/layer_tree_host_common.cc |
| @@ -540,6 +540,30 @@ static void preCalculateMetaInformation(LayerType* layer) |
| layer->drawProperties().descendants_can_clip_selves = descendantsCanClipSelves; |
| } |
| +// Small calculation errors may result near-integer scales like 1.00001. |
| +// Round them to simplify the transform and avoid blurriness. |
| +static void roundNearIntegerScales(gfx::Transform* transform) |
| +{ |
| + const double kErrorThreshold = 0.0001; |
| + if (transform->IsScaleOrTranslation() && !transform->IsIdentityOrTranslation()) { |
| + double scaleX = transform->matrix().getDouble(0, 0); |
| + double roundedScaleX = round(scaleX); |
| + if (std::abs(scaleX - roundedScaleX) < kErrorThreshold) |
|
Sami
2013/03/05 11:28:34
I'm wondering if it'd be better to only do this fo
Xianzhu
2013/03/05 17:26:08
I'm not sure. Considering the case of (scalex, sca
|
| + transform->matrix().setDouble(0, 0, roundedScaleX); |
| + |
| + double scaleY = transform->matrix().getDouble(1, 1); |
| + double roundedScaleY = round(scaleY); |
| + if (std::abs(scaleY - roundedScaleY) < kErrorThreshold) |
| + transform->matrix().setDouble(1, 1, roundedScaleY); |
| + } |
| +} |
| + |
| +static void roundTranslates(gfx::Transform* transform) |
| +{ |
| + transform->matrix().setDouble(0, 3, round(transform->matrix().getDouble(0, 3))); |
| + transform->matrix().setDouble(1, 3, round(transform->matrix().getDouble(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> |
| @@ -707,12 +731,27 @@ 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()); |
| + roundNearIntegerScales(&layerDrawProperties.target_space_transform); |
|
shawnsingh
2013/03/05 05:29:45
(1) It might be a problem that this value is used
Sami
2013/03/05 11:28:34
One problem I can think of is that rounding can mo
Xianzhu
2013/03/05 17:26:08
roundNearIntegerScales() sets back the expected va
Xianzhu
2013/03/05 17:26:08
Will try to round position to screen space pixel,
Xianzhu
2013/03/05 23:03:14
Sorry, I didn't get your point when posting the re
|
| // layerScreenSpaceTransform represents the transform between root layer's "screen space" and local content space. |
| layerDrawProperties.screen_space_transform = fullHierarchyMatrix; |
| if (!layer->preserves3D()) |
| layerDrawProperties.screen_space_transform.FlattenTo2d(); |
| layerDrawProperties.screen_space_transform.PreconcatTransform(layerDrawProperties.target_space_transform); |
| + roundNearIntegerScales(&layerDrawProperties.screen_space_transform); |
| + |
| + // Round the translation in simple transforms if translation is merely caused by the scroll offset, |
| + // so that the pixels of the layer and the target space can be aligned. |
| + LayerType* scrollLayer = LayerTreeHostCommon::findScrollLayerForContentLayer(layer); |
| + if (scrollLayer) { |
|
Sami
2013/03/05 11:28:34
Would it be simpler to do this for all scrollable
Xianzhu
2013/03/05 17:26:08
If the scrollable layer is the content layer itsel
Xianzhu
2013/03/05 23:03:14
I was wrong about this. Actually position() is non
Xianzhu
2013/03/05 23:03:14
Done. Slightly different: now rounds the translati
|
| + gfx::Vector2dF scrollPosition = scrollLayer->scrollOffset() + scrollLayer->scrollDelta(); |
| + if (position.x() == -scrollPosition.x() && position.y() == -scrollPosition.y()) { |
| + if (layerDrawProperties.target_space_transform.IsIdentityOrTranslation()) |
| + roundTranslates(&layerDrawProperties.target_space_transform); |
| + if (layerDrawProperties.screen_space_transform.IsIdentityOrTranslation()) |
| + roundTranslates(&layerDrawProperties.screen_space_transform); |
| + } |
| + } |
| // Adjusting text AA method during animation may cause repaints, which in-turn causes jank. |
| bool adjustTextAA = !animatingOpacityToScreen && !animatingTransformToScreen; |