Changeset 109851 in webkit
- Timestamp:
- Mar 5, 2012 9:13:00 PM (12 years ago)
- Location:
- trunk
- Files:
-
- 4 added
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r109846 r109851 1 2012-03-05 Adrienne Walker <enne@google.com> 2 3 Compositing overlap testing can throw layers into compositing when they should not be. 4 https://bugs.webkit.org/show_bug.cgi?id=50192 5 6 Reviewed by Simon Fraser. 7 8 * compositing/layer-creation/stacking-context-overlap-expected.txt: Added. 9 * compositing/layer-creation/stacking-context-overlap.html: Added. 10 * compositing/layer-creation/stacking-context-overlap-nested-expected.txt: Added. 11 * compositing/layer-creation/stacking-context-overlap-nested.html: Added. 12 * platform/chromium/test_expectations.txt: 13 1 14 2012-03-05 Yoshifumi Inoue <yosin@chromium.org> 2 15 -
trunk/LayoutTests/platform/chromium/test_expectations.txt
r109828 r109851 3410 3410 BUGWK75161 GPU : media/video-poster-blocked-by-willsendrequest.html = PASS TEXT 3411 3411 BUGWK75161 CPU : media/video-poster-blocked-by-willsendrequest.html = TEXT 3412 3413 BUGWK75237 SNOWLEOPARD CPU : compositing/reflections/reflection-on-composited.html = PASS IMAGE3414 3412 3415 3413 BUGWK75367 : svg/css/composite-shadow-example.html = PASS TEXT … … 4313 4311 // New test; landed at r109779 but results look wrong on most Chrome platforms. 4314 4312 BUGSENORBLANCO : http/tests/incremental/partial-jpeg.html = FAIL 4313 4314 // Needs rebaselining. Layers are merged, and rotated text drawn better. 4315 BUGWK50192 : compositing/geometry/limit-layer-bounds-fixed-positioned.html = TEXT 4316 BUGWK50192 : compositing/geometry/limit-layer-bounds-overflow-root.html = TEXT 4317 BUGWK50192 : compositing/geometry/limit-layer-bounds-positioned-transition.html = TEXT 4318 BUGWK50192 : compositing/geometry/limit-layer-bounds-positioned.html = TEXT 4319 BUGWK50192 WIN LINUX : compositing/geometry/limit-layer-bounds-transformed-overflow.html = TEXT 4320 BUGWK50192 MAC LEOPARD : compositing/geometry/limit-layer-bounds-transformed-overflow.html = TEXT 4321 BUGWK50192 : compositing/geometry/limit-layer-bounds-transformed.html = TEXT 4322 BUGWK50192 : compositing/geometry/fixed-position-transform-composited-page-scale-down.html = IMAGE 4323 BUGWK50192 LINUX MAC : compositing/geometry/fixed-position-transform-composited-page-scale.html = IMAGE 4324 BUGWK50192 : compositing/reflections/reflection-on-composited.html = IMAGE 4325 BUGWK50192 : compositing/shadows/shadow-drawing.html = IMAGE 4326 BUGWK50192 : fast/repaint/block-selection-gap-in-composited-layer.html = IMAGE -
trunk/Source/WebCore/ChangeLog
r109847 r109851 1 2012-03-05 Adrienne Walker <enne@google.com> 2 3 Compositing overlap testing can throw layers into compositing when they should not be. 4 https://bugs.webkit.org/show_bug.cgi?id=50192 5 6 Reviewed by Simon Fraser. 7 8 The previous overlap map behavior was that a non-composited query 9 layer would become composited due to overlap if and only if the query 10 layer's absolute bounds overlapped the absolute bounds of some other 11 layer which: 12 - draws before the query layer 13 - is or has a compositing ancestor 14 15 This behavior, while correct, was too permissive in throwing layers 16 into compositing, causing many layers to get their own backing when 17 they could have just gone into their compositing ancestor's backing. 18 19 The correct logic is that non-composited query layer needs to be 20 composited due to overlap if and only if the query layer's absolute 21 bounds overlap the absolute bounds of some other layer which: 22 - draws before the query layer 23 - has a different compositing ancestor than the query layer 24 - is or has a compositing ancestor that is a descendent of the 25 query layer's compositing ancestor 26 27 This patch changes the semantics of the overlap map to enable this 28 behavior. 29 30 Rather than having one global overlap map, there is now a stack of 31 overlap maps. New (empty) overlap maps are pushed onto the stack 32 whenever a layer becomes a compositing ancestor and popped after all 33 of the compositing requirements for that layer's children have been 34 computed. 35 36 The compositing ancestor and all of its non-composited children of a 37 compositing ancestor do not get considered for overlap until their 38 composited ancestor has been popped off the stack. If a compositing 39 ancestor has a compositing subtree, then any descendents of that 40 compositing ancestor that draw after that subtree will consider 41 everything in the compositing subtree for overlap. 42 43 Test: compositing/layer-creation/stacking-context-overlap.html 44 45 * platform/graphics/Region.cpp: 46 (WebCore::Region::intersects): 47 (WebCore): 48 * platform/graphics/Region.h: 49 (Region): 50 * rendering/RenderLayerCompositor.cpp: 51 (RenderLayerCompositor::OverlapMap): 52 (WebCore::RenderLayerCompositor::OverlapMap::OverlapMap): 53 (WebCore::RenderLayerCompositor::OverlapMap::add): 54 (WebCore::RenderLayerCompositor::OverlapMap::contains): 55 (WebCore::RenderLayerCompositor::OverlapMap::overlapsLayers): 56 (WebCore::RenderLayerCompositor::OverlapMap::isEmpty): 57 (WebCore::RenderLayerCompositor::OverlapMap::popCompositingContainer): 58 (WebCore::RenderLayerCompositor::OverlapMap::pushCompositingContainer): 59 (WebCore::RenderLayerCompositor::addToOverlapMapRecursive): 60 (WebCore::RenderLayerCompositor::computeCompositingRequirements): 61 * rendering/RenderLayerCompositor.h: 62 (RenderLayerCompositor): 63 1 64 2012-03-05 Anders Carlsson <andersca@apple.com> 2 65 -
trunk/Source/WebCore/platform/graphics/Region.cpp
r109273 r109851 78 78 } 79 79 80 bool Region::intersects(const Region& region) const 81 { 82 if (!m_bounds.intersects(region.m_bounds)) 83 return false; 84 85 // FIXME: this could be optimized. 86 Region tempRegion(*this); 87 tempRegion.intersect(region); 88 return !tempRegion.isEmpty(); 89 } 90 80 91 unsigned Region::totalArea() const 81 92 { -
trunk/Source/WebCore/platform/graphics/Region.h
r109273 r109851 52 52 53 53 bool contains(const IntPoint&) const; 54 55 // Returns true if the query region intersects any part of this region. 56 bool intersects(const Region&) const; 54 57 55 58 unsigned totalArea() const; -
trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp
r109788 r109851 76 76 using namespace HTMLNames; 77 77 78 class RenderLayerCompositor::OverlapMap { 79 WTF_MAKE_NONCOPYABLE(OverlapMap); 80 public: 81 OverlapMap() 82 { 83 // Begin assuming the root layer will be composited so that there is 84 // something on the stack. The root layer should also never get an 85 // popCompositingContainer call. 86 pushCompositingContainer(); 87 } 88 89 void add(const RenderLayer* layer, const IntRect& bounds) 90 { 91 // Layers do not contribute to overlap immediately--instead, they will 92 // contribute to overlap as soon as their composited ancestor has been 93 // recursively processed and popped off the stack. 94 ASSERT(m_overlapStack.size() >= 2); 95 m_overlapStack[m_overlapStack.size() - 2].unite(bounds); 96 m_layers.add(layer); 97 } 98 99 bool contains(const RenderLayer* layer) 100 { 101 return m_layers.contains(layer); 102 } 103 104 bool overlapsLayers(const IntRect& bounds) const 105 { 106 return m_overlapStack.last().intersects(bounds); 107 } 108 109 bool isEmpty() 110 { 111 return m_layers.isEmpty(); 112 } 113 114 void pushCompositingContainer() 115 { 116 m_overlapStack.append(Region()); 117 } 118 119 void popCompositingContainer() 120 { 121 m_overlapStack[m_overlapStack.size() - 2].unite(m_overlapStack.last()); 122 m_overlapStack.removeLast(); 123 } 124 125 private: 126 Vector<Region> m_overlapStack; 127 HashSet<const RenderLayer*> m_layers; 128 }; 129 78 130 struct CompositingState { 79 131 CompositingState(RenderLayer* compAncestor) … … 638 690 } 639 691 640 bool RenderLayerCompositor::overlapsCompositedLayers(OverlapMap& overlapMap, const IntRect& layerBounds)641 {642 RenderLayerCompositor::OverlapMap::const_iterator end = overlapMap.end();643 for (RenderLayerCompositor::OverlapMap::const_iterator it = overlapMap.begin(); it != end; ++it) {644 const IntRect& bounds = it->second;645 if (layerBounds.intersects(bounds))646 return true;647 }648 649 return false;650 }651 652 692 // Recurse through the layers in z-index and overflow order (which is equivalent to painting order) 653 693 // For the z-order children of a compositing layer: … … 679 719 absBounds.setSize(IntSize(1, 1)); 680 720 haveComputedBounds = true; 681 mustOverlapCompositedLayers = overlap sCompositedLayers(*overlapMap,absBounds);721 mustOverlapCompositedLayers = overlapMap->overlapsLayers(absBounds); 682 722 } 683 723 … … 689 729 CompositingState childState(compositingState.m_compositingAncestor); 690 730 #ifndef NDEBUG 691 ++childState.m_depth;731 childState.m_depth = compositingState.m_depth + 1; 692 732 #endif 693 733 … … 698 738 // This layer now acts as the ancestor for kids. 699 739 childState.m_compositingAncestor = layer; 700 } 701 702 if (overlapMap && childState.m_compositingAncestor && !childState.m_compositingAncestor->isRootLayer()) { 703 addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds); 740 741 if (overlapMap) 742 overlapMap->pushCompositingContainer(); 704 743 } 705 744 … … 727 766 childState.m_compositingAncestor = layer; 728 767 if (overlapMap) 729 addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds);768 overlapMap->pushCompositingContainer(); 730 769 willBeComposited = true; 731 770 } … … 761 800 ASSERT(willBeComposited == needsToBeComposited(layer)); 762 801 802 // All layers (even ones that aren't being composited) need to get added to 803 // the overlap map. Layers that do not composite will draw into their 804 // compositing ancestor's backing, and so are still considered for overlap. 805 if (overlapMap && childState.m_compositingAncestor && !childState.m_compositingAncestor->isRootLayer()) 806 addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds); 807 763 808 // If we have a software transform, and we have layers under us, we need to also 764 809 // be composited. Also, if we have opacity < 1, then we need to be a layer so that … … 766 811 if (!willBeComposited && canBeComposited(layer) && childState.m_subtreeIsCompositing && requiresCompositingWhenDescendantsAreCompositing(layer->renderer())) { 767 812 layer->setMustOverlapCompositedLayers(true); 768 if (overlapMap) 813 childState.m_compositingAncestor = layer; 814 if (overlapMap) { 815 overlapMap->pushCompositingContainer(); 769 816 addToOverlapMapRecursive(*overlapMap, layer); 817 } 770 818 willBeComposited = true; 771 819 } … … 785 833 // so test that again. 786 834 if (!willBeComposited && canBeComposited(layer) && clipsCompositingDescendants(layer)) { 787 if (overlapMap) 835 childState.m_compositingAncestor = layer; 836 if (overlapMap) { 837 overlapMap->pushCompositingContainer(); 788 838 addToOverlapMapRecursive(*overlapMap, layer); 839 } 789 840 willBeComposited = true; 790 841 } 842 843 if (overlapMap && childState.m_compositingAncestor == layer && !layer->isRootLayer()) 844 overlapMap->popCompositingContainer(); 791 845 792 846 // If we're back at the root, and no other layers need to be composited, and the root layer itself doesn't need -
trunk/Source/WebCore/rendering/RenderLayerCompositor.h
r108140 r109851 211 211 212 212 private: 213 class OverlapMap; 214 213 215 // GraphicsLayerClient Implementation 214 216 virtual void notifyAnimationStarted(const GraphicsLayer*, double) { } … … 234 236 void recursiveRepaintLayerRect(RenderLayer*, const IntRect&); 235 237 236 typedef HashMap<RenderLayer*, IntRect> OverlapMap;237 238 void addToOverlapMap(OverlapMap&, RenderLayer*, IntRect& layerBounds, bool& boundsComputed); 238 239 void addToOverlapMapRecursive(OverlapMap&, RenderLayer*); 239 static bool overlapsCompositedLayers(OverlapMap&, const IntRect& layerBounds);240 240 241 241 void updateCompositingLayersTimerFired(Timer<RenderLayerCompositor>*);
Note: See TracChangeset
for help on using the changeset viewer.