Changeset 183943 in webkit
- Timestamp:
- May 7, 2015, 1:45:42 PM (11 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 7 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/platform/mac-wk1/compositing/visible-rect (added)
-
LayoutTests/platform/mac-wk1/compositing/visible-rect/iframe-no-layers-expected.txt (added)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/page/FrameView.cpp (modified) (2 diffs)
-
Source/WebCore/page/FrameView.h (modified) (1 diff)
-
Source/WebCore/rendering/RenderLayerCompositor.cpp (modified) (34 diffs)
-
Source/WebCore/rendering/RenderLayerCompositor.h (modified) (2 diffs)
-
Source/WebCore/rendering/RenderWidget.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r183942 r183943 1 2015-05-07 Simon Fraser <simon.fraser@apple.com> 2 3 Remove the WK1-only code path for independently composited iframes 4 https://bugs.webkit.org/show_bug.cgi?id=144722 5 6 Reviewed by Dean Jackson. 7 8 Results different from WK2, because WK1 does not make layers for scrollbars. 9 10 * platform/mac-wk1/compositing/visible-rect/iframe-no-layers-expected.txt: Added. 11 1 12 2015-05-06 Dean Jackson <dino@apple.com> 2 13 -
trunk/Source/WebCore/ChangeLog
r183942 r183943 1 2015-05-07 Simon Fraser <simon.fraser@apple.com> 2 3 Remove the WK1-only code path for independently composited iframes 4 https://bugs.webkit.org/show_bug.cgi?id=144722 5 6 Reviewed by Dean Jackson. 7 8 In WebKit1 on Mac, we allowed iframes to be composited independently of their 9 parent document, relying on the fact that the frame's platform view can host 10 a layer-backed view. However, this ran into bugs (rdar://problem/18862298), 11 and triggers the assertion at the end of FrameView::updateLayoutAndStyleIfNeededRecursive(), 12 because the compositing update after a layout can dirty style in notifyIFramesOfCompositingChange(). 13 14 Removing the WK1-only code path solves these problems. It also eliminates the need 15 to do compositing-specific frame overlap testing. 16 17 * page/FrameView.cpp: 18 (WebCore::FrameView::setIsOverlapped): No need to do compositing-related things here. 19 Any iframe that gets composited will participate in the normal compositing overlap 20 testing in its parent frame. 21 (WebCore::FrameView::hasCompositedContentIncludingDescendants): Deleted. 22 (WebCore::FrameView::hasCompositingAncestor): Deleted. 23 * page/FrameView.h: 24 * rendering/RenderLayerCompositor.cpp: Replace ownerElement() checks in this file 25 with an isMainFrameCompositor() for readability. Some 0->nullptr. 26 (WebCore::RenderLayerCompositor::cacheAcceleratedCompositingFlags): 27 (WebCore::RenderLayerCompositor::chromeClient): 28 (WebCore::RenderLayerCompositor::enclosingCompositorFlushingLayers): 29 (WebCore::RenderLayerCompositor::updateCompositingLayers): 30 (WebCore::RenderLayerCompositor::appendDocumentOverlayLayers): 31 (WebCore::RenderLayerCompositor::updateBacking): 32 (WebCore::RenderLayerCompositor::layerTreeAsText): 33 (WebCore::RenderLayerCompositor::frameContentsCompositor): 34 (WebCore::RenderLayerCompositor::setIsInWindow): 35 (WebCore::RenderLayerCompositor::requiresCompositingForScrollableFrame): 36 (WebCore::RenderLayerCompositor::requiresCompositingForFrame): frameRenderer.requiresAcceleratedCompositing() 37 already bails on no content RenderView, so the shouldPropagateCompositingToEnclosingFrame() check does 38 nothing and is removed. 39 (WebCore::RenderLayerCompositor::isAsyncScrollableStickyLayer): 40 (WebCore::RenderLayerCompositor::requiresScrollLayer): 41 (WebCore::RenderLayerCompositor::documentUsesTiledBacking): 42 (WebCore::RenderLayerCompositor::isMainFrameCompositor): 43 (WebCore::RenderLayerCompositor::shouldCompositeOverflowControls): 44 (WebCore::RenderLayerCompositor::requiresOverhangAreasLayer): 45 (WebCore::RenderLayerCompositor::requiresContentShadowLayer): 46 (WebCore::RenderLayerCompositor::updateLayerForTopOverhangArea): 47 (WebCore::RenderLayerCompositor::updateLayerForBottomOverhangArea): 48 (WebCore::RenderLayerCompositor::updateLayerForHeader): 49 (WebCore::RenderLayerCompositor::updateLayerForFooter): 50 (WebCore::RenderLayerCompositor::ensureRootLayer): Main frame attaches via ChromeClient, 51 all other frames attach via parent frame. 52 (WebCore::RenderLayerCompositor::notifyIFramesOfCompositingChange): This call to 53 scheduleSetNeedsStyleRecalc(SyntheticStyleChange) was the source of dirtying style after 54 layout, but is no longer needed so remove it. 55 (WebCore::RenderLayerCompositor::registerAllViewportConstrainedLayers): 56 (WebCore::RenderLayerCompositor::unregisterAllViewportConstrainedLayers): 57 (WebCore::RenderLayerCompositor::scrollingCoordinator): 58 (WebCore::RenderLayerCompositor::graphicsLayerFactory): 59 (WebCore::RenderLayerCompositor::allowsIndependentlyCompositedFrames): Deleted. 60 (WebCore::RenderLayerCompositor::shouldPropagateCompositingToEnclosingFrame): Deleted. 61 (WebCore::RenderLayerCompositor::mainFrameBackingIsTiled): Deleted. This was mis-named; 62 it really asks whether the document uses tiled backing, but does not check for main frame. 63 * rendering/RenderLayerCompositor.h: 64 * rendering/RenderWidget.cpp: 65 (WebCore::RenderWidget::paintContents): No need to do frame overlap testing for 66 compositing now. 67 1 68 2015-05-06 Dean Jackson <dino@apple.com> 2 69 -
trunk/Source/WebCore/page/FrameView.cpp
r183891 r183943 1018 1018 } 1019 1019 1020 bool FrameView::hasCompositedContentIncludingDescendants() const1021 {1022 for (auto* frame = m_frame.ptr(); frame; frame = frame->tree().traverseNext(m_frame.ptr())) {1023 RenderView* renderView = frame->contentRenderer();1024 if (RenderLayerCompositor* compositor = renderView ? &renderView->compositor() : nullptr) {1025 if (compositor->inCompositingMode())1026 return true;1027 1028 if (!RenderLayerCompositor::allowsIndependentlyCompositedFrames(this))1029 break;1030 }1031 }1032 return false;1033 }1034 1035 bool FrameView::hasCompositingAncestor() const1036 {1037 for (Frame* frame = this->frame().tree().parent(); frame; frame = frame->tree().parent()) {1038 if (FrameView* view = frame->view()) {1039 if (view->hasCompositedContent())1040 return true;1041 }1042 }1043 return false;1044 }1045 1046 1020 // Sometimes (for plug-ins) we need to eagerly go into compositing mode. 1047 1021 void FrameView::enterCompositingMode() … … 1911 1885 m_isOverlapped = isOverlapped; 1912 1886 updateCanBlitOnScrollRecursively(); 1913 1914 if (hasCompositedContentIncludingDescendants()) {1915 // Overlap can affect compositing tests, so if it changes, we need to trigger1916 // a layer update in the parent document.1917 if (Frame* parentFrame = frame().tree().parent()) {1918 if (RenderView* parentView = parentFrame->contentRenderer()) {1919 RenderLayerCompositor& compositor = parentView->compositor();1920 compositor.setCompositingLayersNeedRebuild();1921 compositor.scheduleCompositingLayerUpdate();1922 }1923 }1924 1925 if (RenderLayerCompositor::allowsIndependentlyCompositedFrames(this)) {1926 // We also need to trigger reevaluation for this and all descendant frames,1927 // since a frame uses compositing if any ancestor is compositing.1928 for (auto* frame = m_frame.ptr(); frame; frame = frame->tree().traverseNext(m_frame.ptr())) {1929 if (RenderView* view = frame->contentRenderer()) {1930 RenderLayerCompositor& compositor = view->compositor();1931 compositor.setCompositingLayersNeedRebuild();1932 compositor.scheduleCompositingLayerUpdate();1933 }1934 }1935 }1936 }1937 1887 } 1938 1888 -
trunk/Source/WebCore/page/FrameView.h
r183891 r183943 171 171 172 172 bool hasCompositedContent() const; 173 bool hasCompositedContentIncludingDescendants() const;174 bool hasCompositingAncestor() const;175 173 WEBCORE_EXPORT void enterCompositingMode(); 176 174 WEBCORE_EXPORT bool isEnclosedInCompositingLayer() const; -
trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp
r183843 r183943 347 347 forceCompositingMode = settings.forceCompositingMode() && hasAcceleratedCompositing; 348 348 349 if (forceCompositingMode && m_renderView.document().ownerElement())349 if (forceCompositingMode && !isMainFrameCompositor()) 350 350 forceCompositingMode = requiresCompositingForScrollableFrame(); 351 351 … … 443 443 Page* page = m_renderView.frameView().frame().page(); 444 444 if (!page) 445 return 0;445 return nullptr; 446 446 return &page->chrome().client(); 447 447 } … … 644 644 } 645 645 646 return 0;646 return nullptr; 647 647 } 648 648 … … 760 760 761 761 Frame& frame = m_renderView.frameView().frame(); 762 bool isMainFrame = !m_renderView.document().ownerElement();762 bool isMainFrame = isMainFrameCompositor(); 763 763 LOG(Compositing, "\nUpdate %d of %s.\n", m_rootLayerUpdateCount, isMainFrame ? "main frame" : frame.tree().uniqueName().string().utf8().data()); 764 764 } … … 810 810 void RenderLayerCompositor::appendDocumentOverlayLayers(Vector<GraphicsLayer*>& childList) 811 811 { 812 if (!isMainFrameCompositor()) 813 return; 814 812 815 Frame& frame = m_renderView.frameView().frame(); 813 if (!frame.isMainFrame())814 return;815 816 816 Page* page = frame.page(); 817 817 if (!page) … … 999 999 1000 1000 // At this time, the ScrollingCoordinator only supports the top-level frame. 1001 if (layer.isRootLayer() && !m_renderView.document().ownerElement()) {1001 if (layer.isRootLayer() && isMainFrameCompositor()) { 1002 1002 updateScrollCoordinatedStatus(layer); 1003 1003 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) … … 1822 1822 // Dump an empty layer tree only if the only composited layer is the main frame's tiled backing, 1823 1823 // so that tests expecting us to drop out of accelerated compositing when there are no layers succeed. 1824 if (!hasAnyAdditionalCompositedLayers(rootRenderLayer()) && mainFrameBackingIsTiled() && !(layerTreeBehavior & LayerTreeAsTextIncludeTileCaches))1824 if (!hasAnyAdditionalCompositedLayers(rootRenderLayer()) && documentUsesTiledBacking() && !(layerTreeBehavior & LayerTreeAsTextIncludeTileCaches)) 1825 1825 layerTreeText = ""; 1826 1826 … … 1839 1839 return &view->compositor(); 1840 1840 } 1841 return 0;1841 return nullptr; 1842 1842 } 1843 1843 … … 2065 2065 return; 2066 2066 2067 RootLayerAttachment attachment = shouldPropagateCompositingToEnclosingFrame() ? RootLayerAttachedViaEnclosingFrame : RootLayerAttachedViaChromeClient;2067 RootLayerAttachment attachment = isMainFrameCompositor() ? RootLayerAttachedViaChromeClient : RootLayerAttachedViaEnclosingFrame; 2068 2068 attachRootLayer(attachment); 2069 2069 #if PLATFORM(IOS) … … 2128 2128 { 2129 2129 return layerHas3DContent(rootRenderLayer()); 2130 }2131 2132 bool RenderLayerCompositor::allowsIndependentlyCompositedFrames(const FrameView* view)2133 {2134 #if PLATFORM(MAC)2135 // frames are only independently composited in Mac pre-WebKit2.2136 return view->platformWidget();2137 #else2138 UNUSED_PARAM(view);2139 #endif2140 return false;2141 }2142 2143 bool RenderLayerCompositor::shouldPropagateCompositingToEnclosingFrame() const2144 {2145 // Parent document content needs to be able to render on top of a composited frame, so correct behavior2146 // is to have the parent document become composited too. However, this can cause problems on platforms that2147 // use native views for frames (like Mac), so disable that behavior on those platforms for now.2148 HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerElement();2149 2150 // If we are the top-level frame, don't propagate.2151 if (!ownerElement)2152 return false;2153 2154 if (!allowsIndependentlyCompositedFrames(&m_renderView.frameView()))2155 return true;2156 2157 RenderElement* renderer = ownerElement->renderer();2158 if (!is<RenderWidget>(renderer))2159 return false;2160 2161 // On Mac, only propagate compositing if the frame is overlapped in the parent2162 // document, or the parent is already compositing, or the main frame is scaled.2163 Page* page = this->page();2164 if (page && page->pageScaleFactor() != 1)2165 return true;2166 2167 RenderWidget& frameRenderer = downcast<RenderWidget>(*renderer);2168 if (frameRenderer.widget()) {2169 FrameView& view = downcast<FrameView>(*frameRenderer.widget());2170 if (view.isOverlappedIncludingAncestors() || view.hasCompositingAncestor())2171 return true;2172 }2173 2174 return false;2175 2130 } 2176 2131 … … 2498 2453 // Need this done first to determine overflow. 2499 2454 ASSERT(!m_renderView.needsLayout()); 2500 HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerElement(); 2501 if (!ownerElement) 2455 if (isMainFrameCompositor()) 2502 2456 return false; 2503 2457 … … 2598 2552 2599 2553 auto& frameRenderer = downcast<RenderWidget>(renderer); 2600 2601 2554 if (!frameRenderer.requiresAcceleratedCompositing()) 2602 2555 return false; 2603 2556 2604 2557 m_reevaluateCompositingAfterLayout = true; 2605 2606 RenderLayerCompositor* innerCompositor = frameContentsCompositor(&frameRenderer);2607 if (!innerCompositor || !innerCompositor->shouldPropagateCompositingToEnclosingFrame())2608 return false;2609 2558 2610 2559 // If we can't reliably know the size of the iframe yet, don't change compositing state. … … 2696 2645 #if PLATFORM(IOS) 2697 2646 // iOS WK1 has fixed/sticky support in the main frame via WebFixedPositionContent. 2698 return m_renderView.frameView().frame().isMainFrame();2647 return isMainFrameCompositor(); 2699 2648 #else 2700 2649 return false; … … 2840 2789 2841 2790 // This applies when the application UI handles scrolling, in which case RenderLayerCompositor doesn't need to manage it. 2842 if (frameView.delegatesScrolling() && frameView.frame().isMainFrame())2791 if (frameView.delegatesScrolling() && isMainFrameCompositor()) 2843 2792 return false; 2844 2793 … … 2980 2929 } 2981 2930 2982 bool RenderLayerCompositor:: mainFrameBackingIsTiled() const2931 bool RenderLayerCompositor::documentUsesTiledBacking() const 2983 2932 { 2984 2933 RenderLayer* layer = m_renderView.layer(); … … 2993 2942 } 2994 2943 2944 bool RenderLayerCompositor::isMainFrameCompositor() const 2945 { 2946 return m_renderView.frameView().frame().isMainFrame(); 2947 } 2948 2995 2949 bool RenderLayerCompositor::shouldCompositeOverflowControls() const 2996 2950 { … … 3003 2957 return false; 3004 2958 3005 if ( mainFrameBackingIsTiled())2959 if (documentUsesTiledBacking()) 3006 2960 return true; 3007 2961 … … 3030 2984 bool RenderLayerCompositor::requiresOverhangAreasLayer() const 3031 2985 { 3032 // We don't want a layer if this is a subframe. 3033 if (m_renderView.document().ownerElement()) 2986 if (!isMainFrameCompositor()) 3034 2987 return false; 3035 2988 3036 2989 // We do want a layer if we're using tiled drawing and can scroll. 3037 if ( mainFrameBackingIsTiled() && m_renderView.frameView().hasOpaqueBackground() && !m_renderView.frameView().prohibitsScrolling())2990 if (documentUsesTiledBacking() && m_renderView.frameView().hasOpaqueBackground() && !m_renderView.frameView().prohibitsScrolling()) 3038 2991 return true; 3039 2992 … … 3043 2996 bool RenderLayerCompositor::requiresContentShadowLayer() const 3044 2997 { 3045 // We don't want a layer if this is a subframe. 3046 if (m_renderView.document().ownerElement()) 2998 if (!isMainFrameCompositor()) 3047 2999 return false; 3048 3000 … … 3056 3008 3057 3009 // On Mac, we want a content shadow layer if we're using tiled drawing and can scroll. 3058 if ( mainFrameBackingIsTiled() && !m_renderView.frameView().prohibitsScrolling())3010 if (documentUsesTiledBacking() && !m_renderView.frameView().prohibitsScrolling()) 3059 3011 return true; 3060 3012 #endif … … 3065 3017 GraphicsLayer* RenderLayerCompositor::updateLayerForTopOverhangArea(bool wantsLayer) 3066 3018 { 3067 if ( m_renderView.document().ownerElement())3068 return 0;3019 if (!isMainFrameCompositor()) 3020 return nullptr; 3069 3021 3070 3022 if (!wantsLayer) { … … 3073 3025 m_layerForTopOverhangArea = nullptr; 3074 3026 } 3075 return 0;3027 return nullptr; 3076 3028 } 3077 3029 … … 3089 3041 GraphicsLayer* RenderLayerCompositor::updateLayerForBottomOverhangArea(bool wantsLayer) 3090 3042 { 3091 if ( m_renderView.document().ownerElement())3092 return 0;3043 if (!isMainFrameCompositor()) 3044 return nullptr; 3093 3045 3094 3046 if (!wantsLayer) { … … 3097 3049 m_layerForBottomOverhangArea = nullptr; 3098 3050 } 3099 return 0;3051 return nullptr; 3100 3052 } 3101 3053 … … 3115 3067 GraphicsLayer* RenderLayerCompositor::updateLayerForHeader(bool wantsLayer) 3116 3068 { 3117 if ( m_renderView.document().ownerElement())3118 return 0;3069 if (!isMainFrameCompositor()) 3070 return nullptr; 3119 3071 3120 3072 if (!wantsLayer) { … … 3128 3080 scrollingCoordinator->frameViewRootLayerDidChange(m_renderView.frameView()); 3129 3081 } 3130 return 0;3082 return nullptr; 3131 3083 } 3132 3084 … … 3156 3108 GraphicsLayer* RenderLayerCompositor::updateLayerForFooter(bool wantsLayer) 3157 3109 { 3158 if ( m_renderView.document().ownerElement())3159 return 0;3110 if (!isMainFrameCompositor()) 3111 return nullptr; 3160 3112 3161 3113 if (!wantsLayer) { … … 3169 3121 scrollingCoordinator->frameViewRootLayerDidChange(m_renderView.frameView()); 3170 3122 } 3171 return 0;3123 return nullptr; 3172 3124 } 3173 3125 … … 3372 3324 void RenderLayerCompositor::ensureRootLayer() 3373 3325 { 3374 RootLayerAttachment expectedAttachment = shouldPropagateCompositingToEnclosingFrame() ? RootLayerAttachedViaEnclosingFrame : RootLayerAttachedViaChromeClient;3326 RootLayerAttachment expectedAttachment = isMainFrameCompositor() ? RootLayerAttachedViaChromeClient : RootLayerAttachedViaEnclosingFrame; 3375 3327 if (expectedAttachment == m_rootLayerAttachment) 3376 3328 return; … … 3606 3558 } 3607 3559 3608 // IFrames are special, because we hook compositing layers together across iframe boundaries3609 // when both parent and iframe content are composited. So when this frame becomes composited, we have3610 // to use a synthetic style change to get the iframes into RenderLayers in order to allow them to composite.3611 3560 void RenderLayerCompositor::notifyIFramesOfCompositingChange() 3612 3561 { 3613 Frame& frame = m_renderView.frameView().frame(); 3614 for (Frame* child = frame.tree().firstChild(); child; child = child->tree().traverseNext(&frame)) { 3615 if (child->document() && child->document()->ownerElement()) 3616 child->document()->ownerElement()->scheduleSetNeedsStyleRecalc(SyntheticStyleChange); 3617 } 3618 3619 // Compositing also affects the answer to RenderIFrame::requiresAcceleratedCompositing(), so 3562 // Compositing affects the answer to RenderIFrame::requiresAcceleratedCompositing(), so 3620 3563 // we need to schedule a style recalc in our parent document. 3621 3564 if (HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerElement()) … … 3992 3935 { 3993 3936 // Only the main frame should register fixed/sticky layers. 3994 if ( m_renderView.document().ownerElement())3937 if (!isMainFrameCompositor()) 3995 3938 return; 3996 3939 … … 4027 3970 { 4028 3971 // Only the main frame should register fixed/sticky layers. 4029 if ( m_renderView.document().ownerElement())3972 if (!isMainFrameCompositor()) 4030 3973 return; 4031 3974 … … 4116 4059 return page->scrollingCoordinator(); 4117 4060 4118 return 0;4061 return nullptr; 4119 4062 } 4120 4063 … … 4124 4067 return page->chrome().client().graphicsLayerFactory(); 4125 4068 4126 return 0;4069 return nullptr; 4127 4070 } 4128 4071 -
trunk/Source/WebCore/rendering/RenderLayerCompositor.h
r183775 r183943 228 228 bool has3DContent() const; 229 229 230 // Most platforms connect compositing layer trees between iframes and their parent document.231 // Some (currently just Mac) allow iframes to do their own compositing.232 static bool allowsIndependentlyCompositedFrames(const FrameView*);233 bool shouldPropagateCompositingToEnclosingFrame() const;234 235 230 static RenderLayerCompositor* frameContentsCompositor(RenderWidget*); 236 231 // Return true if the layers changed. … … 477 472 #endif 478 473 479 bool mainFrameBackingIsTiled() const; 474 bool documentUsesTiledBacking() const; 475 bool isMainFrameCompositor() const; 480 476 481 477 private: -
trunk/Source/WebCore/rendering/RenderWidget.cpp
r183788 r183943 240 240 if (is<FrameView>(*m_widget)) { 241 241 FrameView& frameView = downcast<FrameView>(*m_widget); 242 bool runOverlapTests = !frameView.useSlowRepaintsIfNotOverlapped() || frameView.hasCompositedContentIncludingDescendants();242 bool runOverlapTests = !frameView.useSlowRepaintsIfNotOverlapped(); 243 243 if (paintInfo.overlapTestRequests && runOverlapTests) { 244 244 ASSERT(!paintInfo.overlapTestRequests->contains(this));
Note:
See TracChangeset
for help on using the changeset viewer.