Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / WebKit / Source / platform / graphics / ImageFrameGeneratorTest.cpp
blobd42610275a0d5e9a2ef20760a7517935dbd2c14c
1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
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.
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.
26 #include "config.h"
27 #include "platform/graphics/ImageFrameGenerator.h"
29 #include "platform/SharedBuffer.h"
30 #include "platform/Task.h"
31 #include "platform/ThreadSafeFunctional.h"
32 #include "platform/graphics/ImageDecodingStore.h"
33 #include "platform/graphics/test/MockImageDecoder.h"
34 #include "public/platform/Platform.h"
35 #include "public/platform/WebThread.h"
36 #include "public/platform/WebTraceLocation.h"
37 #include <gtest/gtest.h>
39 namespace blink {
41 namespace {
43 // Helper methods to generate standard sizes.
44 SkISize fullSize() { return SkISize::Make(100, 100); }
46 SkImageInfo imageInfo()
48 return SkImageInfo::Make(100, 100, kBGRA_8888_SkColorType, kOpaque_SkAlphaType);
51 } // namespace
53 class ImageFrameGeneratorTest : public ::testing::Test, public MockImageDecoderClient {
54 public:
55 void SetUp() override
57 ImageDecodingStore::instance().setCacheLimitInBytes(1024 * 1024);
58 m_data = SharedBuffer::create();
59 m_generator = ImageFrameGenerator::create(fullSize(), m_data, false);
60 useMockImageDecoderFactory();
61 m_decodersDestroyed = 0;
62 m_decodeRequestCount = 0;
63 m_status = ImageFrame::FrameEmpty;
64 m_frameCount = 1;
67 void TearDown() override
69 ImageDecodingStore::instance().clear();
72 void decoderBeingDestroyed() override
74 ++m_decodersDestroyed;
77 void decodeRequested() override
79 ++m_decodeRequestCount;
82 ImageFrame::Status status() override
84 ImageFrame::Status currentStatus = m_status;
85 m_status = m_nextFrameStatus;
86 return currentStatus;
89 size_t frameCount() override { return m_frameCount; }
90 int repetitionCount() const override { return m_frameCount == 1 ? cAnimationNone:cAnimationLoopOnce; }
91 float frameDuration() const override { return 0; }
93 protected:
94 void useMockImageDecoderFactory()
96 m_generator->setImageDecoderFactory(MockImageDecoderFactory::create(this, fullSize()));
99 void addNewData()
101 m_data->append("g", 1);
102 m_generator->setData(m_data, false);
105 void setFrameStatus(ImageFrame::Status status) { m_status = m_nextFrameStatus = status; }
106 void setNextFrameStatus(ImageFrame::Status status) { m_nextFrameStatus = status; }
107 void setFrameCount(size_t count)
109 m_frameCount = count;
110 if (count > 1) {
111 m_generator.clear();
112 m_generator = ImageFrameGenerator::create(fullSize(), m_data, true, true);
113 useMockImageDecoderFactory();
117 RefPtr<SharedBuffer> m_data;
118 RefPtr<ImageFrameGenerator> m_generator;
119 int m_decodersDestroyed;
120 int m_decodeRequestCount;
121 ImageFrame::Status m_status;
122 ImageFrame::Status m_nextFrameStatus;
123 size_t m_frameCount;
126 TEST_F(ImageFrameGeneratorTest, incompleteDecode)
128 setFrameStatus(ImageFrame::FramePartial);
130 char buffer[100 * 100 * 4];
131 m_generator->decodeAndScale(imageInfo(), 0, buffer, 100 * 4);
132 EXPECT_EQ(1, m_decodeRequestCount);
134 addNewData();
135 m_generator->decodeAndScale(imageInfo(), 0, buffer, 100 * 4);
136 EXPECT_EQ(2, m_decodeRequestCount);
137 EXPECT_EQ(0, m_decodersDestroyed);
140 TEST_F(ImageFrameGeneratorTest, incompleteDecodeBecomesComplete)
142 setFrameStatus(ImageFrame::FramePartial);
144 char buffer[100 * 100 * 4];
145 m_generator->decodeAndScale(imageInfo(), 0, buffer, 100 * 4);
146 EXPECT_EQ(1, m_decodeRequestCount);
147 EXPECT_EQ(0, m_decodersDestroyed);
149 setFrameStatus(ImageFrame::FrameComplete);
150 addNewData();
152 m_generator->decodeAndScale(imageInfo(), 0, buffer, 100 * 4);
153 EXPECT_EQ(2, m_decodeRequestCount);
154 EXPECT_EQ(1, m_decodersDestroyed);
156 // Decoder created again.
157 m_generator->decodeAndScale(imageInfo(), 0, buffer, 100 * 4);
158 EXPECT_EQ(3, m_decodeRequestCount);
161 static void decodeThreadMain(ImageFrameGenerator* generator)
163 char buffer[100 * 100 * 4];
164 generator->decodeAndScale(imageInfo(), 0, buffer, 100 * 4);
167 TEST_F(ImageFrameGeneratorTest, incompleteDecodeBecomesCompleteMultiThreaded)
169 setFrameStatus(ImageFrame::FramePartial);
171 char buffer[100 * 100 * 4];
172 m_generator->decodeAndScale(imageInfo(), 0, buffer, 100 * 4);
173 EXPECT_EQ(1, m_decodeRequestCount);
174 EXPECT_EQ(0, m_decodersDestroyed);
176 // LocalFrame can now be decoded completely.
177 setFrameStatus(ImageFrame::FrameComplete);
178 addNewData();
179 OwnPtr<WebThread> thread = adoptPtr(Platform::current()->createThread("DecodeThread"));
180 thread->taskRunner()->postTask(FROM_HERE, new Task(threadSafeBind(&decodeThreadMain, AllowCrossThreadAccess(m_generator.get()))));
181 thread.clear();
182 EXPECT_EQ(2, m_decodeRequestCount);
183 EXPECT_EQ(1, m_decodersDestroyed);
185 // Decoder created again.
186 m_generator->decodeAndScale(imageInfo(), 0, buffer, 100 * 4);
187 EXPECT_EQ(3, m_decodeRequestCount);
190 TEST_F(ImageFrameGeneratorTest, frameHasAlpha)
192 setFrameStatus(ImageFrame::FramePartial);
194 char buffer[100 * 100 * 4];
195 m_generator->decodeAndScale(imageInfo(), 0, buffer, 100 * 4);
196 EXPECT_TRUE(m_generator->hasAlpha(0));
197 EXPECT_EQ(1, m_decodeRequestCount);
199 ImageDecoder* tempDecoder = 0;
200 EXPECT_TRUE(ImageDecodingStore::instance().lockDecoder(m_generator.get(), fullSize(), &tempDecoder));
201 ASSERT_TRUE(tempDecoder);
202 tempDecoder->frameBufferAtIndex(0)->setHasAlpha(false);
203 ImageDecodingStore::instance().unlockDecoder(m_generator.get(), tempDecoder);
204 EXPECT_EQ(2, m_decodeRequestCount);
206 setFrameStatus(ImageFrame::FrameComplete);
207 m_generator->decodeAndScale(imageInfo(), 0, buffer, 100 * 4);
208 EXPECT_EQ(3, m_decodeRequestCount);
209 EXPECT_FALSE(m_generator->hasAlpha(0));
212 TEST_F(ImageFrameGeneratorTest, removeMultiFrameDecoder)
214 setFrameCount(3);
215 setFrameStatus(ImageFrame::FrameComplete);
217 char buffer[100 * 100 * 4];
218 m_generator->decodeAndScale(imageInfo(), 0, buffer, 100 * 4);
219 EXPECT_EQ(1, m_decodeRequestCount);
220 EXPECT_EQ(0, m_decodersDestroyed);
222 setFrameStatus(ImageFrame::FrameComplete);
224 m_generator->decodeAndScale(imageInfo(), 1, buffer, 100 * 4);
225 EXPECT_EQ(2, m_decodeRequestCount);
226 EXPECT_EQ(0, m_decodersDestroyed);
228 setFrameStatus(ImageFrame::FrameComplete);
230 // Multi frame decoder should be removed.
231 m_generator->decodeAndScale(imageInfo(), 2, buffer, 100 * 4);
232 EXPECT_EQ(3, m_decodeRequestCount);
233 EXPECT_EQ(1, m_decodersDestroyed);
236 } // namespace blink