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