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