| Index: sky/engine/core/rendering/RenderLayer.cpp
|
| diff --git a/sky/engine/core/rendering/RenderLayer.cpp b/sky/engine/core/rendering/RenderLayer.cpp
|
| index d56b04193cd2215c2bd3b5f0636fc371e2a3b65e..b1a279d10edd26170b0803e9f3e855fbd7b9a0c6 100644
|
| --- a/sky/engine/core/rendering/RenderLayer.cpp
|
| +++ b/sky/engine/core/rendering/RenderLayer.cpp
|
| @@ -1042,14 +1042,11 @@
|
| bool deferredFiltersEnabled = renderer()->document().settings()->deferredFiltersEnabled();
|
| FilterEffectRendererHelper filterPainter(filterRenderer() && paintsWithFilters());
|
|
|
| - // FIXME(sky): There's only one fragment. Get rid of the vector.
|
| LayerFragments layerFragments;
|
| - LayerFragment fragment;
|
| - ClipRectsContext clipRectsContext(localPaintingInfo.rootLayer, PaintingClipRects, localPaintingInfo.subPixelAccumulation);
|
| - clipper().calculateRects(clipRectsContext, localPaintingInfo.paintDirtyRect,
|
| - fragment.layerBounds, fragment.backgroundRect, fragment.foregroundRect, fragment.outlineRect,
|
| - &offsetFromRoot);
|
| - layerFragments.append(fragment);
|
| + // Collect the fragments. This will compute the clip rectangles and paint offsets for each layer fragment, as well as whether or not the content of each
|
| + // fragment should paint.
|
| + collectFragments(layerFragments, localPaintingInfo.rootLayer, localPaintingInfo.paintDirtyRect,
|
| + PaintingClipRects, &offsetFromRoot, localPaintingInfo.subPixelAccumulation);
|
|
|
| bool isPaintingOverlayScrollbars = paintFlags == PaintOverlayScrollbars;
|
| bool shouldPaintContent = isSelfPaintingLayer() && !isPaintingOverlayScrollbars;
|
| @@ -1080,7 +1077,7 @@
|
| // We'll handle clipping to the dirty rect before filter rasterization.
|
| // Filter processing will automatically expand the clip rect and the offscreen to accommodate any filter outsets.
|
| // FIXME: It is incorrect to just clip to the damageRect here once multiple fragments are involved.
|
| - ClipRect backgroundRect = fragment.backgroundRect;
|
| + ClipRect backgroundRect = layerFragments.isEmpty() ? ClipRect() : layerFragments[0].backgroundRect;
|
| clipToRect(localPaintingInfo, context, backgroundRect);
|
| // Subsequent code should not clip to the dirty rect, since we've already
|
| // done it above, and doing it later will defeat the outsets.
|
| @@ -1133,7 +1130,7 @@
|
| if (filterPainter.hasStartedFilterEffect()) {
|
| // Apply the correct clipping (ie. overflow: hidden).
|
| // FIXME: It is incorrect to just clip to the damageRect here once multiple fragments are involved.
|
| - ClipRect backgroundRect = fragment.backgroundRect;
|
| + ClipRect backgroundRect = layerFragments.isEmpty() ? ClipRect() : layerFragments[0].backgroundRect;
|
| if (!deferredFiltersEnabled)
|
| clipToRect(localPaintingInfo, transparencyLayerContext, backgroundRect);
|
|
|
| @@ -1193,6 +1190,17 @@
|
| while (RenderLayerStackingNode* child = iterator.next()) {
|
| child->layer()->paintLayer(context, paintingInfo, paintFlags);
|
| }
|
| +}
|
| +
|
| +void RenderLayer::collectFragments(LayerFragments& fragments, const RenderLayer* rootLayer, const LayoutRect& dirtyRect,
|
| + ClipRectsCacheSlot clipRectsCacheSlot, const LayoutPoint* offsetFromRoot,
|
| + const LayoutSize& subPixelAccumulation, const LayoutRect* layerBoundingBox)
|
| +{
|
| + // For unpaginated layers, there is only one fragment.
|
| + LayerFragment fragment;
|
| + ClipRectsContext clipRectsContext(rootLayer, clipRectsCacheSlot, subPixelAccumulation);
|
| + clipper().calculateRects(clipRectsContext, dirtyRect, fragment.layerBounds, fragment.backgroundRect, fragment.foregroundRect, fragment.outlineRect, offsetFromRoot);
|
| + fragments.append(fragment);
|
| }
|
|
|
| void RenderLayer::updatePaintingInfoForFragments(LayerFragments& fragments, const LayerPaintingInfo& localPaintingInfo,
|
| @@ -1563,16 +1571,17 @@
|
| candidateLayer = hitLayer;
|
| }
|
|
|
| - LayoutRect layerBounds;
|
| - ClipRect backgroundRect, foregroundRect, outlineRect;
|
| - ClipRectsContext clipRectsContext(rootLayer, RootRelativeClipRects);
|
| - clipper().calculateRects(clipRectsContext, hitTestRect, layerBounds, backgroundRect, foregroundRect, outlineRect);
|
| -
|
| - // Next we want to see if the mouse pos is inside the child RenderObjects of the layer.
|
| - if (isSelfPaintingLayer() && !foregroundRect.intersects(hitTestLocation)) {
|
| + // Collect the fragments. This will compute the clip rectangles for each layer fragment.
|
| + LayerFragments layerFragments;
|
| + collectFragments(layerFragments, rootLayer, hitTestRect, RootRelativeClipRects);
|
| +
|
| + // Next we want to see if the mouse pos is inside the child RenderObjects of the layer. Check
|
| + // every fragment in reverse order.
|
| + if (isSelfPaintingLayer()) {
|
| // Hit test with a temporary HitTestResult, because we only want to commit to 'result' if we know we're frontmost.
|
| HitTestResult tempResult(result.hitTestLocation());
|
| - if (hitTestContents(request, tempResult, layerBounds, hitTestLocation, HitTestDescendants)
|
| + bool insideFragmentForegroundRect = false;
|
| + if (hitTestContentsForFragments(layerFragments, request, tempResult, hitTestLocation, HitTestDescendants, insideFragmentForegroundRect)
|
| && isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTransformState.get())) {
|
| if (result.isRectBasedTest())
|
| result.append(tempResult);
|
| @@ -1582,9 +1591,8 @@
|
| return this;
|
| // Foreground can depth-sort with descendant layers, so keep this as a candidate.
|
| candidateLayer = this;
|
| - } else if (result.isRectBasedTest()) {
|
| + } else if (insideFragmentForegroundRect && result.isRectBasedTest())
|
| result.append(tempResult);
|
| - }
|
| }
|
|
|
| // Now check our negative z-index children.
|
| @@ -1600,9 +1608,10 @@
|
| if (candidateLayer)
|
| return candidateLayer;
|
|
|
| - if (isSelfPaintingLayer() && !backgroundRect.intersects(hitTestLocation)) {
|
| + if (isSelfPaintingLayer()) {
|
| HitTestResult tempResult(result.hitTestLocation());
|
| - if (hitTestContents(request, tempResult, layerBounds, hitTestLocation, HitTestSelf)
|
| + bool insideFragmentBackgroundRect = false;
|
| + if (hitTestContentsForFragments(layerFragments, request, tempResult, hitTestLocation, HitTestSelf, insideFragmentBackgroundRect)
|
| && isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTransformState.get())) {
|
| if (result.isRectBasedTest())
|
| result.append(tempResult);
|
| @@ -1610,11 +1619,30 @@
|
| result = tempResult;
|
| return this;
|
| }
|
| - if (result.isRectBasedTest())
|
| + if (insideFragmentBackgroundRect && result.isRectBasedTest())
|
| result.append(tempResult);
|
| }
|
|
|
| return 0;
|
| +}
|
| +
|
| +bool RenderLayer::hitTestContentsForFragments(const LayerFragments& layerFragments, const HitTestRequest& request, HitTestResult& result,
|
| + const HitTestLocation& hitTestLocation, HitTestFilter hitTestFilter, bool& insideClipRect) const
|
| +{
|
| + if (layerFragments.isEmpty())
|
| + return false;
|
| +
|
| + for (int i = layerFragments.size() - 1; i >= 0; --i) {
|
| + const LayerFragment& fragment = layerFragments.at(i);
|
| + if ((hitTestFilter == HitTestSelf && !fragment.backgroundRect.intersects(hitTestLocation))
|
| + || (hitTestFilter == HitTestDescendants && !fragment.foregroundRect.intersects(hitTestLocation)))
|
| + continue;
|
| + insideClipRect = true;
|
| + if (hitTestContents(request, result, fragment.layerBounds, hitTestLocation, hitTestFilter))
|
| + return true;
|
| + }
|
| +
|
| + return false;
|
| }
|
|
|
| RenderLayer* RenderLayer::hitTestLayerByApplyingTransform(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& result,
|
|
|