1926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)/*
2926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * Copyright (C) 2012 Google Inc. All rights reserved.
3926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) *
4926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * Redistribution and use in source and binary forms, with or without
5926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * modification, are permitted provided that the following conditions
6926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * are met:
7926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) *
8926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * 1.  Redistributions of source code must retain the above copyright
9926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) *     notice, this list of conditions and the following disclaimer.
10926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * 2.  Redistributions in binary form must reproduce the above copyright
11926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) *     notice, this list of conditions and the following disclaimer in the
12926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) *     documentation and/or other materials provided with the distribution.
13926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) *
14926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
15926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) */
25926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
26926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#include "config.h"
27a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/ImageFrameGenerator.h"
28926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
29f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)#include "platform/SharedBuffer.h"
30f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)#include "platform/Task.h"
31a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/ImageDecodingStore.h"
3209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "platform/graphics/test/MockImageDecoder.h"
33f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)#include "public/platform/Platform.h"
34f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)#include "public/platform/WebThread.h"
35521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include <gtest/gtest.h>
36926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
37bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)namespace WebCore {
38926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
39926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)namespace {
40926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
41926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)// Helper methods to generate standard sizes.
42926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)SkISize fullSize() { return SkISize::Make(100, 100); }
43926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
44bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)} // namespace
45926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
46926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)class ImageFrameGeneratorTest : public ::testing::Test, public MockImageDecoderClient {
47926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)public:
4806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    virtual void SetUp() OVERRIDE
49926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
50d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        ImageDecodingStore::instance()->setCacheLimitInBytes(1024 * 1024);
5109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        ImageDecodingStore::instance()->setImageCachingEnabled(true);
52926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        m_data = SharedBuffer::create();
5309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        m_generator = ImageFrameGenerator::create(fullSize(), m_data, false);
54bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        useMockImageDecoderFactory();
55926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        m_decodersDestroyed = 0;
56926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        m_frameBufferRequestCount = 0;
57c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)        m_status = ImageFrame::FrameEmpty;
58926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
59926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
6006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    virtual void TearDown() OVERRIDE
61926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
62d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        ImageDecodingStore::instance()->clear();
63926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
64926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
6506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    virtual void decoderBeingDestroyed() OVERRIDE
66926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
67926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        ++m_decodersDestroyed;
68926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
69926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
7006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    virtual void frameBufferRequested() OVERRIDE
71926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
72926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        ++m_frameBufferRequestCount;
73926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
74926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
7506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    virtual ImageFrame::Status status() OVERRIDE
76926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
77c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)        ImageFrame::Status currentStatus = m_status;
78c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)        m_status = m_nextFrameStatus;
79e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        return currentStatus;
80926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
81926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
8206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    virtual size_t frameCount() OVERRIDE { return 1; }
8306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    virtual int repetitionCount() const OVERRIDE { return cAnimationNone; }
8406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    virtual float frameDuration() const OVERRIDE { return 0; }
857757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
86926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)protected:
87bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    void useMockImageDecoderFactory()
88bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    {
89bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        m_generator->setImageDecoderFactory(MockImageDecoderFactory::create(this, fullSize()));
90bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    }
91bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)
92926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    PassOwnPtr<ScaledImageFragment> createCompleteImage(const SkISize& size)
93926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
94926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        SkBitmap bitmap;
9543e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)        if (!bitmap.allocN32Pixels(size.width(), size.height()))
9643e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)            return nullptr;
97e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        return ScaledImageFragment::createComplete(size, 0, bitmap);
98926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
99926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
100926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    void addNewData()
101926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    {
102926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        m_data->append("g", 1);
103926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        m_generator->setData(m_data, false);
104926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
105926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
106c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    void setFrameStatus(ImageFrame::Status status)  { m_status = m_nextFrameStatus = status; }
107c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    void setNextFrameStatus(ImageFrame::Status status)  { m_nextFrameStatus = status; }
108926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
109bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    SkBitmap::Allocator* allocator() const { return m_generator->allocator(); }
110bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    void setAllocator(PassOwnPtr<SkBitmap::Allocator> allocator)
111bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    {
112bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        m_generator->setAllocator(allocator);
113bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    }
114bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)
115bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    PassOwnPtr<ScaledImageFragment> decode(size_t index)
116bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    {
117bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        ImageDecoder* decoder = 0;
118d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        OwnPtr<ScaledImageFragment> fragment = m_generator->decode(index, &decoder);
119d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        delete decoder;
120d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return fragment.release();
121bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    }
122bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)
123926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    RefPtr<SharedBuffer> m_data;
124926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    RefPtr<ImageFrameGenerator> m_generator;
125926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    int m_decodersDestroyed;
126926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    int m_frameBufferRequestCount;
127c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    ImageFrame::Status m_status;
128c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    ImageFrame::Status m_nextFrameStatus;
129926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)};
130926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
131926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)TEST_F(ImageFrameGeneratorTest, cacheHit)
132926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
13343e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    OwnPtr<ScaledImageFragment> completeImageTemp = createCompleteImage(fullSize());
13443e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)    ASSERT_TRUE(completeImageTemp);
135926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    const ScaledImageFragment* fullImage = ImageDecodingStore::instance()->insertAndLockCache(
13643e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)        m_generator.get(), completeImageTemp.release());
137926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    EXPECT_EQ(fullSize(), fullImage->scaledSize());
138926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ImageDecodingStore::instance()->unlockCache(m_generator.get(), fullImage);
139926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
140926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    const ScaledImageFragment* tempImage = m_generator->decodeAndScale(fullSize());
141926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    EXPECT_EQ(fullImage, tempImage);
142926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    EXPECT_EQ(fullSize(), tempImage->scaledSize());
1437757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    EXPECT_TRUE(m_generator->hasAlpha(0));
144926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ImageDecodingStore::instance()->unlockCache(m_generator.get(), tempImage);
145926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    EXPECT_EQ(0, m_frameBufferRequestCount);
146926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
147926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
148926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)TEST_F(ImageFrameGeneratorTest, cacheMissWithIncompleteDecode)
149926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
150926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    setFrameStatus(ImageFrame::FramePartial);
151926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
15209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    const ScaledImageFragment* tempImage = m_generator->decodeAndScale(fullSize());
153926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    EXPECT_FALSE(tempImage->isComplete());
154926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    EXPECT_EQ(1, m_frameBufferRequestCount);
155926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ImageDecodingStore::instance()->unlockCache(m_generator.get(), tempImage);
156f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
157f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    EXPECT_EQ(1, ImageDecodingStore::instance()->imageCacheEntries());
158f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    EXPECT_EQ(1, ImageDecodingStore::instance()->decoderCacheEntries());
159926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
160926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    addNewData();
161926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    tempImage = m_generator->decodeAndScale(fullSize());
162926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    EXPECT_FALSE(tempImage->isComplete());
163926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    EXPECT_EQ(2, m_frameBufferRequestCount);
164926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ImageDecodingStore::instance()->unlockCache(m_generator.get(), tempImage);
165f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    EXPECT_EQ(3, ImageDecodingStore::instance()->cacheEntries());
166f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    EXPECT_EQ(2, ImageDecodingStore::instance()->imageCacheEntries());
167f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    EXPECT_EQ(1, ImageDecodingStore::instance()->decoderCacheEntries());
168926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    EXPECT_EQ(0, m_decodersDestroyed);
169926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
170926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
171926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)TEST_F(ImageFrameGeneratorTest, incompleteDecodeBecomesComplete)
172926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
173926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    setFrameStatus(ImageFrame::FramePartial);
174926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
175926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    const ScaledImageFragment* tempImage = m_generator->decodeAndScale(fullSize());
176926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    EXPECT_FALSE(tempImage->isComplete());
177926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    EXPECT_EQ(1, m_frameBufferRequestCount);
178926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    EXPECT_EQ(0, m_decodersDestroyed);
179926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ImageDecodingStore::instance()->unlockCache(m_generator.get(), tempImage);
180f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
181f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    EXPECT_EQ(1, ImageDecodingStore::instance()->imageCacheEntries());
182f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    EXPECT_EQ(1, ImageDecodingStore::instance()->decoderCacheEntries());
183926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
184926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    setFrameStatus(ImageFrame::FrameComplete);
185926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    addNewData();
186926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
187926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    tempImage = m_generator->decodeAndScale(fullSize());
188926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    EXPECT_TRUE(tempImage->isComplete());
189926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    EXPECT_EQ(2, m_frameBufferRequestCount);
190926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    EXPECT_EQ(1, m_decodersDestroyed);
191926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ImageDecodingStore::instance()->unlockCache(m_generator.get(), tempImage);
192f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
193f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    EXPECT_EQ(2, ImageDecodingStore::instance()->imageCacheEntries());
194f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    EXPECT_EQ(0, ImageDecodingStore::instance()->decoderCacheEntries());
195926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
196926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    tempImage = m_generator->decodeAndScale(fullSize());
197926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    EXPECT_TRUE(tempImage->isComplete());
198926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    EXPECT_EQ(2, m_frameBufferRequestCount);
199926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ImageDecodingStore::instance()->unlockCache(m_generator.get(), tempImage);
200926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
201926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
202f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)static void decodeThreadMain(ImageFrameGenerator* generator)
203926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
204926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    const ScaledImageFragment* tempImage = generator->decodeAndScale(fullSize());
205926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ImageDecodingStore::instance()->unlockCache(generator, tempImage);
206926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
207926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
208926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)TEST_F(ImageFrameGeneratorTest, incompleteDecodeBecomesCompleteMultiThreaded)
209926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
210926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    setFrameStatus(ImageFrame::FramePartial);
211926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
212926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    const ScaledImageFragment* tempImage = m_generator->decodeAndScale(fullSize());
213926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    EXPECT_FALSE(tempImage->isComplete());
214926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    EXPECT_EQ(1, m_frameBufferRequestCount);
215926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    EXPECT_EQ(0, m_decodersDestroyed);
216926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ImageDecodingStore::instance()->unlockCache(m_generator.get(), tempImage);
217f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
218f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    EXPECT_EQ(1, ImageDecodingStore::instance()->imageCacheEntries());
219f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    EXPECT_EQ(1, ImageDecodingStore::instance()->decoderCacheEntries());
220926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
221d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // LocalFrame can now be decoded completely.
222926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    setFrameStatus(ImageFrame::FrameComplete);
223926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    addNewData();
22451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    OwnPtr<blink::WebThread> thread = adoptPtr(blink::Platform::current()->createThread("DecodeThread"));
225f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    thread->postTask(new Task(WTF::bind(&decodeThreadMain, m_generator.get())));
226f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    thread.clear();
227926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
228926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    EXPECT_EQ(2, m_frameBufferRequestCount);
229926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    EXPECT_EQ(1, m_decodersDestroyed);
230f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
231f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    EXPECT_EQ(2, ImageDecodingStore::instance()->imageCacheEntries());
232f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    EXPECT_EQ(0, ImageDecodingStore::instance()->decoderCacheEntries());
233926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
234926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    tempImage = m_generator->decodeAndScale(fullSize());
235926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    EXPECT_TRUE(tempImage->isComplete());
236926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    EXPECT_EQ(2, m_frameBufferRequestCount);
237926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ImageDecodingStore::instance()->unlockCache(m_generator.get(), tempImage);
238926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
239926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
240e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben MurdochTEST_F(ImageFrameGeneratorTest, incompleteBitmapCopied)
241e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch{
242e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    setFrameStatus(ImageFrame::FramePartial);
243e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch
244e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    const ScaledImageFragment* tempImage= m_generator->decodeAndScale(fullSize());
245e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    EXPECT_FALSE(tempImage->isComplete());
246e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    EXPECT_EQ(1, m_frameBufferRequestCount);
247e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch
248e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    ImageDecoder* tempDecoder = 0;
249e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    EXPECT_TRUE(ImageDecodingStore::instance()->lockDecoder(m_generator.get(), fullSize(), &tempDecoder));
250e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    ASSERT_TRUE(tempDecoder);
251e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    EXPECT_NE(tempDecoder->frameBufferAtIndex(0)->getSkBitmap().getPixels(), tempImage->bitmap().getPixels());
252e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    ImageDecodingStore::instance()->unlockCache(m_generator.get(), tempImage);
253e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    ImageDecodingStore::instance()->unlockDecoder(m_generator.get(), tempDecoder);
254e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch}
255e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch
256e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)TEST_F(ImageFrameGeneratorTest, resumeDecodeEmptyFrameTurnsComplete)
2577757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch{
2587757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    m_generator = ImageFrameGenerator::create(fullSize(), m_data, false, true);
259bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    useMockImageDecoderFactory();
2607757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    setFrameStatus(ImageFrame::FrameComplete);
2617757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
2627757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    const ScaledImageFragment* tempImage = m_generator->decodeAndScale(fullSize(), 0);
2637757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    EXPECT_TRUE(tempImage->isComplete());
2647757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    ImageDecodingStore::instance()->unlockCache(m_generator.get(), tempImage);
2657757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
2667757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    setFrameStatus(ImageFrame::FrameEmpty);
267e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    setNextFrameStatus(ImageFrame::FrameComplete);
2687757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    EXPECT_FALSE(m_generator->decodeAndScale(fullSize(), 1));
2697757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch}
2707757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
2717757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen MurdochTEST_F(ImageFrameGeneratorTest, frameHasAlpha)
2727757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch{
2737757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    setFrameStatus(ImageFrame::FramePartial);
274d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ImageDecodingStore::instance()->unlockCache(m_generator.get(), m_generator->decodeAndScale(fullSize(), 1));
275d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    EXPECT_TRUE(m_generator->hasAlpha(1));
2767757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
2777757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    ImageDecoder* tempDecoder = 0;
2787757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    EXPECT_TRUE(ImageDecodingStore::instance()->lockDecoder(m_generator.get(), fullSize(), &tempDecoder));
2797757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    ASSERT_TRUE(tempDecoder);
2807757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    static_cast<MockImageDecoder*>(tempDecoder)->setFrameHasAlpha(false);
2817757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    ImageDecodingStore::instance()->unlockDecoder(m_generator.get(), tempDecoder);
2827757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
2837757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    setFrameStatus(ImageFrame::FrameComplete);
284d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ImageDecodingStore::instance()->unlockCache(m_generator.get(), m_generator->decodeAndScale(fullSize(), 1));
285d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    EXPECT_FALSE(m_generator->hasAlpha(1));
2867757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch}
2877757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
288bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)namespace {
289bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)
290bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)class MockAllocator : public SkBitmap::Allocator {
291bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)public:
292bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    // N starts from 0.
293bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    MockAllocator(int failAtNthCall)
294bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        : m_callCount(0)
295bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        , m_failAtNthCall(failAtNthCall)
296bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        , m_defaultAllocator(adoptPtr(new DiscardablePixelRefAllocator()))
297bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    {
298bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    }
299bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)
300bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* colorTable) OVERRIDE
301bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    {
302bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        if (m_callCount++ == m_failAtNthCall)
303bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)            return false;
304bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        return m_defaultAllocator->allocPixelRef(bitmap, colorTable);
305bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    }
306bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)
307bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    int m_callCount;
308bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    int m_failAtNthCall;
309bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    OwnPtr<SkBitmap::Allocator> m_defaultAllocator;
310bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)};
311bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)
312926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} // namespace
313bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)
314bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)TEST_F(ImageFrameGeneratorTest, decodingAllocatorFailure)
315bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles){
316bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    // Try to emulate allocation failures at different stages. For now, the
317bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    // first allocation is for the bitmap in ImageFrame, the second is for the
318bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    // copy of partial bitmap. The loop will still work if the number or purpose
319bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    // of allocations change in the future.
320bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    for (int i = 0; ; ++i) {
321bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        SCOPED_TRACE(testing::Message() << "Allocation failure at call " << i);
322bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        setFrameStatus(ImageFrame::FramePartial);
323bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        setAllocator(adoptPtr(new MockAllocator(i)));
324bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        OwnPtr<ScaledImageFragment> image = decode(0);
325bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        if (i >= static_cast<MockAllocator*>(allocator())->m_callCount) {
326bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)            // We have tested failures of all stages. This time all allocations
327bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)            // were successful.
328bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)            EXPECT_TRUE(image);
329bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)            break;
330bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        }
331bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)        EXPECT_FALSE(image);
332bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)    }
333bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)}
334bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)
335bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)} // namespace WebCore
336