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
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.
27 #include "platform/graphics/DeferredImageDecoder.h"
29 #include "SkBitmapDevice.h"
31 #include "SkPicture.h"
32 #include "SkPictureRecorder.h"
33 #include "platform/SharedBuffer.h"
34 #include "platform/Task.h"
35 #include "platform/graphics/ImageDecodingStore.h"
36 #include "platform/graphics/skia/NativeImageSkia.h"
37 #include "platform/graphics/test/MockImageDecoder.h"
38 #include "public/platform/Platform.h"
39 #include "public/platform/WebThread.h"
40 #include "wtf/PassRefPtr.h"
41 #include "wtf/RefPtr.h"
42 #include <gtest/gtest.h>
48 // Raw data for a PNG file with 1x1 white pixels.
49 const unsigned char whitePNG[] = {
50 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00,
51 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x01,
52 0x00, 0x00, 0x00, 0x01, 0x08, 0x02, 0x00, 0x00, 0x00, 0x90,
53 0x77, 0x53, 0xde, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47,
54 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, 0x00, 0x09,
55 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00,
56 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00,
57 0x0c, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, 0x63, 0xf8, 0xff,
58 0xff, 0x3f, 0x00, 0x05, 0xfe, 0x02, 0xfe, 0xdc, 0xcc, 0x59,
59 0xe7, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae,
70 class DeferredImageDecoderTest : public ::testing::Test, public MockImageDecoderClient {
72 virtual void SetUp() OVERRIDE
74 ImageDecodingStore::initializeOnce();
75 DeferredImageDecoder::setEnabled(true);
76 m_data = SharedBuffer::create(whitePNG, sizeof(whitePNG));
77 OwnPtr<MockImageDecoder> decoder = MockImageDecoder::create(this);
78 m_actualDecoder = decoder.get();
79 m_actualDecoder->setSize(1, 1);
80 m_lazyDecoder = DeferredImageDecoder::createForTesting(decoder.release());
81 m_canvas.reset(SkCanvas::NewRasterN32(100, 100));
82 ASSERT_TRUE(m_canvas);
83 m_frameBufferRequestCount = 0;
85 m_repetitionCount = cAnimationNone;
86 m_status = ImageFrame::FrameComplete;
88 m_decodedSize = m_actualDecoder->size();
91 virtual void TearDown() OVERRIDE
93 ImageDecodingStore::shutdown();
96 virtual void decoderBeingDestroyed() OVERRIDE
101 virtual void frameBufferRequested() OVERRIDE
103 ++m_frameBufferRequestCount;
106 virtual size_t frameCount() OVERRIDE
111 virtual int repetitionCount() const OVERRIDE
113 return m_repetitionCount;
116 virtual ImageFrame::Status status() OVERRIDE
121 virtual float frameDuration() const OVERRIDE
123 return m_frameDuration;
126 virtual IntSize decodedSize() const OVERRIDE
128 return m_decodedSize;
132 void useMockImageDecoderFactory()
134 m_lazyDecoder->frameGenerator()->setImageDecoderFactory(MockImageDecoderFactory::create(this, m_decodedSize));
137 // Don't own this but saves the pointer to query states.
138 MockImageDecoder* m_actualDecoder;
139 OwnPtr<DeferredImageDecoder> m_lazyDecoder;
140 SkAutoTUnref<SkCanvas> m_canvas;
141 int m_frameBufferRequestCount;
142 RefPtr<SharedBuffer> m_data;
144 int m_repetitionCount;
145 ImageFrame::Status m_status;
146 float m_frameDuration;
147 IntSize m_decodedSize;
150 TEST_F(DeferredImageDecoderTest, drawIntoSkPicture)
152 m_lazyDecoder->setData(*m_data, true);
153 RefPtr<NativeImageSkia> image = m_lazyDecoder->frameBufferAtIndex(0)->asNewNativeImage();
154 EXPECT_EQ(1, image->bitmap().width());
155 EXPECT_EQ(1, image->bitmap().height());
156 EXPECT_FALSE(image->bitmap().isNull());
157 EXPECT_TRUE(image->bitmap().isImmutable());
159 SkPictureRecorder recorder;
160 SkCanvas* tempCanvas = recorder.beginRecording(100, 100, 0, 0);
161 tempCanvas->drawBitmap(image->bitmap(), 0, 0);
162 RefPtr<SkPicture> picture = adoptRef(recorder.endRecording());
163 EXPECT_EQ(0, m_frameBufferRequestCount);
165 m_canvas->drawPicture(*picture);
166 EXPECT_EQ(0, m_frameBufferRequestCount);
168 SkBitmap canvasBitmap;
169 ASSERT_TRUE(canvasBitmap.allocN32Pixels(100, 100));
170 ASSERT_TRUE(m_canvas->readPixels(&canvasBitmap, 0, 0));
171 SkAutoLockPixels autoLock(canvasBitmap);
172 EXPECT_EQ(SkColorSetARGB(255, 255, 255, 255), canvasBitmap.getColor(0, 0));
175 TEST_F(DeferredImageDecoderTest, drawIntoSkPictureProgressive)
177 RefPtr<SharedBuffer> partialData = SharedBuffer::create(m_data->data(), m_data->size() - 10);
179 // Received only half the file.
180 m_lazyDecoder->setData(*partialData, false);
181 RefPtr<NativeImageSkia> image = m_lazyDecoder->frameBufferAtIndex(0)->asNewNativeImage();
182 SkPictureRecorder recorder;
183 SkCanvas* tempCanvas = recorder.beginRecording(100, 100, 0, 0);
184 tempCanvas->drawBitmap(image->bitmap(), 0, 0);
185 RefPtr<SkPicture> picture = adoptRef(recorder.endRecording());
186 m_canvas->drawPicture(*picture);
188 // Fully received the file and draw the SkPicture again.
189 m_lazyDecoder->setData(*m_data, true);
190 image = m_lazyDecoder->frameBufferAtIndex(0)->asNewNativeImage();
191 tempCanvas = recorder.beginRecording(100, 100, 0, 0);
192 tempCanvas->drawBitmap(image->bitmap(), 0, 0);
193 picture = adoptRef(recorder.endRecording());
194 m_canvas->drawPicture(*picture);
196 SkBitmap canvasBitmap;
197 ASSERT_TRUE(canvasBitmap.allocN32Pixels(100, 100));
198 ASSERT_TRUE(m_canvas->readPixels(&canvasBitmap, 0, 0));
199 SkAutoLockPixels autoLock(canvasBitmap);
200 EXPECT_EQ(SkColorSetARGB(255, 255, 255, 255), canvasBitmap.getColor(0, 0));
203 static void rasterizeMain(SkCanvas* canvas, SkPicture* picture)
205 canvas->drawPicture(*picture);
208 TEST_F(DeferredImageDecoderTest, decodeOnOtherThread)
210 m_lazyDecoder->setData(*m_data, true);
211 RefPtr<NativeImageSkia> image = m_lazyDecoder->frameBufferAtIndex(0)->asNewNativeImage();
212 EXPECT_EQ(1, image->bitmap().width());
213 EXPECT_EQ(1, image->bitmap().height());
214 EXPECT_FALSE(image->bitmap().isNull());
215 EXPECT_TRUE(image->bitmap().isImmutable());
217 SkPictureRecorder recorder;
218 SkCanvas* tempCanvas = recorder.beginRecording(100, 100, 0, 0);
219 tempCanvas->drawBitmap(image->bitmap(), 0, 0);
220 RefPtr<SkPicture> picture = adoptRef(recorder.endRecording());
221 EXPECT_EQ(0, m_frameBufferRequestCount);
223 // Create a thread to rasterize SkPicture.
224 OwnPtr<blink::WebThread> thread = adoptPtr(blink::Platform::current()->createThread("RasterThread"));
225 thread->postTask(new Task(WTF::bind(&rasterizeMain, m_canvas.get(), picture.get())));
227 EXPECT_EQ(0, m_frameBufferRequestCount);
229 SkBitmap canvasBitmap;
230 ASSERT_TRUE(canvasBitmap.allocN32Pixels(100, 100));
231 ASSERT_TRUE(m_canvas->readPixels(&canvasBitmap, 0, 0));
232 SkAutoLockPixels autoLock(canvasBitmap);
233 EXPECT_EQ(SkColorSetARGB(255, 255, 255, 255), canvasBitmap.getColor(0, 0));
236 TEST_F(DeferredImageDecoderTest, singleFrameImageLoading)
238 m_status = ImageFrame::FramePartial;
239 m_lazyDecoder->setData(*m_data, false);
240 EXPECT_FALSE(m_lazyDecoder->frameIsCompleteAtIndex(0));
241 ImageFrame* frame = m_lazyDecoder->frameBufferAtIndex(0);
242 unsigned firstId = frame->getSkBitmap().getGenerationID();
243 EXPECT_EQ(ImageFrame::FramePartial, frame->status());
244 EXPECT_TRUE(m_actualDecoder);
246 m_status = ImageFrame::FrameComplete;
247 m_data->append(" ", 1);
248 m_lazyDecoder->setData(*m_data, true);
249 EXPECT_FALSE(m_actualDecoder);
250 EXPECT_TRUE(m_lazyDecoder->frameIsCompleteAtIndex(0));
251 frame = m_lazyDecoder->frameBufferAtIndex(0);
252 unsigned secondId = frame->getSkBitmap().getGenerationID();
253 EXPECT_EQ(ImageFrame::FrameComplete, frame->status());
254 EXPECT_FALSE(m_frameBufferRequestCount);
255 EXPECT_NE(firstId, secondId);
257 EXPECT_EQ(secondId, m_lazyDecoder->frameBufferAtIndex(0)->getSkBitmap().getGenerationID());
260 TEST_F(DeferredImageDecoderTest, multiFrameImageLoading)
262 m_repetitionCount = 10;
264 m_frameDuration = 10;
265 m_status = ImageFrame::FramePartial;
266 m_lazyDecoder->setData(*m_data, false);
267 EXPECT_EQ(ImageFrame::FramePartial, m_lazyDecoder->frameBufferAtIndex(0)->status());
268 unsigned firstId = m_lazyDecoder->frameBufferAtIndex(0)->getSkBitmap().getGenerationID();
269 EXPECT_FALSE(m_lazyDecoder->frameIsCompleteAtIndex(0));
270 EXPECT_EQ(10.0f, m_lazyDecoder->frameBufferAtIndex(0)->duration());
271 EXPECT_EQ(10.0f, m_lazyDecoder->frameDurationAtIndex(0));
274 m_frameDuration = 20;
275 m_status = ImageFrame::FrameComplete;
276 m_data->append(" ", 1);
277 m_lazyDecoder->setData(*m_data, false);
278 EXPECT_EQ(ImageFrame::FrameComplete, m_lazyDecoder->frameBufferAtIndex(0)->status());
279 EXPECT_EQ(ImageFrame::FrameComplete, m_lazyDecoder->frameBufferAtIndex(1)->status());
280 unsigned secondId = m_lazyDecoder->frameBufferAtIndex(0)->getSkBitmap().getGenerationID();
281 EXPECT_NE(firstId, secondId);
282 EXPECT_TRUE(m_lazyDecoder->frameIsCompleteAtIndex(0));
283 EXPECT_TRUE(m_lazyDecoder->frameIsCompleteAtIndex(1));
284 EXPECT_EQ(20.0f, m_lazyDecoder->frameDurationAtIndex(1));
285 EXPECT_EQ(10.0f, m_lazyDecoder->frameBufferAtIndex(0)->duration());
286 EXPECT_EQ(20.0f, m_lazyDecoder->frameBufferAtIndex(1)->duration());
287 EXPECT_TRUE(m_actualDecoder);
290 m_frameDuration = 30;
291 m_status = ImageFrame::FrameComplete;
292 m_lazyDecoder->setData(*m_data, true);
293 EXPECT_FALSE(m_actualDecoder);
294 EXPECT_EQ(ImageFrame::FrameComplete, m_lazyDecoder->frameBufferAtIndex(0)->status());
295 EXPECT_EQ(ImageFrame::FrameComplete, m_lazyDecoder->frameBufferAtIndex(1)->status());
296 EXPECT_EQ(ImageFrame::FrameComplete, m_lazyDecoder->frameBufferAtIndex(2)->status());
297 EXPECT_EQ(secondId, m_lazyDecoder->frameBufferAtIndex(0)->getSkBitmap().getGenerationID());
298 EXPECT_TRUE(m_lazyDecoder->frameIsCompleteAtIndex(0));
299 EXPECT_TRUE(m_lazyDecoder->frameIsCompleteAtIndex(1));
300 EXPECT_TRUE(m_lazyDecoder->frameIsCompleteAtIndex(2));
301 EXPECT_EQ(10.0f, m_lazyDecoder->frameDurationAtIndex(0));
302 EXPECT_EQ(20.0f, m_lazyDecoder->frameDurationAtIndex(1));
303 EXPECT_EQ(30.0f, m_lazyDecoder->frameDurationAtIndex(2));
304 EXPECT_EQ(10.0f, m_lazyDecoder->frameBufferAtIndex(0)->duration());
305 EXPECT_EQ(20.0f, m_lazyDecoder->frameBufferAtIndex(1)->duration());
306 EXPECT_EQ(30.0f, m_lazyDecoder->frameBufferAtIndex(2)->duration());
307 EXPECT_EQ(10, m_lazyDecoder->repetitionCount());
310 TEST_F(DeferredImageDecoderTest, decodedSize)
312 m_decodedSize = IntSize(22, 33);
313 m_lazyDecoder->setData(*m_data, true);
314 RefPtr<NativeImageSkia> image = m_lazyDecoder->frameBufferAtIndex(0)->asNewNativeImage();
315 EXPECT_EQ(m_decodedSize.width(), image->bitmap().width());
316 EXPECT_EQ(m_decodedSize.height(), image->bitmap().height());
317 EXPECT_FALSE(image->bitmap().isNull());
318 EXPECT_TRUE(image->bitmap().isImmutable());
320 useMockImageDecoderFactory();
322 // The following code should not fail any assert.
323 SkPictureRecorder recorder;
324 SkCanvas* tempCanvas = recorder.beginRecording(100, 100, 0, 0);
325 tempCanvas->drawBitmap(image->bitmap(), 0, 0);
326 RefPtr<SkPicture> picture = adoptRef(recorder.endRecording());
327 EXPECT_EQ(0, m_frameBufferRequestCount);
328 m_canvas->drawPicture(*picture);
329 EXPECT_EQ(1, m_frameBufferRequestCount);
332 TEST_F(DeferredImageDecoderTest, smallerFrameCount)
335 m_lazyDecoder->setData(*m_data, false);
336 EXPECT_EQ(m_frameCount, m_lazyDecoder->frameCount());
338 m_lazyDecoder->setData(*m_data, false);
339 EXPECT_EQ(m_frameCount, m_lazyDecoder->frameCount());
341 m_lazyDecoder->setData(*m_data, true);
342 EXPECT_EQ(m_frameCount, m_lazyDecoder->frameCount());
345 } // namespace WebCore