| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights
reserved. | 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights
reserved. |
| 3 * | 3 * |
| 4 * Portions are Copyright (C) 1998 Netscape Communications Corporation. | 4 * Portions are Copyright (C) 1998 Netscape Communications Corporation. |
| 5 * | 5 * |
| 6 * Other contributors: | 6 * Other contributors: |
| 7 * Robert O'Callahan <roc+@cs.cmu.edu> | 7 * Robert O'Callahan <roc+@cs.cmu.edu> |
| 8 * David Baron <dbaron@fas.harvard.edu> | 8 * David Baron <dbaron@fas.harvard.edu> |
| 9 * Christian Biesinger <cbiesinger@web.de> | 9 * Christian Biesinger <cbiesinger@web.de> |
| 10 * Randall Jesup <rjesup@wgate.com> | 10 * Randall Jesup <rjesup@wgate.com> |
| (...skipping 1024 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1035 | 1035 |
| 1036 context->clipPath(clipPath->path(rootRelativeBounds), clipPath->
windRule()); | 1036 context->clipPath(clipPath->path(rootRelativeBounds), clipPath->
windRule()); |
| 1037 } | 1037 } |
| 1038 } | 1038 } |
| 1039 } | 1039 } |
| 1040 | 1040 |
| 1041 LayerPaintingInfo localPaintingInfo(paintingInfo); | 1041 LayerPaintingInfo localPaintingInfo(paintingInfo); |
| 1042 bool deferredFiltersEnabled = renderer()->document().settings()->deferredFil
tersEnabled(); | 1042 bool deferredFiltersEnabled = renderer()->document().settings()->deferredFil
tersEnabled(); |
| 1043 FilterEffectRendererHelper filterPainter(filterRenderer() && paintsWithFilte
rs()); | 1043 FilterEffectRendererHelper filterPainter(filterRenderer() && paintsWithFilte
rs()); |
| 1044 | 1044 |
| 1045 // FIXME(sky): There's only one fragment. Get rid of the vector. | |
| 1046 LayerFragments layerFragments; | 1045 LayerFragments layerFragments; |
| 1047 LayerFragment fragment; | 1046 // Collect the fragments. This will compute the clip rectangles and paint of
fsets for each layer fragment, as well as whether or not the content of each |
| 1048 ClipRectsContext clipRectsContext(localPaintingInfo.rootLayer, PaintingClipR
ects, localPaintingInfo.subPixelAccumulation); | 1047 // fragment should paint. |
| 1049 clipper().calculateRects(clipRectsContext, localPaintingInfo.paintDirtyRect, | 1048 collectFragments(layerFragments, localPaintingInfo.rootLayer, localPaintingI
nfo.paintDirtyRect, |
| 1050 fragment.layerBounds, fragment.backgroundRect, fragment.foregroundRect,
fragment.outlineRect, | 1049 PaintingClipRects, &offsetFromRoot, localPaintingInfo.subPixelAccumulati
on); |
| 1051 &offsetFromRoot); | |
| 1052 layerFragments.append(fragment); | |
| 1053 | 1050 |
| 1054 bool isPaintingOverlayScrollbars = paintFlags == PaintOverlayScrollbars; | 1051 bool isPaintingOverlayScrollbars = paintFlags == PaintOverlayScrollbars; |
| 1055 bool shouldPaintContent = isSelfPaintingLayer() && !isPaintingOverlayScrollb
ars; | 1052 bool shouldPaintContent = isSelfPaintingLayer() && !isPaintingOverlayScrollb
ars; |
| 1056 updatePaintingInfoForFragments(layerFragments, localPaintingInfo, shouldPain
tContent, &offsetFromRoot); | 1053 updatePaintingInfoForFragments(layerFragments, localPaintingInfo, shouldPain
tContent, &offsetFromRoot); |
| 1057 | 1054 |
| 1058 bool haveTransparency = isTransparent(); | 1055 bool haveTransparency = isTransparent(); |
| 1059 | 1056 |
| 1060 if (filterPainter.haveFilterEffect()) { | 1057 if (filterPainter.haveFilterEffect()) { |
| 1061 ASSERT(this->filterInfo()); | 1058 ASSERT(this->filterInfo()); |
| 1062 | 1059 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1073 // filter processing. | 1070 // filter processing. |
| 1074 // FIXME: when the legacy path is removed, remove the transparencyLa
yerContext as well. | 1071 // FIXME: when the legacy path is removed, remove the transparencyLa
yerContext as well. |
| 1075 if (deferredFiltersEnabled) { | 1072 if (deferredFiltersEnabled) { |
| 1076 if (haveTransparency) { | 1073 if (haveTransparency) { |
| 1077 // If we have a filter and transparency, we have to eagerly
start a transparency layer here, rather than risk a child layer lazily starts on
e after filter processing. | 1074 // If we have a filter and transparency, we have to eagerly
start a transparency layer here, rather than risk a child layer lazily starts on
e after filter processing. |
| 1078 beginTransparencyLayers(context, localPaintingInfo.rootLayer
, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation); | 1075 beginTransparencyLayers(context, localPaintingInfo.rootLayer
, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation); |
| 1079 } | 1076 } |
| 1080 // We'll handle clipping to the dirty rect before filter rasteri
zation. | 1077 // We'll handle clipping to the dirty rect before filter rasteri
zation. |
| 1081 // Filter processing will automatically expand the clip rect and
the offscreen to accommodate any filter outsets. | 1078 // Filter processing will automatically expand the clip rect and
the offscreen to accommodate any filter outsets. |
| 1082 // FIXME: It is incorrect to just clip to the damageRect here on
ce multiple fragments are involved. | 1079 // FIXME: It is incorrect to just clip to the damageRect here on
ce multiple fragments are involved. |
| 1083 ClipRect backgroundRect = fragment.backgroundRect; | 1080 ClipRect backgroundRect = layerFragments.isEmpty() ? ClipRect()
: layerFragments[0].backgroundRect; |
| 1084 clipToRect(localPaintingInfo, context, backgroundRect); | 1081 clipToRect(localPaintingInfo, context, backgroundRect); |
| 1085 // Subsequent code should not clip to the dirty rect, since we'v
e already | 1082 // Subsequent code should not clip to the dirty rect, since we'v
e already |
| 1086 // done it above, and doing it later will defeat the outsets. | 1083 // done it above, and doing it later will defeat the outsets. |
| 1087 localPaintingInfo.clipToDirtyRect = false; | 1084 localPaintingInfo.clipToDirtyRect = false; |
| 1088 } | 1085 } |
| 1089 context = filterPainter.beginFilterEffect(context); | 1086 context = filterPainter.beginFilterEffect(context); |
| 1090 | 1087 |
| 1091 // Check that we didn't fail to allocate the graphics context for th
e offscreen buffer. | 1088 // Check that we didn't fail to allocate the graphics context for th
e offscreen buffer. |
| 1092 if (filterPainter.hasStartedFilterEffect() && !deferredFiltersEnable
d) { | 1089 if (filterPainter.hasStartedFilterEffect() && !deferredFiltersEnable
d) { |
| 1093 localPaintingInfo.paintDirtyRect = filterPainter.paintInvalidati
onRect(); | 1090 localPaintingInfo.paintDirtyRect = filterPainter.paintInvalidati
onRect(); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1126 | 1123 |
| 1127 paintOutlineForFragments(layerFragments, context, localPaintingInfo, paintin
gRootForRenderer); | 1124 paintOutlineForFragments(layerFragments, context, localPaintingInfo, paintin
gRootForRenderer); |
| 1128 paintChildren(NormalFlowChildren | PositiveZOrderChildren, context, painting
Info, paintFlags); | 1125 paintChildren(NormalFlowChildren | PositiveZOrderChildren, context, painting
Info, paintFlags); |
| 1129 | 1126 |
| 1130 if (isPaintingOverlayScrollbars) | 1127 if (isPaintingOverlayScrollbars) |
| 1131 paintOverflowControlsForFragments(layerFragments, context, localPainting
Info); | 1128 paintOverflowControlsForFragments(layerFragments, context, localPainting
Info); |
| 1132 | 1129 |
| 1133 if (filterPainter.hasStartedFilterEffect()) { | 1130 if (filterPainter.hasStartedFilterEffect()) { |
| 1134 // Apply the correct clipping (ie. overflow: hidden). | 1131 // Apply the correct clipping (ie. overflow: hidden). |
| 1135 // FIXME: It is incorrect to just clip to the damageRect here once multi
ple fragments are involved. | 1132 // FIXME: It is incorrect to just clip to the damageRect here once multi
ple fragments are involved. |
| 1136 ClipRect backgroundRect = fragment.backgroundRect; | 1133 ClipRect backgroundRect = layerFragments.isEmpty() ? ClipRect() : layerF
ragments[0].backgroundRect; |
| 1137 if (!deferredFiltersEnabled) | 1134 if (!deferredFiltersEnabled) |
| 1138 clipToRect(localPaintingInfo, transparencyLayerContext, backgroundRe
ct); | 1135 clipToRect(localPaintingInfo, transparencyLayerContext, backgroundRe
ct); |
| 1139 | 1136 |
| 1140 context = filterPainter.applyFilterEffect(); | 1137 context = filterPainter.applyFilterEffect(); |
| 1141 restoreClip(transparencyLayerContext, localPaintingInfo.paintDirtyRect,
backgroundRect); | 1138 restoreClip(transparencyLayerContext, localPaintingInfo.paintDirtyRect,
backgroundRect); |
| 1142 } | 1139 } |
| 1143 | 1140 |
| 1144 // Make sure that we now use the original transparency context. | 1141 // Make sure that we now use the original transparency context. |
| 1145 ASSERT(transparencyLayerContext == context); | 1142 ASSERT(transparencyLayerContext == context); |
| 1146 | 1143 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1188 #if ENABLE(ASSERT) | 1185 #if ENABLE(ASSERT) |
| 1189 LayerListMutationDetector mutationChecker(m_stackingNode.get()); | 1186 LayerListMutationDetector mutationChecker(m_stackingNode.get()); |
| 1190 #endif | 1187 #endif |
| 1191 | 1188 |
| 1192 RenderLayerStackingNodeIterator iterator(*m_stackingNode, childrenToVisit); | 1189 RenderLayerStackingNodeIterator iterator(*m_stackingNode, childrenToVisit); |
| 1193 while (RenderLayerStackingNode* child = iterator.next()) { | 1190 while (RenderLayerStackingNode* child = iterator.next()) { |
| 1194 child->layer()->paintLayer(context, paintingInfo, paintFlags); | 1191 child->layer()->paintLayer(context, paintingInfo, paintFlags); |
| 1195 } | 1192 } |
| 1196 } | 1193 } |
| 1197 | 1194 |
| 1195 void RenderLayer::collectFragments(LayerFragments& fragments, const RenderLayer*
rootLayer, const LayoutRect& dirtyRect, |
| 1196 ClipRectsCacheSlot clipRectsCacheSlot, const LayoutPoint* offsetFromRoot, |
| 1197 const LayoutSize& subPixelAccumulation, const LayoutRect* layerBoundingBox) |
| 1198 { |
| 1199 // For unpaginated layers, there is only one fragment. |
| 1200 LayerFragment fragment; |
| 1201 ClipRectsContext clipRectsContext(rootLayer, clipRectsCacheSlot, subPixelAcc
umulation); |
| 1202 clipper().calculateRects(clipRectsContext, dirtyRect, fragment.layerBounds,
fragment.backgroundRect, fragment.foregroundRect, fragment.outlineRect, offsetFr
omRoot); |
| 1203 fragments.append(fragment); |
| 1204 } |
| 1205 |
| 1198 void RenderLayer::updatePaintingInfoForFragments(LayerFragments& fragments, cons
t LayerPaintingInfo& localPaintingInfo, | 1206 void RenderLayer::updatePaintingInfoForFragments(LayerFragments& fragments, cons
t LayerPaintingInfo& localPaintingInfo, |
| 1199 bool shouldPaintContent, const LayoutPoint* offsetFromRoot) | 1207 bool shouldPaintContent, const LayoutPoint* offsetFromRoot) |
| 1200 { | 1208 { |
| 1201 ASSERT(offsetFromRoot); | 1209 ASSERT(offsetFromRoot); |
| 1202 for (size_t i = 0; i < fragments.size(); ++i) { | 1210 for (size_t i = 0; i < fragments.size(); ++i) { |
| 1203 LayerFragment& fragment = fragments.at(i); | 1211 LayerFragment& fragment = fragments.at(i); |
| 1204 LayoutPoint newOffsetFromRoot = *offsetFromRoot; | 1212 LayoutPoint newOffsetFromRoot = *offsetFromRoot; |
| 1205 fragment.shouldPaintContent = shouldPaintContent && intersectsDamageRect
(fragment.layerBounds, fragment.backgroundRect.rect(), localPaintingInfo.rootLay
er, &newOffsetFromRoot); | 1213 fragment.shouldPaintContent = shouldPaintContent && intersectsDamageRect
(fragment.layerBounds, fragment.backgroundRect.rect(), localPaintingInfo.rootLay
er, &newOffsetFromRoot); |
| 1206 } | 1214 } |
| 1207 } | 1215 } |
| (...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1556 | 1564 |
| 1557 // Now check our overflow objects. | 1565 // Now check our overflow objects. |
| 1558 hitLayer = hitTestChildren(NormalFlowChildren, rootLayer, request, result, h
itTestRect, hitTestLocation, | 1566 hitLayer = hitTestChildren(NormalFlowChildren, rootLayer, request, result, h
itTestRect, hitTestLocation, |
| 1559 localTransformState.get(), zOffsetForDescendantsPtr,
zOffset, unflattenedTransformState.get(), depthSortDescendants); | 1567 localTransformState.get(), zOffsetForDescendantsPtr,
zOffset, unflattenedTransformState.get(), depthSortDescendants); |
| 1560 if (hitLayer) { | 1568 if (hitLayer) { |
| 1561 if (!depthSortDescendants) | 1569 if (!depthSortDescendants) |
| 1562 return hitLayer; | 1570 return hitLayer; |
| 1563 candidateLayer = hitLayer; | 1571 candidateLayer = hitLayer; |
| 1564 } | 1572 } |
| 1565 | 1573 |
| 1566 LayoutRect layerBounds; | 1574 // Collect the fragments. This will compute the clip rectangles for each lay
er fragment. |
| 1567 ClipRect backgroundRect, foregroundRect, outlineRect; | 1575 LayerFragments layerFragments; |
| 1568 ClipRectsContext clipRectsContext(rootLayer, RootRelativeClipRects); | 1576 collectFragments(layerFragments, rootLayer, hitTestRect, RootRelativeClipRec
ts); |
| 1569 clipper().calculateRects(clipRectsContext, hitTestRect, layerBounds, backgro
undRect, foregroundRect, outlineRect); | |
| 1570 | 1577 |
| 1571 // Next we want to see if the mouse pos is inside the child RenderObjects of
the layer. | 1578 // Next we want to see if the mouse pos is inside the child RenderObjects of
the layer. Check |
| 1572 if (isSelfPaintingLayer() && !foregroundRect.intersects(hitTestLocation)) { | 1579 // every fragment in reverse order. |
| 1580 if (isSelfPaintingLayer()) { |
| 1573 // Hit test with a temporary HitTestResult, because we only want to comm
it to 'result' if we know we're frontmost. | 1581 // Hit test with a temporary HitTestResult, because we only want to comm
it to 'result' if we know we're frontmost. |
| 1574 HitTestResult tempResult(result.hitTestLocation()); | 1582 HitTestResult tempResult(result.hitTestLocation()); |
| 1575 if (hitTestContents(request, tempResult, layerBounds, hitTestLocation, H
itTestDescendants) | 1583 bool insideFragmentForegroundRect = false; |
| 1584 if (hitTestContentsForFragments(layerFragments, request, tempResult, hit
TestLocation, HitTestDescendants, insideFragmentForegroundRect) |
| 1576 && isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTra
nsformState.get())) { | 1585 && isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTra
nsformState.get())) { |
| 1577 if (result.isRectBasedTest()) | 1586 if (result.isRectBasedTest()) |
| 1578 result.append(tempResult); | 1587 result.append(tempResult); |
| 1579 else | 1588 else |
| 1580 result = tempResult; | 1589 result = tempResult; |
| 1581 if (!depthSortDescendants) | 1590 if (!depthSortDescendants) |
| 1582 return this; | 1591 return this; |
| 1583 // Foreground can depth-sort with descendant layers, so keep this as
a candidate. | 1592 // Foreground can depth-sort with descendant layers, so keep this as
a candidate. |
| 1584 candidateLayer = this; | 1593 candidateLayer = this; |
| 1585 } else if (result.isRectBasedTest()) { | 1594 } else if (insideFragmentForegroundRect && result.isRectBasedTest()) |
| 1586 result.append(tempResult); | 1595 result.append(tempResult); |
| 1587 } | |
| 1588 } | 1596 } |
| 1589 | 1597 |
| 1590 // Now check our negative z-index children. | 1598 // Now check our negative z-index children. |
| 1591 hitLayer = hitTestChildren(NegativeZOrderChildren, rootLayer, request, resul
t, hitTestRect, hitTestLocation, | 1599 hitLayer = hitTestChildren(NegativeZOrderChildren, rootLayer, request, resul
t, hitTestRect, hitTestLocation, |
| 1592 localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattene
dTransformState.get(), depthSortDescendants); | 1600 localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattene
dTransformState.get(), depthSortDescendants); |
| 1593 if (hitLayer) { | 1601 if (hitLayer) { |
| 1594 if (!depthSortDescendants) | 1602 if (!depthSortDescendants) |
| 1595 return hitLayer; | 1603 return hitLayer; |
| 1596 candidateLayer = hitLayer; | 1604 candidateLayer = hitLayer; |
| 1597 } | 1605 } |
| 1598 | 1606 |
| 1599 // If we found a layer, return. Child layers, and foreground always render i
n front of background. | 1607 // If we found a layer, return. Child layers, and foreground always render i
n front of background. |
| 1600 if (candidateLayer) | 1608 if (candidateLayer) |
| 1601 return candidateLayer; | 1609 return candidateLayer; |
| 1602 | 1610 |
| 1603 if (isSelfPaintingLayer() && !backgroundRect.intersects(hitTestLocation)) { | 1611 if (isSelfPaintingLayer()) { |
| 1604 HitTestResult tempResult(result.hitTestLocation()); | 1612 HitTestResult tempResult(result.hitTestLocation()); |
| 1605 if (hitTestContents(request, tempResult, layerBounds, hitTestLocation, H
itTestSelf) | 1613 bool insideFragmentBackgroundRect = false; |
| 1614 if (hitTestContentsForFragments(layerFragments, request, tempResult, hit
TestLocation, HitTestSelf, insideFragmentBackgroundRect) |
| 1606 && isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTra
nsformState.get())) { | 1615 && isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTra
nsformState.get())) { |
| 1607 if (result.isRectBasedTest()) | 1616 if (result.isRectBasedTest()) |
| 1608 result.append(tempResult); | 1617 result.append(tempResult); |
| 1609 else | 1618 else |
| 1610 result = tempResult; | 1619 result = tempResult; |
| 1611 return this; | 1620 return this; |
| 1612 } | 1621 } |
| 1613 if (result.isRectBasedTest()) | 1622 if (insideFragmentBackgroundRect && result.isRectBasedTest()) |
| 1614 result.append(tempResult); | 1623 result.append(tempResult); |
| 1615 } | 1624 } |
| 1616 | 1625 |
| 1617 return 0; | 1626 return 0; |
| 1618 } | 1627 } |
| 1619 | 1628 |
| 1629 bool RenderLayer::hitTestContentsForFragments(const LayerFragments& layerFragmen
ts, const HitTestRequest& request, HitTestResult& result, |
| 1630 const HitTestLocation& hitTestLocation, HitTestFilter hitTestFilter, bool& i
nsideClipRect) const |
| 1631 { |
| 1632 if (layerFragments.isEmpty()) |
| 1633 return false; |
| 1634 |
| 1635 for (int i = layerFragments.size() - 1; i >= 0; --i) { |
| 1636 const LayerFragment& fragment = layerFragments.at(i); |
| 1637 if ((hitTestFilter == HitTestSelf && !fragment.backgroundRect.intersects
(hitTestLocation)) |
| 1638 || (hitTestFilter == HitTestDescendants && !fragment.foregroundRect.
intersects(hitTestLocation))) |
| 1639 continue; |
| 1640 insideClipRect = true; |
| 1641 if (hitTestContents(request, result, fragment.layerBounds, hitTestLocati
on, hitTestFilter)) |
| 1642 return true; |
| 1643 } |
| 1644 |
| 1645 return false; |
| 1646 } |
| 1647 |
| 1620 RenderLayer* RenderLayer::hitTestLayerByApplyingTransform(RenderLayer* rootLayer
, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& res
ult, | 1648 RenderLayer* RenderLayer::hitTestLayerByApplyingTransform(RenderLayer* rootLayer
, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& res
ult, |
| 1621 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, const
HitTestingTransformState* transformState, double* zOffset, | 1649 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, const
HitTestingTransformState* transformState, double* zOffset, |
| 1622 const LayoutPoint& translationOffset) | 1650 const LayoutPoint& translationOffset) |
| 1623 { | 1651 { |
| 1624 // Create a transform state to accumulate this transform. | 1652 // Create a transform state to accumulate this transform. |
| 1625 RefPtr<HitTestingTransformState> newTransformState = createLocalTransformSta
te(rootLayer, containerLayer, hitTestRect, hitTestLocation, transformState, tran
slationOffset); | 1653 RefPtr<HitTestingTransformState> newTransformState = createLocalTransformSta
te(rootLayer, containerLayer, hitTestRect, hitTestLocation, transformState, tran
slationOffset); |
| 1626 | 1654 |
| 1627 // If the transform can't be inverted, then don't hit test this layer at all
. | 1655 // If the transform can't be inverted, then don't hit test this layer at all
. |
| 1628 if (!newTransformState->m_accumulatedTransform.isInvertible()) | 1656 if (!newTransformState->m_accumulatedTransform.isInvertible()) |
| 1629 return 0; | 1657 return 0; |
| (...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2116 } | 2144 } |
| 2117 } | 2145 } |
| 2118 | 2146 |
| 2119 void showLayerTree(const blink::RenderObject* renderer) | 2147 void showLayerTree(const blink::RenderObject* renderer) |
| 2120 { | 2148 { |
| 2121 if (!renderer) | 2149 if (!renderer) |
| 2122 return; | 2150 return; |
| 2123 showLayerTree(renderer->enclosingLayer()); | 2151 showLayerTree(renderer->enclosingLayer()); |
| 2124 } | 2152 } |
| 2125 #endif | 2153 #endif |
| OLD | NEW |