Upstream version 11.40.277.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 blink {
38
39 namespace {
40
41 // Helper methods to generate standard sizes.
42 SkISize fullSize() { return SkISize::Make(100, 100); }
43
44 SkImageInfo imageInfo()
45 {
46     return SkImageInfo::Make(100, 100, kBGRA_8888_SkColorType, kOpaque_SkAlphaType);
47 }
48
49 } // namespace
50
51 class ImageFrameGeneratorTest : public ::testing::Test, public MockImageDecoderClient {
52 public:
53     virtual void SetUp() override
54     {
55         ImageDecodingStore::instance()->setCacheLimitInBytes(1024 * 1024);
56         m_data = SharedBuffer::create();
57         m_generator = ImageFrameGenerator::create(fullSize(), m_data, false);
58         useMockImageDecoderFactory();
59         m_decodersDestroyed = 0;
60         m_frameBufferRequestCount = 0;
61         m_status = ImageFrame::FrameEmpty;
62     }
63
64     virtual void TearDown() override
65     {
66         ImageDecodingStore::instance()->clear();
67     }
68
69     virtual void decoderBeingDestroyed() override
70     {
71         ++m_decodersDestroyed;
72     }
73
74     virtual void frameBufferRequested() override
75     {
76         ++m_frameBufferRequestCount;
77     }
78
79     virtual ImageFrame::Status status() override
80     {
81         ImageFrame::Status currentStatus = m_status;
82         m_status = m_nextFrameStatus;
83         return currentStatus;
84     }
85
86     virtual size_t frameCount() override { return 1; }
87     virtual int repetitionCount() const override { return cAnimationNone; }
88     virtual float frameDuration() const override { return 0; }
89
90 protected:
91     void useMockImageDecoderFactory()
92     {
93         m_generator->setImageDecoderFactory(MockImageDecoderFactory::create(this, fullSize()));
94     }
95
96     void addNewData()
97     {
98         m_data->append("g", 1);
99         m_generator->setData(m_data, false);
100     }
101
102     void setFrameStatus(ImageFrame::Status status)  { m_status = m_nextFrameStatus = status; }
103     void setNextFrameStatus(ImageFrame::Status status)  { m_nextFrameStatus = status; }
104
105     RefPtr<SharedBuffer> m_data;
106     RefPtr<ImageFrameGenerator> m_generator;
107     int m_decodersDestroyed;
108     int m_frameBufferRequestCount;
109     ImageFrame::Status m_status;
110     ImageFrame::Status m_nextFrameStatus;
111 };
112
113 TEST_F(ImageFrameGeneratorTest, incompleteDecode)
114 {
115     setFrameStatus(ImageFrame::FramePartial);
116
117     char buffer[100 * 100 * 4];
118     m_generator->decodeAndScale(imageInfo(), 0, buffer, 100 * 4);
119     EXPECT_EQ(1, m_frameBufferRequestCount);
120
121     addNewData();
122     m_generator->decodeAndScale(imageInfo(), 0, buffer, 100 * 4);
123     EXPECT_EQ(2, m_frameBufferRequestCount);
124     EXPECT_EQ(0, m_decodersDestroyed);
125 }
126
127 TEST_F(ImageFrameGeneratorTest, incompleteDecodeBecomesComplete)
128 {
129     setFrameStatus(ImageFrame::FramePartial);
130
131     char buffer[100 * 100 * 4];
132     m_generator->decodeAndScale(imageInfo(), 0, buffer, 100 * 4);
133     EXPECT_EQ(1, m_frameBufferRequestCount);
134     EXPECT_EQ(0, m_decodersDestroyed);
135
136     setFrameStatus(ImageFrame::FrameComplete);
137     addNewData();
138
139     m_generator->decodeAndScale(imageInfo(), 0, buffer, 100 * 4);
140     EXPECT_EQ(2, m_frameBufferRequestCount);
141     EXPECT_EQ(1, m_decodersDestroyed);
142
143     // Decoder created again.
144     m_generator->decodeAndScale(imageInfo(), 0, buffer, 100 * 4);
145     EXPECT_EQ(3, m_frameBufferRequestCount);
146 }
147
148 static void decodeThreadMain(ImageFrameGenerator* generator)
149 {
150     char buffer[100 * 100 * 4];
151     generator->decodeAndScale(imageInfo(), 0, buffer, 100 * 4);
152 }
153
154 TEST_F(ImageFrameGeneratorTest, incompleteDecodeBecomesCompleteMultiThreaded)
155 {
156     setFrameStatus(ImageFrame::FramePartial);
157
158     char buffer[100 * 100 * 4];
159     m_generator->decodeAndScale(imageInfo(), 0, buffer, 100 * 4);
160     EXPECT_EQ(1, m_frameBufferRequestCount);
161     EXPECT_EQ(0, m_decodersDestroyed);
162
163     // LocalFrame can now be decoded completely.
164     setFrameStatus(ImageFrame::FrameComplete);
165     addNewData();
166     OwnPtr<WebThread> thread = adoptPtr(Platform::current()->createThread("DecodeThread"));
167     thread->postTask(new Task(WTF::bind(&decodeThreadMain, m_generator.get())));
168     thread.clear();
169     EXPECT_EQ(2, m_frameBufferRequestCount);
170     EXPECT_EQ(1, m_decodersDestroyed);
171
172     // Decoder created again.
173     m_generator->decodeAndScale(imageInfo(), 0, buffer, 100 * 4);
174     EXPECT_EQ(3, m_frameBufferRequestCount);
175 }
176
177 TEST_F(ImageFrameGeneratorTest, frameHasAlpha)
178 {
179     setFrameStatus(ImageFrame::FramePartial);
180
181     char buffer[100 * 100 * 4];
182     m_generator->decodeAndScale(imageInfo(), 1, buffer, 100 * 4);
183     EXPECT_TRUE(m_generator->hasAlpha(1));
184     EXPECT_EQ(1, m_frameBufferRequestCount);
185
186     ImageDecoder* tempDecoder = 0;
187     EXPECT_TRUE(ImageDecodingStore::instance()->lockDecoder(m_generator.get(), fullSize(), &tempDecoder));
188     ASSERT_TRUE(tempDecoder);
189     static_cast<MockImageDecoder*>(tempDecoder)->setFrameHasAlpha(false);
190     ImageDecodingStore::instance()->unlockDecoder(m_generator.get(), tempDecoder);
191
192     setFrameStatus(ImageFrame::FrameComplete);
193     m_generator->decodeAndScale(imageInfo(), 1, buffer, 100 * 4);
194     EXPECT_EQ(2, m_frameBufferRequestCount);
195     EXPECT_FALSE(m_generator->hasAlpha(1));
196 }
197
198 } // namespace blink