Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / WebKit / Source / platform / graphics / DeferredImageDecoderTest.cpp
bloba2fa511d493c559c5bb95232bc1a6a0a08779053
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/DeferredImageDecoder.h"
29 #include "SkBitmapDevice.h"
30 #include "SkCanvas.h"
31 #include "SkPicture.h"
32 #include "SkPictureRecorder.h"
33 #include "SkSurface.h"
34 #include "platform/SharedBuffer.h"
35 #include "platform/Task.h"
36 #include "platform/ThreadSafeFunctional.h"
37 #include "platform/graphics/ImageDecodingStore.h"
38 #include "platform/graphics/test/MockImageDecoder.h"
39 #include "public/platform/Platform.h"
40 #include "public/platform/WebThread.h"
41 #include "public/platform/WebTraceLocation.h"
42 #include "third_party/skia/include/core/SkImage.h"
43 #include "third_party/skia/include/core/SkPixmap.h"
44 #include "wtf/PassRefPtr.h"
45 #include "wtf/RefPtr.h"
46 #include <gtest/gtest.h>
48 namespace blink {
50 namespace {
52 // Raw data for a PNG file with 1x1 white pixels.
53 const unsigned char whitePNG[] = {
54 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00,
55 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x01,
56 0x00, 0x00, 0x00, 0x01, 0x08, 0x02, 0x00, 0x00, 0x00, 0x90,
57 0x77, 0x53, 0xde, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47,
58 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, 0x00, 0x09,
59 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00,
60 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00,
61 0x0c, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, 0x63, 0xf8, 0xff,
62 0xff, 0x3f, 0x00, 0x05, 0xfe, 0x02, 0xfe, 0xdc, 0xcc, 0x59,
63 0xe7, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae,
64 0x42, 0x60, 0x82,
67 struct Rasterizer {
68 SkCanvas* canvas;
69 SkPicture* picture;
72 } // namespace
74 class DeferredImageDecoderTest : public ::testing::Test, public MockImageDecoderClient {
75 public:
76 void SetUp() override
78 ImageDecodingStore::instance().setCacheLimitInBytes(1024 * 1024);
79 DeferredImageDecoder::setEnabled(true);
80 m_data = SharedBuffer::create(whitePNG, sizeof(whitePNG));
81 m_frameCount = 1;
82 OwnPtr<MockImageDecoder> decoder = MockImageDecoder::create(this);
83 m_actualDecoder = decoder.get();
84 m_actualDecoder->setSize(1, 1);
85 m_lazyDecoder = DeferredImageDecoder::createForTesting(decoder.release());
86 m_surface.reset(SkSurface::NewRasterN32Premul(100, 100));
87 ASSERT_TRUE(m_surface.get());
88 m_decodeRequestCount = 0;
89 m_repetitionCount = cAnimationNone;
90 m_status = ImageFrame::FrameComplete;
91 m_frameDuration = 0;
92 m_decodedSize = m_actualDecoder->size();
95 void TearDown() override
97 ImageDecodingStore::instance().clear();
100 void decoderBeingDestroyed() override
102 m_actualDecoder = 0;
105 void decodeRequested() override
107 ++m_decodeRequestCount;
110 size_t frameCount() override
112 return m_frameCount;
115 int repetitionCount() const override
117 return m_repetitionCount;
120 ImageFrame::Status status() override
122 return m_status;
125 float frameDuration() const override
127 return m_frameDuration;
130 IntSize decodedSize() const override
132 return m_decodedSize;
135 protected:
136 void useMockImageDecoderFactory()
138 m_lazyDecoder->frameGenerator()->setImageDecoderFactory(MockImageDecoderFactory::create(this, m_decodedSize));
141 // Don't own this but saves the pointer to query states.
142 MockImageDecoder* m_actualDecoder;
143 OwnPtr<DeferredImageDecoder> m_lazyDecoder;
144 SkAutoTUnref<SkSurface> m_surface;
145 int m_decodeRequestCount;
146 RefPtr<SharedBuffer> m_data;
147 size_t m_frameCount;
148 int m_repetitionCount;
149 ImageFrame::Status m_status;
150 float m_frameDuration;
151 IntSize m_decodedSize;
154 TEST_F(DeferredImageDecoderTest, drawIntoSkPicture)
156 m_lazyDecoder->setData(*m_data, true);
157 RefPtr<SkImage> image = m_lazyDecoder->createFrameAtIndex(0);
158 ASSERT_TRUE(image);
159 EXPECT_EQ(1, image->width());
160 EXPECT_EQ(1, image->height());
162 SkPictureRecorder recorder;
163 SkCanvas* tempCanvas = recorder.beginRecording(100, 100, 0, 0);
164 tempCanvas->drawImage(image.get(), 0, 0);
165 RefPtr<SkPicture> picture = adoptRef(recorder.endRecording());
166 EXPECT_EQ(0, m_decodeRequestCount);
168 m_surface->getCanvas()->drawPicture(picture.get());
169 EXPECT_EQ(0, m_decodeRequestCount);
171 SkBitmap canvasBitmap;
172 canvasBitmap.allocN32Pixels(100, 100);
173 ASSERT_TRUE(m_surface->getCanvas()->readPixels(&canvasBitmap, 0, 0));
174 SkAutoLockPixels autoLock(canvasBitmap);
175 EXPECT_EQ(SkColorSetARGB(255, 255, 255, 255), canvasBitmap.getColor(0, 0));
178 TEST_F(DeferredImageDecoderTest, drawIntoSkPictureProgressive)
180 RefPtr<SharedBuffer> partialData = SharedBuffer::create(m_data->data(), m_data->size() - 10);
182 // Received only half the file.
183 m_lazyDecoder->setData(*partialData, false);
184 RefPtr<SkImage> image = m_lazyDecoder->createFrameAtIndex(0);
185 ASSERT_TRUE(image);
186 SkPictureRecorder recorder;
187 SkCanvas* tempCanvas = recorder.beginRecording(100, 100, 0, 0);
188 tempCanvas->drawImage(image.get(), 0, 0);
189 RefPtr<SkPicture> picture = adoptRef(recorder.endRecording());
190 m_surface->getCanvas()->drawPicture(picture.get());
192 // Fully received the file and draw the SkPicture again.
193 m_lazyDecoder->setData(*m_data, true);
194 image = m_lazyDecoder->createFrameAtIndex(0);
195 ASSERT_TRUE(image);
196 tempCanvas = recorder.beginRecording(100, 100, 0, 0);
197 tempCanvas->drawImage(image.get(), 0, 0);
198 picture = adoptRef(recorder.endRecording());
199 m_surface->getCanvas()->drawPicture(picture.get());
201 SkBitmap canvasBitmap;
202 canvasBitmap.allocN32Pixels(100, 100);
203 ASSERT_TRUE(m_surface->getCanvas()->readPixels(&canvasBitmap, 0, 0));
204 SkAutoLockPixels autoLock(canvasBitmap);
205 EXPECT_EQ(SkColorSetARGB(255, 255, 255, 255), canvasBitmap.getColor(0, 0));
208 static void rasterizeMain(SkCanvas* canvas, SkPicture* picture)
210 canvas->drawPicture(picture);
213 TEST_F(DeferredImageDecoderTest, decodeOnOtherThread)
215 m_lazyDecoder->setData(*m_data, true);
216 RefPtr<SkImage> image = m_lazyDecoder->createFrameAtIndex(0);
217 ASSERT_TRUE(image);
218 EXPECT_EQ(1, image->width());
219 EXPECT_EQ(1, image->height());
221 SkPictureRecorder recorder;
222 SkCanvas* tempCanvas = recorder.beginRecording(100, 100, 0, 0);
223 tempCanvas->drawImage(image.get(), 0, 0);
224 RefPtr<SkPicture> picture = adoptRef(recorder.endRecording());
225 EXPECT_EQ(0, m_decodeRequestCount);
227 // Create a thread to rasterize SkPicture.
228 OwnPtr<WebThread> thread = adoptPtr(Platform::current()->createThread("RasterThread"));
229 thread->taskRunner()->postTask(FROM_HERE, new Task(threadSafeBind(&rasterizeMain, AllowCrossThreadAccess(m_surface->getCanvas()), AllowCrossThreadAccess(picture.get()))));
230 thread.clear();
231 EXPECT_EQ(0, m_decodeRequestCount);
233 SkBitmap canvasBitmap;
234 canvasBitmap.allocN32Pixels(100, 100);
235 ASSERT_TRUE(m_surface->getCanvas()->readPixels(&canvasBitmap, 0, 0));
236 SkAutoLockPixels autoLock(canvasBitmap);
237 EXPECT_EQ(SkColorSetARGB(255, 255, 255, 255), canvasBitmap.getColor(0, 0));
240 TEST_F(DeferredImageDecoderTest, singleFrameImageLoading)
242 m_status = ImageFrame::FramePartial;
243 m_lazyDecoder->setData(*m_data, false);
244 EXPECT_FALSE(m_lazyDecoder->frameIsCompleteAtIndex(0));
245 RefPtr<SkImage> image = m_lazyDecoder->createFrameAtIndex(0);
246 ASSERT_TRUE(image);
247 unsigned firstId = image->uniqueID();
248 EXPECT_FALSE(m_lazyDecoder->frameIsCompleteAtIndex(0));
249 EXPECT_TRUE(m_actualDecoder);
251 m_status = ImageFrame::FrameComplete;
252 m_data->append(" ", 1);
253 m_lazyDecoder->setData(*m_data, true);
254 EXPECT_FALSE(m_actualDecoder);
255 EXPECT_TRUE(m_lazyDecoder->frameIsCompleteAtIndex(0));
257 image = m_lazyDecoder->createFrameAtIndex(0);
258 ASSERT_TRUE(image);
259 unsigned secondId = image->uniqueID();
260 EXPECT_FALSE(m_decodeRequestCount);
261 EXPECT_NE(firstId, secondId);
264 TEST_F(DeferredImageDecoderTest, multiFrameImageLoading)
266 m_repetitionCount = 10;
267 m_frameCount = 1;
268 m_frameDuration = 10;
269 m_status = ImageFrame::FramePartial;
270 m_lazyDecoder->setData(*m_data, false);
272 RefPtr<SkImage> image = m_lazyDecoder->createFrameAtIndex(0);
273 ASSERT_TRUE(image);
274 unsigned firstId = image->uniqueID();
275 EXPECT_FALSE(m_lazyDecoder->frameIsCompleteAtIndex(0));
276 EXPECT_EQ(10.0f, m_lazyDecoder->frameDurationAtIndex(0));
278 m_frameCount = 2;
279 m_frameDuration = 20;
280 m_status = ImageFrame::FrameComplete;
281 m_data->append(" ", 1);
282 m_lazyDecoder->setData(*m_data, false);
284 image = m_lazyDecoder->createFrameAtIndex(0);
285 ASSERT_TRUE(image);
286 unsigned secondId = image->uniqueID();
287 EXPECT_NE(firstId, secondId);
288 EXPECT_TRUE(m_lazyDecoder->frameIsCompleteAtIndex(0));
289 EXPECT_TRUE(m_lazyDecoder->frameIsCompleteAtIndex(1));
290 EXPECT_EQ(20.0f, m_lazyDecoder->frameDurationAtIndex(1));
291 EXPECT_TRUE(m_actualDecoder);
293 m_frameCount = 3;
294 m_frameDuration = 30;
295 m_status = ImageFrame::FrameComplete;
296 m_lazyDecoder->setData(*m_data, true);
297 EXPECT_FALSE(m_actualDecoder);
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, m_lazyDecoder->repetitionCount());
307 TEST_F(DeferredImageDecoderTest, decodedSize)
309 m_decodedSize = IntSize(22, 33);
310 m_lazyDecoder->setData(*m_data, true);
311 RefPtr<SkImage> image = m_lazyDecoder->createFrameAtIndex(0);
312 ASSERT_TRUE(image);
313 EXPECT_EQ(m_decodedSize.width(), image->width());
314 EXPECT_EQ(m_decodedSize.height(), image->height());
316 useMockImageDecoderFactory();
318 // The following code should not fail any assert.
319 SkPictureRecorder recorder;
320 SkCanvas* tempCanvas = recorder.beginRecording(100, 100, 0, 0);
321 tempCanvas->drawImage(image.get(), 0, 0);
322 RefPtr<SkPicture> picture = adoptRef(recorder.endRecording());
323 EXPECT_EQ(0, m_decodeRequestCount);
324 m_surface->getCanvas()->drawPicture(picture.get());
325 EXPECT_EQ(1, m_decodeRequestCount);
328 TEST_F(DeferredImageDecoderTest, smallerFrameCount)
330 m_frameCount = 1;
331 m_lazyDecoder->setData(*m_data, false);
332 EXPECT_EQ(m_frameCount, m_lazyDecoder->frameCount());
333 m_frameCount = 2;
334 m_lazyDecoder->setData(*m_data, false);
335 EXPECT_EQ(m_frameCount, m_lazyDecoder->frameCount());
336 m_frameCount = 0;
337 m_lazyDecoder->setData(*m_data, true);
338 EXPECT_EQ(m_frameCount, m_lazyDecoder->frameCount());
341 TEST_F(DeferredImageDecoderTest, frameOpacity)
343 OwnPtr<ImageDecoder> actualDecoder = ImageDecoder::create(*m_data,
344 ImageDecoder::AlphaPremultiplied, ImageDecoder::GammaAndColorProfileApplied);
345 OwnPtr<DeferredImageDecoder> decoder = DeferredImageDecoder::createForTesting(actualDecoder.release());
346 decoder->setData(*m_data, true);
348 SkImageInfo pixInfo = SkImageInfo::MakeN32Premul(1, 1);
349 SkAutoPixmapStorage pixels;
350 pixels.alloc(pixInfo);
352 // Before decoding, the frame is not known to be opaque.
353 RefPtr<SkImage> frame = decoder->createFrameAtIndex(0);
354 ASSERT_TRUE(frame);
355 EXPECT_FALSE(frame->isOpaque());
357 // Force a lazy decode by reading pixels.
358 EXPECT_TRUE(frame->readPixels(pixels, 0, 0));
360 // After decoding, the frame is known to be opaque.
361 frame = decoder->createFrameAtIndex(0);
362 ASSERT_TRUE(frame);
363 EXPECT_TRUE(frame->isOpaque());
365 // Re-generating the opaque-marked frame should not fail.
366 EXPECT_TRUE(frame->readPixels(pixels, 0, 0));
369 } // namespace blink