Passing alpha to DeferredImageDecoder once decoding completes
[WebKit-https.git] / Source / WebKit / chromium / tests / 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
28 #include "ImageFrameGenerator.h"
29
30 #include "ImageDecodingStore.h"
31 #include "MockImageDecoder.h"
32 #include "SharedBuffer.h"
33 #include <gtest/gtest.h>
34 #include <wtf/Threading.h>
35
36 using namespace WebCore;
37
38 namespace {
39
40 class ImageFrameGeneratorTest;
41
42 // Helper methods to generate standard sizes.
43 SkISize fullSize() { return SkISize::Make(100, 100); }
44 SkISize scaledSize() { return SkISize::Make(50, 50); }
45
46 class ImageFrameGeneratorTest;
47
48 class MockImageDecoderFactory : public ImageDecoderFactory {
49 public:
50     static PassOwnPtr<MockImageDecoderFactory> create(ImageFrameGeneratorTest* test)
51     {
52         return adoptPtr(new MockImageDecoderFactory(test));
53     }
54
55     virtual PassOwnPtr<ImageDecoder> create();
56
57 private:
58     MockImageDecoderFactory(ImageFrameGeneratorTest* test)
59         : m_test(test)
60     {
61     }
62
63     ImageFrameGeneratorTest* m_test;
64 };
65
66 class ImageFrameGeneratorTest : public ::testing::Test, public MockImageDecoderClient {
67 public:
68     virtual void SetUp()
69     {
70         ImageDecodingStore::initializeOnce();
71         m_data = SharedBuffer::create();
72         m_generator = ImageFrameGenerator::create(fullSize(), m_data, true);
73         m_generator->setImageDecoderFactoryForTesting(MockImageDecoderFactory::create(this));
74         m_decodersDestroyed = 0;
75         m_frameBufferRequestCount = 0;
76         m_frameStatus = ImageFrame::FrameEmpty;
77     }
78
79     virtual void TearDown()
80     {
81         ImageDecodingStore::shutdown();
82     }
83
84     virtual void decoderBeingDestroyed()
85     {
86         ++m_decodersDestroyed;
87     }
88
89     virtual void frameBufferRequested()
90     {
91         ++m_frameBufferRequestCount;
92     }
93
94     virtual ImageFrame::FrameStatus frameStatus()
95     {
96         return m_frameStatus;
97     }
98
99 protected:
100     PassOwnPtr<ScaledImageFragment> createCompleteImage(const SkISize& size)
101     {
102         SkBitmap bitmap;
103         bitmap.setConfig(SkBitmap::kARGB_8888_Config, size.width(), size.height());
104         bitmap.allocPixels();
105         return ScaledImageFragment::create(size, bitmap, true);
106     }
107
108     void addNewData()
109     {
110         m_data->append("g", 1);
111         m_generator->setData(m_data, false);
112     }
113
114     void setFrameStatus(ImageFrame::FrameStatus status)  { m_frameStatus = status; }
115
116     RefPtr<SharedBuffer> m_data;
117     RefPtr<ImageFrameGenerator> m_generator;
118     int m_decodersDestroyed;
119     int m_frameBufferRequestCount;
120     ImageFrame::FrameStatus m_frameStatus;
121 };
122
123 PassOwnPtr<ImageDecoder> MockImageDecoderFactory::create()
124 {
125     OwnPtr<MockImageDecoder> decoder = MockImageDecoder::create(m_test);
126     decoder->setSize(fullSize().width(), fullSize().height());
127     decoder->setFrameHasAlpha(false);
128     return decoder.release();
129 }
130
131 TEST_F(ImageFrameGeneratorTest, cacheHit)
132 {
133     const ScaledImageFragment* fullImage = ImageDecodingStore::instance()->insertAndLockCache(
134         m_generator.get(), createCompleteImage(fullSize()));
135     EXPECT_EQ(fullSize(), fullImage->scaledSize());
136     ImageDecodingStore::instance()->unlockCache(m_generator.get(), fullImage);
137
138     const ScaledImageFragment* tempImage = m_generator->decodeAndScale(fullSize());
139     EXPECT_EQ(fullImage, tempImage);
140     EXPECT_EQ(fullSize(), tempImage->scaledSize());
141     EXPECT_TRUE(m_generator->hasAlpha());
142     ImageDecodingStore::instance()->unlockCache(m_generator.get(), tempImage);
143     EXPECT_EQ(0, m_frameBufferRequestCount);
144 }
145
146 TEST_F(ImageFrameGeneratorTest, cacheMissWithScale)
147 {
148     const ScaledImageFragment* fullImage = ImageDecodingStore::instance()->insertAndLockCache(
149         m_generator.get(), createCompleteImage(fullSize()));
150     EXPECT_EQ(fullSize(), fullImage->scaledSize());
151     ImageDecodingStore::instance()->unlockCache(m_generator.get(), fullImage);
152
153     // Cache miss because of scaled size not found.
154     const ScaledImageFragment* scaledImage = m_generator->decodeAndScale(scaledSize());
155     EXPECT_NE(fullImage, scaledImage);
156     EXPECT_EQ(scaledSize(), scaledImage->scaledSize());
157     EXPECT_TRUE(m_generator->hasAlpha());
158     ImageDecodingStore::instance()->unlockCache(m_generator.get(), scaledImage);
159
160     // Cache hit.
161     const ScaledImageFragment* tempImage = m_generator->decodeAndScale(scaledSize());
162     EXPECT_EQ(scaledImage, tempImage);
163     EXPECT_EQ(scaledSize(), tempImage->scaledSize());
164     EXPECT_TRUE(m_generator->hasAlpha());
165     ImageDecodingStore::instance()->unlockCache(m_generator.get(), tempImage);
166     EXPECT_EQ(0, m_frameBufferRequestCount);
167 }
168
169 TEST_F(ImageFrameGeneratorTest, cacheMissWithDecodeAndScale)
170 {
171     setFrameStatus(ImageFrame::FrameComplete);
172
173     // Cache miss.
174     const ScaledImageFragment* scaledImage = m_generator->decodeAndScale(scaledSize());
175     EXPECT_EQ(1, m_frameBufferRequestCount);
176     EXPECT_EQ(scaledSize(), scaledImage->scaledSize());
177     EXPECT_FALSE(m_generator->hasAlpha());
178     ImageDecodingStore::instance()->unlockCache(m_generator.get(), scaledImage);
179     EXPECT_EQ(1, m_decodersDestroyed);
180
181     // Cache hit.
182     const ScaledImageFragment* fullImage = m_generator->decodeAndScale(fullSize());
183     EXPECT_NE(scaledImage, fullImage);
184     EXPECT_EQ(fullSize(), fullImage->scaledSize());
185     EXPECT_FALSE(m_generator->hasAlpha());
186     ImageDecodingStore::instance()->unlockCache(m_generator.get(), fullImage);
187
188     // Cache hit.
189     const ScaledImageFragment* tempImage = m_generator->decodeAndScale(scaledSize());
190     EXPECT_EQ(scaledImage, tempImage);
191     EXPECT_EQ(scaledSize(), tempImage->scaledSize());
192     EXPECT_FALSE(m_generator->hasAlpha());
193     ImageDecodingStore::instance()->unlockCache(m_generator.get(), tempImage);
194     EXPECT_EQ(1, m_frameBufferRequestCount);
195 }
196
197 TEST_F(ImageFrameGeneratorTest, cacheMissWithIncompleteDecode)
198 {
199     setFrameStatus(ImageFrame::FramePartial);
200
201     const ScaledImageFragment* tempImage= m_generator->decodeAndScale(fullSize());
202     EXPECT_FALSE(tempImage->isComplete());
203     EXPECT_EQ(1, m_frameBufferRequestCount);
204     ImageDecodingStore::instance()->unlockCache(m_generator.get(), tempImage);
205     EXPECT_EQ(1u, ImageDecodingStore::instance()->cacheEntries());
206
207     addNewData();
208     tempImage = m_generator->decodeAndScale(fullSize());
209     EXPECT_FALSE(tempImage->isComplete());
210     EXPECT_EQ(2, m_frameBufferRequestCount);
211     ImageDecodingStore::instance()->unlockCache(m_generator.get(), tempImage);
212     EXPECT_EQ(1u, ImageDecodingStore::instance()->cacheEntries());
213     EXPECT_EQ(0, m_decodersDestroyed);
214 }
215
216 TEST_F(ImageFrameGeneratorTest, cacheMissWithIncompleteDecodeNoNewData)
217 {
218     setFrameStatus(ImageFrame::FramePartial);
219
220     const ScaledImageFragment* tempImage= m_generator->decodeAndScale(fullSize());
221     EXPECT_FALSE(tempImage->isComplete());
222     EXPECT_EQ(1, m_frameBufferRequestCount);
223     ImageDecodingStore::instance()->unlockCache(m_generator.get(), tempImage);
224     EXPECT_EQ(1u, ImageDecodingStore::instance()->cacheEntries());
225
226     tempImage = m_generator->decodeAndScale(fullSize());
227     EXPECT_FALSE(tempImage->isComplete());
228     EXPECT_EQ(1, m_frameBufferRequestCount);
229     ImageDecodingStore::instance()->unlockCache(m_generator.get(), tempImage);
230     EXPECT_EQ(1u, ImageDecodingStore::instance()->cacheEntries());
231     EXPECT_EQ(0, m_decodersDestroyed);
232 }
233
234 TEST_F(ImageFrameGeneratorTest, cacheMissWithIncompleteDecodeAndScale)
235 {
236     setFrameStatus(ImageFrame::FramePartial);
237
238     const ScaledImageFragment* tempImage= m_generator->decodeAndScale(scaledSize());
239     EXPECT_FALSE(tempImage->isComplete());
240     EXPECT_EQ(1, m_frameBufferRequestCount);
241     ImageDecodingStore::instance()->unlockCache(m_generator.get(), tempImage);
242     EXPECT_EQ(2u, ImageDecodingStore::instance()->cacheEntries());
243
244     addNewData();
245     tempImage = m_generator->decodeAndScale(scaledSize());
246     EXPECT_FALSE(tempImage->isComplete());
247     EXPECT_EQ(2, m_frameBufferRequestCount);
248     ImageDecodingStore::instance()->unlockCache(m_generator.get(), tempImage);
249     EXPECT_EQ(2u, ImageDecodingStore::instance()->cacheEntries());
250     EXPECT_EQ(0, m_decodersDestroyed);
251 }
252
253 TEST_F(ImageFrameGeneratorTest, incompleteDecodeBecomesComplete)
254 {
255     setFrameStatus(ImageFrame::FramePartial);
256
257     const ScaledImageFragment* tempImage = m_generator->decodeAndScale(fullSize());
258     EXPECT_FALSE(tempImage->isComplete());
259     EXPECT_EQ(1, m_frameBufferRequestCount);
260     EXPECT_EQ(0, m_decodersDestroyed);
261     ImageDecodingStore::instance()->unlockCache(m_generator.get(), tempImage);
262     EXPECT_EQ(1u, ImageDecodingStore::instance()->cacheEntries());
263
264     setFrameStatus(ImageFrame::FrameComplete);
265     addNewData();
266
267     tempImage = m_generator->decodeAndScale(fullSize());
268     EXPECT_TRUE(tempImage->isComplete());
269     EXPECT_EQ(2, m_frameBufferRequestCount);
270     EXPECT_EQ(1, m_decodersDestroyed);
271     ImageDecodingStore::instance()->unlockCache(m_generator.get(), tempImage);
272     EXPECT_EQ(1u, ImageDecodingStore::instance()->cacheEntries());
273
274     tempImage = m_generator->decodeAndScale(fullSize());
275     EXPECT_TRUE(tempImage->isComplete());
276     EXPECT_EQ(2, m_frameBufferRequestCount);
277     ImageDecodingStore::instance()->unlockCache(m_generator.get(), tempImage);
278 }
279
280 TEST_F(ImageFrameGeneratorTest, incompleteDecodeAndScaleBecomesComplete)
281 {
282     setFrameStatus(ImageFrame::FramePartial);
283
284     const ScaledImageFragment* tempImage = m_generator->decodeAndScale(scaledSize());
285     EXPECT_FALSE(tempImage->isComplete());
286     EXPECT_EQ(1, m_frameBufferRequestCount);
287     EXPECT_EQ(0, m_decodersDestroyed);
288     ImageDecodingStore::instance()->unlockCache(m_generator.get(), tempImage);
289     EXPECT_EQ(2u, ImageDecodingStore::instance()->cacheEntries());
290
291     setFrameStatus(ImageFrame::FrameComplete);
292     addNewData();
293
294     tempImage = m_generator->decodeAndScale(scaledSize());
295     EXPECT_TRUE(tempImage->isComplete());
296     EXPECT_EQ(2, m_frameBufferRequestCount);
297     EXPECT_EQ(1, m_decodersDestroyed);
298     ImageDecodingStore::instance()->unlockCache(m_generator.get(), tempImage);
299     EXPECT_EQ(2u, ImageDecodingStore::instance()->cacheEntries());
300
301     tempImage = m_generator->decodeAndScale(scaledSize());
302     EXPECT_TRUE(tempImage->isComplete());
303     ImageDecodingStore::instance()->unlockCache(m_generator.get(), tempImage);
304
305     tempImage = m_generator->decodeAndScale(fullSize());
306     EXPECT_TRUE(tempImage->isComplete());
307     ImageDecodingStore::instance()->unlockCache(m_generator.get(), tempImage);
308
309     EXPECT_EQ(2, m_frameBufferRequestCount);
310 }
311
312 static void decodeThreadMain(void* arg)
313 {
314     ImageFrameGenerator* generator = reinterpret_cast<ImageFrameGenerator*>(arg);
315     const ScaledImageFragment* tempImage = generator->decodeAndScale(fullSize());
316     ImageDecodingStore::instance()->unlockCache(generator, tempImage);
317 }
318
319 TEST_F(ImageFrameGeneratorTest, incompleteDecodeBecomesCompleteMultiThreaded)
320 {
321     WTF::initializeThreading();
322     setFrameStatus(ImageFrame::FramePartial);
323
324     const ScaledImageFragment* tempImage = m_generator->decodeAndScale(fullSize());
325     EXPECT_FALSE(tempImage->isComplete());
326     EXPECT_EQ(1, m_frameBufferRequestCount);
327     EXPECT_EQ(0, m_decodersDestroyed);
328     ImageDecodingStore::instance()->unlockCache(m_generator.get(), tempImage);
329     EXPECT_EQ(1u, ImageDecodingStore::instance()->cacheEntries());
330
331     // Frame can now be decoded completely.
332     setFrameStatus(ImageFrame::FrameComplete);
333     addNewData();
334     ThreadIdentifier threadID = createThread(&decodeThreadMain, m_generator.get(), "DecodeThread");
335     waitForThreadCompletion(threadID);
336
337     EXPECT_EQ(2, m_frameBufferRequestCount);
338     EXPECT_EQ(1, m_decodersDestroyed);
339     EXPECT_EQ(1u, ImageDecodingStore::instance()->cacheEntries());
340
341     tempImage = m_generator->decodeAndScale(fullSize());
342     EXPECT_TRUE(tempImage->isComplete());
343     EXPECT_EQ(2, m_frameBufferRequestCount);
344     ImageDecodingStore::instance()->unlockCache(m_generator.get(), tempImage);
345 }
346
347 } // namespace