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