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/DeferredImageDecoder.h"
28
29#include "SkBitmapDevice.h"
30#include "SkCanvas.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>
43
44namespace blink {
45
46namespace {
47
48// Raw data for a PNG file with 1x1 white pixels.
49const 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,
60    0x42, 0x60, 0x82,
61};
62
63struct Rasterizer {
64    SkCanvas* canvas;
65    SkPicture* picture;
66};
67
68} // namespace
69
70class DeferredImageDecoderTest : public ::testing::Test, public MockImageDecoderClient {
71public:
72    virtual void SetUp() OVERRIDE
73    {
74        ImageDecodingStore::instance()->setCacheLimitInBytes(1024 * 1024);
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.get());
83        m_frameBufferRequestCount = 0;
84        m_frameCount = 1;
85        m_repetitionCount = cAnimationNone;
86        m_status = ImageFrame::FrameComplete;
87        m_frameDuration = 0;
88        m_decodedSize = m_actualDecoder->size();
89    }
90
91    virtual void TearDown() OVERRIDE
92    {
93        ImageDecodingStore::instance()->clear();
94    }
95
96    virtual void decoderBeingDestroyed() OVERRIDE
97    {
98        m_actualDecoder = 0;
99    }
100
101    virtual void frameBufferRequested() OVERRIDE
102    {
103        ++m_frameBufferRequestCount;
104    }
105
106    virtual size_t frameCount() OVERRIDE
107    {
108        return m_frameCount;
109    }
110
111    virtual int repetitionCount() const OVERRIDE
112    {
113        return m_repetitionCount;
114    }
115
116    virtual ImageFrame::Status status() OVERRIDE
117    {
118        return m_status;
119    }
120
121    virtual float frameDuration() const OVERRIDE
122    {
123        return m_frameDuration;
124    }
125
126    virtual IntSize decodedSize() const OVERRIDE
127    {
128        return m_decodedSize;
129    }
130
131protected:
132    void useMockImageDecoderFactory()
133    {
134        m_lazyDecoder->frameGenerator()->setImageDecoderFactory(MockImageDecoderFactory::create(this, m_decodedSize));
135    }
136
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;
143    size_t m_frameCount;
144    int m_repetitionCount;
145    ImageFrame::Status m_status;
146    float m_frameDuration;
147    IntSize m_decodedSize;
148};
149
150TEST_F(DeferredImageDecoderTest, drawIntoSkPicture)
151{
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());
158
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);
164
165    m_canvas->drawPicture(picture.get());
166    EXPECT_EQ(0, m_frameBufferRequestCount);
167
168    SkBitmap canvasBitmap;
169    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));
173}
174
175TEST_F(DeferredImageDecoderTest, drawIntoSkPictureProgressive)
176{
177    RefPtr<SharedBuffer> partialData = SharedBuffer::create(m_data->data(), m_data->size() - 10);
178
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.get());
187
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.get());
195
196    SkBitmap canvasBitmap;
197    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));
201}
202
203static void rasterizeMain(SkCanvas* canvas, SkPicture* picture)
204{
205    canvas->drawPicture(picture);
206}
207
208TEST_F(DeferredImageDecoderTest, decodeOnOtherThread)
209{
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());
216
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);
222
223    // Create a thread to rasterize SkPicture.
224    OwnPtr<WebThread> thread = adoptPtr(Platform::current()->createThread("RasterThread"));
225    thread->postTask(new Task(WTF::bind(&rasterizeMain, m_canvas.get(), picture.get())));
226    thread.clear();
227    EXPECT_EQ(0, m_frameBufferRequestCount);
228
229    SkBitmap canvasBitmap;
230    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));
234}
235
236TEST_F(DeferredImageDecoderTest, singleFrameImageLoading)
237{
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);
245
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);
256
257    EXPECT_EQ(secondId, m_lazyDecoder->frameBufferAtIndex(0)->getSkBitmap().getGenerationID());
258}
259
260TEST_F(DeferredImageDecoderTest, multiFrameImageLoading)
261{
262    m_repetitionCount = 10;
263    m_frameCount = 1;
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));
272
273    m_frameCount = 2;
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);
288
289    m_frameCount = 3;
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());
308}
309
310TEST_F(DeferredImageDecoderTest, decodedSize)
311{
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());
319
320    useMockImageDecoderFactory();
321
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.get());
329    EXPECT_EQ(1, m_frameBufferRequestCount);
330}
331
332TEST_F(DeferredImageDecoderTest, smallerFrameCount)
333{
334    m_frameCount = 1;
335    m_lazyDecoder->setData(*m_data, false);
336    EXPECT_EQ(m_frameCount, m_lazyDecoder->frameCount());
337    m_frameCount = 2;
338    m_lazyDecoder->setData(*m_data, false);
339    EXPECT_EQ(m_frameCount, m_lazyDecoder->frameCount());
340    m_frameCount = 0;
341    m_lazyDecoder->setData(*m_data, true);
342    EXPECT_EQ(m_frameCount, m_lazyDecoder->frameCount());
343}
344
345} // namespace blink
346