| 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 |