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
icsLayerBackingForScrolling(); |
112 return 0; | 112 if (!newGraphicsLayer) |
113 | 113 return; |
114 RenderLayer* renderLayer = m_node->renderer()->enclosingLayer()->enclosingLa
yerForPaintInvalidationCrossingFrameBoundaries(); | |
115 | |
116 ASSERT(renderLayer->compositingState() != NotComposited); | |
117 | |
118 GraphicsLayer* newGraphicsLayer = renderLayer->graphicsLayerBackingForScroll
ing(); | |
119 | 114 |
120 m_clipLayer->setTransform(SkMatrix44(SkMatrix44::kIdentity_Constructor)); | 115 m_clipLayer->setTransform(SkMatrix44(SkMatrix44::kIdentity_Constructor)); |
121 | 116 |
122 if (m_currentGraphicsLayer != newGraphicsLayer) { | 117 if (m_currentGraphicsLayer != newGraphicsLayer) { |
123 if (m_currentGraphicsLayer) | 118 if (m_currentGraphicsLayer) |
124 clearGraphicsLayerLinkHighlightPointer(); | 119 clearGraphicsLayerLinkHighlightPointer(); |
125 | 120 |
126 m_currentGraphicsLayer = newGraphicsLayer; | 121 m_currentGraphicsLayer = newGraphicsLayer; |
127 m_currentGraphicsLayer->addLinkHighlight(this); | 122 m_currentGraphicsLayer->addLinkHighlight(this); |
128 } | 123 } |
129 | |
130 return renderLayer; | |
131 } | 124 } |
132 | 125 |
133 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) |
134 { | 127 { |
135 ASSERT(targetRenderer); | 128 ASSERT(targetRenderer); |
136 ASSERT(compositedRenderer); | 129 ASSERT(paintInvalidationContainer); |
137 | |
138 for (unsigned i = 0; i < 4; ++i) { | 130 for (unsigned i = 0; i < 4; ++i) { |
139 IntPoint point; | 131 IntPoint point; |
140 switch (i) { | 132 switch (i) { |
141 case 0: point = roundedIntPoint(targetSpaceQuad.p1()); break; | 133 case 0: point = roundedIntPoint(targetSpaceQuad.p1()); break; |
142 case 1: point = roundedIntPoint(targetSpaceQuad.p2()); break; | 134 case 1: point = roundedIntPoint(targetSpaceQuad.p2()); break; |
143 case 2: point = roundedIntPoint(targetSpaceQuad.p3()); break; | 135 case 2: point = roundedIntPoint(targetSpaceQuad.p3()); break; |
144 case 3: point = roundedIntPoint(targetSpaceQuad.p4()); break; | 136 case 3: point = roundedIntPoint(targetSpaceQuad.p4()); break; |
145 } | 137 } |
146 | 138 |
| 139 // FIXME: this does not need to be absolute, just in the paint invalidat
ion container's space. |
147 point = targetRenderer->frame()->view()->contentsToWindow(point); | 140 point = targetRenderer->frame()->view()->contentsToWindow(point); |
148 point = compositedRenderer->frame()->view()->windowToContents(point); | 141 point = paintInvalidationContainer->frame()->view()->windowToContents(po
int); |
149 FloatPoint floatPoint = compositedRenderer->absoluteToLocal(point, UseTr
ansforms); | 142 FloatPoint floatPoint = paintInvalidationContainer->absoluteToLocal(poin
t, UseTransforms); |
| 143 RenderLayer::mapPointToPaintBackingCoordinates(paintInvalidationContaine
r, floatPoint); |
150 | 144 |
151 switch (i) { | 145 switch (i) { |
152 case 0: compositedSpaceQuad.setP1(floatPoint); break; | 146 case 0: compositedSpaceQuad.setP1(floatPoint); break; |
153 case 1: compositedSpaceQuad.setP2(floatPoint); break; | 147 case 1: compositedSpaceQuad.setP2(floatPoint); break; |
154 case 2: compositedSpaceQuad.setP3(floatPoint); break; | 148 case 2: compositedSpaceQuad.setP3(floatPoint); break; |
155 case 3: compositedSpaceQuad.setP4(floatPoint); break; | 149 case 3: compositedSpaceQuad.setP4(floatPoint); break; |
156 } | 150 } |
157 } | 151 } |
158 } | 152 } |
159 | 153 |
(...skipping 16 matching lines...) Expand all Loading... |
176 | 170 |
177 // 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 |
178 // 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 |
179 // 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 |
180 // 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 |
181 // boxes. | 175 // boxes. |
182 if (renderer->isRenderInline()) { | 176 if (renderer->isRenderInline()) { |
183 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)) |
184 computeQuads(*child, outQuads); | 178 computeQuads(*child, outQuads); |
185 } else { | 179 } else { |
| 180 // FIXME: this does not need to be absolute, just in the paint invalidat
ion container's space. |
186 renderer->absoluteQuads(outQuads); | 181 renderer->absoluteQuads(outQuads); |
187 } | 182 } |
188 } | 183 } |
189 | 184 |
190 bool LinkHighlight::computeHighlightLayerPathAndPosition(RenderLayer* compositin
gLayer) | 185 bool LinkHighlight::computeHighlightLayerPathAndPosition(const RenderLayerModelO
bject* paintInvalidationContainer) |
191 { | 186 { |
192 if (!m_node || !m_node->renderer() || !m_currentGraphicsLayer) | 187 if (!m_node || !m_node->renderer() || !m_currentGraphicsLayer) |
193 return false; | 188 return false; |
194 | 189 ASSERT(paintInvalidationContainer); |
195 ASSERT(compositingLayer); | |
196 | 190 |
197 // Get quads for node in absolute coordinates. | 191 // Get quads for node in absolute coordinates. |
198 Vector<FloatQuad> quads; | 192 Vector<FloatQuad> quads; |
199 computeQuads(*m_node, quads); | 193 computeQuads(*m_node, quads); |
200 ASSERT(quads.size()); | 194 ASSERT(quads.size()); |
| 195 Path newPath; |
201 | 196 |
202 // Adjust for offset between target graphics layer and the node's renderer. | 197 FloatPoint positionAdjustForCompositedScrolling = IntPoint(m_currentGraphics
Layer->offsetFromRenderer()); |
203 FloatPoint positionAdjust = IntPoint(m_currentGraphicsLayer->offsetFromRende
rer()); | |
204 | 198 |
205 Path newPath; | |
206 for (size_t quadIndex = 0; quadIndex < quads.size(); ++quadIndex) { | 199 for (size_t quadIndex = 0; quadIndex < quads.size(); ++quadIndex) { |
207 FloatQuad absoluteQuad = quads[quadIndex]; | 200 FloatQuad absoluteQuad = quads[quadIndex]; |
208 absoluteQuad.move(-positionAdjust.x(), -positionAdjust.y()); | 201 |
| 202 // FIXME: this hack should not be necessary. It's a consequence of the f
act that composited layers for scrolling are represented |
| 203 // differently in Blink than other composited layers. |
| 204 if (paintInvalidationContainer->layer()->needsCompositedScrolling() && m
_node->renderer() != paintInvalidationContainer) |
| 205 absoluteQuad.move(-positionAdjustForCompositedScrolling.x(), -positi
onAdjustForCompositedScrolling.y()); |
209 | 206 |
210 // Transform node quads in target absolute coords to local coordinates i
n the compositor layer. | 207 // Transform node quads in target absolute coords to local coordinates i
n the compositor layer. |
211 FloatQuad transformedQuad; | 208 FloatQuad transformedQuad; |
212 convertTargetSpaceQuadToCompositedLayer(absoluteQuad, m_node->renderer()
, compositingLayer->renderer(), transformedQuad); | 209 convertTargetSpaceQuadToCompositedLayer(absoluteQuad, m_node->renderer()
, paintInvalidationContainer, transformedQuad); |
213 | 210 |
214 // FIXME: for now, we'll only use rounded paths if we have a single node
quad. The reason for this is that | 211 // FIXME: for now, we'll only use rounded paths if we have a single node
quad. The reason for this is that |
215 // we may sometimes get a chain of adjacent boxes (e.g. for text nodes)
which end up looking like sausage | 212 // we may sometimes get a chain of adjacent boxes (e.g. for text nodes)
which end up looking like sausage |
216 // links: these should ideally be merged into a single rect before creat
ing the path, but that's | 213 // links: these should ideally be merged into a single rect before creat
ing the path, but that's |
217 // another CL. | 214 // another CL. |
218 if (quads.size() == 1 && transformedQuad.isRectilinear() | 215 if (quads.size() == 1 && transformedQuad.isRectilinear() |
219 && !m_owningWebViewImpl->settingsImpl()->mockGestureTapHighlightsEna
bled()) { | 216 && !m_owningWebViewImpl->settingsImpl()->mockGestureTapHighlightsEna
bled()) { |
220 FloatSize rectRoundingRadii(3, 3); | 217 FloatSize rectRoundingRadii(3, 3); |
221 newPath.addRoundedRect(transformedQuad.boundingBox(), rectRoundingRa
dii); | 218 newPath.addRoundedRect(transformedQuad.boundingBox(), rectRoundingRa
dii); |
222 } else | 219 } else |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
312 | 309 |
313 void LinkHighlight::updateGeometry() | 310 void LinkHighlight::updateGeometry() |
314 { | 311 { |
315 // To avoid unnecessary updates (e.g. other entities have requested animatio
ns from our WebViewImpl), | 312 // To avoid unnecessary updates (e.g. other entities have requested animatio
ns from our WebViewImpl), |
316 // only proceed if we actually requested an update. | 313 // only proceed if we actually requested an update. |
317 if (!m_geometryNeedsUpdate) | 314 if (!m_geometryNeedsUpdate) |
318 return; | 315 return; |
319 | 316 |
320 m_geometryNeedsUpdate = false; | 317 m_geometryNeedsUpdate = false; |
321 | 318 |
322 RenderLayer* compositingLayer = computeEnclosingCompositingLayer(); | 319 bool hasRenderer = m_node && m_node->renderer(); |
323 if (compositingLayer && computeHighlightLayerPathAndPosition(compositingLaye
r)) { | 320 const RenderLayerModelObject* paintInvalidationContainer = hasRenderer ? m_n
ode->renderer()->containerForPaintInvalidation() : 0; |
| 321 if (paintInvalidationContainer) |
| 322 attachLinkHighlightToCompositingLayer(paintInvalidationContainer); |
| 323 if (paintInvalidationContainer && computeHighlightLayerPathAndPosition(paint
InvalidationContainer)) { |
324 // We only need to invalidate the layer if the highlight size has change
d, otherwise | 324 // We only need to invalidate the layer if the highlight size has change
d, otherwise |
325 // we can just re-position the layer without needing to repaint. | 325 // we can just re-position the layer without needing to repaint. |
326 m_contentLayer->layer()->invalidate(); | 326 m_contentLayer->layer()->invalidate(); |
327 | 327 |
328 if (m_currentGraphicsLayer) | 328 if (m_currentGraphicsLayer) |
329 m_currentGraphicsLayer->addRepaintRect(FloatRect(layer()->position()
.x, layer()->position().y, layer()->bounds().width, layer()->bounds().height)); | 329 m_currentGraphicsLayer->addRepaintRect(FloatRect(layer()->position()
.x, layer()->position().y, layer()->bounds().width, layer()->bounds().height)); |
330 } else if (!m_node || !m_node->renderer()) { | 330 } else if (!hasRenderer) { |
331 clearGraphicsLayerLinkHighlightPointer(); | 331 clearGraphicsLayerLinkHighlightPointer(); |
332 releaseResources(); | 332 releaseResources(); |
333 } | 333 } |
334 } | 334 } |
335 | 335 |
336 void LinkHighlight::clearCurrentGraphicsLayer() | 336 void LinkHighlight::clearCurrentGraphicsLayer() |
337 { | 337 { |
338 m_currentGraphicsLayer = 0; | 338 m_currentGraphicsLayer = 0; |
339 m_geometryNeedsUpdate = true; | 339 m_geometryNeedsUpdate = true; |
340 } | 340 } |
341 | 341 |
342 void LinkHighlight::invalidate() | 342 void LinkHighlight::invalidate() |
343 { | 343 { |
344 // Make sure we update geometry on the next callback from WebViewImpl::layou
t(). | 344 // Make sure we update geometry on the next callback from WebViewImpl::layou
t(). |
345 m_geometryNeedsUpdate = true; | 345 m_geometryNeedsUpdate = true; |
346 } | 346 } |
347 | 347 |
348 WebLayer* LinkHighlight::layer() | 348 WebLayer* LinkHighlight::layer() |
349 { | 349 { |
350 return clipLayer(); | 350 return clipLayer(); |
351 } | 351 } |
352 | 352 |
353 } // namespace blink | 353 } // namespace blink |
OLD | NEW |