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 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace WebCore; 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) 4609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)class MockWebGraphicsContext3DProvider : public blink::WebGraphicsContext3DProvider { 4709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)public: 4809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) MockWebGraphicsContext3DProvider(blink::WebGraphicsContext3D* context3d) 4909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) : m_context3d(context3d) { } 5009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 5109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) blink::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: 6209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) blink::WebGraphicsContext3D* m_context3d; 6309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}; 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class FakeCanvas2DLayerBridge : public Canvas2DLayerBridge { 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public: 6709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) FakeCanvas2DLayerBridge(blink::WebGraphicsContext3D* context, PassOwnPtr<SkDeferredCanvas> canvas) 6809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) : Canvas2DLayerBridge(adoptPtr(new MockWebGraphicsContext3DProvider(context)), canvas, 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)static PassOwnPtr<SkDeferredCanvas> createCanvas() 1308abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles){ 131d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) RefPtr<SkSurface> surface = adoptRef(SkSurface::NewRasterPMColor(1, 1)); 132d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return adoptPtr(SkDeferredCanvas::Create(surface.get())); 1338abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)} 1348abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) 13509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)} // unnamed namespace 13609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class Canvas2DLayerManagerTest : public Test { 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)protected: 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void storageAllocationTrackingTest() 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Canvas2DLayerManager& manager = Canvas2DLayerManager::get(); 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) manager.init(10, 10); 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 14409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) OwnPtr<blink::MockWebGraphicsContext3D> webContext = adoptPtr(new blink::MockWebGraphicsContext3D); 14509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) OwnPtr<SkDeferredCanvas> canvas1 = createCanvas(); 14609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) FakeCanvas2DLayerBridgePtr layer1(adoptRef(new FakeCanvas2DLayerBridge(webContext.get(), canvas1.release()))); 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ((size_t)0, manager.m_bytesAllocated); 1488abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) layer1->storageAllocatedForRecordingChanged(1); 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ((size_t)1, manager.m_bytesAllocated); 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Test allocation increase 1518abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) layer1->storageAllocatedForRecordingChanged(2); 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ((size_t)2, manager.m_bytesAllocated); 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Test allocation decrease 1548abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) layer1->storageAllocatedForRecordingChanged(1); 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ((size_t)1, manager.m_bytesAllocated); 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 15709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) OwnPtr<SkDeferredCanvas> canvas2 = createCanvas(); 15809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) FakeCanvas2DLayerBridgePtr layer2(adoptRef(new FakeCanvas2DLayerBridge(webContext.get(), canvas2.release()))); 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ((size_t)1, manager.m_bytesAllocated); 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // verify multi-layer allocation tracking 1618abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) layer2->storageAllocatedForRecordingChanged(2); 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ((size_t)3, manager.m_bytesAllocated); 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Verify tracking after destruction 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_EQ((size_t)1, manager.m_bytesAllocated); 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void evictionTest() 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 17109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) OwnPtr<blink::MockWebGraphicsContext3D> webContext = adoptPtr(new blink::MockWebGraphicsContext3D); 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Canvas2DLayerManager& manager = Canvas2DLayerManager::get(); 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) manager.init(10, 5); 17409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) OwnPtr<SkDeferredCanvas> canvas = createCanvas(); 17509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) FakeCanvas2DLayerBridgePtr layer(adoptRef(new FakeCanvas2DLayerBridge(webContext.get(), canvas.release()))); 176a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) layer->fakeFreeableBytes(10); 1778abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) layer->storageAllocatedForRecordingChanged(8); // under the max 178a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) EXPECT_EQ(0, layer->m_freeMemoryIfPossibleCount); 1798abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) layer->storageAllocatedForRecordingChanged(12); // over the max 180a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) EXPECT_EQ(1, layer->m_freeMemoryIfPossibleCount); 181a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) EXPECT_EQ((size_t)3, layer->m_freeableBytes); 182a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) EXPECT_EQ(0, layer->m_flushCount); // eviction succeeded without triggering a flush 1838abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) EXPECT_EQ((size_t)5, layer->bytesAllocated()); 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 18609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) void hiddenCanvasTest() 18709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) { 18809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) OwnPtr<blink::MockWebGraphicsContext3D> webContext = adoptPtr(new blink::MockWebGraphicsContext3D); 18909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) Canvas2DLayerManager& manager = Canvas2DLayerManager::get(); 19009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) manager.init(20, 5); 19109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) OwnPtr<SkDeferredCanvas> canvas = createCanvas(); 19209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) FakeCanvas2DLayerBridgePtr layer(adoptRef(new FakeCanvas2DLayerBridge(webContext.get(), canvas.release()))); 19309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) layer->fakeFreeableBytes(5); 19409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) layer->storageAllocatedForRecordingChanged(10); 19509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) EXPECT_EQ(0, layer->m_freeMemoryIfPossibleCount); 19609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) EXPECT_EQ(0, layer->m_flushCount); 19709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) EXPECT_EQ((size_t)10, layer->bytesAllocated()); 19809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) layer->setIsHidden(true); 19909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) EXPECT_EQ(1, layer->m_freeMemoryIfPossibleCount); 20009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) EXPECT_EQ((size_t)0, layer->m_freeableBytes); 20109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) EXPECT_EQ((size_t)0, layer->bytesAllocated()); 20209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) EXPECT_EQ(1, layer->m_flushCount); 20309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 20409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 20509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) void addRemoveLayerTest() 20609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) { 20709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) OwnPtr<blink::MockWebGraphicsContext3D> webContext = adoptPtr(new blink::MockWebGraphicsContext3D); 20809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) Canvas2DLayerManager& manager = Canvas2DLayerManager::get(); 20909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) manager.init(10, 5); 21009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) OwnPtr<SkDeferredCanvas> canvas = createCanvas(); 21109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) FakeCanvas2DLayerBridgePtr layer(adoptRef(new FakeCanvas2DLayerBridge(webContext.get(), canvas.release()))); 21209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) EXPECT_FALSE(manager.isInList(layer.get())); 21309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) layer->storageAllocatedForRecordingChanged(5); 21409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) EXPECT_TRUE(manager.isInList(layer.get())); 21509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) layer->storageAllocatedForRecordingChanged(0); 21609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) EXPECT_FALSE(manager.isInList(layer.get())); 21709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 21809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void flushEvictionTest() 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 22109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) OwnPtr<blink::MockWebGraphicsContext3D> webContext = adoptPtr(new blink::MockWebGraphicsContext3D); 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Canvas2DLayerManager& manager = Canvas2DLayerManager::get(); 2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) manager.init(10, 5); 22409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) OwnPtr<SkDeferredCanvas> canvas = createCanvas(); 22509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) FakeCanvas2DLayerBridgePtr layer(adoptRef(new FakeCanvas2DLayerBridge(webContext.get(), canvas.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) { 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_FALSE(Canvas2DLayerManager::get().m_taskObserverActive); 240a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) layer->willUse(); 2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) layer->storageAllocatedForRecordingChanged(1); 2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_TRUE(Canvas2DLayerManager::get().m_taskObserverActive); 2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (skipCommands) { 244a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) layer->willUse(); 2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) layer->skippedPendingDrawCommands(); 2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 24751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) blink::Platform::current()->currentThread()->exitRunLoop(); 2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 25051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) class DeferredFrameTestTask : public blink::WebThread::Task { 2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) public: 2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DeferredFrameTestTask(Canvas2DLayerManagerTest* test, FakeCanvas2DLayerBridge* layer, bool skipCommands) 2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_test = test; 2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_layer = layer; 2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_skipCommands = skipCommands; 2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) virtual void run() OVERRIDE 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_test->doDeferredFrameTestTask(m_layer, m_skipCommands); 2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) private: 2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Canvas2DLayerManagerTest* m_test; 2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FakeCanvas2DLayerBridge* m_layer; 2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool m_skipCommands; 2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }; 2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void deferredFrameTest() 2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 27109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) OwnPtr<blink::MockWebGraphicsContext3D> webContext = adoptPtr(new blink::MockWebGraphicsContext3D); 2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Canvas2DLayerManager::get().init(10, 10); 27309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) OwnPtr<SkDeferredCanvas> canvas = createCanvas(); 27409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) FakeCanvas2DLayerBridgePtr layer(adoptRef(new FakeCanvas2DLayerBridge(webContext.get(), canvas.release()))); 275a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) blink::Platform::current()->currentThread()->postTask(new DeferredFrameTestTask(this, layer.get(), true)); 27651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) blink::Platform::current()->currentThread()->enterRunLoop(); 2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Verify that didProcessTask was called upon completion 2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_FALSE(Canvas2DLayerManager::get().m_taskObserverActive); 2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Verify that no flush was performed because frame is fresh 280a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) EXPECT_EQ(0, layer->m_flushCount); 2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Verify that no flushes are triggered as long as frame are fresh 283a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) blink::Platform::current()->currentThread()->postTask(new DeferredFrameTestTask(this, layer.get(), true)); 28451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) blink::Platform::current()->currentThread()->enterRunLoop(); 2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_FALSE(Canvas2DLayerManager::get().m_taskObserverActive); 286a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) EXPECT_EQ(0, layer->m_flushCount); 2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 288a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) blink::Platform::current()->currentThread()->postTask(new DeferredFrameTestTask(this, layer.get(), true)); 28951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) blink::Platform::current()->currentThread()->enterRunLoop(); 2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_FALSE(Canvas2DLayerManager::get().m_taskObserverActive); 291a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) EXPECT_EQ(0, layer->m_flushCount); 2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 293e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch // Verify that a flush is triggered when queue is accumulating a multi-frame backlog. 294a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) blink::Platform::current()->currentThread()->postTask(new DeferredFrameTestTask(this, layer.get(), false)); 29551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) blink::Platform::current()->currentThread()->enterRunLoop(); 2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_FALSE(Canvas2DLayerManager::get().m_taskObserverActive); 297a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) EXPECT_EQ(1, layer->m_flushCount); 2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 299a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) blink::Platform::current()->currentThread()->postTask(new DeferredFrameTestTask(this, layer.get(), false)); 30051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) blink::Platform::current()->currentThread()->enterRunLoop(); 3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EXPECT_FALSE(Canvas2DLayerManager::get().m_taskObserverActive); 302a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) EXPECT_EQ(2, layer->m_flushCount); 3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace { 3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)TEST_F(Canvas2DLayerManagerTest, testStorageAllocationTracking) 3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) storageAllocationTrackingTest(); 3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)TEST_F(Canvas2DLayerManagerTest, testEviction) 3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) evictionTest(); 3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)TEST_F(Canvas2DLayerManagerTest, testFlushEviction) 3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) flushEvictionTest(); 3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)TEST_F(Canvas2DLayerManagerTest, testDeferredFrame) 3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) deferredFrameTest(); 3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 32809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)TEST_F(Canvas2DLayerManagerTest, testHiddenCanvas) 32909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){ 33009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) hiddenCanvasTest(); 33109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)} 33209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 33309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)TEST_F(Canvas2DLayerManagerTest, testAddRemoveLayer) 33409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){ 33509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) addRemoveLayerTest(); 33609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)} 33709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 33809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)} // unnamed namespace 3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 340