summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--third_party/WebKit/Source/core/frame/FrameView.cpp14
-rw-r--r--third_party/WebKit/Source/core/paint/FramePainter.cpp9
-rw-r--r--third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp9
-rw-r--r--third_party/WebKit/Source/web/tests/FrameThrottlingTest.cpp61
4 files changed, 78 insertions, 15 deletions
diff --git a/third_party/WebKit/Source/core/frame/FrameView.cpp b/third_party/WebKit/Source/core/frame/FrameView.cpp
index f94c98e..a6304a7 100644
--- a/third_party/WebKit/Source/core/frame/FrameView.cpp
+++ b/third_party/WebKit/Source/core/frame/FrameView.cpp
@@ -3727,16 +3727,11 @@ void FrameView::paint(GraphicsContext& context, const CullRect& cullRect) const
void FrameView::paint(GraphicsContext& context, const GlobalPaintFlags globalPaintFlags, const CullRect& cullRect) const
{
- // TODO(skyostil): Remove this early-out in favor of painting cached scrollbars.
- if (shouldThrottleRendering())
- return;
FramePainter(*this).paint(context, globalPaintFlags, cullRect);
}
void FrameView::paintContents(GraphicsContext& context, const GlobalPaintFlags globalPaintFlags, const IntRect& damageRect) const
{
- if (shouldThrottleRendering())
- return;
FramePainter(*this).paintContents(context, globalPaintFlags, damageRect);
}
@@ -4032,8 +4027,15 @@ void FrameView::notifyRenderThrottlingObservers()
}
bool becameUnthrottled = wasThrottled && !canThrottleRendering();
- if (becameUnthrottled)
+ if (becameUnthrottled) {
+ // Start ticking animation frames again if necessary.
page()->animator().scheduleVisualUpdate(m_frame.get());
+ // Force a full repaint of this frame to ensure we are not left with a
+ // partially painted version of this frame's contents if we skipped
+ // painting them while the frame was throttled.
+ if (LayoutView* layoutView = this->layoutView())
+ layoutView->setShouldDoFullPaintInvalidation(PaintInvalidationBecameVisible);
+ }
}
bool FrameView::shouldThrottleRendering() const
diff --git a/third_party/WebKit/Source/core/paint/FramePainter.cpp b/third_party/WebKit/Source/core/paint/FramePainter.cpp
index a6eb08c..ba89543 100644
--- a/third_party/WebKit/Source/core/paint/FramePainter.cpp
+++ b/third_party/WebKit/Source/core/paint/FramePainter.cpp
@@ -111,8 +111,10 @@ void FramePainter::paintContents(GraphicsContext& context, const GlobalPaintFlag
return;
}
- RELEASE_ASSERT(!frameView().needsLayout());
- ASSERT(document->lifecycle().state() >= DocumentLifecycle::CompositingClean);
+ if (!frameView().shouldThrottleRendering()) {
+ RELEASE_ASSERT(!frameView().needsLayout());
+ ASSERT(document->lifecycle().state() >= DocumentLifecycle::CompositingClean);
+ }
TRACE_EVENT1("devtools.timeline", "Paint", "data", InspectorPaintEvent::data(layoutView, LayoutRect(rect), 0));
@@ -133,7 +135,8 @@ void FramePainter::paintContents(GraphicsContext& context, const GlobalPaintFlag
PaintLayer* rootLayer = layoutView->layer();
#if ENABLE(ASSERT)
- layoutView->assertSubtreeIsLaidOut();
+ if (!frameView().shouldThrottleRendering())
+ layoutView->assertSubtreeIsLaidOut();
LayoutObject::SetLayoutNeededForbiddenScope forbidSetNeedsLayout(*rootLayer->layoutObject());
#endif
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp b/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
index 31bbc5c..4eea6f7 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp
@@ -4,6 +4,7 @@
#include "core/paint/PaintLayerPainter.h"
+#include "core/frame/FrameView.h"
#include "core/frame/Settings.h"
#include "core/layout/ClipPathOperation.h"
#include "core/layout/LayoutBlock.h"
@@ -80,8 +81,7 @@ PaintLayerPainter::PaintResult PaintLayerPainter::paintLayer(GraphicsContext& co
if (shouldSuppressPaintingLayer(&m_paintLayer))
return FullyPainted;
- // TODO(skyostil): Unify this early-out logic with subsequence caching.
- if (m_paintLayer.layoutObject()->isLayoutPart() && toLayoutPart(m_paintLayer.layoutObject())->isThrottledFrameView())
+ if (m_paintLayer.layoutObject()->isLayoutView() && toLayoutView(m_paintLayer.layoutObject())->frameView()->shouldThrottleRendering())
return FullyPainted;
// If this layer is totally invisible then there is nothing to paint.
@@ -270,9 +270,8 @@ PaintLayerPainter::PaintResult PaintLayerPainter::paintLayerContents(GraphicsCon
if (paintFlags & PaintLayerPaintingRootBackgroundOnly && !m_paintLayer.layoutObject()->isLayoutView() && !m_paintLayer.layoutObject()->isDocumentElement())
return result;
- // TODO(skyostil): Unify this early-out logic with subsequence caching.
- if (m_paintLayer.layoutObject()->isLayoutPart() && toLayoutPart(m_paintLayer.layoutObject())->isThrottledFrameView())
- return FullyPainted;
+ if (m_paintLayer.layoutObject()->isLayoutView() && toLayoutView(m_paintLayer.layoutObject())->frameView()->shouldThrottleRendering())
+ return result;
// Ensure our lists are up-to-date.
m_paintLayer.stackingNode()->updateLayerListsIfNeeded();
diff --git a/third_party/WebKit/Source/web/tests/FrameThrottlingTest.cpp b/third_party/WebKit/Source/web/tests/FrameThrottlingTest.cpp
index beca4dd..3abba53 100644
--- a/third_party/WebKit/Source/web/tests/FrameThrottlingTest.cpp
+++ b/third_party/WebKit/Source/web/tests/FrameThrottlingTest.cpp
@@ -211,7 +211,7 @@ TEST_F(FrameThrottlingTest, MutatingThrottledFrameDoesNotCauseAnimation)
frameElement->contentDocument()->documentElement()->setAttribute(styleAttr, "background: green");
EXPECT_FALSE(compositor().needsAnimate());
- // Moving the frame back on screen to unthrottle it.
+ // Move the frame back on screen to unthrottle it.
frameElement->setAttribute(styleAttr, "");
EXPECT_TRUE(compositor().needsAnimate());
@@ -251,6 +251,65 @@ TEST_F(FrameThrottlingTest, SynchronousLayoutInThrottledFrame)
EXPECT_EQ(50, divElement->clientWidth());
}
+TEST_F(FrameThrottlingTest, UnthrottlingTriggersRepaint)
+{
+ // Create a hidden frame which is throttled.
+ SimRequest mainResource("https://example.com/", "text/html");
+ SimRequest frameResource("https://example.com/iframe.html", "text/html");
+
+ loadURL("https://example.com/");
+ mainResource.complete("<iframe id=frame sandbox src=iframe.html></iframe>");
+ frameResource.complete("<style> html { background: green; } </style>");
+
+ // Move the frame offscreen to throttle it.
+ auto* frameElement = toHTMLIFrameElement(document().getElementById("frame"));
+ frameElement->setAttribute(styleAttr, "transform: translateY(480px)");
+ EXPECT_FALSE(frameElement->contentDocument()->view()->shouldThrottleRendering());
+ compositeFrame();
+ EXPECT_TRUE(frameElement->contentDocument()->view()->shouldThrottleRendering());
+
+ // Scroll down to unthrottle the frame. The first frame we composite after
+ // scrolling won't contain the frame yet, but will schedule another repaint.
+ webView().mainFrameImpl()->frameView()->setScrollPosition(DoublePoint(0, 480), ProgrammaticScroll);
+ auto displayItems = compositeFrame();
+ EXPECT_FALSE(displayItems.contains(SimCanvas::Rect, "green"));
+
+ // Now the frame contents should be visible again.
+ auto displayItems2 = compositeFrame();
+ EXPECT_TRUE(displayItems2.contains(SimCanvas::Rect, "green"));
+}
+
+TEST_F(FrameThrottlingTest, ChangeStyleInThrottledFrame)
+{
+ // Create a hidden frame which is throttled.
+ SimRequest mainResource("https://example.com/", "text/html");
+ SimRequest frameResource("https://example.com/iframe.html", "text/html");
+
+ loadURL("https://example.com/");
+ mainResource.complete("<iframe id=frame sandbox src=iframe.html></iframe>");
+ frameResource.complete("<style> html { background: red; } </style>");
+
+ // Move the frame offscreen to throttle it.
+ auto* frameElement = toHTMLIFrameElement(document().getElementById("frame"));
+ frameElement->setAttribute(styleAttr, "transform: translateY(480px)");
+ EXPECT_FALSE(frameElement->contentDocument()->view()->shouldThrottleRendering());
+ compositeFrame();
+ EXPECT_TRUE(frameElement->contentDocument()->view()->shouldThrottleRendering());
+
+ // Change the background color of the frame's contents from red to green.
+ frameElement->contentDocument()->body()->setAttribute(styleAttr, "background: green");
+
+ // Scroll down to unthrottle the frame.
+ webView().mainFrameImpl()->frameView()->setScrollPosition(DoublePoint(0, 480), ProgrammaticScroll);
+ auto displayItems = compositeFrame();
+ EXPECT_FALSE(displayItems.contains(SimCanvas::Rect, "red"));
+ EXPECT_FALSE(displayItems.contains(SimCanvas::Rect, "green"));
+
+ // Make sure the new style shows up instead of the old one.
+ auto displayItems2 = compositeFrame();
+ EXPECT_TRUE(displayItems2.contains(SimCanvas::Rect, "green"));
+}
+
TEST(RemoteFrameThrottlingTest, ThrottledLocalRoot)
{
FrameTestHelpers::TestWebViewClient viewClient;