Upstream version 5.34.92.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / platform / graphics / ImageFrameGeneratorTest.cpp
1 /*
2  * Copyright (C) 2012 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "platform/graphics/ImageFrameGenerator.h"
28
29 #include "platform/SharedBuffer.h"
30 #include "platform/Task.h"
31 #include "platform/graphics/ImageDecodingStore.h"
32 #include "platform/graphics/test/MockImageDecoder.h"
33 #include "public/platform/Platform.h"
34 #include "public/platform/WebThread.h"
35 #include <gtest/gtest.h>
36
37 namespace WebCore {
38
39 namespace {
40
41 // Helper methods to generate standard sizes.
42 SkISize fullSize() { return SkISize::Make(100, 100); }
43
44 } // namespace
45
46 class ImageFrameGeneratorTest : public ::testing::Test, public MockImageDecoderClient {
47 public:
48     virtual void SetUp() OVERRIDE
49     {
50         ImageDecodingStore::initializeOnce();
51         ImageDecodingStore::instance()->setImageCachingEnabled(true);
52         m_data = SharedBuffer::create();
53         m_generator = ImageFrameGenerator::create(fullSize(), m_data, true);
54         useMockImageDecoderFactory();
55         m_decodersDestroyed = 0;
56         m_frameBufferRequestCount = 0;
57         m_status = ImageFrame::FrameEmpty;
58     }
59
60     virtual void TearDown() OVERRIDE
61     {
62         ImageDecodingStore::shutdown();
63     }
64
65     virtual void decoderBeingDestroyed() OVERRIDE
66     {
67         ++m_decodersDestroyed;
68     }
69
70     virtual void frameBufferRequested() OVERRIDE
71     {
72         ++m_frameBufferRequestCount;
73     }
74
75     virtual ImageFrame::Status status() OVERRIDE
76     {
77         ImageFrame::Status currentStatus = m_status;
78         m_status = m_nextFrameStatus;
79         return currentStatus;
80     }
81
82     virtual size_t frameCount() OVERRIDE { return 1; }
83     virtual int repetitionCount() const OVERRIDE { return cAnimationNone; }
84     virtual float frameDuration() const OVERRIDE { return 0; }
85
86 protected:
87     void useMockImageDecoderFactory()
88     {
89         m_generator->setImageDecoderFactory(MockImageDecoderFactory::create(this, fullSize()));
90     }
91
92     PassOwnPtr<ScaledImageFragment> createCompleteImage(const SkISize& size)
93     {
94         SkBitmap bitmap;
95         bitmap.setConfig(SkBitmap::kARGB_8888_Config, size.width(), size.height());
96         bitmap.allocPixels();
97         return ScaledImageFragment::createComplete(size, 0, bitmap);
98     }
99
100     void addNewData()
101     {
102         m_data->append("g", 1);
103         m_generator->setData(m_data, false);
104     }
105
106     void setFrameStatus(ImageFrame::Status status)  { m_status = m_nextFrameStatus = status; }
107     void setNextFrameStatus(ImageFrame::Status status)  { m_nextFrameStatus = status; }
108
109     SkBitmap::Allocator* allocator() const { return m_generator->allocator(); }
110     void setAllocator(PassOwnPtr<SkBitmap::Allocator> allocator)
111     {
112         m_generator->setAllocator(allocator);
113     }
114
115     PassOwnPtr<ScaledImageFragment> decode(size_t index)
116     {
117         ImageDecoder* decoder = 0;
118         return m_generator->decode(index, &decoder);
119     }
120
121     RefPtr<SharedBuffer> m_data;
122     RefPtr<ImageFrameGenerator> m_generator;
123     int m_decodersDestroyed;
124     int m_frameBufferRequestCount;
125     ImageFrame::Status m_status;
126     ImageFrame::Status m_nextFrameStatus;
127 };
128
129 TEST_F(ImageFrameGeneratorTest, cacheHit)
130 {
131     const ScaledImageFragment* fullImage = ImageDecodingStore::instance()->insertAndLockCache(
132         m_generator.get(), createCompleteImage(fullSize()));
133     EXPECT_EQ(fullSize(), fullImage->scaledSize());
134     ImageDecodingStore::instance()->unlockCache(m_generator.get(), fullImage);
135
136     const ScaledImageFragment* tempImage = m_generator->decodeAndScale(fullSize());
137     EXPECT_EQ(fullImage, tempImage);
138     EXPECT_EQ(fullSize(), tempImage->scaledSize());
139     EXPECT_TRUE(m_generator->hasAlpha(0));
140     ImageDecodingStore::instance()->unlockCache(m_generator.get(), tempImage);
141     EXPECT_EQ(0, m_frameBufferRequestCount);
142 }
143
144 TEST_F(ImageFrameGeneratorTest, cacheMissWithIncompleteDecode)
145 {
146     setFrameStatus(ImageFrame::FramePartial);
147
148     const ScaledImageFragment* tempImage= m_generator->decodeAndScale(fullSize());
149     EXPECT_FALSE(tempImage->isComplete());
150     EXPECT_EQ(1, m_frameBufferRequestCount);
151     ImageDecodingStore::instance()->unlockCache(m_generator.get(), tempImage);
152     EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
153     EXPECT_EQ(1, ImageDecodingStore::instance()->imageCacheEntries());
154     EXPECT_EQ(1, ImageDecodingStore::instance()->decoderCacheEntries());
155
156     addNewData();
157     tempImage = m_generator->decodeAndScale(fullSize());
158     EXPECT_FALSE(tempImage->isComplete());
159     EXPECT_EQ(2, m_frameBufferRequestCount);
160     ImageDecodingStore::instance()->unlockCache(m_generator.get(), tempImage);
161     EXPECT_EQ(3, ImageDecodingStore::instance()->cacheEntries());
162     EXPECT_EQ(2, ImageDecodingStore::instance()->imageCacheEntries());
163     EXPECT_EQ(1, ImageDecodingStore::instance()->decoderCacheEntries());
164     EXPECT_EQ(0, m_decodersDestroyed);
165 }
166
167 TEST_F(ImageFrameGeneratorTest, incompleteDecodeBecomesComplete)
168 {
169     setFrameStatus(ImageFrame::FramePartial);
170
171     const ScaledImageFragment* tempImage = m_generator->decodeAndScale(fullSize());
172     EXPECT_FALSE(tempImage->isComplete());
173     EXPECT_EQ(1, m_frameBufferRequestCount);
174     EXPECT_EQ(0, m_decodersDestroyed);
175     ImageDecodingStore::instance()->unlockCache(m_generator.get(), tempImage);
176     EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
177     EXPECT_EQ(1, ImageDecodingStore::instance()->imageCacheEntries());
178     EXPECT_EQ(1, ImageDecodingStore::instance()->decoderCacheEntries());
179
180     setFrameStatus(ImageFrame::FrameComplete);
181     addNewData();
182
183     tempImage = m_generator->decodeAndScale(fullSize());
184     EXPECT_TRUE(tempImage->isComplete());
185     EXPECT_EQ(2, m_frameBufferRequestCount);
186     EXPECT_EQ(1, m_decodersDestroyed);
187     ImageDecodingStore::instance()->unlockCache(m_generator.get(), tempImage);
188     EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
189     EXPECT_EQ(2, ImageDecodingStore::instance()->imageCacheEntries());
190     EXPECT_EQ(0, ImageDecodingStore::instance()->decoderCacheEntries());
191
192     tempImage = m_generator->decodeAndScale(fullSize());
193     EXPECT_TRUE(tempImage->isComplete());
194     EXPECT_EQ(2, m_frameBufferRequestCount);
195     ImageDecodingStore::instance()->unlockCache(m_generator.get(), tempImage);
196 }
197
198 static void decodeThreadMain(ImageFrameGenerator* generator)
199 {
200     const ScaledImageFragment* tempImage = generator->decodeAndScale(fullSize());
201     ImageDecodingStore::instance()->unlockCache(generator, tempImage);
202 }
203
204 TEST_F(ImageFrameGeneratorTest, incompleteDecodeBecomesCompleteMultiThreaded)
205 {
206     setFrameStatus(ImageFrame::FramePartial);
207
208     const ScaledImageFragment* tempImage = m_generator->decodeAndScale(fullSize());
209     EXPECT_FALSE(tempImage->isComplete());
210     EXPECT_EQ(1, m_frameBufferRequestCount);
211     EXPECT_EQ(0, m_decodersDestroyed);
212     ImageDecodingStore::instance()->unlockCache(m_generator.get(), tempImage);
213     EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
214     EXPECT_EQ(1, ImageDecodingStore::instance()->imageCacheEntries());
215     EXPECT_EQ(1, ImageDecodingStore::instance()->decoderCacheEntries());
216
217     // Frame can now be decoded completely.
218     setFrameStatus(ImageFrame::FrameComplete);
219     addNewData();
220     OwnPtr<blink::WebThread> thread = adoptPtr(blink::Platform::current()->createThread("DecodeThread"));
221     thread->postTask(new Task(WTF::bind(&decodeThreadMain, m_generator.get())));
222     thread.clear();
223
224     EXPECT_EQ(2, m_frameBufferRequestCount);
225     EXPECT_EQ(1, m_decodersDestroyed);
226     EXPECT_EQ(2, ImageDecodingStore::instance()->cacheEntries());
227     EXPECT_EQ(2, ImageDecodingStore::instance()->imageCacheEntries());
228     EXPECT_EQ(0, ImageDecodingStore::instance()->decoderCacheEntries());
229
230     tempImage = m_generator->decodeAndScale(fullSize());
231     EXPECT_TRUE(tempImage->isComplete());
232     EXPECT_EQ(2, m_frameBufferRequestCount);
233     ImageDecodingStore::instance()->unlockCache(m_generator.get(), tempImage);
234 }
235
236 TEST_F(ImageFrameGeneratorTest, incompleteBitmapCopied)
237 {
238     setFrameStatus(ImageFrame::FramePartial);
239
240     const ScaledImageFragment* tempImage= m_generator->decodeAndScale(fullSize());
241     EXPECT_FALSE(tempImage->isComplete());
242     EXPECT_EQ(1, m_frameBufferRequestCount);
243
244     ImageDecoder* tempDecoder = 0;
245     EXPECT_TRUE(ImageDecodingStore::instance()->lockDecoder(m_generator.get(), fullSize(), &tempDecoder));
246     ASSERT_TRUE(tempDecoder);
247     EXPECT_NE(tempDecoder->frameBufferAtIndex(0)->getSkBitmap().getPixels(), tempImage->bitmap().getPixels());
248     ImageDecodingStore::instance()->unlockCache(m_generator.get(), tempImage);
249     ImageDecodingStore::instance()->unlockDecoder(m_generator.get(), tempDecoder);
250 }
251
252 TEST_F(ImageFrameGeneratorTest, resumeDecodeEmptyFrameTurnsComplete)
253 {
254     m_generator = ImageFrameGenerator::create(fullSize(), m_data, false, true);
255     useMockImageDecoderFactory();
256     setFrameStatus(ImageFrame::FrameComplete);
257
258     const ScaledImageFragment* tempImage = m_generator->decodeAndScale(fullSize(), 0);
259     EXPECT_TRUE(tempImage->isComplete());
260     ImageDecodingStore::instance()->unlockCache(m_generator.get(), tempImage);
261
262     setFrameStatus(ImageFrame::FrameEmpty);
263     setNextFrameStatus(ImageFrame::FrameComplete);
264     EXPECT_FALSE(m_generator->decodeAndScale(fullSize(), 1));
265 }
266
267 TEST_F(ImageFrameGeneratorTest, frameHasAlpha)
268 {
269     setFrameStatus(ImageFrame::FramePartial);
270     ImageDecodingStore::instance()->unlockCache(m_generator.get(), m_generator->decodeAndScale(fullSize(), 0));
271     EXPECT_TRUE(m_generator->hasAlpha(0));
272
273     ImageDecoder* tempDecoder = 0;
274     EXPECT_TRUE(ImageDecodingStore::instance()->lockDecoder(m_generator.get(), fullSize(), &tempDecoder));
275     ASSERT_TRUE(tempDecoder);
276     static_cast<MockImageDecoder*>(tempDecoder)->setFrameHasAlpha(false);
277     ImageDecodingStore::instance()->unlockDecoder(m_generator.get(), tempDecoder);
278
279     setFrameStatus(ImageFrame::FrameComplete);
280     ImageDecodingStore::instance()->unlockCache(m_generator.get(), m_generator->decodeAndScale(fullSize(), 0));
281     EXPECT_FALSE(m_generator->hasAlpha(0));
282 }
283
284 namespace {
285
286 class MockAllocator : public SkBitmap::Allocator {
287 public:
288     // N starts from 0.
289     MockAllocator(int failAtNthCall)
290         : m_callCount(0)
291         , m_failAtNthCall(failAtNthCall)
292         , m_defaultAllocator(adoptPtr(new DiscardablePixelRefAllocator()))
293     {
294     }
295
296     virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* colorTable) OVERRIDE
297     {
298         if (m_callCount++ == m_failAtNthCall)
299             return false;
300         return m_defaultAllocator->allocPixelRef(bitmap, colorTable);
301     }
302
303     int m_callCount;
304     int m_failAtNthCall;
305     OwnPtr<SkBitmap::Allocator> m_defaultAllocator;
306 };
307
308 } // namespace
309
310 TEST_F(ImageFrameGeneratorTest, decodingAllocatorFailure)
311 {
312     // Try to emulate allocation failures at different stages. For now, the
313     // first allocation is for the bitmap in ImageFrame, the second is for the
314     // copy of partial bitmap. The loop will still work if the number or purpose
315     // of allocations change in the future.
316     for (int i = 0; ; ++i) {
317         SCOPED_TRACE(testing::Message() << "Allocation failure at call " << i);
318         setFrameStatus(ImageFrame::FramePartial);
319         setAllocator(adoptPtr(new MockAllocator(i)));
320         OwnPtr<ScaledImageFragment> image = decode(0);
321         if (i >= static_cast<MockAllocator*>(allocator())->m_callCount) {
322             // We have tested failures of all stages. This time all allocations
323             // were successful.
324             EXPECT_TRUE(image);
325             break;
326         }
327         EXPECT_FALSE(image);
328     }
329 }
330
331 } // namespace WebCore