| Differences between
and this patch
- a/Source/WebCore/ChangeLog +45 lines
Lines 1-3 a/Source/WebCore/ChangeLog_sec1
1
2022-04-19  Simon Fraser  <simon.fraser@apple.com>
2
3
        REGRESSION (r281913): Map toolbar flickers when dragging the map on https://gis.ee/
4
        https://bugs.webkit.org/show_bug.cgi?id=238589
5
        <rdar://90483049>
6
7
        Reviewed by NOBODY (OOPS!).
8
        
9
        If a layer has negative z-order descendants, and one of those descendants becomes
10
        composited, then that layer also has to composite, because its foreground needs to render in
11
        front of those descendants. But this is tricky, because the compositing toggle is
12
        out-of-order; we only know that the layer has to get composited after processing
13
        descendants.
14
15
        In particular, this created a problem with the overlap map, which tracks sets of rectangles
16
        in "compositing scopes" via LayerOverlapMap. The delayed compositing toggle of the layer
17
        with negative z-order descendants meant that any layers processed up to that point had their
18
        bounds added in the wrong overlap scope. This resulted in subsequent bad overlap testing,
19
        and a failure to make later layers composited.
20
21
        The previous fix in this area (r281913) was incorrect. Revert it, and do a better fix, which
22
        is to speculatively push an overlap map entry for the layer with negative z-order
23
        descendants, if necessary. If this layer ends up not getting composited, we unwind the
24
        speculative push, which will merge that scope with its parent scope.
25
26
        In addition give OverlapMapContainer (an "overlap scope") a RenderLayer& which we can use
27
        for logging, and to assert on correct behavior; it is not otherwise used in release builds.
28
29
        Tests: compositing/layer-creation/overlap-with-negative-z-layers.html
30
               compositing/layer-creation/subtree-div-overlaps-multiple-negative-z-divs.html
31
32
        * rendering/LayerOverlapMap.cpp:
33
        (WebCore::OverlapMapContainer::OverlapMapContainer):
34
        (WebCore::OverlapMapContainer::scopeLayer const):
35
        (WebCore::OverlapMapContainer::dump const):
36
        (WebCore::LayerOverlapMap::LayerOverlapMap):
37
        (WebCore::LayerOverlapMap::add):
38
        (WebCore::LayerOverlapMap::pushCompositingContainer):
39
        (WebCore::LayerOverlapMap::popCompositingContainer):
40
        * rendering/LayerOverlapMap.h:
41
        * rendering/RenderLayerCompositor.cpp:
42
        (WebCore::RenderLayerCompositor::computeCompositingRequirements):
43
        (WebCore::RenderLayerCompositor::traverseUnchangedSubtree):
44
        (WebCore::RenderLayerCompositor::updateOverlapMap const):
45
1
2022-04-18  Matt Woodrow  <mattwoodrow@apple.com>
46
2022-04-18  Matt Woodrow  <mattwoodrow@apple.com>
2
47
3
        Implement support for aligning baselines through subgrids
48
        Implement support for aligning baselines through subgrids
- a/Source/WebCore/rendering/LayerOverlapMap.cpp -8 / +17 lines
Lines 25-30 a/Source/WebCore/rendering/LayerOverlapMap.cpp_sec1
25
25
26
#include "config.h"
26
#include "config.h"
27
#include "LayerOverlapMap.h"
27
#include "LayerOverlapMap.h"
28
#include "Logging.h"
28
#include "RenderLayer.h"
29
#include "RenderLayer.h"
29
#include <wtf/text/TextStream.h>
30
#include <wtf/text/TextStream.h>
30
31
Lines 73-80 static TextStream& operator<<(TextStream& ts, const RectList& rectList) a/Source/WebCore/rendering/LayerOverlapMap.cpp_sec2
73
class OverlapMapContainer {
74
class OverlapMapContainer {
74
    WTF_MAKE_FAST_ALLOCATED;
75
    WTF_MAKE_FAST_ALLOCATED;
75
public:
76
public:
76
    OverlapMapContainer(const RenderLayer& rootLayer)
77
    OverlapMapContainer(const RenderLayer& rootLayer, const RenderLayer& scopeLayer)
77
        : m_rootScope(rootLayer)
78
        : m_rootScope(rootLayer)
79
        , m_scopeLayer(scopeLayer)
78
    {
80
    {
79
    }
81
    }
80
82
Lines 84-89 public: a/Source/WebCore/rendering/LayerOverlapMap.cpp_sec3
84
    void append(std::unique_ptr<OverlapMapContainer>&&);
86
    void append(std::unique_ptr<OverlapMapContainer>&&);
85
    
87
    
86
    String dump(unsigned) const;
88
    String dump(unsigned) const;
89
    
90
    const RenderLayer& scopeLayer() const { return m_scopeLayer; }
87
91
88
private:
92
private:
89
    struct ClippingScope {
93
    struct ClippingScope {
Lines 160-165 private: a/Source/WebCore/rendering/LayerOverlapMap.cpp_sec4
160
    ClippingScope& rootScope() { return m_rootScope; }
164
    ClippingScope& rootScope() { return m_rootScope; }
161
165
162
    ClippingScope m_rootScope;
166
    ClippingScope m_rootScope;
167
    const RenderLayer& m_scopeLayer;
163
};
168
};
164
169
165
void OverlapMapContainer::add(const RenderLayer&, const LayoutRect& bounds, const Vector<LayerOverlapMap::LayerAndBounds>& enclosingClippingLayers)
170
void OverlapMapContainer::add(const RenderLayer&, const LayoutRect& bounds, const Vector<LayerOverlapMap::LayerAndBounds>& enclosingClippingLayers)
Lines 258-264 String OverlapMapContainer::dump(unsigned indent) const a/Source/WebCore/rendering/LayerOverlapMap.cpp_sec5
258
{
263
{
259
    TextStream multilineStream;
264
    TextStream multilineStream;
260
    multilineStream.increaseIndent(indent);
265
    multilineStream.increaseIndent(indent);
261
    multilineStream << "overlap container - root scope layer " <<  &m_rootScope.layer << " rects " << m_rootScope.rectList;
266
    multilineStream << "overlap container - root layer " <<  &m_rootScope.layer << " scope layer " << &m_scopeLayer << " rects " << m_rootScope.rectList;
262
267
263
    for (auto& childScope : m_rootScope.children)
268
    for (auto& childScope : m_rootScope.children)
264
        recursiveOutputToStream(multilineStream, childScope, 1);
269
        recursiveOutputToStream(multilineStream, childScope, 1);
Lines 273-279 LayerOverlapMap::LayerOverlapMap(const RenderLayer& rootLayer) a/Source/WebCore/rendering/LayerOverlapMap.cpp_sec6
273
    // Begin assuming the root layer will be composited so that there is
278
    // Begin assuming the root layer will be composited so that there is
274
    // something on the stack. The root layer should also never get an
279
    // something on the stack. The root layer should also never get an
275
    // popCompositingContainer call.
280
    // popCompositingContainer call.
276
    pushCompositingContainer();
281
    pushCompositingContainer(rootLayer);
277
}
282
}
278
283
279
LayerOverlapMap::~LayerOverlapMap() = default;
284
LayerOverlapMap::~LayerOverlapMap() = default;
Lines 284-291 void LayerOverlapMap::add(const RenderLayer& layer, const LayoutRect& bounds, co a/Source/WebCore/rendering/LayerOverlapMap.cpp_sec7
284
    // contribute to overlap as soon as their composited ancestor has been
289
    // contribute to overlap as soon as their composited ancestor has been
285
    // recursively processed and popped off the stack.
290
    // recursively processed and popped off the stack.
286
    ASSERT(m_overlapStack.size() >= 2);
291
    ASSERT(m_overlapStack.size() >= 2);
287
    m_overlapStack[m_overlapStack.size() - 2]->add(layer, bounds, enclosingClippingLayers);
292
    auto& container = m_overlapStack[m_overlapStack.size() - 2];
288
    
293
    container->add(layer, bounds, enclosingClippingLayers);
294
295
    LOG_WITH_STREAM(CompositingOverlap, stream << "layer " << &layer << " contributes to overlap in the scope of layer " << &container->scopeLayer() << ", added to map " << *this);
296
289
    m_isEmpty = false;
297
    m_isEmpty = false;
290
}
298
}
291
299
Lines 294-306 bool LayerOverlapMap::overlapsLayers(const RenderLayer& layer, const LayoutRect& a/Source/WebCore/rendering/LayerOverlapMap.cpp_sec8
294
    return m_overlapStack.last()->overlapsLayers(layer, bounds, enclosingClippingLayers);
302
    return m_overlapStack.last()->overlapsLayers(layer, bounds, enclosingClippingLayers);
295
}
303
}
296
304
297
void LayerOverlapMap::pushCompositingContainer()
305
void LayerOverlapMap::pushCompositingContainer(const RenderLayer& layer)
298
{
306
{
299
    m_overlapStack.append(makeUnique<OverlapMapContainer>(m_rootLayer));
307
    m_overlapStack.append(makeUnique<OverlapMapContainer>(m_rootLayer, layer));
300
}
308
}
301
309
302
void LayerOverlapMap::popCompositingContainer()
310
void LayerOverlapMap::popCompositingContainer(const RenderLayer& layer)
303
{
311
{
312
    ASSERT_UNUSED(layer, &m_overlapStack.last()->scopeLayer() == &layer);
304
    m_overlapStack[m_overlapStack.size() - 2]->append(WTFMove(m_overlapStack.last()));
313
    m_overlapStack[m_overlapStack.size() - 2]->append(WTFMove(m_overlapStack.last()));
305
    m_overlapStack.removeLast();
314
    m_overlapStack.removeLast();
306
}
315
}
- a/Source/WebCore/rendering/LayerOverlapMap.h -2 / +2 lines
Lines 53-60 public: a/Source/WebCore/rendering/LayerOverlapMap.h_sec1
53
    bool overlapsLayers(const RenderLayer&, const LayoutRect&, const Vector<LayerAndBounds>& enclosingClippingLayers) const;
53
    bool overlapsLayers(const RenderLayer&, const LayoutRect&, const Vector<LayerAndBounds>& enclosingClippingLayers) const;
54
    bool isEmpty() const { return m_isEmpty; }
54
    bool isEmpty() const { return m_isEmpty; }
55
55
56
    void pushCompositingContainer();
56
    void pushCompositingContainer(const RenderLayer&);
57
    void popCompositingContainer();
57
    void popCompositingContainer(const RenderLayer&);
58
58
59
    const RenderGeometryMap& geometryMap() const { return m_geometryMap; }
59
    const RenderGeometryMap& geometryMap() const { return m_geometryMap; }
60
    RenderGeometryMap& geometryMap() { return m_geometryMap; }
60
    RenderGeometryMap& geometryMap() { return m_geometryMap; }
- a/Source/WebCore/rendering/RenderLayerCompositor.cpp -21 / +36 lines
Lines 1061-1069 void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor a/Source/WebCore/rendering/RenderLayerCompositor.cpp_sec1
1061
            layer.setIndirectCompositingReason(IndirectCompositingReason::Overlap);
1061
            layer.setIndirectCompositingReason(IndirectCompositingReason::Overlap);
1062
            LOG_WITH_STREAM(Compositing, stream << "layer " << &layer << " was sharing now will composite");
1062
            LOG_WITH_STREAM(Compositing, stream << "layer " << &layer << " was sharing now will composite");
1063
        } else {
1063
        } else {
1064
            overlapMap.pushCompositingContainer();
1064
            if (!didPushOverlapContainer) {
1065
            didPushOverlapContainer = true;
1065
                overlapMap.pushCompositingContainer(layer);
1066
            LOG_WITH_STREAM(CompositingOverlap, stream << "layer " << &layer << " will composite, pushed container " << overlapMap);
1066
                didPushOverlapContainer = true;
1067
                LOG_WITH_STREAM(CompositingOverlap, stream << "layer " << &layer << " will composite, pushed container " << overlapMap);
1068
            }
1067
        }
1069
        }
1068
1070
1069
        willBeComposited = true;
1071
        willBeComposited = true;
Lines 1084-1090 void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor a/Source/WebCore/rendering/RenderLayerCompositor.cpp_sec2
1084
        layerExtent.animationCausesExtentUncertainty |= layerExtent.hasTransformAnimation && compositingState.ancestorHasTransformAnimation;
1086
        layerExtent.animationCausesExtentUncertainty |= layerExtent.hasTransformAnimation && compositingState.ancestorHasTransformAnimation;
1085
    } else if (layerPaintsIntoProvidedBacking) {
1087
    } else if (layerPaintsIntoProvidedBacking) {
1086
        currentState.backingSharingAncestor = &layer;
1088
        currentState.backingSharingAncestor = &layer;
1087
        overlapMap.pushCompositingContainer();
1089
        overlapMap.pushCompositingContainer(layer);
1088
        didPushOverlapContainer = true;
1090
        didPushOverlapContainer = true;
1089
        LOG_WITH_STREAM(CompositingOverlap, stream << "layer " << &layer << " will share, pushed container " << overlapMap);
1091
        LOG_WITH_STREAM(CompositingOverlap, stream << "layer " << &layer << " will share, pushed container " << overlapMap);
1090
    }
1092
    }
Lines 1098-1115 void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor a/Source/WebCore/rendering/RenderLayerCompositor.cpp_sec3
1098
    bool anyDescendantHas3DTransform = false;
1100
    bool anyDescendantHas3DTransform = false;
1099
    bool descendantsAddedToOverlap = currentState.hasNonRootCompositedAncestor();
1101
    bool descendantsAddedToOverlap = currentState.hasNonRootCompositedAncestor();
1100
1102
1101
    unsigned newlyCompositedChildLayerCount = 0;
1103
    if (layer.hasNegativeZOrderLayers()) {
1102
    for (auto* childLayer : layer.negativeZOrderLayers()) {
1104
        // Speculatively push this layer onto the overlap map.
1103
        computeCompositingRequirements(&layer, *childLayer, overlapMap, currentState, backingSharingState, anyDescendantHas3DTransform);
1105
        bool didSpeculativelyPushOverlapContainer = false;
1106
        if (!didPushOverlapContainer) {
1107
            overlapMap.pushCompositingContainer(layer);
1108
            didPushOverlapContainer = true;
1109
            didSpeculativelyPushOverlapContainer = true;
1110
        }
1104
1111
1105
        // If we have to make a layer for this child, make one now so we can have a contents layer
1112
        bool compositeForNegativeZOrderDescendant = false;
1106
        // (since we need to ensure that the -ve z-order child renders underneath our contents).
1113
        
1107
        if (!willBeComposited && currentState.subtreeIsCompositing)
1114
        for (auto* childLayer : layer.negativeZOrderLayers()) {
1108
            ++newlyCompositedChildLayerCount;
1115
            computeCompositingRequirements(&layer, *childLayer, overlapMap, currentState, backingSharingState, anyDescendantHas3DTransform);
1109
    }
1116
1110
    while (newlyCompositedChildLayerCount--) {
1117
            // If we have to make a layer for this child, make one now so we can have a contents layer
1111
        layer.setIndirectCompositingReason(IndirectCompositingReason::BackgroundLayer);
1118
            // (since we need to ensure that the -ve z-order child renders underneath our contents).
1112
        layerWillComposite();
1119
            if (!willBeComposited && currentState.subtreeIsCompositing) {
1120
                layer.setIndirectCompositingReason(IndirectCompositingReason::BackgroundLayer);
1121
                layerWillComposite();
1122
                compositeForNegativeZOrderDescendant = true;
1123
            }
1124
        }
1125
1126
        if (!compositeForNegativeZOrderDescendant && didSpeculativelyPushOverlapContainer) {
1127
            overlapMap.popCompositingContainer(layer);
1128
            didPushOverlapContainer = false;
1129
        }
1113
    }
1130
    }
1114
1131
1115
    for (auto* childLayer : layer.normalFlowLayers())
1132
    for (auto* childLayer : layer.normalFlowLayers())
Lines 1246-1252 void RenderLayerCompositor::traverseUnchangedSubtree(RenderLayer* ancestorLayer, a/Source/WebCore/rendering/RenderLayerCompositor.cpp_sec4
1246
        // This layer now acts as the ancestor for kids.
1263
        // This layer now acts as the ancestor for kids.
1247
        currentState.compositingAncestor = &layer;
1264
        currentState.compositingAncestor = &layer;
1248
        currentState.backingSharingAncestor = nullptr;
1265
        currentState.backingSharingAncestor = nullptr;
1249
        overlapMap.pushCompositingContainer();
1266
        overlapMap.pushCompositingContainer(layer);
1250
        didPushOverlapContainer = true;
1267
        didPushOverlapContainer = true;
1251
        LOG_WITH_STREAM(CompositingOverlap, stream << "unchangedSubtree: layer " << &layer << " will composite, pushed container " << overlapMap);
1268
        LOG_WITH_STREAM(CompositingOverlap, stream << "unchangedSubtree: layer " << &layer << " will composite, pushed container " << overlapMap);
1252
1269
Lines 1255-1261 void RenderLayerCompositor::traverseUnchangedSubtree(RenderLayer* ancestorLayer, a/Source/WebCore/rendering/RenderLayerCompositor.cpp_sec5
1255
        // Too hard to compute animated bounds if both us and some ancestor is animating transform.
1272
        // Too hard to compute animated bounds if both us and some ancestor is animating transform.
1256
        layerExtent.animationCausesExtentUncertainty |= layerExtent.hasTransformAnimation && compositingState.ancestorHasTransformAnimation;
1273
        layerExtent.animationCausesExtentUncertainty |= layerExtent.hasTransformAnimation && compositingState.ancestorHasTransformAnimation;
1257
    } else if (layerPaintsIntoProvidedBacking) {
1274
    } else if (layerPaintsIntoProvidedBacking) {
1258
        overlapMap.pushCompositingContainer();
1275
        overlapMap.pushCompositingContainer(layer);
1259
        currentState.backingSharingAncestor = &layer;
1276
        currentState.backingSharingAncestor = &layer;
1260
        didPushOverlapContainer = true;
1277
        didPushOverlapContainer = true;
1261
        LOG_WITH_STREAM(CompositingOverlap, stream << "unchangedSubtree: layer " << &layer << " will share, pushed container " << overlapMap);
1278
        LOG_WITH_STREAM(CompositingOverlap, stream << "unchangedSubtree: layer " << &layer << " will share, pushed container " << overlapMap);
Lines 2141-2150 void RenderLayerCompositor::addDescendantsToOverlapMapRecursive(LayerOverlapMap& a/Source/WebCore/rendering/RenderLayerCompositor.cpp_sec6
2141
2158
2142
void RenderLayerCompositor::updateOverlapMap(LayerOverlapMap& overlapMap, const RenderLayer& layer, OverlapExtent& layerExtent, bool didPushContainer, bool addLayerToOverlap, bool addDescendantsToOverlap) const
2159
void RenderLayerCompositor::updateOverlapMap(LayerOverlapMap& overlapMap, const RenderLayer& layer, OverlapExtent& layerExtent, bool didPushContainer, bool addLayerToOverlap, bool addDescendantsToOverlap) const
2143
{
2160
{
2144
    if (addLayerToOverlap) {
2161
    if (addLayerToOverlap)
2145
        addToOverlapMap(overlapMap, layer, layerExtent);
2162
        addToOverlapMap(overlapMap, layer, layerExtent);
2146
        LOG_WITH_STREAM(CompositingOverlap, stream << "layer " << &layer << " contributes to overlap, added to map " << overlapMap);
2147
    }
2148
2163
2149
    if (addDescendantsToOverlap) {
2164
    if (addDescendantsToOverlap) {
2150
        // If this is the first non-root layer to composite, we need to add all the descendants we already traversed to the overlap map.
2165
        // If this is the first non-root layer to composite, we need to add all the descendants we already traversed to the overlap map.
Lines 2153-2159 void RenderLayerCompositor::updateOverlapMap(LayerOverlapMap& overlapMap, const a/Source/WebCore/rendering/RenderLayerCompositor.cpp_sec7
2153
    }
2168
    }
2154
2169
2155
    if (didPushContainer) {
2170
    if (didPushContainer) {
2156
        overlapMap.popCompositingContainer();
2171
        overlapMap.popCompositingContainer(layer);
2157
        LOG_WITH_STREAM(CompositingOverlap, stream << "layer " << &layer << " is composited or shared, popped container " << overlapMap);
2172
        LOG_WITH_STREAM(CompositingOverlap, stream << "layer " << &layer << " is composited or shared, popped container " << overlapMap);
2158
    }
2173
    }
2159
}
2174
}
- a/LayoutTests/ChangeLog +16 lines
Lines 1-3 a/LayoutTests/ChangeLog_sec1
1
2022-04-19  Simon Fraser  <simon.fraser@apple.com>
2
3
        REGRESSION (r281913): Map toolbar flickers when dragging the map on https://gis.ee/
4
        https://bugs.webkit.org/show_bug.cgi?id=238589
5
        <rdar://90483049>
6
7
        Reviewed by NOBODY (OOPS!).
8
9
        Move subtree-div-overlaps-multiple-negative-z-divs.html into the layer-creation directory.
10
        Add a new test.
11
12
        * compositing/layer-creation/overlap-with-negative-z-layers-expected.html: Added.
13
        * compositing/layer-creation/overlap-with-negative-z-layers.html: Added.
14
        * compositing/layer-creation/subtree-div-overlaps-multiple-negative-z-divs-expected.html: Renamed from LayoutTests/compositing/subtree-div-overlaps-multiple-negative-z-divs-expected.html.
15
        * compositing/layer-creation/subtree-div-overlaps-multiple-negative-z-divs.html: Renamed from LayoutTests/compositing/subtree-div-overlaps-multiple-negative-z-divs.html.
16
1
2022-04-18  Tim Nguyen  <ntim@apple.com>
17
2022-04-18  Tim Nguyen  <ntim@apple.com>
2
18
3
        [iOS] Skip CSS resize tests added by r292559
19
        [iOS] Skip CSS resize tests added by r292559
- a/LayoutTests/compositing/layer-creation/overlap-with-negative-z-layers-expected.html +49 lines
Line 0 a/LayoutTests/compositing/layer-creation/overlap-with-negative-z-layers-expected.html_sec1
1
<!DOCTYPE html>
2
<html>
3
<head>
4
    <style>
5
        .wrapper {
6
            position: absolute;
7
            height: 400px;
8
            width: 400px;
9
            border: 1px solid black;
10
            z-index: 0;
11
        }
12
        
13
        .container {
14
            position: absolute;
15
            left: 0;
16
            top: 0;
17
            z-index: 0;
18
        }
19
20
        .tile {
21
            position: absolute;
22
            width: 200px;
23
            height: 200px;
24
            left: 100px;
25
            top: 100px;
26
            background-color: orange;
27
        }
28
29
        .green {
30
            position: relative;
31
            width: 200px;
32
            height: 200px;
33
            margin: 10px;
34
            background-color: green;
35
        }
36
    </style>
37
</head>
38
<body>
39
    <p>The green box should be on top.</p>
40
    <div class="wrapper">
41
        <div class="container" style="transform: translate3d(0px, 0px, 0px);">
42
            <div class="container">
43
                <div class="tile"></div>
44
            </div>
45
        </div>
46
        <div class="green"></div>
47
    </div>
48
</body>
49
</html>
- a/LayoutTests/compositing/layer-creation/overlap-with-negative-z-layers.html +61 lines
Line 0 a/LayoutTests/compositing/layer-creation/overlap-with-negative-z-layers.html_sec1
1
<!DOCTYPE html>
2
<html>
3
<head>
4
    <style>
5
        .wrapper {
6
            position: absolute;
7
            height: 400px;
8
            width: 400px;
9
            border: 1px solid black;
10
            z-index: 0;
11
        }
12
        
13
        .container {
14
            position: absolute;
15
            left: 0;
16
            top: 0;
17
            z-index: 0;
18
        }
19
20
        .negative {
21
            position: absolute;
22
            width: 20px;
23
            height: 20px;
24
            background-color: darkred;
25
        }
26
27
        .tile {
28
            position: absolute;
29
            width: 200px;
30
            height: 200px;
31
            left: 100px;
32
            top: 100px;
33
            background-color: orange;
34
        }
35
36
        .green {
37
            position: relative;
38
            width: 200px;
39
            height: 200px;
40
            margin: 10px;
41
            background-color: green;
42
        }
43
    </style>
44
</head>
45
<body>
46
    <p>The green box should be on top.</p>
47
    <div class="wrapper">
48
        <div class="container" style="transform: translate3d(0px, 0px, 0px);">
49
            <div class="container">
50
                <div class="tile"></div>
51
            </div>
52
            <div class="container">
53
                <div class="negative" style="transform: translate3d(50px, 50px, 0px); z-index: -3;"></div>
54
                <div class="negative" style="transform: translate3d(50px, 100px, 0px); z-index: -2;"></div>
55
                <div class="negative" style="transform: translate3d(50px, 150px, 0px); z-index: -1;"></div>
56
            </div>
57
        </div>
58
        <div class="green"></div>
59
    </div>
60
</body>
61
</html>
- a/LayoutTests/compositing/layer-creation/subtree-div-overlaps-multiple-negative-z-divs-expected.html +2 lines
Line 0 a/LayoutTests/compositing/layer-creation/subtree-div-overlaps-multiple-negative-z-divs-expected.html_sec1
1
<!DOCTYPE html>
2
<div style="background:green;width:100px;height:100px"></div>
- a/LayoutTests/compositing/layer-creation/subtree-div-overlaps-multiple-negative-z-divs.html +27 lines
Line 0 a/LayoutTests/compositing/layer-creation/subtree-div-overlaps-multiple-negative-z-divs.html_sec1
1
<!DOCTYPE html>
2
<style>
3
.negative {
4
  z-index: -1;
5
}
6
.abs {
7
  position: absolute;
8
}
9
.green {
10
  width: 100px;
11
  height: 100px;
12
  background-color: green;
13
}
14
15
.red {
16
  width: 100px;
17
  height: 100px;
18
  background-color: red;
19
  will-change: transform;
20
}
21
</style>
22
<body>
23
<div class="negative abs">
24
  <div class="red"></div>
25
</div>
26
<div class="negative abs green"></div>
27
</body>
- a/LayoutTests/compositing/subtree-div-overlaps-multiple-negative-z-divs-expected.html -2 lines
Lines 1-2 a/LayoutTests/compositing/subtree-div-overlaps-multiple-negative-z-divs-expected.html_sec1
1
<!DOCTYPE html>
2
<div style="background:green;width:100px;height:100px"></div>
- a/LayoutTests/compositing/subtree-div-overlaps-multiple-negative-z-divs.html -27 lines
Lines 1-27 a/LayoutTests/compositing/subtree-div-overlaps-multiple-negative-z-divs.html_sec1
1
<!DOCTYPE html>
2
<style>
3
.negative {
4
  z-index: -1;
5
}
6
.abs {
7
  position: absolute;
8
}
9
.green {
10
  width: 100px;
11
  height: 100px;
12
  background-color: green;
13
}
14
15
.red {
16
  width: 100px;
17
  height: 100px;
18
  background-color: red;
19
  will-change: transform;
20
}
21
</style>
22
<body>
23
<div class="negative abs">
24
  <div class="red"></div>
25
</div>
26
<div class="negative abs green"></div>
27
</body>

Return to Bug 238589