Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2012 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * | 7 * |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 99 WebLayer* LinkHighlight::clipLayer() | 99 WebLayer* LinkHighlight::clipLayer() |
| 100 { | 100 { |
| 101 return m_clipLayer.get(); | 101 return m_clipLayer.get(); |
| 102 } | 102 } |
| 103 | 103 |
| 104 void LinkHighlight::releaseResources() | 104 void LinkHighlight::releaseResources() |
| 105 { | 105 { |
| 106 m_node.clear(); | 106 m_node.clear(); |
| 107 } | 107 } |
| 108 | 108 |
| 109 RenderLayer* LinkHighlight::computeEnclosingCompositingLayer() | 109 void LinkHighlight::attachLinkHighlightToCompositingLayer(const RenderLayerModel Object* paintInvalidationContainer) |
| 110 { | 110 { |
| 111 if (!m_node || !m_node->renderer()) | 111 GraphicsLayer* newGraphicsLayer = paintInvalidationContainer->layer()->graph icsLayerBacking(); |
|
trchen
2014/10/29 23:57:30
I think we need to do a null check here. Multicol
chrishtr
2014/10/30 00:01:17
RenderObject::containerForPaintInvalidation should
trchen
2014/10/30 00:08:58
No I meant newGraphicsLayer may be null.
chrishtr
2014/10/30 00:21:59
Oh, yuck. Thanks for pointing that out. Fixed.
| |
| 112 return 0; | 112 if (!newGraphicsLayer->drawsContent()) |
| 113 | 113 newGraphicsLayer = paintInvalidationContainer->layer()->graphicsLayerBac kingForScrolling(); |
| 114 // Find the nearest enclosing composited layer and attach to it. We may need to cross frame boundaries | |
| 115 // to find a suitable layer. | |
| 116 RenderObject* renderer = m_node->renderer(); | |
| 117 RenderLayer* renderLayer; | |
| 118 do { | |
| 119 renderLayer = renderer->enclosingLayer()->enclosingLayerForPaintInvalida tion(); | |
| 120 if (!renderLayer) { | |
| 121 renderer = renderer->frame()->ownerRenderer(); | |
| 122 if (!renderer) | |
| 123 return 0; | |
| 124 } | |
| 125 } while (!renderLayer); | |
| 126 | |
| 127 ASSERT(renderLayer->compositingState() != NotComposited); | |
| 128 | |
| 129 GraphicsLayer* newGraphicsLayer = renderLayer->graphicsLayerBacking(); | |
| 130 if (!newGraphicsLayer->drawsContent()) { | |
| 131 newGraphicsLayer = renderLayer->graphicsLayerBackingForScrolling(); | |
| 132 } | |
| 133 | 114 |
| 134 m_clipLayer->setTransform(SkMatrix44(SkMatrix44::kIdentity_Constructor)); | 115 m_clipLayer->setTransform(SkMatrix44(SkMatrix44::kIdentity_Constructor)); |
| 135 | 116 |
| 136 if (m_currentGraphicsLayer != newGraphicsLayer) { | 117 if (m_currentGraphicsLayer != newGraphicsLayer) { |
| 137 if (m_currentGraphicsLayer) | 118 if (m_currentGraphicsLayer) |
| 138 clearGraphicsLayerLinkHighlightPointer(); | 119 clearGraphicsLayerLinkHighlightPointer(); |
| 139 | 120 |
| 140 m_currentGraphicsLayer = newGraphicsLayer; | 121 m_currentGraphicsLayer = newGraphicsLayer; |
| 141 m_currentGraphicsLayer->addLinkHighlight(this); | 122 m_currentGraphicsLayer->addLinkHighlight(this); |
| 142 } | 123 } |
| 143 | |
| 144 return renderLayer; | |
| 145 } | 124 } |
| 146 | 125 |
| 147 static void convertTargetSpaceQuadToCompositedLayer(const FloatQuad& targetSpace Quad, RenderObject* targetRenderer, RenderObject* compositedRenderer, FloatQuad& compositedSpaceQuad) | 126 static void convertTargetSpaceQuadToCompositedLayer(const FloatQuad& targetSpace Quad, RenderObject* targetRenderer, const RenderLayerModelObject* paintInvalidat ionContainer, FloatQuad& compositedSpaceQuad) |
| 148 { | 127 { |
| 149 ASSERT(targetRenderer); | 128 ASSERT(targetRenderer); |
| 150 ASSERT(compositedRenderer); | 129 ASSERT(paintInvalidationContainer); |
| 151 | |
| 152 for (unsigned i = 0; i < 4; ++i) { | 130 for (unsigned i = 0; i < 4; ++i) { |
| 153 IntPoint point; | 131 IntPoint point; |
| 154 switch (i) { | 132 switch (i) { |
| 155 case 0: point = roundedIntPoint(targetSpaceQuad.p1()); break; | 133 case 0: point = roundedIntPoint(targetSpaceQuad.p1()); break; |
| 156 case 1: point = roundedIntPoint(targetSpaceQuad.p2()); break; | 134 case 1: point = roundedIntPoint(targetSpaceQuad.p2()); break; |
| 157 case 2: point = roundedIntPoint(targetSpaceQuad.p3()); break; | 135 case 2: point = roundedIntPoint(targetSpaceQuad.p3()); break; |
| 158 case 3: point = roundedIntPoint(targetSpaceQuad.p4()); break; | 136 case 3: point = roundedIntPoint(targetSpaceQuad.p4()); break; |
| 159 } | 137 } |
| 160 | 138 |
| 139 // FIXME: this does not need to be absolute, just in the paint invalidat ion container's space. | |
| 161 point = targetRenderer->frame()->view()->contentsToWindow(point); | 140 point = targetRenderer->frame()->view()->contentsToWindow(point); |
| 162 point = compositedRenderer->frame()->view()->windowToContents(point); | 141 point = paintInvalidationContainer->frame()->view()->windowToContents(po int); |
| 163 FloatPoint floatPoint = compositedRenderer->absoluteToLocal(point, UseTr ansforms); | 142 FloatPoint floatPoint = paintInvalidationContainer->absoluteToLocal(poin t, UseTransforms); |
| 143 RenderLayer::mapPointToPaintBackingCoordinates(paintInvalidationContaine r, floatPoint); | |
| 164 | 144 |
| 165 switch (i) { | 145 switch (i) { |
| 166 case 0: compositedSpaceQuad.setP1(floatPoint); break; | 146 case 0: compositedSpaceQuad.setP1(floatPoint); break; |
| 167 case 1: compositedSpaceQuad.setP2(floatPoint); break; | 147 case 1: compositedSpaceQuad.setP2(floatPoint); break; |
| 168 case 2: compositedSpaceQuad.setP3(floatPoint); break; | 148 case 2: compositedSpaceQuad.setP3(floatPoint); break; |
| 169 case 3: compositedSpaceQuad.setP4(floatPoint); break; | 149 case 3: compositedSpaceQuad.setP4(floatPoint); break; |
| 170 } | 150 } |
| 171 } | 151 } |
| 172 } | 152 } |
| 173 | 153 |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 190 | 170 |
| 191 // For inline elements, absoluteQuads will return a line box based on the li ne-height | 171 // For inline elements, absoluteQuads will return a line box based on the li ne-height |
| 192 // and font metrics, which is technically incorrect as replaced elements lik e images | 172 // and font metrics, which is technically incorrect as replaced elements lik e images |
| 193 // should use their intristic height and expand the linebox as needed. To g et an | 173 // should use their intristic height and expand the linebox as needed. To g et an |
| 194 // appropriately sized highlight we descend into the children and have them add their | 174 // appropriately sized highlight we descend into the children and have them add their |
| 195 // boxes. | 175 // boxes. |
| 196 if (renderer->isRenderInline()) { | 176 if (renderer->isRenderInline()) { |
| 197 for (Node* child = NodeRenderingTraversal::firstChild(&node); child; chi ld = NodeRenderingTraversal::nextSibling(child)) | 177 for (Node* child = NodeRenderingTraversal::firstChild(&node); child; chi ld = NodeRenderingTraversal::nextSibling(child)) |
| 198 computeQuads(*child, outQuads); | 178 computeQuads(*child, outQuads); |
| 199 } else { | 179 } else { |
| 180 // FIXME: this does not need to be absolute, just in the paint invalidat ion container's space. | |
| 200 renderer->absoluteQuads(outQuads); | 181 renderer->absoluteQuads(outQuads); |
| 201 } | 182 } |
| 202 } | 183 } |
| 203 | 184 |
| 204 bool LinkHighlight::computeHighlightLayerPathAndPosition(RenderLayer* compositin gLayer) | 185 bool LinkHighlight::computeHighlightLayerPathAndPosition(const RenderLayerModelO bject* paintInvalidationContainer) |
| 205 { | 186 { |
| 206 if (!m_node || !m_node->renderer() || !m_currentGraphicsLayer) | 187 if (!m_node || !m_node->renderer() || !m_currentGraphicsLayer) |
| 207 return false; | 188 return false; |
| 208 | 189 ASSERT(paintInvalidationContainer); |
| 209 ASSERT(compositingLayer); | |
| 210 | 190 |
| 211 // Get quads for node in absolute coordinates. | 191 // Get quads for node in absolute coordinates. |
| 212 Vector<FloatQuad> quads; | 192 Vector<FloatQuad> quads; |
| 213 computeQuads(*m_node, quads); | 193 computeQuads(*m_node, quads); |
| 214 ASSERT(quads.size()); | 194 ASSERT(quads.size()); |
| 215 | |
| 216 // Adjust for offset between target graphics layer and the node's renderer. | |
| 217 FloatPoint positionAdjust = IntPoint(m_currentGraphicsLayer->offsetFromRende rer()); | |
| 218 | |
| 219 Path newPath; | 195 Path newPath; |
| 220 for (size_t quadIndex = 0; quadIndex < quads.size(); ++quadIndex) { | 196 for (size_t quadIndex = 0; quadIndex < quads.size(); ++quadIndex) { |
| 221 FloatQuad absoluteQuad = quads[quadIndex]; | 197 FloatQuad absoluteQuad = quads[quadIndex]; |
| 222 absoluteQuad.move(-positionAdjust.x(), -positionAdjust.y()); | |
| 223 | 198 |
| 224 // Transform node quads in target absolute coords to local coordinates i n the compositor layer. | 199 // Transform node quads in target absolute coords to local coordinates i n the compositor layer. |
| 225 FloatQuad transformedQuad; | 200 FloatQuad transformedQuad; |
| 226 convertTargetSpaceQuadToCompositedLayer(absoluteQuad, m_node->renderer() , compositingLayer->renderer(), transformedQuad); | 201 convertTargetSpaceQuadToCompositedLayer(absoluteQuad, m_node->renderer() , paintInvalidationContainer, transformedQuad); |
| 227 | 202 |
| 228 // FIXME: for now, we'll only use rounded paths if we have a single node quad. The reason for this is that | 203 // FIXME: for now, we'll only use rounded paths if we have a single node quad. The reason for this is that |
| 229 // we may sometimes get a chain of adjacent boxes (e.g. for text nodes) which end up looking like sausage | 204 // we may sometimes get a chain of adjacent boxes (e.g. for text nodes) which end up looking like sausage |
| 230 // links: these should ideally be merged into a single rect before creat ing the path, but that's | 205 // links: these should ideally be merged into a single rect before creat ing the path, but that's |
| 231 // another CL. | 206 // another CL. |
| 232 if (quads.size() == 1 && transformedQuad.isRectilinear() | 207 if (quads.size() == 1 && transformedQuad.isRectilinear() |
| 233 && !m_owningWebViewImpl->settingsImpl()->mockGestureTapHighlightsEna bled()) { | 208 && !m_owningWebViewImpl->settingsImpl()->mockGestureTapHighlightsEna bled()) { |
| 234 FloatSize rectRoundingRadii(3, 3); | 209 FloatSize rectRoundingRadii(3, 3); |
| 235 newPath.addRoundedRect(transformedQuad.boundingBox(), rectRoundingRa dii); | 210 newPath.addRoundedRect(transformedQuad.boundingBox(), rectRoundingRa dii); |
| 236 } else | 211 } else |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 324 releaseResources(); | 299 releaseResources(); |
| 325 } | 300 } |
| 326 | 301 |
| 327 void LinkHighlight::updateGeometry() | 302 void LinkHighlight::updateGeometry() |
| 328 { | 303 { |
| 329 // To avoid unnecessary updates (e.g. other entities have requested animatio ns from our WebViewImpl), | 304 // To avoid unnecessary updates (e.g. other entities have requested animatio ns from our WebViewImpl), |
| 330 // only proceed if we actually requested an update. | 305 // only proceed if we actually requested an update. |
| 331 if (!m_geometryNeedsUpdate) | 306 if (!m_geometryNeedsUpdate) |
| 332 return; | 307 return; |
| 333 | 308 |
| 309 if (!m_node || !m_node->renderer()) | |
| 310 return; | |
| 311 | |
| 334 m_geometryNeedsUpdate = false; | 312 m_geometryNeedsUpdate = false; |
| 335 | 313 const RenderLayerModelObject* paintInvalidationContainer = m_node->renderer( )->containerForPaintInvalidation(); |
| 336 RenderLayer* compositingLayer = computeEnclosingCompositingLayer(); | 314 attachLinkHighlightToCompositingLayer(paintInvalidationContainer); |
| 337 if (compositingLayer && computeHighlightLayerPathAndPosition(compositingLaye r)) { | 315 if (paintInvalidationContainer && computeHighlightLayerPathAndPosition(paint InvalidationContainer)) { |
| 338 // We only need to invalidate the layer if the highlight size has change d, otherwise | 316 // We only need to invalidate the layer if the highlight size has change d, otherwise |
| 339 // we can just re-position the layer without needing to repaint. | 317 // we can just re-position the layer without needing to repaint. |
| 340 m_contentLayer->layer()->invalidate(); | 318 m_contentLayer->layer()->invalidate(); |
| 341 | 319 |
| 342 if (m_currentGraphicsLayer) | 320 if (m_currentGraphicsLayer) |
| 343 m_currentGraphicsLayer->addRepaintRect(FloatRect(layer()->position() .x, layer()->position().y, layer()->bounds().width, layer()->bounds().height)); | 321 m_currentGraphicsLayer->addRepaintRect(FloatRect(layer()->position() .x, layer()->position().y, layer()->bounds().width, layer()->bounds().height)); |
| 344 } else if (!m_node || !m_node->renderer()) { | 322 } else if (!m_node || !m_node->renderer()) { |
| 345 clearGraphicsLayerLinkHighlightPointer(); | 323 clearGraphicsLayerLinkHighlightPointer(); |
| 346 releaseResources(); | 324 releaseResources(); |
| 347 } | 325 } |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 358 // Make sure we update geometry on the next callback from WebViewImpl::layou t(). | 336 // Make sure we update geometry on the next callback from WebViewImpl::layou t(). |
| 359 m_geometryNeedsUpdate = true; | 337 m_geometryNeedsUpdate = true; |
| 360 } | 338 } |
| 361 | 339 |
| 362 WebLayer* LinkHighlight::layer() | 340 WebLayer* LinkHighlight::layer() |
| 363 { | 341 { |
| 364 return clipLayer(); | 342 return clipLayer(); |
| 365 } | 343 } |
| 366 | 344 |
| 367 } // namespace blink | 345 } // namespace blink |
| OLD | NEW |