| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights | 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights |
| 3 * reserved. | 3 * reserved. |
| 4 * | 4 * |
| 5 * Portions are Copyright (C) 1998 Netscape Communications Corporation. | 5 * Portions are Copyright (C) 1998 Netscape Communications Corporation. |
| 6 * | 6 * |
| 7 * Other contributors: | 7 * Other contributors: |
| 8 * Robert O'Callahan <roc+@cs.cmu.edu> | 8 * Robert O'Callahan <roc+@cs.cmu.edu> |
| 9 * David Baron <dbaron@fas.harvard.edu> | 9 * David Baron <dbaron@fas.harvard.edu> |
| 10 * Christian Biesinger <cbiesinger@web.de> | 10 * Christian Biesinger <cbiesinger@web.de> |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 107 intersection(newClip, clipRects.posClipRect()).setIsClippedByClipCss()); | 107 intersection(newClip, clipRects.posClipRect()).setIsClippedByClipCss()); |
| 108 clipRects.setOverflowClipRect( | 108 clipRects.setOverflowClipRect( |
| 109 intersection(newClip, clipRects.overflowClipRect()) | 109 intersection(newClip, clipRects.overflowClipRect()) |
| 110 .setIsClippedByClipCss()); | 110 .setIsClippedByClipCss()); |
| 111 clipRects.setFixedClipRect(intersection(newClip, clipRects.fixedClipRect()) | 111 clipRects.setFixedClipRect(intersection(newClip, clipRects.fixedClipRect()) |
| 112 .setIsClippedByClipCss()); | 112 .setIsClippedByClipCss()); |
| 113 } | 113 } |
| 114 } | 114 } |
| 115 | 115 |
| 116 PaintLayerClipper::PaintLayerClipper(const PaintLayer& layer, | 116 PaintLayerClipper::PaintLayerClipper(const PaintLayer& layer, |
| 117 bool useGeometryMapper) | 117 GeometryMapper* geometryMapper) |
| 118 : m_layer(layer), | 118 : m_layer(layer), m_geometryMapper(geometryMapper) {} |
| 119 m_geometryMapper(useGeometryMapper ? new GeometryMapper : nullptr) {} | |
| 120 | 119 |
| 121 ClipRects* PaintLayerClipper::clipRectsIfCached( | 120 ClipRects* PaintLayerClipper::clipRectsIfCached( |
| 122 const ClipRectsContext& context) const { | 121 const ClipRectsContext& context) const { |
| 123 DCHECK(context.usesCache()); | 122 DCHECK(context.usesCache()); |
| 124 if (!m_layer.clipRectsCache()) | 123 if (!m_layer.clipRectsCache()) |
| 125 return nullptr; | 124 return nullptr; |
| 126 ClipRectsCache::Entry& entry = | 125 ClipRectsCache::Entry& entry = |
| 127 m_layer.clipRectsCache()->get(context.cacheSlot()); | 126 m_layer.clipRectsCache()->get(context.cacheSlot()); |
| 128 // FIXME: We used to ASSERT that we always got a consistent root layer. | 127 // FIXME: We used to ASSERT that we always got a consistent root layer. |
| 129 // We should add a test that has an inconsistent root. See | 128 // We should add a test that has an inconsistent root. See |
| (...skipping 23 matching lines...) Expand all Loading... |
| 153 entry.clipRects = parentClipRects; | 152 entry.clipRects = parentClipRects; |
| 154 return *parentClipRects; | 153 return *parentClipRects; |
| 155 } | 154 } |
| 156 } | 155 } |
| 157 entry.clipRects = ClipRects::create(clipRects); | 156 entry.clipRects = ClipRects::create(clipRects); |
| 158 return *entry.clipRects; | 157 return *entry.clipRects; |
| 159 } | 158 } |
| 160 | 159 |
| 161 ClipRects& PaintLayerClipper::getClipRects( | 160 ClipRects& PaintLayerClipper::getClipRects( |
| 162 const ClipRectsContext& context) const { | 161 const ClipRectsContext& context) const { |
| 162 DCHECK(!m_geometryMapper); |
| 163 if (ClipRects* result = clipRectsIfCached(context)) | 163 if (ClipRects* result = clipRectsIfCached(context)) |
| 164 return *result; | 164 return *result; |
| 165 // Note that it's important that we call getClipRects on our parent | 165 // Note that it's important that we call getClipRects on our parent |
| 166 // before we call calculateClipRects so that calculateClipRects will hit | 166 // before we call calculateClipRects so that calculateClipRects will hit |
| 167 // the cache. | 167 // the cache. |
| 168 ClipRects* parentClipRects = nullptr; | 168 ClipRects* parentClipRects = nullptr; |
| 169 if (context.rootLayer != &m_layer && m_layer.parent()) | 169 if (context.rootLayer != &m_layer && m_layer.parent()) { |
| 170 parentClipRects = &m_layer.parent()->clipper().getClipRects(context); | 170 parentClipRects = |
| 171 &PaintLayerClipper(*m_layer.parent(), nullptr).getClipRects(context); |
| 172 } |
| 171 RefPtr<ClipRects> clipRects = ClipRects::create(); | 173 RefPtr<ClipRects> clipRects = ClipRects::create(); |
| 172 calculateClipRects(context, *clipRects); | 174 calculateClipRects(context, *clipRects); |
| 173 return storeClipRectsInCache(context, parentClipRects, *clipRects); | 175 return storeClipRectsInCache(context, parentClipRects, *clipRects); |
| 174 } | 176 } |
| 175 | 177 |
| 176 void PaintLayerClipper::clearCache(ClipRectsCacheSlot cacheSlot) { | 178 void PaintLayerClipper::clearCache(ClipRectsCacheSlot cacheSlot) { |
| 177 if (cacheSlot == NumberOfClipRectsCacheSlots) | 179 if (cacheSlot == NumberOfClipRectsCacheSlots) |
| 178 m_layer.clearClipRectsCache(); | 180 m_layer.clearClipRectsCache(); |
| 179 else if (ClipRectsCache* cache = m_layer.clipRectsCache()) | 181 else if (ClipRectsCache* cache = m_layer.clipRectsCache()) |
| 180 cache->clear(cacheSlot); | 182 cache->clear(cacheSlot); |
| 181 | |
| 182 if (m_geometryMapper) | |
| 183 m_geometryMapper.reset(new GeometryMapper); | |
| 184 } | 183 } |
| 185 | 184 |
| 186 void PaintLayerClipper::clearClipRectsIncludingDescendants() { | 185 void PaintLayerClipper::clearClipRectsIncludingDescendants() { |
| 187 clearClipRectsIncludingDescendants(NumberOfClipRectsCacheSlots); | 186 clearClipRectsIncludingDescendants(NumberOfClipRectsCacheSlots); |
| 188 } | 187 } |
| 189 | 188 |
| 190 void PaintLayerClipper::clearClipRectsIncludingDescendants( | 189 void PaintLayerClipper::clearClipRectsIncludingDescendants( |
| 191 ClipRectsCacheSlot cacheSlot) { | 190 ClipRectsCacheSlot cacheSlot) { |
| 192 std::stack<const PaintLayer*> layers; | 191 std::stack<const PaintLayer*> layers; |
| 193 layers.push(&m_layer); | 192 layers.push(&m_layer); |
| 194 | 193 |
| 195 while (!layers.empty()) { | 194 while (!layers.empty()) { |
| 196 const PaintLayer* currentLayer = layers.top(); | 195 const PaintLayer* currentLayer = layers.top(); |
| 197 layers.pop(); | 196 layers.pop(); |
| 198 currentLayer->clipper().clearCache(cacheSlot); | 197 PaintLayerClipper(*currentLayer, m_geometryMapper).clearCache(cacheSlot); |
| 199 for (const PaintLayer* layer = currentLayer->firstChild(); layer; | 198 for (const PaintLayer* layer = currentLayer->firstChild(); layer; |
| 200 layer = layer->nextSibling()) | 199 layer = layer->nextSibling()) |
| 201 layers.push(layer); | 200 layers.push(layer); |
| 202 } | 201 } |
| 203 } | 202 } |
| 204 | 203 |
| 205 LayoutRect PaintLayerClipper::localClipRect( | 204 LayoutRect PaintLayerClipper::localClipRect( |
| 206 const PaintLayer& clippingRootLayer) const { | 205 const PaintLayer& clippingRootLayer) const { |
| 207 ClipRectsContext context(&clippingRootLayer, PaintingClipRects); | 206 ClipRectsContext context(&clippingRootLayer, PaintingClipRects); |
| 208 if (m_geometryMapper) { | 207 if (m_geometryMapper) { |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 395 | 394 |
| 396 bool isClippingRoot = &m_layer == context.rootLayer; | 395 bool isClippingRoot = &m_layer == context.rootLayer; |
| 397 | 396 |
| 398 // For transformed layers, the root layer was shifted to be us, so there is no | 397 // For transformed layers, the root layer was shifted to be us, so there is no |
| 399 // need to examine the parent. We want to cache clip rects with us as the | 398 // need to examine the parent. We want to cache clip rects with us as the |
| 400 // root. | 399 // root. |
| 401 PaintLayer* parentLayer = !isClippingRoot ? m_layer.parent() : nullptr; | 400 PaintLayer* parentLayer = !isClippingRoot ? m_layer.parent() : nullptr; |
| 402 // Ensure that our parent's clip has been calculated so that we can examine | 401 // Ensure that our parent's clip has been calculated so that we can examine |
| 403 // the values. | 402 // the values. |
| 404 if (parentLayer) { | 403 if (parentLayer) { |
| 405 parentLayer->clipper().getOrCalculateClipRects(context, clipRects); | 404 PaintLayerClipper(*parentLayer, m_geometryMapper) |
| 405 .getOrCalculateClipRects(context, clipRects); |
| 406 } else { | 406 } else { |
| 407 clipRects.reset(LayoutRect(LayoutRect::infiniteIntRect())); | 407 clipRects.reset(LayoutRect(LayoutRect::infiniteIntRect())); |
| 408 } | 408 } |
| 409 | 409 |
| 410 adjustClipRectsForChildren(layoutObject, clipRects); | 410 adjustClipRectsForChildren(layoutObject, clipRects); |
| 411 | 411 |
| 412 if (shouldClipOverflow(context) || layoutObject.hasClip()) { | 412 if (shouldClipOverflow(context) || layoutObject.hasClip()) { |
| 413 // This offset cannot use convertToLayerCoords, because sometimes our | 413 // This offset cannot use convertToLayerCoords, because sometimes our |
| 414 // rootLayer may be across some transformed layer boundary, for example, in | 414 // rootLayer may be across some transformed layer boundary, for example, in |
| 415 // the PaintLayerCompositor overlapMap, where clipRects are needed in view | 415 // the PaintLayerCompositor overlapMap, where clipRects are needed in view |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 505 PaintLayerClipper(m_layer, false).backgroundClipRect(context); | 505 PaintLayerClipper(m_layer, false).backgroundClipRect(context); |
| 506 CHECK_RECTS_EQ(testBackgroundClipRect, backgroundClipRect); | 506 CHECK_RECTS_EQ(testBackgroundClipRect, backgroundClipRect); |
| 507 #endif | 507 #endif |
| 508 return backgroundClipRect; | 508 return backgroundClipRect; |
| 509 } | 509 } |
| 510 DCHECK(m_layer.parent()); | 510 DCHECK(m_layer.parent()); |
| 511 LayoutView* layoutView = m_layer.layoutObject()->view(); | 511 LayoutView* layoutView = m_layer.layoutObject()->view(); |
| 512 DCHECK(layoutView); | 512 DCHECK(layoutView); |
| 513 | 513 |
| 514 RefPtr<ClipRects> parentClipRects = ClipRects::create(); | 514 RefPtr<ClipRects> parentClipRects = ClipRects::create(); |
| 515 if (&m_layer == context.rootLayer) | 515 if (&m_layer == context.rootLayer) { |
| 516 parentClipRects->reset(LayoutRect(LayoutRect::infiniteIntRect())); | 516 parentClipRects->reset(LayoutRect(LayoutRect::infiniteIntRect())); |
| 517 else | 517 } else { |
| 518 m_layer.parent()->clipper().getOrCalculateClipRects(context, | 518 PaintLayerClipper(*m_layer.parent(), m_geometryMapper) |
| 519 *parentClipRects); | 519 .getOrCalculateClipRects(context, *parentClipRects); |
| 520 } |
| 520 | 521 |
| 521 ClipRect result = backgroundClipRectForPosition( | 522 ClipRect result = backgroundClipRectForPosition( |
| 522 *parentClipRects, m_layer.layoutObject()->styleRef().position()); | 523 *parentClipRects, m_layer.layoutObject()->styleRef().position()); |
| 523 | 524 |
| 524 // Note: infinite clipRects should not be scrolled here, otherwise they will | 525 // Note: infinite clipRects should not be scrolled here, otherwise they will |
| 525 // accidentally no longer be considered infinite. | 526 // accidentally no longer be considered infinite. |
| 526 if (parentClipRects->fixed() && | 527 if (parentClipRects->fixed() && |
| 527 context.rootLayer->layoutObject() == layoutView && | 528 context.rootLayer->layoutObject() == layoutView && |
| 528 result != LayoutRect(LayoutRect::infiniteIntRect())) | 529 result != LayoutRect(LayoutRect::infiniteIntRect())) |
| 529 result.move(LayoutSize(layoutView->frameView()->getScrollOffset())); | 530 result.move(LayoutSize(layoutView->frameView()->getScrollOffset())); |
| 530 | 531 |
| 531 return result; | 532 return result; |
| 532 } | 533 } |
| 533 | 534 |
| 534 void PaintLayerClipper::getOrCalculateClipRects(const ClipRectsContext& context, | 535 void PaintLayerClipper::getOrCalculateClipRects(const ClipRectsContext& context, |
| 535 ClipRects& clipRects) const { | 536 ClipRects& clipRects) const { |
| 537 DCHECK(!m_geometryMapper); |
| 538 |
| 536 if (context.usesCache()) | 539 if (context.usesCache()) |
| 537 clipRects = getClipRects(context); | 540 clipRects = getClipRects(context); |
| 538 else | 541 else |
| 539 calculateClipRects(context, clipRects); | 542 calculateClipRects(context, clipRects); |
| 540 } | 543 } |
| 541 | 544 |
| 542 bool PaintLayerClipper::shouldClipOverflow( | 545 bool PaintLayerClipper::shouldClipOverflow( |
| 543 const ClipRectsContext& context) const { | 546 const ClipRectsContext& context) const { |
| 544 if (!m_layer.layoutObject()->isBox()) | 547 if (!m_layer.layoutObject()->isBox()) |
| 545 return false; | 548 return false; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 572 const LayoutSize& subpixelAccumulation) const { | 575 const LayoutSize& subpixelAccumulation) const { |
| 573 DCHECK(!m_geometryMapper); | 576 DCHECK(!m_geometryMapper); |
| 574 ClipRectsContext context(rootLayer, PaintingClipRects, | 577 ClipRectsContext context(rootLayer, PaintingClipRects, |
| 575 IgnoreOverlayScrollbarSize, subpixelAccumulation); | 578 IgnoreOverlayScrollbarSize, subpixelAccumulation); |
| 576 if (respectOverflowClip == IgnoreOverflowClip) | 579 if (respectOverflowClip == IgnoreOverflowClip) |
| 577 context.setIgnoreOverflowClip(); | 580 context.setIgnoreOverflowClip(); |
| 578 return getClipRects(context); | 581 return getClipRects(context); |
| 579 } | 582 } |
| 580 | 583 |
| 581 } // namespace blink | 584 } // namespace blink |
| OLD | NEW |