Title: [104474] trunk/Source
Revision
104474
Author
[email protected]
Date
2012-01-09 12:15:33 -0800 (Mon, 09 Jan 2012)

Log Message

Avoid unnecessary TextureManager::reduceMemoryToLimit().
https://bugs.webkit.org/show_bug.cgi?id=75632

Source/WebCore:

Unnecessary TextureManager::reduceMemoryToLimit() will cause some tile
textures that are required soon to be unnecessarily removed/replaced,
and degrade performance, sometimes significantly.

For example, CCLayerTreeHost::setViewport will be called during
scrolling. The original code would call TextureManager::reduceMemoryToLimit(),
causing some textures unnecessarily discarded and then recreated
repeatedly during scrolling.

It's also unnecessary to call TextureManager::reduceMemoryToLimit()
from TextureManager::setPreferredMemoryLimitBytes() because the limit
is not a hard limit. The callers should call reduceMemoryToLimit()
explicitly if it wants it when setting the preferred memory limit.

Reviewed by James Robinson.

Tests: webkit_unit_tests --gtest_filter=TextureManagerTest.*:CCLayerTreeHostTestSetViewportSize.*

* platform/graphics/chromium/LayerRendererChromium.cpp:
(WebCore::LayerRendererChromium::finishDrawingFrame): Call reduceMemoryToLimit() explicitly
* platform/graphics/chromium/TextureManager.cpp:
(WebCore::TextureManager::setPreferredMemoryLimitBytes): Removed call to reduceMemoryToLimit().
* platform/graphics/chromium/cc/CCLayerTreeHost.cpp:
(WebCore::CCLayerTreeHost::finishCommitOnImplThread):
(WebCore::CCLayerTreeHost::setViewportSize): Changed name from setViewport(). Check change of viewportSize.
* platform/graphics/chromium/cc/CCLayerTreeHost.h:
* platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp:
(WebCore::CCLayerTreeHostImpl::setViewportSize): Changed name from setViewport()
* platform/graphics/chromium/cc/CCLayerTreeHostImpl.h:

Source/WebKit/chromium:

Main part of the change is in Source/WebCore.

Reviewed by James Robinson.

Tests: webkit_unit_tests --gtest_filter=TextureManagerTest.*:CCLayerTreeHostTestSetViewportSize.*

* WebKit.gypi:
* src/WebLayerTreeView.cpp:
(WebKit::WebLayerTreeView::setViewportSize):
* src/WebViewImpl.cpp:
(WebKit::WebViewImpl::updateLayerTreeViewport):
* tests/CCLayerTreeHostImplTest.cpp:
(WebKit::TEST_F):
* tests/CCLayerTreeHostTest.cpp:
(WTF::MockLayerTreeHost::create):
(WTF::CCLayerTreeHostTestOpacityChange::beginTest):
(WTF::CCLayerTreeHostTestSetViewportSize::CCLayerTreeHostTestSetViewportSize):
(WTF::CCLayerTreeHostTestSetViewportSize::beginTest):
(WTF::CCLayerTreeHostTestSetViewportSize::afterTest):
(WTF::TEST_F):
* tests/TextureManagerTest.cpp: Added.
(WTF::FakeTextureAllocator::createTexture):
(WTF::FakeTextureAllocator::deleteTexture):
(WTF::texturesMemorySize):
(WTF::createTextureManager):
(WTF::requestTexture):
(WTF::TEST):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (104473 => 104474)


--- trunk/Source/WebCore/ChangeLog	2012-01-09 20:02:11 UTC (rev 104473)
+++ trunk/Source/WebCore/ChangeLog	2012-01-09 20:15:33 UTC (rev 104474)
@@ -1,3 +1,38 @@
+2012-01-09  Xianzhu Wang  <[email protected]>
+
+        Avoid unnecessary TextureManager::reduceMemoryToLimit().
+        https://bugs.webkit.org/show_bug.cgi?id=75632
+
+        Unnecessary TextureManager::reduceMemoryToLimit() will cause some tile
+        textures that are required soon to be unnecessarily removed/replaced,
+        and degrade performance, sometimes significantly.
+
+        For example, CCLayerTreeHost::setViewport will be called during
+        scrolling. The original code would call TextureManager::reduceMemoryToLimit(),
+        causing some textures unnecessarily discarded and then recreated
+        repeatedly during scrolling.
+
+        It's also unnecessary to call TextureManager::reduceMemoryToLimit()
+        from TextureManager::setPreferredMemoryLimitBytes() because the limit
+        is not a hard limit. The callers should call reduceMemoryToLimit()
+        explicitly if it wants it when setting the preferred memory limit.
+
+        Reviewed by James Robinson.
+
+        Tests: webkit_unit_tests --gtest_filter=TextureManagerTest.*:CCLayerTreeHostTestSetViewportSize.*
+
+        * platform/graphics/chromium/LayerRendererChromium.cpp:
+        (WebCore::LayerRendererChromium::finishDrawingFrame): Call reduceMemoryToLimit() explicitly
+        * platform/graphics/chromium/TextureManager.cpp:
+        (WebCore::TextureManager::setPreferredMemoryLimitBytes): Removed call to reduceMemoryToLimit().
+        * platform/graphics/chromium/cc/CCLayerTreeHost.cpp:
+        (WebCore::CCLayerTreeHost::finishCommitOnImplThread):
+        (WebCore::CCLayerTreeHost::setViewportSize): Changed name from setViewport(). Check change of viewportSize.
+        * platform/graphics/chromium/cc/CCLayerTreeHost.h:
+        * platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp:
+        (WebCore::CCLayerTreeHostImpl::setViewportSize): Changed name from setViewport()
+        * platform/graphics/chromium/cc/CCLayerTreeHostImpl.h:
+
 2012-01-09  Sami Kyostila  <[email protected]>
 
         [Chromium] JPEG RGB swizzling order should match platform pixel format

Modified: trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp (104473 => 104474)


--- trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp	2012-01-09 20:02:11 UTC (rev 104473)
+++ trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp	2012-01-09 20:15:33 UTC (rev 104474)
@@ -679,11 +679,9 @@
 
     size_t contentsMemoryUseBytes = m_contentsTextureAllocator->currentMemoryUseBytes();
     size_t reclaimLimit = TextureManager::reclaimLimitBytes(viewportSize());
-    if (reclaimLimit > contentsMemoryUseBytes)
-        m_renderSurfaceTextureManager->setPreferredMemoryLimitBytes(reclaimLimit - contentsMemoryUseBytes);
-    else
-        m_renderSurfaceTextureManager->setPreferredMemoryLimitBytes(0);
-
+    size_t preferredLimit = reclaimLimit > contentsMemoryUseBytes ? reclaimLimit - contentsMemoryUseBytes : 0;
+    m_renderSurfaceTextureManager->setPreferredMemoryLimitBytes(preferredLimit);
+    m_renderSurfaceTextureManager->reduceMemoryToLimit(preferredLimit);
     m_renderSurfaceTextureManager->deleteEvictedTextures(m_renderSurfaceTextureAllocator.get());
 
     if (settings().compositeOffscreen)

Modified: trunk/Source/WebCore/platform/graphics/chromium/TextureManager.cpp (104473 => 104474)


--- trunk/Source/WebCore/platform/graphics/chromium/TextureManager.cpp	2012-01-09 20:02:11 UTC (rev 104473)
+++ trunk/Source/WebCore/platform/graphics/chromium/TextureManager.cpp	2012-01-09 20:15:33 UTC (rev 104474)
@@ -112,7 +112,6 @@
 
 void TextureManager::setPreferredMemoryLimitBytes(size_t memoryLimitBytes)
 {
-    reduceMemoryToLimit(memoryLimitBytes);
     m_preferredMemoryLimitBytes = memoryLimitBytes;
 }
 

Modified: trunk/Source/WebCore/platform/graphics/chromium/TextureManager.h (104473 => 104474)


--- trunk/Source/WebCore/platform/graphics/chromium/TextureManager.h	2012-01-09 20:02:11 UTC (rev 104473)
+++ trunk/Source/WebCore/platform/graphics/chromium/TextureManager.h	2012-01-09 20:15:33 UTC (rev 104474)
@@ -64,7 +64,9 @@
     static size_t memoryUseBytes(const IntSize&, GC3Denum format);
 
     void setMaxMemoryLimitBytes(size_t);
+    size_t maxMemoryLimitBytes() { return m_maxMemoryLimitBytes; }
     void setPreferredMemoryLimitBytes(size_t);
+    size_t preferredMemoryLimitBytes() { return m_preferredMemoryLimitBytes; }
 
     TextureToken getToken();
     void releaseToken(TextureToken);

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp (104473 => 104474)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp	2012-01-09 20:02:11 UTC (rev 104473)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.cpp	2012-01-09 20:15:33 UTC (rev 104474)
@@ -156,7 +156,7 @@
 
     hostImpl->setSourceFrameNumber(frameNumber());
     hostImpl->setHaveWheelEventHandlers(m_haveWheelEventHandlers);
-    hostImpl->setViewport(viewportSize());
+    hostImpl->setViewportSize(viewportSize());
     hostImpl->setPageScaleFactorAndLimits(pageScale(), m_minPageScale, m_maxPageScale);
 
     m_frameNumber++;
@@ -247,8 +247,11 @@
     setNeedsCommit();
 }
 
-void CCLayerTreeHost::setViewport(const IntSize& viewportSize)
+void CCLayerTreeHost::setViewportSize(const IntSize& viewportSize)
 {
+    if (viewportSize == m_viewportSize)
+        return;
+
     contentsTextureManager()->setMaxMemoryLimitBytes(TextureManager::highLimitBytes(viewportSize));
     contentsTextureManager()->setPreferredMemoryLimitBytes(TextureManager::reclaimLimitBytes(viewportSize));
     m_viewportSize = viewportSize;

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h (104473 => 104474)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h	2012-01-09 20:02:11 UTC (rev 104473)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHost.h	2012-01-09 20:15:33 UTC (rev 104474)
@@ -169,7 +169,7 @@
 
     const CCSettings& settings() const { return m_settings; }
 
-    void setViewport(const IntSize& viewportSize);
+    void setViewportSize(const IntSize&);
 
     const IntSize& viewportSize() const { return m_viewportSize; }
 

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp (104473 => 104474)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp	2012-01-09 20:02:11 UTC (rev 104473)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.cpp	2012-01-09 20:15:33 UTC (rev 104474)
@@ -361,7 +361,7 @@
     return m_layerRenderer;
 }
 
-void CCLayerTreeHostImpl::setViewport(const IntSize& viewportSize)
+void CCLayerTreeHostImpl::setViewportSize(const IntSize& viewportSize)
 {
     if (viewportSize == m_viewportSize)
         return;

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h (104473 => 104474)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h	2012-01-09 20:02:11 UTC (rev 104473)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostImpl.h	2012-01-09 20:15:33 UTC (rev 104474)
@@ -107,7 +107,7 @@
     int sourceFrameNumber() const { return m_sourceFrameNumber; }
     void setSourceFrameNumber(int frameNumber) { m_sourceFrameNumber = frameNumber; }
 
-    void setViewport(const IntSize& viewportSize);
+    void setViewportSize(const IntSize&);
     const IntSize& viewportSize() const { return m_viewportSize; }
 
     void setPageScaleFactorAndLimits(float pageScale, float minPageScale, float maxPageScale);

Modified: trunk/Source/WebKit/chromium/ChangeLog (104473 => 104474)


--- trunk/Source/WebKit/chromium/ChangeLog	2012-01-09 20:02:11 UTC (rev 104473)
+++ trunk/Source/WebKit/chromium/ChangeLog	2012-01-09 20:15:33 UTC (rev 104474)
@@ -1,3 +1,36 @@
+2012-01-09  Xianzhu Wang  <[email protected]>
+
+        Avoid unnecessary TextureManager::reduceMemoryToLimit().
+        https://bugs.webkit.org/show_bug.cgi?id=75632
+
+        Main part of the change is in Source/WebCore.
+
+        Reviewed by James Robinson.
+
+        Tests: webkit_unit_tests --gtest_filter=TextureManagerTest.*:CCLayerTreeHostTestSetViewportSize.*
+
+        * WebKit.gypi:
+        * src/WebLayerTreeView.cpp:
+        (WebKit::WebLayerTreeView::setViewportSize):
+        * src/WebViewImpl.cpp:
+        (WebKit::WebViewImpl::updateLayerTreeViewport):
+        * tests/CCLayerTreeHostImplTest.cpp:
+        (WebKit::TEST_F):
+        * tests/CCLayerTreeHostTest.cpp:
+        (WTF::MockLayerTreeHost::create):
+        (WTF::CCLayerTreeHostTestOpacityChange::beginTest):
+        (WTF::CCLayerTreeHostTestSetViewportSize::CCLayerTreeHostTestSetViewportSize):
+        (WTF::CCLayerTreeHostTestSetViewportSize::beginTest):
+        (WTF::CCLayerTreeHostTestSetViewportSize::afterTest):
+        (WTF::TEST_F):
+        * tests/TextureManagerTest.cpp: Added.
+        (WTF::FakeTextureAllocator::createTexture):
+        (WTF::FakeTextureAllocator::deleteTexture):
+        (WTF::texturesMemorySize):
+        (WTF::createTextureManager):
+        (WTF::requestTexture):
+        (WTF::TEST):
+
 2012-01-09  Sheriff Bot  <[email protected]>
 
         Unreviewed, rolling out r104418.

Modified: trunk/Source/WebKit/chromium/WebKit.gypi (104473 => 104474)


--- trunk/Source/WebKit/chromium/WebKit.gypi	2012-01-09 20:02:11 UTC (rev 104473)
+++ trunk/Source/WebKit/chromium/WebKit.gypi	2012-01-09 20:15:33 UTC (rev 104474)
@@ -96,6 +96,7 @@
             'tests/PODIntervalTreeTest.cpp',
             'tests/PODRedBlackTreeTest.cpp',
             'tests/RenderTableCellTest.cpp',
+            'tests/TextureManagerTest.cpp',
             'tests/TiledLayerChromiumTest.cpp',
             'tests/TilingDataTest.cpp',
             'tests/TreeSynchronizerTest.cpp',

Modified: trunk/Source/WebKit/chromium/src/WebLayerTreeView.cpp (104473 => 104474)


--- trunk/Source/WebKit/chromium/src/WebLayerTreeView.cpp	2012-01-09 20:02:11 UTC (rev 104473)
+++ trunk/Source/WebKit/chromium/src/WebLayerTreeView.cpp	2012-01-09 20:15:33 UTC (rev 104474)
@@ -81,7 +81,7 @@
 
 void WebLayerTreeView::setViewportSize(const WebSize& viewportSize)
 {
-    m_private->setViewport(viewportSize);
+    m_private->setViewportSize(viewportSize);
 }
 
 WebSize WebLayerTreeView::viewportSize() const

Modified: trunk/Source/WebKit/chromium/src/WebViewImpl.cpp (104473 => 104474)


--- trunk/Source/WebKit/chromium/src/WebViewImpl.cpp	2012-01-09 20:02:11 UTC (rev 104473)
+++ trunk/Source/WebKit/chromium/src/WebViewImpl.cpp	2012-01-09 20:15:33 UTC (rev 104474)
@@ -3089,7 +3089,7 @@
         layerAdjustX = -view->contentsSize().width() + view->visibleContentRect(false).width();
     }
     m_nonCompositedContentHost->setViewport(visibleRect.size(), view->contentsSize(), scroll, pageScaleFactor(), layerAdjustX);
-    m_layerTreeHost->setViewport(visibleRect.size());
+    m_layerTreeHost->setViewportSize(visibleRect.size());
     m_layerTreeHost->setPageScale(pageScaleFactor());
 }
 

Modified: trunk/Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp (104473 => 104474)


--- trunk/Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp	2012-01-09 20:02:11 UTC (rev 104473)
+++ trunk/Source/WebKit/chromium/tests/CCLayerTreeHostImplTest.cpp	2012-01-09 20:15:33 UTC (rev 104474)
@@ -223,7 +223,7 @@
     GraphicsContext3D::Attributes attrs;
     RefPtr<GraphicsContext3D> context = GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(new BlendStateTrackerContext()), attrs, 0, GraphicsContext3D::RenderDirectlyToHostWindow, GraphicsContext3DPrivate::ForUseOnThisThread);
     m_hostImpl->initializeLayerRenderer(context);
-    m_hostImpl->setViewport(IntSize(10, 10));
+    m_hostImpl->setViewportSize(IntSize(10, 10));
 
     RefPtr<CCLayerImpl> root = CCLayerImpl::create(0);
     root->setAnchorPoint(FloatPoint(0, 0));
@@ -322,7 +322,7 @@
     ReshapeTrackerContext* reshapeTracker = new ReshapeTrackerContext();
     RefPtr<GraphicsContext3D> context = GraphicsContext3DPrivate::createGraphicsContextFromWebContext(adoptPtr(reshapeTracker), attrs, 0, GraphicsContext3D::RenderDirectlyToHostWindow, GraphicsContext3DPrivate::ForUseOnThisThread);
     m_hostImpl->initializeLayerRenderer(context);
-    m_hostImpl->setViewport(IntSize(10, 10));
+    m_hostImpl->setViewportSize(IntSize(10, 10));
 
     RefPtr<CCLayerImpl> root = adoptRef(new FakeDrawableCCLayerImpl(1));
     root->setAnchorPoint(FloatPoint(0, 0));
@@ -372,7 +372,7 @@
     settings.partialSwapEnabled = true;
     OwnPtr<CCLayerTreeHostImpl> layerTreeHostImpl = CCLayerTreeHostImpl::create(settings, this);
     layerTreeHostImpl->initializeLayerRenderer(context);
-    layerTreeHostImpl->setViewport(IntSize(500, 500));
+    layerTreeHostImpl->setViewportSize(IntSize(500, 500));
 
     RefPtr<CCLayerImpl> root = adoptRef(new FakeDrawableCCLayerImpl(1));
     RefPtr<CCLayerImpl> child = adoptRef(new FakeDrawableCCLayerImpl(2));
@@ -413,7 +413,7 @@
     // Make sure that partial swap is constrained to the viewport dimensions
     // expected damage rect: IntRect(IntPoint::zero(), IntSize(500, 500));
     // expected swap rect: flipped damage rect, but also clamped to viewport
-    layerTreeHostImpl->setViewport(IntSize(10, 10));
+    layerTreeHostImpl->setViewportSize(IntSize(10, 10));
     root->setOpacity(0.7); // this will damage everything
     layerTreeHostImpl->drawLayers();
     layerTreeHostImpl->swapBuffers();

Modified: trunk/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp (104473 => 104474)


--- trunk/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp	2012-01-09 20:02:11 UTC (rev 104473)
+++ trunk/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp	2012-01-09 20:15:33 UTC (rev 104474)
@@ -110,7 +110,7 @@
         layerTreeHost->setRootLayer(rootLayer);
 
         // LayerTreeHostImpl won't draw if it has 1x1 viewport.
-        layerTreeHost->setViewport(IntSize(1, 1));
+        layerTreeHost->setViewportSize(IntSize(1, 1));
 
         return layerTreeHost.release();
     }
@@ -988,7 +988,7 @@
     virtual void beginTest()
     {
         m_layerTreeHost->setRootLayer(m_updateCheckLayer);
-        m_layerTreeHost->setViewport(IntSize(10, 10));
+        m_layerTreeHost->setViewportSize(IntSize(10, 10));
 
         postSetNeedsCommitToMainThread();
     }
@@ -1025,4 +1025,47 @@
     runTest(true);
 }
 
+class CCLayerTreeHostTestSetViewportSize : public CCLayerTreeHostTest {
+public:
+
+    CCLayerTreeHostTestSetViewportSize()
+        : m_numCommits(0)
+        , m_numDraws(0)
+    {
+    }
+
+    virtual void beginTest()
+    {
+        IntSize viewportSize(10, 10);
+        layerTreeHost()->setViewportSize(viewportSize);
+        EXPECT_EQ(viewportSize, layerTreeHost()->viewportSize());
+        EXPECT_EQ(TextureManager::highLimitBytes(viewportSize), layerTreeHost()->contentsTextureManager()->maxMemoryLimitBytes());
+        EXPECT_EQ(TextureManager::reclaimLimitBytes(viewportSize), layerTreeHost()->contentsTextureManager()->preferredMemoryLimitBytes());
+
+        // setViewportSize() should not call TextureManager::setMaxMemoryLimitBytes() or TextureManager::setPreferredMemoryLimitBytes()
+        // if the viewport size is not changed.
+        IntSize fakeSize(5, 5);
+        layerTreeHost()->contentsTextureManager()->setMaxMemoryLimitBytes(TextureManager::highLimitBytes(fakeSize));
+        layerTreeHost()->contentsTextureManager()->setPreferredMemoryLimitBytes(TextureManager::reclaimLimitBytes(fakeSize));
+        layerTreeHost()->setViewportSize(viewportSize);
+        EXPECT_EQ(TextureManager::highLimitBytes(fakeSize), layerTreeHost()->contentsTextureManager()->maxMemoryLimitBytes());
+        EXPECT_EQ(TextureManager::reclaimLimitBytes(fakeSize), layerTreeHost()->contentsTextureManager()->preferredMemoryLimitBytes());
+
+        endTest();
+    }
+
+    virtual void afterTest()
+    {
+    }
+
+private:
+    int m_numCommits;
+    int m_numDraws;
+};
+
+TEST_F(CCLayerTreeHostTestSetViewportSize, runSingleThread)
+{
+    runTest(false);
+}
+
 } // namespace

Added: trunk/Source/WebKit/chromium/tests/TextureManagerTest.cpp (0 => 104474)


--- trunk/Source/WebKit/chromium/tests/TextureManagerTest.cpp	                        (rev 0)
+++ trunk/Source/WebKit/chromium/tests/TextureManagerTest.cpp	2012-01-09 20:15:33 UTC (rev 104474)
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "TextureManager.h"
+
+#include <gtest/gtest.h>
+
+using namespace WebCore;
+using namespace WTF;
+
+namespace {
+
+class FakeTextureAllocator : public TextureAllocator {
+public:
+    virtual unsigned createTexture(const IntSize&, GC3Denum) { return 1; }
+    virtual void deleteTexture(unsigned, const IntSize&, GC3Denum) { }
+};
+
+FakeTextureAllocator fakeTextureAllocator;
+const IntSize textureSize(256, 256);
+const GC3Denum textureFormat = GraphicsContext3D::RGBA;
+
+size_t texturesMemorySize(size_t textureCount)
+{
+    return TextureManager::memoryUseBytes(textureSize, textureFormat) * textureCount;
+}
+
+PassOwnPtr<TextureManager> createTextureManager(size_t maxTextures, size_t preferredTextures)
+{
+    return TextureManager::create(texturesMemorySize(maxTextures), texturesMemorySize(preferredTextures), 1024);
+}
+
+bool requestTexture(TextureManager* manager, TextureToken token)
+{
+    unsigned textureId;
+    bool result = manager->requestTexture(token, textureSize, textureFormat, textureId);
+    if (result)
+        manager->allocateTexture(&fakeTextureAllocator, token);
+    return result;
+}
+
+TEST(TextureManagerTest, requestTextureInPreferredLimit)
+{
+    const size_t preferredTextures = 8;
+    OwnPtr<TextureManager> textureManager = createTextureManager(preferredTextures * 2, preferredTextures);
+    TextureToken tokens[preferredTextures];
+    for (size_t i = 0; i < preferredTextures; ++i) {
+        tokens[i] = textureManager->getToken();
+        if (i)
+            EXPECT_GT(tokens[i], tokens[i - 1]);
+        EXPECT_TRUE(requestTexture(textureManager.get(), tokens[i]));
+        EXPECT_TRUE(textureManager->hasTexture(tokens[i]));
+        EXPECT_TRUE(textureManager->isProtected(tokens[i]));
+    }
+
+    for (size_t i = 0; i < preferredTextures; ++i)
+        EXPECT_TRUE(textureManager->hasTexture(tokens[i]));
+
+    EXPECT_EQ(texturesMemorySize(preferredTextures), textureManager->currentMemoryUseBytes());
+}
+
+TEST(TextureManagerTest, requestTextureExceedingPreferredLimit)
+{
+    const size_t maxTextures = 8;
+    const size_t preferredTextures = 4;
+    OwnPtr<TextureManager> textureManager = createTextureManager(maxTextures, preferredTextures);
+    TextureToken tokens[maxTextures];
+    for (size_t i = 0; i < preferredTextures; ++i) {
+        tokens[i] = textureManager->getToken();
+        EXPECT_TRUE(requestTexture(textureManager.get(), tokens[i]));
+        EXPECT_TRUE(textureManager->hasTexture(tokens[i]));
+    }
+
+    textureManager->unprotectTexture(tokens[0]);
+    textureManager->unprotectTexture(tokens[2]);
+
+    for (size_t i = preferredTextures; i < maxTextures; ++i) {
+        tokens[i] = textureManager->getToken();
+        EXPECT_TRUE(requestTexture(textureManager.get(), tokens[i]));
+        EXPECT_TRUE(textureManager->hasTexture(tokens[i]));
+        textureManager->unprotectTexture(tokens[i]);
+    }
+
+    EXPECT_FALSE(textureManager->hasTexture(tokens[0]));
+    EXPECT_TRUE(textureManager->hasTexture(tokens[1]));
+    EXPECT_TRUE(textureManager->isProtected(tokens[1]));
+    EXPECT_FALSE(textureManager->hasTexture(tokens[2]));
+    EXPECT_TRUE(textureManager->hasTexture(tokens[3]));
+    EXPECT_TRUE(textureManager->isProtected(tokens[3]));
+
+    EXPECT_EQ(texturesMemorySize(preferredTextures), textureManager->currentMemoryUseBytes());
+}
+
+TEST(TextureManagerTest, requestTextureExceedingMaxLimit)
+{
+    const size_t maxTextures = 8;
+    const size_t preferredTextures = 4;
+    OwnPtr<TextureManager> textureManager = createTextureManager(maxTextures, preferredTextures);
+    TextureToken tokens[maxTextures];
+    for (size_t i = 0; i < maxTextures; ++i) {
+        tokens[i] = textureManager->getToken();
+        EXPECT_TRUE(requestTexture(textureManager.get(), tokens[i]));
+        EXPECT_TRUE(textureManager->hasTexture(tokens[i]));
+    }
+
+    EXPECT_EQ(texturesMemorySize(maxTextures), textureManager->currentMemoryUseBytes());
+
+    for (size_t i = 0; i < maxTextures; ++i) {
+        TextureToken token = textureManager->getToken();
+        EXPECT_FALSE(requestTexture(textureManager.get(), token));
+        EXPECT_FALSE(textureManager->hasTexture(token));
+    }
+
+    EXPECT_EQ(textureManager->currentMemoryUseBytes(), texturesMemorySize(maxTextures));
+
+    textureManager->unprotectTexture(tokens[1]);
+    textureManager->unprotectTexture(tokens[3]);
+    EXPECT_TRUE(requestTexture(textureManager.get(), textureManager->getToken()));
+    EXPECT_TRUE(requestTexture(textureManager.get(), textureManager->getToken()));
+    EXPECT_FALSE(requestTexture(textureManager.get(), textureManager->getToken()));
+    EXPECT_EQ(texturesMemorySize(maxTextures), textureManager->currentMemoryUseBytes());
+    EXPECT_FALSE(textureManager->hasTexture(tokens[1]));
+    EXPECT_FALSE(textureManager->hasTexture(tokens[3]));
+}
+
+TEST(TextureManagerTest, reduceMemoryToLimit)
+{
+    const size_t maxTextures = 8;
+    const size_t preferredTextures = 4;
+    OwnPtr<TextureManager> textureManager = createTextureManager(maxTextures, preferredTextures);
+    TextureToken tokens[maxTextures];
+    for (size_t i = 0; i < maxTextures; ++i) {
+        tokens[i] = textureManager->getToken();
+        EXPECT_TRUE(requestTexture(textureManager.get(), tokens[i]));
+    }
+
+    EXPECT_EQ(texturesMemorySize(maxTextures), textureManager->currentMemoryUseBytes());
+    textureManager->reduceMemoryToLimit(texturesMemorySize(maxTextures));
+    EXPECT_EQ(texturesMemorySize(maxTextures), textureManager->currentMemoryUseBytes());
+    textureManager->reduceMemoryToLimit(texturesMemorySize(preferredTextures));
+    EXPECT_EQ(texturesMemorySize(maxTextures), textureManager->currentMemoryUseBytes());
+
+    const size_t unprotectedTextures = preferredTextures + 1;
+    for (size_t i = 0; i < preferredTextures + 1; ++i)
+        textureManager->unprotectTexture(tokens[i]);
+
+    textureManager->reduceMemoryToLimit(texturesMemorySize(maxTextures));
+    EXPECT_EQ(texturesMemorySize(maxTextures), textureManager->currentMemoryUseBytes());
+    textureManager->reduceMemoryToLimit(texturesMemorySize(preferredTextures));
+    EXPECT_EQ(texturesMemorySize(preferredTextures), textureManager->currentMemoryUseBytes());
+    textureManager->reduceMemoryToLimit(texturesMemorySize(1));
+    EXPECT_EQ(texturesMemorySize(maxTextures - unprotectedTextures), textureManager->currentMemoryUseBytes());
+
+    // reduceMemoryToLimit doesn't change the current memory limits.
+    EXPECT_EQ(texturesMemorySize(maxTextures), textureManager->maxMemoryLimitBytes());
+    EXPECT_EQ(texturesMemorySize(preferredTextures), textureManager->preferredMemoryLimitBytes());
+}
+
+TEST(TextureManagerTest, setMaxMemoryLimitBytes)
+{
+    const size_t maxTextures = 8;
+    const size_t preferredTextures = 4;
+    OwnPtr<TextureManager> textureManager = createTextureManager(maxTextures, preferredTextures);
+    TextureToken tokens[maxTextures];
+    for (size_t i = 0; i < maxTextures; ++i) {
+        tokens[i] = textureManager->getToken();
+        EXPECT_TRUE(requestTexture(textureManager.get(), tokens[i]));
+    }
+
+    EXPECT_EQ(texturesMemorySize(maxTextures), textureManager->currentMemoryUseBytes());
+
+    const size_t unprotectedTextures = preferredTextures + 1;
+    for (size_t i = 0; i < unprotectedTextures; ++i)
+        textureManager->unprotectTexture(tokens[i]);
+
+    textureManager->setMaxMemoryLimitBytes(texturesMemorySize(maxTextures));
+    EXPECT_EQ(texturesMemorySize(maxTextures), textureManager->currentMemoryUseBytes());
+    textureManager->setMaxMemoryLimitBytes(texturesMemorySize(preferredTextures));
+    EXPECT_EQ(texturesMemorySize(preferredTextures), textureManager->currentMemoryUseBytes());
+    EXPECT_EQ(texturesMemorySize(preferredTextures), textureManager->maxMemoryLimitBytes());
+}
+
+TEST(TextureManagerTest, setPreferredMemoryLimitBytes)
+{
+    const size_t maxTextures = 8;
+    const size_t preferredTextures = 4;
+    OwnPtr<TextureManager> textureManager = createTextureManager(maxTextures, preferredTextures);
+    TextureToken tokens[maxTextures];
+    for (size_t i = 0; i < maxTextures; ++i) {
+        tokens[i] = textureManager->getToken();
+        EXPECT_TRUE(requestTexture(textureManager.get(), tokens[i]));
+    }
+
+    const size_t unprotectedTextures = preferredTextures + 1;
+    for (size_t i = 0; i < unprotectedTextures; ++i)
+        textureManager->unprotectTexture(tokens[i]);
+
+    EXPECT_EQ(texturesMemorySize(maxTextures), textureManager->currentMemoryUseBytes());
+    EXPECT_EQ(texturesMemorySize(maxTextures), textureManager->maxMemoryLimitBytes());
+
+    // Setting preferred memory limit only won't force reduceMemoryToLimit.
+    textureManager->setPreferredMemoryLimitBytes(texturesMemorySize(preferredTextures));
+    EXPECT_EQ(texturesMemorySize(maxTextures), textureManager->currentMemoryUseBytes());
+    EXPECT_EQ(texturesMemorySize(maxTextures), textureManager->maxMemoryLimitBytes());
+    EXPECT_EQ(texturesMemorySize(preferredTextures), textureManager->preferredMemoryLimitBytes());
+}
+
+} // namespace
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to