- Revision
- 89316
- Author
- [email protected]
- Date
- 2011-06-20 17:01:04 -0700 (Mon, 20 Jun 2011)
Log Message
2011-06-20 Joseph Pecoraro <[email protected]>
Reviewed by Darin Adler.
Minimize memory due to layer backing stores for pages in the Page Cache
https://bugs.webkit.org/show_bug.cgi?id=62675
Test the layer tree of a page with composited content,
including content in iframes, looks like we expect.
Enabling clearing backing stores in the PageCache should
produce the same expected results.
* compositing/iframes/page-cache-layer-tree-expected.txt: Added.
* compositing/iframes/page-cache-layer-tree.html: Added.
* compositing/iframes/resources/page-cache-helper.html: Added.
* compositing/iframes/resources/page-cache-iframe.html: Added.
2011-06-20 Joseph Pecoraro <[email protected]>
Reviewed by Simon Fraser.
Minimize memory due to layer backing stores for pages in the Page Cache
https://bugs.webkit.org/show_bug.cgi?id=62675
When a page enters the page cache there is now an option on
the PageCache singleton to clear the backing stores and layers
of the cached page. This can be useful to minimize the amount
of memory the stored page consumes.
This only affects memory usage and is disabled by default, so no test.
* history/CachedFrame.h:
* history/CachedFrame.cpp:
(WebCore::CachedFrameBase::CachedFrameBase):
Save whether or not the page had composited content or not
in a new instance variable, m_isComposited.
(WebCore::CachedFrameBase::restore):
When restoring, rebuild the compositing tree if it may have
been destroyed.
(WebCore::CachedFrame::CachedFrame):
When saving, clear the backing stores if the page is in
compositing mode, and the PageCache setting is enabled.
* history/PageCache.cpp:
(WebCore::PageCache::PageCache):
* history/PageCache.h:
(WebCore::PageCache::shouldClearBackingStores):
(WebCore::PageCache::setShouldClearBackingStores):
A setting to opt-in to the new behavior of clearing
the backing stores.
* page/FrameView.h:
* page/FrameView.cpp:
(WebCore::FrameView::clearBackingStores):
(WebCore::FrameView::restoreBackingStores):
To clear all backing stores we disable compositing
for the frame, to detach the root platform layer,
and recursively clear backing stores from the root
layer of the FrameView.
* rendering/RenderLayer.h:
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::clearBackingIncludingDescendants):
Recursively call clearBacking.
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (89315 => 89316)
--- trunk/LayoutTests/ChangeLog 2011-06-20 23:54:07 UTC (rev 89315)
+++ trunk/LayoutTests/ChangeLog 2011-06-21 00:01:04 UTC (rev 89316)
@@ -1,3 +1,20 @@
+2011-06-20 Joseph Pecoraro <[email protected]>
+
+ Reviewed by Darin Adler.
+
+ Minimize memory due to layer backing stores for pages in the Page Cache
+ https://bugs.webkit.org/show_bug.cgi?id=62675
+
+ Test the layer tree of a page with composited content,
+ including content in iframes, looks like we expect.
+ Enabling clearing backing stores in the PageCache should
+ produce the same expected results.
+
+ * compositing/iframes/page-cache-layer-tree-expected.txt: Added.
+ * compositing/iframes/page-cache-layer-tree.html: Added.
+ * compositing/iframes/resources/page-cache-helper.html: Added.
+ * compositing/iframes/resources/page-cache-iframe.html: Added.
+
2011-06-20 Mark Pilgrim <[email protected]>
Reviewed by Adam Barth.
Added: trunk/LayoutTests/compositing/iframes/page-cache-layer-tree-expected.txt (0 => 89316)
--- trunk/LayoutTests/compositing/iframes/page-cache-layer-tree-expected.txt (rev 0)
+++ trunk/LayoutTests/compositing/iframes/page-cache-layer-tree-expected.txt 2011-06-21 00:01:04 UTC (rev 89316)
@@ -0,0 +1,103 @@
+ALERT: pageshow - not from cache
+ALERT: pagehide - entering cache
+ALERT: pageshow - from cache
+This tests that layers are rebuilt properly after the page is restored from the page cache.
+
+
+
+(GraphicsLayer
+ (bounds 800.00 600.00)
+ (children 1
+ (GraphicsLayer
+ (bounds 800.00 600.00)
+ (children 4
+ (GraphicsLayer
+ (position 8.00 50.00)
+ (bounds 370.00 220.00)
+ (drawsContent 1)
+ (children 1
+ (GraphicsLayer
+ (position 35.00 35.00)
+ (children 1
+ (GraphicsLayer
+ (bounds 285.00 135.00)
+ (children 1
+ (GraphicsLayer
+ (children 1
+ (GraphicsLayer
+ (bounds 352.00 352.00)
+ (children 1
+ (GraphicsLayer
+ (bounds 352.00 352.00)
+ (drawsContent 1)
+ (children 1
+ (GraphicsLayer
+ (position 8.00 8.00)
+ (bounds 202.00 202.00)
+ (drawsContent 1)
+ (transform [0.71 0.71 0.00 0.00] [-0.71 0.71 0.00 0.00] [0.00 0.00 1.00 0.00] [100.00 100.00 0.00 1.00])
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ (GraphicsLayer
+ (position 13.00 55.00)
+ (bounds 50.00 50.00)
+ (drawsContent 1)
+ )
+ (GraphicsLayer
+ (position 8.00 274.00)
+ (bounds 370.00 220.00)
+ (drawsContent 1)
+ (children 1
+ (GraphicsLayer
+ (position 35.00 35.00)
+ (children 1
+ (GraphicsLayer
+ (bounds 285.00 135.00)
+ (children 1
+ (GraphicsLayer
+ (children 1
+ (GraphicsLayer
+ (bounds 508.00 608.00)
+ (children 1
+ (GraphicsLayer
+ (bounds 508.00 608.00)
+ (drawsContent 1)
+ (children 1
+ (GraphicsLayer
+ (position 108.00 100.00)
+ (bounds 200.00 200.00)
+ (drawsContent 1)
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ )
+ (GraphicsLayer
+ (position 13.00 279.00)
+ (bounds 50.00 50.00)
+ (drawsContent 1)
+ )
+ )
+ )
+ )
+)
+
Added: trunk/LayoutTests/compositing/iframes/page-cache-layer-tree.html (0 => 89316)
--- trunk/LayoutTests/compositing/iframes/page-cache-layer-tree.html (rev 0)
+++ trunk/LayoutTests/compositing/iframes/page-cache-layer-tree.html 2011-06-21 00:01:04 UTC (rev 89316)
@@ -0,0 +1,82 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <style>
+ iframe {
+ border: 10px solid black;
+ padding: 5px;
+ margin: 20px;
+ height: 150px;
+ width: 300px;
+ -webkit-box-shadow: 0 0 20px black;
+ }
+
+ .container {
+ position: relative;
+ }
+
+ .overlay {
+ position: absolute;
+ width: 50px;
+ height: 50px;
+ top: 5px;
+ left: 5px;
+ background-color: rgba(0, 0, 0, 0.2);
+ }
+ </style>
+</head>
+<body>
+
+ <p>
+ This tests that layers are rebuilt properly after the page
+ is restored from the page cache.
+ </p>
+
+ <!-- Some iframes with composited content. -->
+ <div class="container">
+ <iframe src=""
+ <div class="overlay"></div>
+ </div>
+ <div class="container">
+ <iframe src=""
+ <div class="overlay"></div>
+ </div>
+
+ <!-- Dump the layer tree output here. -->
+ <pre id="output"></pre>
+
+ <script>
+ if (window.layoutTestController) {
+ window.layoutTestController.dumpAsText();
+ window.layoutTestController.waitUntilDone();
+ window.layoutTestController.overridePreference("WebKitUsesPageCachePreferenceKey", 1);
+ }
+
+ function finishTest() {
+ var output = document.getElementById("output");
+ output.innerText = layoutTestController.layerTreeAsText();
+
+ if (window.layoutTestController)
+ window.layoutTestController.notifyDone();
+ }
+
+ window.addEventListener("pageshow", function(event) {
+ alert("pageshow - " + (event.persisted ? "" : "not ") + "from cache");
+ if (event.persisted)
+ setTimeout(finishTest, 0);
+ }, false);
+
+ window.addEventListener("pagehide", function(event) {
+ alert("pagehide - " + (event.persisted ? "" : "not ") + "entering cache");
+ }, false);
+
+ // Force a back navigation back to this page.
+ window.addEventListener("load", function(event) {
+ setTimeout(function() {
+ window.location.href = ""
+ }, 0);
+ }, false);
+ </script>
+
+</body>
+</html>
Added: trunk/LayoutTests/compositing/iframes/resources/page-cache-helper.html (0 => 89316)
--- trunk/LayoutTests/compositing/iframes/resources/page-cache-helper.html (rev 0)
+++ trunk/LayoutTests/compositing/iframes/resources/page-cache-helper.html 2011-06-21 00:01:04 UTC (rev 89316)
@@ -0,0 +1,8 @@
+This page should go back.
+<script>
+ window.addEventListener("load", function() {
+ setTimeout(function() {
+ history.back();
+ }, 0);
+ }, false);
+</script>
Added: trunk/LayoutTests/compositing/iframes/resources/page-cache-iframe.html (0 => 89316)
--- trunk/LayoutTests/compositing/iframes/resources/page-cache-iframe.html (rev 0)
+++ trunk/LayoutTests/compositing/iframes/resources/page-cache-iframe.html 2011-06-21 00:01:04 UTC (rev 89316)
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <style>
+ .layer {
+ width: 200px;
+ height: 200px;
+ border: 1px solid black;
+ background-color: blue;
+ -webkit-transform: translate3d(100px, 100px, 0) rotate(45deg);
+ }
+ </style>
+</head>
+<body>
+
+ <!-- Content that requires a layer. -->
+ <div class="layer"><p>Check this out</p></div>
+
+ <!-- Content that does not require a layer. -->
+ <div><p>I feel so regular...</p></div>
+
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (89315 => 89316)
--- trunk/Source/WebCore/ChangeLog 2011-06-20 23:54:07 UTC (rev 89315)
+++ trunk/Source/WebCore/ChangeLog 2011-06-21 00:01:04 UTC (rev 89316)
@@ -1,3 +1,53 @@
+2011-06-20 Joseph Pecoraro <[email protected]>
+
+ Reviewed by Simon Fraser.
+
+ Minimize memory due to layer backing stores for pages in the Page Cache
+ https://bugs.webkit.org/show_bug.cgi?id=62675
+
+ When a page enters the page cache there is now an option on
+ the PageCache singleton to clear the backing stores and layers
+ of the cached page. This can be useful to minimize the amount
+ of memory the stored page consumes.
+
+ This only affects memory usage and is disabled by default, so no test.
+
+ * history/CachedFrame.h:
+ * history/CachedFrame.cpp:
+ (WebCore::CachedFrameBase::CachedFrameBase):
+ Save whether or not the page had composited content or not
+ in a new instance variable, m_isComposited.
+
+ (WebCore::CachedFrameBase::restore):
+ When restoring, rebuild the compositing tree if it may have
+ been destroyed.
+
+ (WebCore::CachedFrame::CachedFrame):
+ When saving, clear the backing stores if the page is in
+ compositing mode, and the PageCache setting is enabled.
+
+ * history/PageCache.cpp:
+ (WebCore::PageCache::PageCache):
+ * history/PageCache.h:
+ (WebCore::PageCache::shouldClearBackingStores):
+ (WebCore::PageCache::setShouldClearBackingStores):
+ A setting to opt-in to the new behavior of clearing
+ the backing stores.
+
+ * page/FrameView.h:
+ * page/FrameView.cpp:
+ (WebCore::FrameView::clearBackingStores):
+ (WebCore::FrameView::restoreBackingStores):
+ To clear all backing stores we disable compositing
+ for the frame, to detach the root platform layer,
+ and recursively clear backing stores from the root
+ layer of the FrameView.
+
+ * rendering/RenderLayer.h:
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::clearBackingIncludingDescendants):
+ Recursively call clearBacking.
+
2011-06-20 Mark Pilgrim <[email protected]>
Reviewed by Adam Barth.
Modified: trunk/Source/WebCore/history/CachedFrame.cpp (89315 => 89316)
--- trunk/Source/WebCore/history/CachedFrame.cpp 2011-06-20 23:54:07 UTC (rev 89315)
+++ trunk/Source/WebCore/history/CachedFrame.cpp 2011-06-21 00:01:04 UTC (rev 89316)
@@ -52,6 +52,10 @@
#include "ChromeClient.h"
#endif
+#if USE(ACCELERATED_COMPOSITING)
+#include "PageCache.h"
+#endif
+
namespace WebCore {
#ifndef NDEBUG
@@ -69,6 +73,9 @@
, m_mousePressNode(frame->eventHandler()->mousePressNode())
, m_url(frame->document()->url())
, m_isMainFrame(!frame->tree()->parent())
+#if USE(ACCELERATED_COMPOSITING)
+ , m_isComposited(frame->view()->hasCompositedContent())
+#endif
{
}
@@ -105,6 +112,11 @@
// cached page.
frame->script()->updatePlatformScriptObjects();
+#if USE(ACCELERATED_COMPOSITING)
+ if (m_isComposited)
+ frame->view()->restoreBackingStores();
+#endif
+
frame->loader()->client()->didRestoreFromPageCache();
// Reconstruct the FrameTree
@@ -164,6 +176,11 @@
frame->loader()->client()->savePlatformDataToCachedFrame(this);
+#if USE(ACCELERATED_COMPOSITING)
+ if (m_isComposited && pageCache()->shouldClearBackingStores())
+ frame->view()->clearBackingStores();
+#endif
+
// Deconstruct the FrameTree, to restore it later.
// We do this for two reasons:
// 1 - We reuse the main frame, so when it navigates to a new page load it needs to start with a blank FrameTree.
Modified: trunk/Source/WebCore/history/CachedFrame.h (89315 => 89316)
--- trunk/Source/WebCore/history/CachedFrame.h 2011-06-20 23:54:07 UTC (rev 89315)
+++ trunk/Source/WebCore/history/CachedFrame.h 2011-06-21 00:01:04 UTC (rev 89316)
@@ -64,6 +64,9 @@
OwnPtr<ScriptCachedFrameData> m_cachedFrameScriptData;
OwnPtr<CachedFramePlatformData> m_cachedFramePlatformData;
bool m_isMainFrame;
+#if USE(ACCELERATED_COMPOSITING)
+ bool m_isComposited;
+#endif
CachedFrameVector m_childFrames;
};
Modified: trunk/Source/WebCore/history/PageCache.cpp (89315 => 89316)
--- trunk/Source/WebCore/history/PageCache.cpp 2011-06-20 23:54:07 UTC (rev 89315)
+++ trunk/Source/WebCore/history/PageCache.cpp 2011-06-21 00:01:04 UTC (rev 89316)
@@ -240,6 +240,9 @@
, m_head(0)
, m_tail(0)
, m_autoreleaseTimer(this, &PageCache::releaseAutoreleasedPagesNowOrReschedule)
+#if USE(ACCELERATED_COMPOSITING)
+ , m_shouldClearBackingStores(false)
+#endif
{
}
Modified: trunk/Source/WebCore/history/PageCache.h (89315 => 89316)
--- trunk/Source/WebCore/history/PageCache.h 2011-06-20 23:54:07 UTC (rev 89315)
+++ trunk/Source/WebCore/history/PageCache.h 2011-06-21 00:01:04 UTC (rev 89316)
@@ -60,6 +60,11 @@
void markPagesForVistedLinkStyleRecalc();
+#if USE(ACCELERATED_COMPOSITING)
+ bool shouldClearBackingStores() const { return m_shouldClearBackingStores; }
+ void setShouldClearBackingStores(bool flag) { m_shouldClearBackingStores = flag; }
+#endif
+
private:
typedef HashSet<RefPtr<CachedPage> > CachedPageSet;
@@ -85,6 +90,10 @@
Timer<PageCache> m_autoreleaseTimer;
CachedPageSet m_autoreleaseSet;
+
+#if USE(ACCELERATED_COMPOSITING)
+ bool m_shouldClearBackingStores;
+#endif
};
// Function to obtain the global page cache.
Modified: trunk/Source/WebCore/page/FrameView.cpp (89315 => 89316)
--- trunk/Source/WebCore/page/FrameView.cpp 2011-06-20 23:54:07 UTC (rev 89315)
+++ trunk/Source/WebCore/page/FrameView.cpp 2011-06-21 00:01:04 UTC (rev 89316)
@@ -636,6 +636,30 @@
#endif
}
+void FrameView::clearBackingStores()
+{
+ RenderView* root = m_frame->contentRenderer();
+ if (!root)
+ return;
+
+ RenderLayerCompositor* compositor = root->compositor();
+ ASSERT(compositor->inCompositingMode());
+ compositor->enableCompositingMode(false);
+ root->layer()->clearBackingIncludingDescendants();
+}
+
+void FrameView::restoreBackingStores()
+{
+ RenderView* root = m_frame->contentRenderer();
+ if (!root)
+ return;
+
+ RenderLayerCompositor* compositor = root->compositor();
+ compositor->enableCompositingMode(true);
+ compositor->setCompositingLayersNeedRebuild();
+ compositor->scheduleCompositingLayerUpdate();
+}
+
GraphicsLayer* FrameView::layerForHorizontalScrollbar() const
{
RenderView* view = m_frame->contentRenderer();
Modified: trunk/Source/WebCore/page/FrameView.h (89315 => 89316)
--- trunk/Source/WebCore/page/FrameView.h 2011-06-20 23:54:07 UTC (rev 89315)
+++ trunk/Source/WebCore/page/FrameView.h 2011-06-21 00:01:04 UTC (rev 89316)
@@ -112,6 +112,9 @@
void updateCompositingLayers();
bool syncCompositingStateForThisFrame();
+ void clearBackingStores();
+ void restoreBackingStores();
+
// Called when changes to the GraphicsLayer hierarchy have to be synchronized with
// content rendered via the normal painting path.
void setNeedsOneShotDrawingSynchronization();
Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (89315 => 89316)
--- trunk/Source/WebCore/rendering/RenderLayer.cpp 2011-06-20 23:54:07 UTC (rev 89315)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp 2011-06-21 00:01:04 UTC (rev 89316)
@@ -3646,6 +3646,14 @@
m_backing.clear();
}
+void RenderLayer::clearBackingIncludingDescendants()
+{
+ clearBacking();
+
+ for (RenderLayer* l = firstChild(); l; l = l->nextSibling())
+ l->clearBackingIncludingDescendants();
+}
+
bool RenderLayer::hasCompositedMask() const
{
return m_backing && m_backing->hasMaskLayer();
Modified: trunk/Source/WebCore/rendering/RenderLayer.h (89315 => 89316)
--- trunk/Source/WebCore/rendering/RenderLayer.h 2011-06-20 23:54:07 UTC (rev 89315)
+++ trunk/Source/WebCore/rendering/RenderLayer.h 2011-06-21 00:01:04 UTC (rev 89316)
@@ -433,6 +433,7 @@
RenderLayerBacking* backing() const { return m_backing.get(); }
RenderLayerBacking* ensureBacking();
void clearBacking();
+ void clearBackingIncludingDescendants();
virtual GraphicsLayer* layerForHorizontalScrollbar() const;
virtual GraphicsLayer* layerForVerticalScrollbar() const;
virtual GraphicsLayer* layerForScrollCorner() const;