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 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 point = roundedIntPoint(targetSpaceQuad.p2()); | 173 point = roundedIntPoint(targetSpaceQuad.p2()); |
174 break; | 174 break; |
175 case 2: | 175 case 2: |
176 point = roundedIntPoint(targetSpaceQuad.p3()); | 176 point = roundedIntPoint(targetSpaceQuad.p3()); |
177 break; | 177 break; |
178 case 3: | 178 case 3: |
179 point = roundedIntPoint(targetSpaceQuad.p4()); | 179 point = roundedIntPoint(targetSpaceQuad.p4()); |
180 break; | 180 break; |
181 } | 181 } |
182 | 182 |
183 // FIXME: this does not need to be absolute, just in the paint invalidation
container's space. | 183 // FIXME: this does not need to be absolute, just in the paint invalidation |
| 184 // container's space. |
184 point = targetLayoutObject->frame()->view()->contentsToRootFrame(point); | 185 point = targetLayoutObject->frame()->view()->contentsToRootFrame(point); |
185 point = | 186 point = |
186 paintInvalidationContainer.frame()->view()->rootFrameToContents(point); | 187 paintInvalidationContainer.frame()->view()->rootFrameToContents(point); |
187 FloatPoint floatPoint = | 188 FloatPoint floatPoint = |
188 paintInvalidationContainer.absoluteToLocal(point, UseTransforms); | 189 paintInvalidationContainer.absoluteToLocal(point, UseTransforms); |
189 PaintLayer::mapPointInPaintInvalidationContainerToBacking( | 190 PaintLayer::mapPointInPaintInvalidationContainerToBacking( |
190 paintInvalidationContainer, floatPoint); | 191 paintInvalidationContainer, floatPoint); |
191 | 192 |
192 switch (i) { | 193 switch (i) { |
193 case 0: | 194 case 0: |
194 compositedSpaceQuad.setP1(floatPoint); | 195 compositedSpaceQuad.setP1(floatPoint); |
195 break; | 196 break; |
196 case 1: | 197 case 1: |
197 compositedSpaceQuad.setP2(floatPoint); | 198 compositedSpaceQuad.setP2(floatPoint); |
198 break; | 199 break; |
199 case 2: | 200 case 2: |
200 compositedSpaceQuad.setP3(floatPoint); | 201 compositedSpaceQuad.setP3(floatPoint); |
201 break; | 202 break; |
202 case 3: | 203 case 3: |
203 compositedSpaceQuad.setP4(floatPoint); | 204 compositedSpaceQuad.setP4(floatPoint); |
204 break; | 205 break; |
205 } | 206 } |
206 } | 207 } |
207 } | 208 } |
208 | 209 |
209 static void addQuadToPath(const FloatQuad& quad, Path& path) { | 210 static void addQuadToPath(const FloatQuad& quad, Path& path) { |
210 // FIXME: Make this create rounded quad-paths, just like the axis-aligned case
. | 211 // FIXME: Make this create rounded quad-paths, just like the axis-aligned |
| 212 // case. |
211 path.moveTo(quad.p1()); | 213 path.moveTo(quad.p1()); |
212 path.addLineTo(quad.p2()); | 214 path.addLineTo(quad.p2()); |
213 path.addLineTo(quad.p3()); | 215 path.addLineTo(quad.p3()); |
214 path.addLineTo(quad.p4()); | 216 path.addLineTo(quad.p4()); |
215 path.closeSubpath(); | 217 path.closeSubpath(); |
216 } | 218 } |
217 | 219 |
218 void LinkHighlightImpl::computeQuads(const Node& node, | 220 void LinkHighlightImpl::computeQuads(const Node& node, |
219 Vector<FloatQuad>& outQuads) const { | 221 Vector<FloatQuad>& outQuads) const { |
220 if (!node.layoutObject()) | 222 if (!node.layoutObject()) |
221 return; | 223 return; |
222 | 224 |
223 LayoutObject* layoutObject = node.layoutObject(); | 225 LayoutObject* layoutObject = node.layoutObject(); |
224 | 226 |
225 // For inline elements, absoluteQuads will return a line box based on the line
-height | 227 // For inline elements, absoluteQuads will return a line box based on the |
226 // and font metrics, which is technically incorrect as replaced elements like
images | 228 // line-height and font metrics, which is technically incorrect as replaced |
227 // should use their intristic height and expand the linebox as needed. To get
an | 229 // elements like images should use their intristic height and expand the |
228 // appropriately sized highlight we descend into the children and have them ad
d their | 230 // linebox as needed. To get an appropriately sized highlight we descend |
229 // boxes. | 231 // into the children and have them add their boxes. |
230 if (layoutObject->isLayoutInline()) { | 232 if (layoutObject->isLayoutInline()) { |
231 for (Node* child = LayoutTreeBuilderTraversal::firstChild(node); child; | 233 for (Node* child = LayoutTreeBuilderTraversal::firstChild(node); child; |
232 child = LayoutTreeBuilderTraversal::nextSibling(*child)) | 234 child = LayoutTreeBuilderTraversal::nextSibling(*child)) |
233 computeQuads(*child, outQuads); | 235 computeQuads(*child, outQuads); |
234 } else { | 236 } else { |
235 // FIXME: this does not need to be absolute, just in the paint invalidation
container's space. | 237 // FIXME: this does not need to be absolute, just in the paint invalidation |
| 238 // container's space. |
236 layoutObject->absoluteQuads(outQuads); | 239 layoutObject->absoluteQuads(outQuads); |
237 } | 240 } |
238 } | 241 } |
239 | 242 |
240 bool LinkHighlightImpl::computeHighlightLayerPathAndPosition( | 243 bool LinkHighlightImpl::computeHighlightLayerPathAndPosition( |
241 const LayoutBoxModelObject& paintInvalidationContainer) { | 244 const LayoutBoxModelObject& paintInvalidationContainer) { |
242 if (!m_node || !m_node->layoutObject() || !m_currentGraphicsLayer) | 245 if (!m_node || !m_node->layoutObject() || !m_currentGraphicsLayer) |
243 return false; | 246 return false; |
244 | 247 |
245 // FIXME: This is defensive code to avoid crashes such as those described in | 248 // FIXME: This is defensive code to avoid crashes such as those described in |
246 // crbug.com/440887. This should be cleaned up once we fix the root cause of | 249 // crbug.com/440887. This should be cleaned up once we fix the root cause of |
247 // of the paint invalidation container not being composited. | 250 // of the paint invalidation container not being composited. |
248 if (!paintInvalidationContainer.layer()->compositedLayerMapping() && | 251 if (!paintInvalidationContainer.layer()->compositedLayerMapping() && |
249 !paintInvalidationContainer.layer()->groupedMapping()) | 252 !paintInvalidationContainer.layer()->groupedMapping()) |
250 return false; | 253 return false; |
251 | 254 |
252 // Get quads for node in absolute coordinates. | 255 // Get quads for node in absolute coordinates. |
253 Vector<FloatQuad> quads; | 256 Vector<FloatQuad> quads; |
254 computeQuads(*m_node, quads); | 257 computeQuads(*m_node, quads); |
255 DCHECK(quads.size()); | 258 DCHECK(quads.size()); |
256 Path newPath; | 259 Path newPath; |
257 | 260 |
258 for (size_t quadIndex = 0; quadIndex < quads.size(); ++quadIndex) { | 261 for (size_t quadIndex = 0; quadIndex < quads.size(); ++quadIndex) { |
259 FloatQuad absoluteQuad = quads[quadIndex]; | 262 FloatQuad absoluteQuad = quads[quadIndex]; |
260 | 263 |
261 // Scrolling content layers have the same offset from layout object as the n
on-scrolling layers. Thus we need | 264 // Scrolling content layers have the same offset from layout object as the |
262 // to adjust for their scroll offset. | 265 // non-scrolling layers. Thus we need to adjust for their scroll offset. |
263 if (m_isScrollingGraphicsLayer) { | 266 if (m_isScrollingGraphicsLayer) { |
264 DoubleSize adjustedScrollOffset = paintInvalidationContainer.layer() | 267 DoubleSize adjustedScrollOffset = paintInvalidationContainer.layer() |
265 ->getScrollableArea() | 268 ->getScrollableArea() |
266 ->adjustedScrollOffset(); | 269 ->adjustedScrollOffset(); |
267 absoluteQuad.move(adjustedScrollOffset.width(), | 270 absoluteQuad.move(adjustedScrollOffset.width(), |
268 adjustedScrollOffset.height()); | 271 adjustedScrollOffset.height()); |
269 } | 272 } |
270 | 273 |
271 // Transform node quads in target absolute coords to local coordinates in th
e compositor layer. | 274 // Transform node quads in target absolute coords to local coordinates in |
| 275 // the compositor layer. |
272 FloatQuad transformedQuad; | 276 FloatQuad transformedQuad; |
273 convertTargetSpaceQuadToCompositedLayer( | 277 convertTargetSpaceQuadToCompositedLayer( |
274 absoluteQuad, m_node->layoutObject(), paintInvalidationContainer, | 278 absoluteQuad, m_node->layoutObject(), paintInvalidationContainer, |
275 transformedQuad); | 279 transformedQuad); |
276 | 280 |
277 // FIXME: for now, we'll only use rounded paths if we have a single node qua
d. The reason for this is that | 281 // FIXME: for now, we'll only use rounded paths if we have a single node |
278 // we may sometimes get a chain of adjacent boxes (e.g. for text nodes) whic
h end up looking like sausage | 282 // quad. The reason for this is that we may sometimes get a chain of |
279 // links: these should ideally be merged into a single rect before creating
the path, but that's | 283 // adjacent boxes (e.g. for text nodes) which end up looking like sausage |
280 // another CL. | 284 // links: these should ideally be merged into a single rect before creating |
| 285 // the path, but that's another CL. |
281 if (quads.size() == 1 && transformedQuad.isRectilinear() && | 286 if (quads.size() == 1 && transformedQuad.isRectilinear() && |
282 !m_owningWebViewImpl->settingsImpl() | 287 !m_owningWebViewImpl->settingsImpl() |
283 ->mockGestureTapHighlightsEnabled()) { | 288 ->mockGestureTapHighlightsEnabled()) { |
284 FloatSize rectRoundingRadii(3, 3); | 289 FloatSize rectRoundingRadii(3, 3); |
285 newPath.addRoundedRect(transformedQuad.boundingBox(), rectRoundingRadii); | 290 newPath.addRoundedRect(transformedQuad.boundingBox(), rectRoundingRadii); |
286 } else { | 291 } else { |
287 addQuadToPath(transformedQuad, newPath); | 292 addQuadToPath(transformedQuad, newPath); |
288 } | 293 } |
289 } | 294 } |
290 | 295 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
342 | 347 |
343 m_contentLayer->layer()->setOpacity(startOpacity); | 348 m_contentLayer->layer()->setOpacity(startOpacity); |
344 | 349 |
345 std::unique_ptr<CompositorFloatAnimationCurve> curve = | 350 std::unique_ptr<CompositorFloatAnimationCurve> curve = |
346 CompositorFloatAnimationCurve::create(); | 351 CompositorFloatAnimationCurve::create(); |
347 | 352 |
348 const auto& timingFunction = *CubicBezierTimingFunction::preset( | 353 const auto& timingFunction = *CubicBezierTimingFunction::preset( |
349 CubicBezierTimingFunction::EaseType::EASE); | 354 CubicBezierTimingFunction::EaseType::EASE); |
350 | 355 |
351 curve->addKeyframe(CompositorFloatKeyframe(0, startOpacity, timingFunction)); | 356 curve->addKeyframe(CompositorFloatKeyframe(0, startOpacity, timingFunction)); |
352 // Make sure we have displayed for at least minPreFadeDuration before starting
to fade out. | 357 // Make sure we have displayed for at least minPreFadeDuration before starting |
| 358 // to fade out. |
353 float extraDurationRequired = std::max( | 359 float extraDurationRequired = std::max( |
354 0.f, minPreFadeDuration - | 360 0.f, minPreFadeDuration - |
355 static_cast<float>(monotonicallyIncreasingTime() - m_startTime)); | 361 static_cast<float>(monotonicallyIncreasingTime() - m_startTime)); |
356 if (extraDurationRequired) | 362 if (extraDurationRequired) |
357 curve->addKeyframe(CompositorFloatKeyframe(extraDurationRequired, | 363 curve->addKeyframe(CompositorFloatKeyframe(extraDurationRequired, |
358 startOpacity, timingFunction)); | 364 startOpacity, timingFunction)); |
359 // For layout tests we don't fade out. | 365 // For layout tests we don't fade out. |
360 curve->addKeyframe(CompositorFloatKeyframe( | 366 curve->addKeyframe(CompositorFloatKeyframe( |
361 fadeDuration + extraDurationRequired, layoutTestMode() ? startOpacity : 0, | 367 fadeDuration + extraDurationRequired, layoutTestMode() ? startOpacity : 0, |
362 timingFunction)); | 368 timingFunction)); |
(...skipping 23 matching lines...) Expand all Loading... |
386 clearGraphicsLayerLinkHighlightPointer(); | 392 clearGraphicsLayerLinkHighlightPointer(); |
387 releaseResources(); | 393 releaseResources(); |
388 } | 394 } |
389 | 395 |
390 class LinkHighlightDisplayItemClientForTracking : public DisplayItemClient { | 396 class LinkHighlightDisplayItemClientForTracking : public DisplayItemClient { |
391 String debugName() const final { return "LinkHighlight"; } | 397 String debugName() const final { return "LinkHighlight"; } |
392 LayoutRect visualRect() const final { return LayoutRect(); } | 398 LayoutRect visualRect() const final { return LayoutRect(); } |
393 }; | 399 }; |
394 | 400 |
395 void LinkHighlightImpl::updateGeometry() { | 401 void LinkHighlightImpl::updateGeometry() { |
396 // To avoid unnecessary updates (e.g. other entities have requested animations
from our WebViewImpl), | 402 // To avoid unnecessary updates (e.g. other entities have requested animations |
397 // only proceed if we actually requested an update. | 403 // from our WebViewImpl), only proceed if we actually requested an update. |
398 if (!m_geometryNeedsUpdate) | 404 if (!m_geometryNeedsUpdate) |
399 return; | 405 return; |
400 | 406 |
401 m_geometryNeedsUpdate = false; | 407 m_geometryNeedsUpdate = false; |
402 | 408 |
403 bool hasLayoutObject = m_node && m_node->layoutObject(); | 409 bool hasLayoutObject = m_node && m_node->layoutObject(); |
404 if (hasLayoutObject) { | 410 if (hasLayoutObject) { |
405 const LayoutBoxModelObject& paintInvalidationContainer = | 411 const LayoutBoxModelObject& paintInvalidationContainer = |
406 m_node->layoutObject()->containerForPaintInvalidation(); | 412 m_node->layoutObject()->containerForPaintInvalidation(); |
407 attachLinkHighlightToCompositingLayer(paintInvalidationContainer); | 413 attachLinkHighlightToCompositingLayer(paintInvalidationContainer); |
408 if (computeHighlightLayerPathAndPosition(paintInvalidationContainer)) { | 414 if (computeHighlightLayerPathAndPosition(paintInvalidationContainer)) { |
409 // We only need to invalidate the layer if the highlight size has changed,
otherwise | 415 // We only need to invalidate the layer if the highlight size has changed, |
410 // we can just re-position the layer without needing to repaint. | 416 // otherwise we can just re-position the layer without needing to |
| 417 // repaint. |
411 m_contentLayer->layer()->invalidate(); | 418 m_contentLayer->layer()->invalidate(); |
412 | 419 |
413 if (m_currentGraphicsLayer) | 420 if (m_currentGraphicsLayer) |
414 m_currentGraphicsLayer->trackPaintInvalidation( | 421 m_currentGraphicsLayer->trackPaintInvalidation( |
415 LinkHighlightDisplayItemClientForTracking(), | 422 LinkHighlightDisplayItemClientForTracking(), |
416 enclosingIntRect( | 423 enclosingIntRect( |
417 FloatRect(layer()->position().x, layer()->position().y, | 424 FloatRect(layer()->position().x, layer()->position().y, |
418 layer()->bounds().width, layer()->bounds().height)), | 425 layer()->bounds().width, layer()->bounds().height)), |
419 PaintInvalidationFull); | 426 PaintInvalidationFull); |
420 } | 427 } |
421 } else { | 428 } else { |
422 clearGraphicsLayerLinkHighlightPointer(); | 429 clearGraphicsLayerLinkHighlightPointer(); |
423 releaseResources(); | 430 releaseResources(); |
424 } | 431 } |
425 } | 432 } |
426 | 433 |
427 void LinkHighlightImpl::clearCurrentGraphicsLayer() { | 434 void LinkHighlightImpl::clearCurrentGraphicsLayer() { |
428 m_currentGraphicsLayer = 0; | 435 m_currentGraphicsLayer = 0; |
429 m_geometryNeedsUpdate = true; | 436 m_geometryNeedsUpdate = true; |
430 } | 437 } |
431 | 438 |
432 void LinkHighlightImpl::invalidate() { | 439 void LinkHighlightImpl::invalidate() { |
433 // Make sure we update geometry on the next callback from WebViewImpl::layout(
). | 440 // Make sure we update geometry on the next callback from |
| 441 // WebViewImpl::layout(). |
434 m_geometryNeedsUpdate = true; | 442 m_geometryNeedsUpdate = true; |
435 } | 443 } |
436 | 444 |
437 WebLayer* LinkHighlightImpl::layer() { | 445 WebLayer* LinkHighlightImpl::layer() { |
438 return clipLayer(); | 446 return clipLayer(); |
439 } | 447 } |
440 | 448 |
441 CompositorAnimationPlayer* LinkHighlightImpl::compositorPlayer() const { | 449 CompositorAnimationPlayer* LinkHighlightImpl::compositorPlayer() const { |
442 return m_compositorPlayer.get(); | 450 return m_compositorPlayer.get(); |
443 } | 451 } |
444 | 452 |
445 } // namespace blink | 453 } // namespace blink |
OLD | NEW |