15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2012 Google Inc. All rights reserved. 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met: 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer in the 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * documentation and/or other materials provided with the distribution. 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 27a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/Canvas2DLayerManager.h" 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "SkDevice.h" 303c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch#include "SkSurface.h" 3143e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)#include "platform/graphics/test/MockWebGraphicsContext3D.h" 325267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "public/platform/Platform.h" 3309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "public/platform/WebGraphicsContext3DProvider.h" 345267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)#include "public/platform/WebThread.h" 355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 36e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include <gmock/gmock.h> 37e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include <gtest/gtest.h> 38e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 39c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)using namespace blink; 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using testing::InSequence; 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using testing::Return; 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using testing::Test; 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)namespace { 4509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 46e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)class MockWebGraphicsContext3DProvider : public WebGraphicsContext3DProvider { 4709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)public: 48e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) MockWebGraphicsContext3DProvider(WebGraphicsContext3D* context3d) 4909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) : m_context3d(context3d) { } 5009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 51e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) WebGraphicsContext3D* context3d() 5209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) { 5309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return m_context3d; 5409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 5509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 5609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) GrContext* grContext() 5709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) { 5809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return 0; 5909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 6009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 6109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)private: 62e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) WebGraphicsContext3D* m_context3d; 6309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}; 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class FakeCanvas2DLayerBridge : public Canvas2DLayerBridge { 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public: 67e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) FakeCanvas2DLayerBridge(WebGraphicsContext3D* context, PassOwnPtr<SkDeferredCanvas> canvas, PassRefPtr<SkSurface> surface) 68197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch : Canvas2DLayerBridge(adoptPtr(new MockWebGraphicsContext3DProvider(context)), canvas, surface, 0, NonOpaque) 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_freeableBytes(0) 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_freeMemoryIfPossibleCount(0) 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_flushCount(0) 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) virtual size_t storageAllocatedForRecording() OVERRIDE 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Because the fake layer has no canvas to query, just 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // return status quo. Allocation changes that would normally be 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // initiated by the canvas can be faked by invoking 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // storageAllocatedForRecordingChanged directly from the test code. 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_bytesAllocated; 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void fakeFreeableBytes(size_t size) 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_freeableBytes = size; 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) virtual size_t freeMemoryIfPossible(size_t size) OVERRIDE 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_freeMemoryIfPossibleCount++; 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) size_t bytesFreed = size < m_freeableBytes ? size : m_freeableBytes; 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_freeableBytes -= bytesFreed; 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (bytesFreed) 9509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) storageAllocatedForRecordingChanged(m_bytesAllocated - bytesFreed); 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return bytesFreed; 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) virtual void flush() OVERRIDE 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) flushedDrawCommands(); 10209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) m_freeableBytes = bytesAllocated(); 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_flushCount++; 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public: 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) size_t m_freeableBytes; 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int m_freeMemoryIfPossibleCount; 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int m_flushCount; 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 112a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)class FakeCanvas2DLayerBridgePtr { 113a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)public: 114a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) FakeCanvas2DLayerBridgePtr(PassRefPtr<FakeCanvas2DLayerBridge> layerBridge) 115a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) : m_layerBridge(layerBridge) { } 116a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 117a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) ~FakeCanvas2DLayerBridgePtr() 118a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) { 119a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) m_layerBridge->beginDestruction(); 120a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) } 121a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 122a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) FakeCanvas2DLayerBridge* operator->() { return m_layerBridge.get(); } 123a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) FakeCanvas2DLayerBridge* get() { return m_layerBridge.get(); } 124a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 125a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)private: 126a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) RefPtr<FakeCanvas2DLayerBridge> m_layerBridge; 127a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)}; 12853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 12909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)} // unnamed namespace 13009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class Canvas2DLayerManagerTest : public Test { 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)protected: 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void storageAllocationTrackingTest() 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Canvas2DLayerManager& manager = Canvas2DLayerManager::get(); 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) manager.init(10, 10); 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 138e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) OwnPtr<MockWebGraphicsContext3D> webContext = adoptPtr(new MockWebGraphicsContext3D); 139197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch RefPtr<SkSurface> surface1 = adoptRef(SkSurface::NewRasterPMColor(1, 1)); 140197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch OwnPtr<SkDeferredCanvas> canvas1 = adoptPtr(SkDeferredCanvas::Create(surface1.get())); 141197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch FakeCanvas2DLayerBridgePtr layer1(adoptRef(new FakeCanvas2DLayerBridge(webContext.get(), canvas1.release(), surface1.release()))); 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ((size_t)0, manager.m_bytesAllocated); 1438abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) layer1->storageAllocatedForRecordingChanged(1); 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ((size_t)1, manager.m_bytesAllocated); 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Test allocation increase 1468abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) layer1->storageAllocatedForRecordingChanged(2); 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ((size_t)2, manager.m_bytesAllocated); 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Test allocation decrease 1498abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) layer1->storageAllocatedForRecordingChanged(1); 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ((size_t)1, manager.m_bytesAllocated); 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 152197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch RefPtr<SkSurface> surface2 = adoptRef(SkSurface::NewRasterPMColor(1, 1)); 153197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch OwnPtr<SkDeferredCanvas> canvas2 = adoptPtr(SkDeferredCanvas::Create(surface2.get())); 154197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch FakeCanvas2DLayerBridgePtr layer2(adoptRef(new FakeCanvas2DLayerBridge(webContext.get(), canvas2.release(), surface2.release()))); 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ((size_t)1, manager.m_bytesAllocated); 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // verify multi-layer allocation tracking 1578abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) layer2->storageAllocatedForRecordingChanged(2); 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ((size_t)3, manager.m_bytesAllocated); 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Verify tracking after destruction 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ((size_t)1, manager.m_bytesAllocated); 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void evictionTest() 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 167e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) OwnPtr<MockWebGraphicsContext3D> webContext = adoptPtr(new MockWebGraphicsContext3D); 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Canvas2DLayerManager& manager = Canvas2DLayerManager::get(); 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) manager.init(10, 5); 170197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch RefPtr<SkSurface> surface = adoptRef(SkSurface::NewRasterPMColor(1, 1)); 171197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch OwnPtr<SkDeferredCanvas> canvas = adoptPtr(SkDeferredCanvas::Create(surface.get())); 172197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch FakeCanvas2DLayerBridgePtr layer(adoptRef(new FakeCanvas2DLayerBridge(webContext.get(), canvas.release(), surface.release()))); 173a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) layer->fakeFreeableBytes(10); 1748abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) layer->storageAllocatedForRecordingChanged(8); // under the max 175a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) EXPECT_EQ(0, layer->m_freeMemoryIfPossibleCount); 1768abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) layer->storageAllocatedForRecordingChanged(12); // over the max 177a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) EXPECT_EQ(1, layer->m_freeMemoryIfPossibleCount); 178a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) EXPECT_EQ((size_t)3, layer->m_freeableBytes); 179a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) EXPECT_EQ(0, layer->m_flushCount); // eviction succeeded without triggering a flush 1808abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) EXPECT_EQ((size_t)5, layer->bytesAllocated()); 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 18309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) void hiddenCanvasTest() 18409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) { 185e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) OwnPtr<MockWebGraphicsContext3D> webContext = adoptPtr(new MockWebGraphicsContext3D); 18609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) Canvas2DLayerManager& manager = Canvas2DLayerManager::get(); 18709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) manager.init(20, 5); 188197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch RefPtr<SkSurface> surface = adoptRef(SkSurface::NewRasterPMColor(1, 1)); 189197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch OwnPtr<SkDeferredCanvas> canvas = adoptPtr(SkDeferredCanvas::Create(surface.get())); 190197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch FakeCanvas2DLayerBridgePtr layer(adoptRef(new FakeCanvas2DLayerBridge(webContext.get(), canvas.release(), surface.release()))); 19109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) layer->fakeFreeableBytes(5); 19209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) layer->storageAllocatedForRecordingChanged(10); 19309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) EXPECT_EQ(0, layer->m_freeMemoryIfPossibleCount); 19409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) EXPECT_EQ(0, layer->m_flushCount); 19509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) EXPECT_EQ((size_t)10, layer->bytesAllocated()); 19609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) layer->setIsHidden(true); 19709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) EXPECT_EQ(1, layer->m_freeMemoryIfPossibleCount); 19809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) EXPECT_EQ((size_t)0, layer->m_freeableBytes); 19909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) EXPECT_EQ((size_t)0, layer->bytesAllocated()); 20009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) EXPECT_EQ(1, layer->m_flushCount); 20109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 20209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 20309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) void addRemoveLayerTest() 20409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) { 205e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) OwnPtr<MockWebGraphicsContext3D> webContext = adoptPtr(new MockWebGraphicsContext3D); 20609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) Canvas2DLayerManager& manager = Canvas2DLayerManager::get(); 20709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) manager.init(10, 5); 208197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch RefPtr<SkSurface> surface = adoptRef(SkSurface::NewRasterPMColor(1, 1)); 209197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch OwnPtr<SkDeferredCanvas> canvas = adoptPtr(SkDeferredCanvas::Create(surface.get())); 210197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch FakeCanvas2DLayerBridgePtr layer(adoptRef(new FakeCanvas2DLayerBridge(webContext.get(), canvas.release(), surface.release()))); 21109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) EXPECT_FALSE(manager.isInList(layer.get())); 21209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) layer->storageAllocatedForRecordingChanged(5); 21309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) EXPECT_TRUE(manager.isInList(layer.get())); 21409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) layer->storageAllocatedForRecordingChanged(0); 21509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) EXPECT_FALSE(manager.isInList(layer.get())); 21609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 21709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void flushEvictionTest() 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 220e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) OwnPtr<MockWebGraphicsContext3D> webContext = adoptPtr(new MockWebGraphicsContext3D); 2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Canvas2DLayerManager& manager = Canvas2DLayerManager::get(); 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) manager.init(10, 5); 223197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch RefPtr<SkSurface> surface = adoptRef(SkSurface::NewRasterPMColor(1, 1)); 224197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch OwnPtr<SkDeferredCanvas> canvas = adoptPtr(SkDeferredCanvas::Create(surface.get())); 225197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch FakeCanvas2DLayerBridgePtr layer(adoptRef(new FakeCanvas2DLayerBridge(webContext.get(), canvas.release(), surface.release()))); 226a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) layer->fakeFreeableBytes(1); // Not enough freeable bytes, will cause aggressive eviction by flushing 2278abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) layer->storageAllocatedForRecordingChanged(8); // under the max 228a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) EXPECT_EQ(0, layer->m_freeMemoryIfPossibleCount); 2298abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) layer->storageAllocatedForRecordingChanged(12); // over the max 230a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) EXPECT_EQ(2, layer->m_freeMemoryIfPossibleCount); // Two tries, one before flush, one after flush 23109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) EXPECT_EQ((size_t)5, layer->m_freeableBytes); 232a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) EXPECT_EQ(1, layer->m_flushCount); // flush was attempted 23309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) EXPECT_EQ((size_t)5, layer->bytesAllocated()); 23409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) EXPECT_TRUE(manager.isInList(layer.get())); 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void doDeferredFrameTestTask(FakeCanvas2DLayerBridge* layer, bool skipCommands) 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2397242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci FloatRect invalidationRect(0, 0, 1, 1); 2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_FALSE(Canvas2DLayerManager::get().m_taskObserverActive); 2417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci layer->finalizeFrame(invalidationRect); 2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) layer->storageAllocatedForRecordingChanged(1); 2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_TRUE(Canvas2DLayerManager::get().m_taskObserverActive); 2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (skipCommands) { 2457242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci layer->finalizeFrame(invalidationRect); 2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) layer->skippedPendingDrawCommands(); 2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 248e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) Platform::current()->currentThread()->exitRunLoop(); 2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 251e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) class DeferredFrameTestTask : public WebThread::Task { 2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) public: 2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DeferredFrameTestTask(Canvas2DLayerManagerTest* test, FakeCanvas2DLayerBridge* layer, bool skipCommands) 2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_test = test; 2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_layer = layer; 2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_skipCommands = skipCommands; 2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) virtual void run() OVERRIDE 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_test->doDeferredFrameTestTask(m_layer, m_skipCommands); 2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) private: 2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Canvas2DLayerManagerTest* m_test; 2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FakeCanvas2DLayerBridge* m_layer; 2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool m_skipCommands; 2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }; 2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void deferredFrameTest() 2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 272e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) OwnPtr<MockWebGraphicsContext3D> webContext = adoptPtr(new MockWebGraphicsContext3D); 2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Canvas2DLayerManager::get().init(10, 10); 274197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch RefPtr<SkSurface> surface = adoptRef(SkSurface::NewRasterPMColor(1, 1)); 275197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch OwnPtr<SkDeferredCanvas> canvas = adoptPtr(SkDeferredCanvas::Create(surface.get())); 276197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch FakeCanvas2DLayerBridgePtr layer(adoptRef(new FakeCanvas2DLayerBridge(webContext.get(), canvas.release(), surface.release()))); 277e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) Platform::current()->currentThread()->postTask(new DeferredFrameTestTask(this, layer.get(), true)); 278e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) Platform::current()->currentThread()->enterRunLoop(); 2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Verify that didProcessTask was called upon completion 2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_FALSE(Canvas2DLayerManager::get().m_taskObserverActive); 2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Verify that no flush was performed because frame is fresh 282a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) EXPECT_EQ(0, layer->m_flushCount); 2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Verify that no flushes are triggered as long as frame are fresh 285e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) Platform::current()->currentThread()->postTask(new DeferredFrameTestTask(this, layer.get(), true)); 286e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) Platform::current()->currentThread()->enterRunLoop(); 2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_FALSE(Canvas2DLayerManager::get().m_taskObserverActive); 288a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) EXPECT_EQ(0, layer->m_flushCount); 2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 290e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) Platform::current()->currentThread()->postTask(new DeferredFrameTestTask(this, layer.get(), true)); 291e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) Platform::current()->currentThread()->enterRunLoop(); 2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_FALSE(Canvas2DLayerManager::get().m_taskObserverActive); 293a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) EXPECT_EQ(0, layer->m_flushCount); 2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 295e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch // Verify that a flush is triggered when queue is accumulating a multi-frame backlog. 296e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) Platform::current()->currentThread()->postTask(new DeferredFrameTestTask(this, layer.get(), false)); 297e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) Platform::current()->currentThread()->enterRunLoop(); 2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_FALSE(Canvas2DLayerManager::get().m_taskObserverActive); 299a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) EXPECT_EQ(1, layer->m_flushCount); 3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 301e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) Platform::current()->currentThread()->postTask(new DeferredFrameTestTask(this, layer.get(), false)); 302e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) Platform::current()->currentThread()->enterRunLoop(); 3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_FALSE(Canvas2DLayerManager::get().m_taskObserverActive); 304a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) EXPECT_EQ(2, layer->m_flushCount); 3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace { 3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)TEST_F(Canvas2DLayerManagerTest, testStorageAllocationTracking) 3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) storageAllocationTrackingTest(); 3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)TEST_F(Canvas2DLayerManagerTest, testEviction) 3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) evictionTest(); 3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)TEST_F(Canvas2DLayerManagerTest, testFlushEviction) 3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) flushEvictionTest(); 3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)TEST_F(Canvas2DLayerManagerTest, testDeferredFrame) 3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) deferredFrameTest(); 3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 33009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)TEST_F(Canvas2DLayerManagerTest, testHiddenCanvas) 33109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){ 33209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) hiddenCanvasTest(); 33309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)} 33409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 33509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)TEST_F(Canvas2DLayerManagerTest, testAddRemoveLayer) 33609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){ 33709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) addRemoveLayerTest(); 33809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)} 33909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 34009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)} // unnamed namespace 3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 342