diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-01-06 14:44:00 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-01-06 14:44:00 +0100 |
commit | 40736c5763bf61337c8c14e16d8587db021a87d4 (patch) | |
tree | b17a9c00042ad89cb1308e2484491799aa14e9f8 /Source/WebKit/chromium/tests/TiledLayerChromiumTest.cpp | |
download | qtwebkit-40736c5763bf61337c8c14e16d8587db021a87d4.tar.gz |
Imported WebKit commit 2ea9d364d0f6efa8fa64acf19f451504c59be0e4 (http://svn.webkit.org/repository/webkit/trunk@104285)
Diffstat (limited to 'Source/WebKit/chromium/tests/TiledLayerChromiumTest.cpp')
-rw-r--r-- | Source/WebKit/chromium/tests/TiledLayerChromiumTest.cpp | 262 |
1 files changed, 262 insertions, 0 deletions
diff --git a/Source/WebKit/chromium/tests/TiledLayerChromiumTest.cpp b/Source/WebKit/chromium/tests/TiledLayerChromiumTest.cpp new file mode 100644 index 000000000..93e2ee8be --- /dev/null +++ b/Source/WebKit/chromium/tests/TiledLayerChromiumTest.cpp @@ -0,0 +1,262 @@ +/* + * Copyright (C) 2011 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 "TiledLayerChromium.h" + +#include "LayerTextureUpdater.h" +#include "TextureManager.h" +#include "cc/CCSingleThreadProxy.h" // For DebugScopedSetImplThread +#include "cc/CCTextureUpdater.h" +#include "cc/CCTiledLayerImpl.h" +#include <gtest/gtest.h> + +using namespace WebCore; +using namespace WTF; + +namespace { + +class FakeTextureAllocator : public TextureAllocator { +public: + virtual unsigned createTexture(const IntSize&, GC3Denum) { return 0; } + virtual void deleteTexture(unsigned, const IntSize&, GC3Denum) { } +}; + +class FakeLayerTextureUpdater : public LayerTextureUpdater { +public: + class Texture : public LayerTextureUpdater::Texture { + public: + Texture(PassOwnPtr<ManagedTexture> texture) : LayerTextureUpdater::Texture(texture) { } + virtual ~Texture() { } + + virtual void updateRect(GraphicsContext3D*, TextureAllocator*, const IntRect&, const IntRect&) { } + }; + + FakeLayerTextureUpdater() { } + virtual ~FakeLayerTextureUpdater() { } + + virtual PassOwnPtr<LayerTextureUpdater::Texture> createTexture(TextureManager* manager) { return adoptPtr(new Texture(ManagedTexture::create(manager))); } + virtual SampledTexelFormat sampledTexelFormat(GC3Denum) { return SampledTexelFormatRGBA; } + virtual void prepareToUpdate(const IntRect&, const IntSize&, int, float) { } +}; + +class FakeCCTiledLayerImpl : public CCTiledLayerImpl { +public: + explicit FakeCCTiledLayerImpl(int id) + : CCTiledLayerImpl(id) { } + virtual ~FakeCCTiledLayerImpl() { } + + bool hasTileAt(int i, int j) + { + return CCTiledLayerImpl::hasTileAt(i, j); + } +}; + +class FakeTiledLayerChromium : public TiledLayerChromium { +public: + explicit FakeTiledLayerChromium(TextureManager* textureManager) + : TiledLayerChromium(0) + , m_fakeTextureUpdater(adoptRef(new FakeLayerTextureUpdater)) + , m_textureManager(textureManager) + { + setTileSize(IntSize(100, 100)); + setTextureFormat(GraphicsContext3D::RGBA); + setBorderTexelOption(CCLayerTilingData::NoBorderTexels); + setIsDrawable(true); // So that we don't get false positives if any of these tests expect to return false from drawsContent() for other reasons. + } + virtual ~FakeTiledLayerChromium() { } + + void invalidateRect(const IntRect& rect) + { + TiledLayerChromium::invalidateRect(rect); + } + + void prepareToUpdate(const IntRect& rect) + { + TiledLayerChromium::prepareToUpdate(rect); + } + + void prepareToUpdateIdle(const IntRect& rect) + { + TiledLayerChromium::prepareToUpdateIdle(rect); + } + + bool needsIdlePaint(const IntRect& rect) + { + return TiledLayerChromium::needsIdlePaint(rect); + } + + virtual TextureManager* textureManager() const { return m_textureManager; } + +private: + virtual void createTextureUpdater(const CCLayerTreeHost*) { } + + virtual LayerTextureUpdater* textureUpdater() const + { + return m_fakeTextureUpdater.get(); + } + + RefPtr<FakeLayerTextureUpdater> m_fakeTextureUpdater; + TextureManager* m_textureManager; +}; + +TEST(TiledLayerChromiumTest, pushDirtyTiles) +{ + OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024); + RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get())); + DebugScopedSetImplThread implThread; + RefPtr<FakeCCTiledLayerImpl> layerImpl = adoptRef(new FakeCCTiledLayerImpl(0)); + + FakeTextureAllocator textureAllocator; + CCTextureUpdater updater(&textureAllocator); + + // The tile size is 100x100, so this invalidates and then paints two tiles. + layer->setBounds(IntSize(100, 200)); + layer->invalidateRect(IntRect(0, 0, 100, 200)); + layer->prepareToUpdate(IntRect(0, 0, 100, 200)); + layer->updateCompositorResources(0, updater); + layer->pushPropertiesTo(layerImpl.get()); + + // We should have both tiles on the impl side. + EXPECT_TRUE(layerImpl->hasTileAt(0, 0)); + EXPECT_TRUE(layerImpl->hasTileAt(0, 1)); + + textureManager->unprotectAllTextures(); + + // Invalidates both tiles... + layer->invalidateRect(IntRect(0, 0, 100, 200)); + // ....but then only update one of them. + layer->prepareToUpdate(IntRect(0, 0, 100, 100)); + layer->updateCompositorResources(0, updater); + layer->pushPropertiesTo(layerImpl.get()); + + // We should only have the first tile since the other tile was invalidated but not painted. + EXPECT_TRUE(layerImpl->hasTileAt(0, 0)); + EXPECT_FALSE(layerImpl->hasTileAt(0, 1)); +} + +TEST(TiledLayerChromiumTest, pushIdlePaintTiles) +{ + OwnPtr<TextureManager> textureManager = TextureManager::create(4*1024*1024, 2*1024*1024, 1024); + RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get())); + DebugScopedSetImplThread implThread; + RefPtr<FakeCCTiledLayerImpl> layerImpl = adoptRef(new FakeCCTiledLayerImpl(0)); + + FakeTextureAllocator textureAllocator; + CCTextureUpdater updater(&textureAllocator); + + // The tile size is 100x100. Setup 5x5 tiles with one visible tile in the center. + IntSize contentBounds(500, 500); + IntRect contentRect(IntPoint::zero(), contentBounds); + IntRect visibleRect(200, 200, 100, 100); + + // This invalidates 25 tiles and then paints one visible tile. + layer->setBounds(contentBounds); + layer->setVisibleLayerRect(visibleRect); + layer->invalidateRect(contentRect); + layer->prepareToUpdate(visibleRect); + + // We should need idle-painting for 3x3 tiles in the center. + EXPECT_TRUE(layer->needsIdlePaint(visibleRect)); + + layer->updateCompositorResources(0, updater); + layer->pushPropertiesTo(layerImpl.get()); + + // We should have one tile on the impl side. + EXPECT_TRUE(layerImpl->hasTileAt(2, 2)); + + textureManager->unprotectAllTextures(); + + // For the next four updates, we should detect we still need idle painting. + for (int i = 0; i < 4; i++) { + layer->prepareToUpdate(visibleRect); + EXPECT_TRUE(layer->needsIdlePaint(visibleRect)); + layer->prepareToUpdateIdle(visibleRect); + layer->updateCompositorResources(0, updater); + layer->pushPropertiesTo(layerImpl.get()); + textureManager->unprotectAllTextures(); + } + + // After four passes of idle painting, we should be finished painting + EXPECT_FALSE(layer->needsIdlePaint(visibleRect)); + + // We should have one tile surrounding the visible tile on all sides, but no other tiles. + IntRect idlePaintTiles(1, 1, 3, 3); + for (int i = 0; i < 5; i++) { + for (int j = 0; j < 5; j++) { + if (idlePaintTiles.contains(i, j)) + EXPECT_TRUE(layerImpl->hasTileAt(i, j)); + else + EXPECT_FALSE(layerImpl->hasTileAt(i, j)); + } + } +} + + +TEST(TiledLayerChromiumTest, idlePaintOutOfMemory) +{ + // The tile size is 100x100. Setup 5x5 tiles with one 1x1 visible tile in the center. + IntSize contentBounds(300, 300); + IntRect contentRect(IntPoint::zero(), contentBounds); + IntRect visibleRect(100, 100, 100, 100); + + // We have enough memory for only the visible rect, so we will run out of memory in first idle paint. + int memoryLimit = 4 * 100 * 100; // 2 tiles, 4 bytes per pixel. + + OwnPtr<TextureManager> textureManager = TextureManager::create(memoryLimit, memoryLimit / 2, 1024); + RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get())); + DebugScopedSetImplThread implThread; + RefPtr<FakeCCTiledLayerImpl> layerImpl = adoptRef(new FakeCCTiledLayerImpl(0)); + + FakeTextureAllocator textureAllocator; + CCTextureUpdater updater(&textureAllocator); + + // This invalidates 9 tiles and then paints one visible tile. + layer->setBounds(contentBounds); + layer->setVisibleLayerRect(visibleRect); + layer->invalidateRect(contentRect); + layer->prepareToUpdate(visibleRect); + + // We should need idle-painting for 3x3 tiles surounding visible tile. + EXPECT_TRUE(layer->needsIdlePaint(visibleRect)); + + layer->updateCompositorResources(0, updater); + layer->pushPropertiesTo(layerImpl.get()); + + // We should have one tile on the impl side. + EXPECT_TRUE(layerImpl->hasTileAt(1, 1)); + + textureManager->unprotectAllTextures(); + layer->prepareToUpdate(visibleRect); + layer->prepareToUpdateIdle(visibleRect); + + // We shouldn't signal we need another idle paint after we run out of memory. + EXPECT_FALSE(layer->needsIdlePaint(visibleRect)); + + layer->updateCompositorResources(0, updater); + layer->pushPropertiesTo(layerImpl.get()); +} + +} // namespace |