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